LeanMCP provides TypeScript decorators to define tools, prompts, and resources with automatic type inference and schema generation.
Core Decorators
Marks a method as an MCP tool (callable function).
@ Tool ( options ?: ToolOptions ): MethodDecorator
Human-readable description of what the tool does
Input class for automatic JSON Schema generation (optional for tools with no input)
Security requirements (MCP authorization spec):
{ type: 'noauth' } - Callable anonymously
{ type: 'oauth2', scopes: ['read:user'] } - Requires OAuth with scopes
Example
import { Tool } from '@leanmcp/core' ;
class AnalyzeSentimentInput {
@ SchemaConstraint ({ description: 'Text to analyze' })
text !: string ;
@ Optional ()
language ?: string ;
}
class SentimentService {
@ Tool ({
description: 'Analyze sentiment of text' ,
inputClass: AnalyzeSentimentInput ,
})
async analyzeSentiment ( args : AnalyzeSentimentInput ) {
return {
sentiment: 'positive' ,
score: 0.85 ,
text: args . text ,
};
}
// Tool with OAuth requirement
@ Tool ({
description: 'Fetch private user data' ,
securitySchemes: [{ type: 'oauth2' , scopes: [ 'read:user' ] }],
})
async fetchPrivateData () {
return { data: 'private' };
}
}
@Prompt
Marks a method as an MCP prompt template.
@ Prompt ( options ?: PromptOptions ): MethodDecorator
Human-readable description of the prompt
Input class for automatic JSON Schema generation
Example
import { Prompt } from '@leanmcp/core' ;
class PromptInput {
@ SchemaConstraint ({ description: 'Topic to write about' })
topic !: string ;
}
class PromptService {
@ Prompt ({
description: 'Generate a blog post prompt' ,
inputClass: PromptInput ,
})
blogPostPrompt ( args : PromptInput ) {
return {
messages: [
{
role: 'user' ,
content: {
type: 'text' ,
text: `Write a blog post about ${ args . topic } ` ,
},
},
],
};
}
}
@Resource
Marks a method as an MCP resource (data source/endpoint).
@ Resource ( options ?: ResourceOptions ): MethodDecorator
Human-readable description of the resource
mimeType
string
default: "'application/json'"
MIME type of the resource content
Input class for automatic JSON Schema generation
Explicit resource URI (default: ui://classname/methodname)
Example
import { Resource } from '@leanmcp/core' ;
class StatsService {
@ Resource ({
description: 'Service statistics' ,
mimeType: 'application/json' ,
})
getStats () {
return {
requests: 1234 ,
uptime: process . uptime (),
};
}
@ Resource ({
description: 'Custom resource' ,
uri: 'custom://my-resource' ,
mimeType: 'text/plain' ,
})
getCustomResource () {
return 'Custom resource content' ;
}
}
Schema Decorators
@Optional
Marks a class property as optional in the JSON Schema.
@ Optional (): PropertyDecorator
Example
import { Optional , SchemaConstraint } from '@leanmcp/core' ;
class MyInput {
@ SchemaConstraint ({ description: 'Required field' })
required !: string ;
@ Optional ()
@ SchemaConstraint ({ description: 'Optional field' })
optional ?: string ;
}
@SchemaConstraint
Adds JSON Schema constraints and metadata to a property.
@ SchemaConstraint ( constraints : {
description? : string ;
minLength ?: number ;
maxLength ?: number ;
minimum ?: number ;
maximum ?: number ;
pattern ?: string ;
enum ?: any [];
default ?: any ;
type ?: string ;
}): PropertyDecorator
Human-readable description of the field
Regular expression pattern (string fields)
Explicit JSON Schema type
Example
import { SchemaConstraint , Optional } from '@leanmcp/core' ;
class ValidationExample {
@ SchemaConstraint ({
description: 'User email address' ,
pattern: '^[a-z0-9._%+-]+@[a-z0-9.-]+ \\ .[a-z]{2,}$' ,
})
email !: string ;
@ SchemaConstraint ({
description: 'User age' ,
minimum: 0 ,
maximum: 120 ,
})
age !: number ;
@ SchemaConstraint ({
description: 'Account type' ,
enum: [ 'free' , 'pro' , 'enterprise' ],
})
accountType !: string ;
@ Optional ()
@ SchemaConstraint ({
description: 'Bio (max 500 chars)' ,
maxLength: 500 ,
})
bio ?: string ;
}
Authentication Decorators
@Auth
Basic metadata decorator : @Auth adds authentication metadata but does not enforce authentication. For full authentication with token verification, use @Authenticated from @leanmcp/auth .
Adds authentication requirements to a class or method.
@ Auth ( options : AuthOptions ): ClassDecorator & MethodDecorator
Authentication provider name (e.g., ‘clerk’, ‘stripe’, ‘github’)
Example
import { Auth , Tool } from '@leanmcp/core' ;
// Class-level auth (applies to all methods)
@ Auth ({ provider: 'clerk' })
class SecureService {
@ Tool ({ description: 'Get user data' })
async getUserData () {
return { user: 'data' };
}
}
// Method-level auth
class MixedService {
@ Tool ({ description: 'Public method' })
async publicMethod () {
return 'public' ;
}
@ Tool ({ description: 'Premium feature' })
@ Auth ({ provider: 'stripe' })
async premiumMethod () {
return 'premium' ;
}
}
The examples above add authentication metadata to tools but do not enforce authentication. To enforce authentication with token verification, use @Authenticated from @leanmcp/auth. See Authentication Integration for more details.
@UserEnvs
Injects environment variables or user-level configuration into the service instance.
@ UserEnvs (): PropertyDecorator
Example
import { UserEnvs , Tool } from '@leanmcp/core' ;
class ConfigurableService {
@ UserEnvs ()
envs !: Record < string , string | undefined >;
@ Tool ({ description: 'Get API key' })
async getApiKey () {
return this . envs . API_KEY || 'not-configured' ;
}
}
UI & Rendering Decorators
@UI
Links a UI component or frontend visualization to a tool or resource.
@ UI ( component : string ): ClassDecorator & MethodDecorator
UI component name or path
Example
import { UI , Tool } from '@leanmcp/core' ;
@ UI ( 'ChartComponent' )
class VisualizationService {
@ Tool ({ description: 'Get chart data' })
async getChartData () {
return {
labels: [ 'Jan' , 'Feb' , 'Mar' ],
values: [ 10 , 20 , 30 ],
};
}
}
@Render
Specifies how the output should be rendered.
@ Render ( format : 'markdown' | 'html' | 'json' | 'chart' | 'table' | string ): MethodDecorator
Render format: ‘markdown’, ‘html’, ‘json’, ‘chart’, ‘table’, or custom format
Example
import { Render , Tool } from '@leanmcp/core' ;
class ContentService {
@ Tool ({ description: 'Get formatted report' })
@ Render ( 'markdown' )
async getReport () {
return '# Report \n\n This is a **markdown** report.' ;
}
@ Tool ({ description: 'Get JSON data' })
@ Render ( 'json' )
async getData () {
return { data: 'value' };
}
}
Workflow Decorators
@Deprecated
Marks a tool, prompt, or resource as deprecated.
@ Deprecated ( message ?: string ): ClassDecorator & MethodDecorator
Optional deprecation message (default: ‘This feature is deprecated’)
Example
import { Deprecated , Tool } from '@leanmcp/core' ;
class LegacyService {
@ Tool ({ description: 'Old method' })
@ Deprecated ( 'Use newMethod instead' )
async oldMethod () {
return 'old' ;
}
@ Tool ({ description: 'New method' })
async newMethod () {
return 'new' ;
}
}
// When oldMethod is called, logs: "DEPRECATED: oldMethod - Use newMethod instead"
Helper Functions
Get all metadata for a specific method.
function getMethodMetadata ( method : Function ) : {
toolName ?: string ;
toolDescription ?: string ;
promptName ?: string ;
promptDescription ?: string ;
resourceUri ?: string ;
resourceName ?: string ;
resourceDescription ?: string ;
inputSchema ?: object ;
outputSchema ?: object ;
authProvider ?: string ;
authRequired ?: boolean ;
uiComponent ?: string ;
renderFormat ?: string ;
deprecated ?: boolean ;
deprecationMessage ?: string ;
}
getDecoratedMethods()
Get all methods with a specific decorator from a class.
function getDecoratedMethods (
target : any ,
metadataKey : string
) : Array <{
method : Function ;
propertyKey : string ;
metadata : any ;
}>
Example
import { getDecoratedMethods } from '@leanmcp/core' ;
class MyService {
@ Tool ({ description: 'Tool 1' })
async tool1 () {}
@ Tool ({ description: 'Tool 2' })
async tool2 () {}
}
const toolMethods = getDecoratedMethods ( MyService , 'tool:name' );
console . log ( toolMethods ); // [{ method: ..., propertyKey: 'tool1', ... }, ...]