Install
$ agentstack add mcp-leanmcp-leanmcp-sdk ✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ● Network access Used
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ● Environment & secrets Used
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
Verified badge
Passed review? Show it. Paste this badge into your README, it links to the public security report.
Reliability & compatibility
Declared compatibility
Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.
We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.
How agent discovery & health will work →About
LeanMCP SDK: Production-Ready Infra for MCP Servers.
Build and Deploy Scalable MCP Servers with Full Backend Capabilities
Production-grade support:
✅ Authentication ✅ Multi-tenant isolation ✅ Request logging ✅ Observability & Monitoring ✅ Private Cloud deployment
Ideal for teams building:
- Agent platforms
- Customer-facing intelligent workflows
- Multi-tenant SaaS AI systems
Links
- Docs: https://docs.leanmcp.com
- Build & Deploy: https://ship.leanmcp.com
- Observability Platform: https://app.leanmcp.com
- npm packages: https://www.npmjs.com/search?q=%40leanmcp
- GitHub org: https://github.com/LeanMCP
Thanks for your Interest !
If you're:
- An Infra / AI / DevTool developer — you're warmly welcome to contribute ideas or code.
- Building your own Agent platform — reach out for enterprise-grade deployment support.
For partnerships & business inquiries: founders@leanmcp.com
If you find this project valuable, please consider giving us a GitHub star 🌟 !
Table of Contents
- [Quick Start](#quick-start)
- [Installation & Packages](#installation--packages)
- [Core Concepts](#core-concepts)
- [Common Patterns](#common-patterns)
- [Detailed Reference](#detailed-reference)
- [CLI Commands](#cli-commands)
- [Decorators](#decorators)
- [Project Structure](#project-structure)
- [API Reference](#api-reference)
- [Examples](#examples)
- [Development](#development)
- [Contributing](#contributing)
- [Business Collaboration](#business-collaboration-what-can-we-do-for-you)
Quick Start
1. Create a new project
npx @leanmcp/cli create my-mcp-server
cd my-mcp-server
npm install
This generates a clean project structure:
my-mcp-server/
├── main.ts # Entry point with HTTP server
├── package.json # Dependencies
├── tsconfig.json # TypeScript config
└── mcp/ # Services directory
└── example/
└── index.ts # Example service
2. Define your service
The generated mcp/example/index.ts shows class-based schema validation:
import { Tool, Optional, SchemaConstraint } from "@leanmcp/core";
// Define input schema as a TypeScript class
class AnalyzeSentimentInput {
@SchemaConstraint({
description: 'Text to analyze',
minLength: 1
})
text!: string;
@Optional()
@SchemaConstraint({
description: 'Language code',
enum: ['en', 'es', 'fr', 'de'],
default: 'en'
})
language?: string;
}
// Define output schema
class AnalyzeSentimentOutput {
@SchemaConstraint({ enum: ['positive', 'negative', 'neutral'] })
sentiment!: string;
@SchemaConstraint({ minimum: -1, maximum: 1 })
score!: number;
@SchemaConstraint({ minimum: 0, maximum: 1 })
confidence!: number;
}
export class SentimentService {
@Tool({
description: 'Analyze sentiment of text',
inputClass: AnalyzeSentimentInput
})
async analyzeSentiment(args: AnalyzeSentimentInput): Promise {
const sentiment = this.detectSentiment(args.text);
return {
sentiment: sentiment > 0 ? 'positive' : sentiment {
if (positiveWords.includes(word)) score += 0.3;
if (negativeWords.includes(word)) score -= 0.3;
});
return Math.max(-1, Math.min(1, score));
}
}
3. Run your server
npm start
Your MCP server starts on http://localhost:8080 with:
- HTTP endpoint:
http://localhost:8080/mcp - Health check:
http://localhost:8080/health
Installation & Packages
LeanMCP is modular. Start with the core packages, then add capabilities as needed.
Required for every MCP server
| Package | Purpose | Install | | ------- | ------- | ------- | | @leanmcp/cli | Project scaffolding and local dev / deploy workflow | npm install -g @leanmcp/cli or npx @leanmcp/cli | | @leanmcp/core | MCP server runtime, decorators, schema validation | npm install @leanmcp/core |
Optional capability packages
| Package | Purpose | When to use | Install | | ------- | ------- | ----------- | ------- | | @leanmcp/auth | Authentication and access control | Real users, permissions, multi-user MCP servers | npm install @leanmcp/auth | | @leanmcp/elicitation | Structured user input during execution | Tools need guided or multi-step input | npm install @leanmcp/elicitation | | @leanmcp/ui | UI components for MCP Apps | Interactive MCP experiences (advanced) | npm install @leanmcp/ui | | @leanmcp/env-injection | Request-scoped environment / secret injection | Multi-tenant secrets, per-request config | npm install @leanmcp/env-injection | | @leanmcp/utils | Shared utilities | Extending or building on LeanMCP internals | npm install @leanmcp/utils |
Global CLI Installation
npm install -g @leanmcp/cli
Project-Level Installation
npm install @leanmcp/core
npm install --save-dev @leanmcp/cli
Core Concepts (Click to expand)
Tools
Callable functions that perform actions (like API endpoints).
class AddInput {
@SchemaConstraint({ description: 'First number' })
a!: number;
@SchemaConstraint({ description: 'Second number' })
b!: number;
}
@Tool({
description: 'Calculate sum of two numbers',
inputClass: AddInput
})
async add(input: AddInput): Promise {
return { result: input.a + input.b };
}
// Tool name: "add" (from function name)
Prompts
Reusable prompt templates for LLM interactions.
@Prompt({ description: 'Generate a greeting prompt' })
greetingPrompt(args: { name?: string }) {
return {
messages: [{
role: 'user',
content: { type: 'text', text: `Say hello to ${args.name || 'there'}!` }
}]
};
}
// Prompt name: "greetingPrompt" (from function name)
Resources
Data endpoints that provide information (like REST GET endpoints).
@Resource({ description: 'Service statistics' })
getStats() {
return {
uptime: process.uptime(),
requestCount: 1523
};
}
// Resource URI: "servicename://getStats" (auto-generated)
Common Patterns (Click to expand)
Define a tool
@tool("search_docs")
async searchDocs(query: string) {
return await this.vectorStore.search(query)
}
Require authentication
@requireAuth()
@tool("get_user_data")
async getUserData() {
...
}
Ask for structured input
const input = await elicit({
type: "form",
fields: [...]
})
These snippets show common patterns only. Full API details live in the documentation.
Detailed Reference
CLI Commands (Click to expand)
The LeanMCP CLI provides an interactive experience for creating and managing MCP projects.
leanmcp create
Creates a new MCP server project with interactive setup:
leanmcp create my-mcp-server
Interactive prompts:
- Auto-install dependencies (optional)
- Start dev server after creation (optional)
Generated structure:
my-mcp-server/
├── main.ts # Entry point with HTTP server
├── package.json # Project dependencies
├── tsconfig.json # TypeScript configuration
├── .gitignore # Git ignore rules
├── .dockerignore # Docker ignore rules
├── .env # Environment variables
├── .env.local # Local overrides
└── mcp/ # Services directory
└── example/
└── index.ts # Example service
leanmcp add
Adds a new service to an existing project with auto-registration:
leanmcp add weather
What it does:
- Creates
mcp/weather/index.tswith boilerplate (Tool, Prompt, Resource examples) - Auto-registers the service in
main.ts - Ready to customize and use immediately
More CLI Features
For complete CLI documentation including all commands, options, and advanced usage, see [@leanmcp/cli README](./packages/cli/README.md).
Decorators (Click to expand)
Core Decorators
| Decorator | Purpose | Usage | |-----------|---------|-------| | @Tool | Callable function | @Tool({ description?: string, inputClass?: Class }) | | @Prompt | Prompt template | @Prompt({ description?: string }) | | @Resource | Data endpoint | @Resource({ description?: string }) |
Schema Decorators
| Decorator | Purpose | Usage | |-----------|---------|-------| | @Optional | Mark property as optional | Property decorator | | @SchemaConstraint | Add validation rules | Property decorator with constraints |
Available Constraints:
- String:
minLength,maxLength,pattern,enum,format,description,default - Number:
minimum,maximum,description,default - Array:
minItems,maxItems,description - Common:
description,default
Example:
class UserInput {
@SchemaConstraint({
description: 'User email address',
format: 'email'
})
email!: string;
@Optional()
@SchemaConstraint({
description: 'User age',
minimum: 18,
maximum: 120
})
age?: number;
@SchemaConstraint({
description: 'User roles',
enum: ['admin', 'user', 'guest'],
default: 'user'
})
role!: string;
}
Project Structure (Click to expand)
Main Entry Point (main.ts)
Simplified API (Recommended):
import { createHTTPServer } from "@leanmcp/core";
// Services are automatically discovered from ./mcp directory
await createHTTPServer({
name: "my-mcp-server",
version: "1.0.0",
port: 8080,
cors: true,
logging: true
});
Factory Pattern (Advanced):
import { createHTTPServer, MCPServer } from "@leanmcp/core";
import { ExampleService } from "./mcp/example/index.js";
const serverFactory = async () => {
const server = new MCPServer({
name: "my-mcp-server",
version: "1.0.0",
autoDiscover: false
});
server.registerService(new ExampleService());
return server.getServer();
};
await createHTTPServer(serverFactory, {
port: 8080,
cors: true
});
Service Structure (mcp/service-name/index.ts)
import { Tool, Prompt, Resource } from "@leanmcp/core";
class ToolInput {
@SchemaConstraint({ description: 'Input parameter' })
param!: string;
}
export class ServiceName {
@Tool({
description: 'Tool description',
inputClass: ToolInput
})
async toolMethod(args: ToolInput) {
// Tool implementation
return { result: 'success' };
}
@Prompt({ description: 'Prompt description' })
promptMethod(args: { param?: string }) {
// Prompt implementation
return {
messages: [{
role: 'user',
content: { type: 'text', text: 'Prompt text' }
}]
};
}
@Resource({ description: 'Resource description' })
resourceMethod() {
// Resource implementation
return { data: 'value' };
}
}
API Reference (Click to expand)
createHTTPServer(options | serverFactory, options?)
Creates and starts an HTTP server with MCP support.
Simplified API (Recommended):
await createHTTPServer({
name: string; // Server name (required)
version: string; // Server version (required)
port?: number; // Port number (default: 3001)
cors?: boolean | object; // Enable CORS (default: false)
logging?: boolean; // Enable logging (default: false)
debug?: boolean; // Enable debug logs (default: false)
autoDiscover?: boolean; // Auto-discover services (default: true)
mcpDir?: string; // Custom mcp directory path (optional)
sessionTimeout?: number; // Session timeout in ms (optional)
});
Example:
import { createHTTPServer } from "@leanmcp/core";
// Services automatically discovered from ./mcp directory
await createHTTPServer({
name: "my-mcp-server",
version: "1.0.0",
port: 3000,
cors: true,
logging: true
});
Factory Pattern (Advanced):
import { createHTTPServer, MCPServer } from "@leanmcp/core";
import { MyService } from "./mcp/myservice/index.js";
const serverFactory = async () => {
const server = new MCPServer({
name: "my-mcp-server",
version: "1.0.0",
autoDiscover: false
});
server.registerService(new MyService());
return server.getServer();
};
await createHTTPServer(serverFactory, {
port: 3000,
cors: true
});
MCPServer
Main server class for manual service registration.
Constructor Options:
const server = new MCPServer({
name: string; // Server name (required)
version: string; // Server version (required)
logging?: boolean; // Enable logging (default: false)
debug?: boolean; // Enable debug logs (default: false)
autoDiscover?: boolean; // Auto-discover services (default: true)
mcpDir?: string; // Custom mcp directory path (optional)
});
Methods:
registerService(instance)- Manually register a service instancegetServer()- Get the underlying MCP SDK server
Example:
import { MCPServer } from "@leanmcp/core";
const server = new MCPServer({
name: "my-server",
version: "1.0.0",
autoDiscover: false
});
server.registerService(new WeatherService());
server.registerService(new PaymentService());
Examples (Click to expand)
Complete Weather Service
import { Tool, Prompt, Resource, SchemaConstraint, Optional } from "@leanmcp/core";
class WeatherInput {
@SchemaConstraint({
description: 'City name',
minLength: 1
})
city!: string;
@Optional()
@SchemaConstraint({
description: 'Units',
enum: ['metric', 'imperial'],
default: 'metric'
})
units?: string;
}
class WeatherOutput {
@SchemaConstraint({ description: 'Temperature value' })
temperature!: number;
@SchemaConstraint({
description: 'Weather conditions',
enum: ['sunny', 'cloudy', 'rainy', 'snowy']
})
conditions!: string;
@SchemaConstraint({
description: 'Humidity percentage',
minimum: 0,
maximum: 100
})
humidity!: number;
}
export class WeatherService {
@Tool({
description: 'Get current weather for a city',
inputClass: WeatherInput
})
async getCurrentWeather(args: WeatherInput): Promise {
// Simulate API call
return {
temperature: 72,
conditions: 'sunny',
humidity: 65
};
}
@Prompt({ description: 'Generate weather query prompt' })
weatherPrompt(args: { city?: string }) {
return {
messages: [{
role: 'user',
content: {
type: 'text',
text: `What's the weather forecast for ${args.city || 'the city'}?`
}
}]
};
}
@Resource({ description: 'Supported cities list' })
getSupportedCities() {
return {
cities: ['New York', 'London', 'Tokyo', 'Paris', 'Sydney'],
count: 5
};
}
}
Calculator Service with Validation
import { Tool, SchemaConstraint } from "@leanmcp/core";
class CalculatorInput {
@SchemaConstraint({
description: 'First number',
minimum: -1000000,
maximum: 1000000
})
a!: number;
@SchemaConstraint({
description: 'Second number',
minimum: -1000000,
maximum: 1000000
})
b!: number;
}
class CalculatorOutput {
@SchemaConstraint({ description: 'Calculation result' })
result!: number;
}
export class CalculatorService {
@Tool({
description: 'Add two numbers',
inputClass: CalculatorInput
})
async add(args: CalculatorInput): Promise {
return { result: args.a + args.b };
}
@Tool({
description: 'Subtract two numbers',
inputClass: CalculatorInput
})
async subtrac
…
## Source & license
This open-source MCP server is cataloged on AgentStack and links to its original source — we do not rehost the code.
- **Author:** [Leanmcp](https://github.com/Leanmcp)
- **Source:** [Leanmcp/leanmcp-sdk](https://github.com/Leanmcp/leanmcp-sdk)
- **License:** MIT
- **Homepage:** https://leanmcp.com
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet, be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.