@leanmcp/core 0.3.16 → 0.3.18-alpha.6.6dae082

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -27,6 +27,10 @@
27
27
  <a href="https://x.com/LeanMcp">
28
28
  <img src="https://img.shields.io/badge/@LeanMCP-f5f5f5?logo=x&logoColor=000000" />
29
29
  </a>
30
+ <a href="https://leanmcp.com/">
31
+ <img src="https://img.shields.io/badge/Website-leanmcp-0A66C2?" />
32
+ </a>
33
+ <a href="https://deepwiki.com/LeanMCP/leanmcp-sdk"><img src="https://deepwiki.com/badge.svg" alt="Ask DeepWiki"></a>
30
34
  </p>
31
35
 
32
36
  ## Features
@@ -46,6 +50,7 @@ npm install @leanmcp/core
46
50
  ```
47
51
 
48
52
  For HTTP server support:
53
+
49
54
  ```bash
50
55
  npm install express cors
51
56
  ```
@@ -57,20 +62,21 @@ npm install express cors
57
62
  The simplest way to create an MCP server with auto-discovery:
58
63
 
59
64
  ```typescript
60
- import { createHTTPServer } from "@leanmcp/core";
65
+ import { createHTTPServer } from '@leanmcp/core';
61
66
 
62
67
  await createHTTPServer({
63
- name: "my-mcp-server",
64
- version: "1.0.0",
68
+ name: 'my-mcp-server',
69
+ version: '1.0.0',
65
70
  port: 3001,
66
71
  cors: true,
67
- logging: true
72
+ logging: true,
68
73
  });
69
74
 
70
75
  // Services are automatically discovered from ./mcp directory
71
76
  ```
72
77
 
73
78
  **Directory Structure:**
79
+
74
80
  ```
75
81
  your-project/
76
82
  ├── main.ts
@@ -86,12 +92,12 @@ your-project/
86
92
 
87
93
  ```typescript
88
94
  // mcp/sentiment/index.ts
89
- import { Tool, SchemaConstraint, Optional } from "@leanmcp/core";
95
+ import { Tool, SchemaConstraint, Optional } from '@leanmcp/core';
90
96
 
91
97
  class AnalyzeSentimentInput {
92
98
  @SchemaConstraint({
93
99
  description: 'Text to analyze',
94
- minLength: 1
100
+ minLength: 1,
95
101
  })
96
102
  text!: string;
97
103
 
@@ -99,20 +105,20 @@ class AnalyzeSentimentInput {
99
105
  @SchemaConstraint({
100
106
  description: 'Language code',
101
107
  enum: ['en', 'es', 'fr'],
102
- default: 'en'
108
+ default: 'en',
103
109
  })
104
110
  language?: string;
105
111
  }
106
112
 
107
113
  export class SentimentService {
108
- @Tool({
114
+ @Tool({
109
115
  description: 'Analyze sentiment of text',
110
- inputClass: AnalyzeSentimentInput
116
+ inputClass: AnalyzeSentimentInput,
111
117
  })
112
118
  async analyzeSentiment(input: AnalyzeSentimentInput) {
113
119
  return {
114
120
  sentiment: 'positive',
115
- score: 0.8
121
+ score: 0.8,
116
122
  };
117
123
  }
118
124
  }
@@ -130,12 +136,12 @@ Marks a method as a callable MCP tool.
130
136
  class CalculateInput {
131
137
  @SchemaConstraint({ description: 'First number' })
132
138
  a!: number;
133
-
139
+
134
140
  @SchemaConstraint({ description: 'Second number' })
135
141
  b!: number;
136
142
  }
137
143
 
138
- @Tool({
144
+ @Tool({
139
145
  description: 'Calculate sum of two numbers',
140
146
  inputClass: CalculateInput
141
147
  })
@@ -146,10 +152,10 @@ async calculate(input: CalculateInput) {
146
152
 
147
153
  **Options:**
148
154
 
149
- | Option | Type | Description |
150
- |--------|------|-------------|
155
+ | Option | Type | Description |
156
+ | ------------- | -------- | --------------------------- |
151
157
  | `description` | `string` | Tool description for the AI |
152
- | `inputClass` | `Class` | Class defining input schema |
158
+ | `inputClass` | `Class` | Class defining input schema |
153
159
 
154
160
  ### @Prompt
155
161
 
@@ -159,7 +165,7 @@ Marks a method as a reusable prompt template.
159
165
  class CodeReviewInput {
160
166
  @SchemaConstraint({ description: 'Code to review' })
161
167
  code!: string;
162
-
168
+
163
169
  @SchemaConstraint({ description: 'Programming language' })
164
170
  language!: string;
165
171
  }
@@ -183,9 +189,9 @@ codeReview(input: CodeReviewInput) {
183
189
  Marks a method as an MCP resource (data source).
184
190
 
185
191
  ```typescript
186
- @Resource({
187
- description: 'Get system configuration',
188
- mimeType: 'application/json'
192
+ @Resource({
193
+ description: 'Get system configuration',
194
+ mimeType: 'application/json'
189
195
  })
190
196
  async getConfig() {
191
197
  return {
@@ -205,14 +211,14 @@ class UserInput {
205
211
  description: 'User email',
206
212
  format: 'email',
207
213
  minLength: 5,
208
- maxLength: 100
214
+ maxLength: 100,
209
215
  })
210
216
  email!: string;
211
217
 
212
218
  @SchemaConstraint({
213
219
  description: 'User age',
214
220
  minimum: 18,
215
- maximum: 120
221
+ maximum: 120,
216
222
  })
217
223
  age!: number;
218
224
 
@@ -220,13 +226,14 @@ class UserInput {
220
226
  @SchemaConstraint({
221
227
  description: 'User role',
222
228
  enum: ['admin', 'user', 'guest'],
223
- default: 'user'
229
+ default: 'user',
224
230
  })
225
231
  role?: string;
226
232
  }
227
233
  ```
228
234
 
229
235
  **Common constraints:**
236
+
230
237
  - `description`, `default` — Documentation
231
238
  - `minLength`, `maxLength` — String length
232
239
  - `minimum`, `maximum` — Number range
@@ -258,6 +265,7 @@ class SearchInput {
258
265
  Create and start an HTTP server with auto-discovery.
259
266
 
260
267
  **Simplified API (Recommended):**
268
+
261
269
  ```typescript
262
270
  await createHTTPServer({
263
271
  name: string; // Server name (required)
@@ -275,21 +283,22 @@ await createHTTPServer({
275
283
  ```
276
284
 
277
285
  **Factory Pattern (Advanced):**
286
+
278
287
  ```typescript
279
288
  const serverFactory = async () => {
280
289
  const server = new MCPServer({
281
- name: "my-server",
282
- version: "1.0.0",
283
- autoDiscover: false // Disable for manual registration
290
+ name: 'my-server',
291
+ version: '1.0.0',
292
+ autoDiscover: false, // Disable for manual registration
284
293
  });
285
-
294
+
286
295
  server.registerService(new MyService());
287
296
  return server.getServer();
288
297
  };
289
298
 
290
299
  await createHTTPServer(serverFactory, {
291
300
  port: 3001,
292
- cors: true
301
+ cors: true,
293
302
  });
294
303
  ```
295
304
 
@@ -329,12 +338,12 @@ For services needing shared configuration (auth, database, etc.), create a `conf
329
338
 
330
339
  ```typescript
331
340
  // mcp/config.ts
332
- import { AuthProvider } from "@leanmcp/auth";
341
+ import { AuthProvider } from '@leanmcp/auth';
333
342
 
334
343
  export const authProvider = new AuthProvider('cognito', {
335
344
  region: process.env.AWS_REGION,
336
345
  userPoolId: process.env.COGNITO_USER_POOL_ID,
337
- clientId: process.env.COGNITO_CLIENT_ID
346
+ clientId: process.env.COGNITO_CLIENT_ID,
338
347
  });
339
348
 
340
349
  await authProvider.init();
@@ -344,9 +353,9 @@ Then import in your services:
344
353
 
345
354
  ```typescript
346
355
  // mcp/slack/index.ts
347
- import { Tool } from "@leanmcp/core";
348
- import { Authenticated } from "@leanmcp/auth";
349
- import { authProvider } from "../config.js";
356
+ import { Tool } from '@leanmcp/core';
357
+ import { Authenticated } from '@leanmcp/auth';
358
+ import { authProvider } from '../config.js';
350
359
 
351
360
  @Authenticated(authProvider)
352
361
  export class SlackService {
@@ -388,7 +397,7 @@ If your tool returns a manual MCP response (with `content` array), the SDK extra
388
397
 
389
398
  ```typescript
390
399
  return {
391
- content: [{ type: 'text', text: JSON.stringify({ channels }) }]
400
+ content: [{ type: 'text', text: JSON.stringify({ channels }) }],
392
401
  };
393
402
  // structuredContent will be { channels: [...] }
394
403
  ```
@@ -397,11 +406,11 @@ return {
397
406
 
398
407
  ## HTTP Endpoints
399
408
 
400
- | Endpoint | Method | Description |
401
- |----------|--------|-------------|
402
- | `/mcp` | POST | MCP protocol endpoint (JSON-RPC 2.0) |
403
- | `/health` | GET | Health check |
404
- | `/` | GET | Welcome message |
409
+ | Endpoint | Method | Description |
410
+ | --------- | ------ | ------------------------------------ |
411
+ | `/mcp` | POST | MCP protocol endpoint (JSON-RPC 2.0) |
412
+ | `/health` | GET | Health check |
413
+ | `/` | GET | Welcome message |
405
414
 
406
415
  ## Error Handling
407
416
 
@@ -418,9 +427,10 @@ async divide(input: DivideInput) {
418
427
  ```
419
428
 
420
429
  Returns:
430
+
421
431
  ```json
422
432
  {
423
- "content": [{"type": "text", "text": "Error: Division by zero"}],
433
+ "content": [{ "type": "text", "text": "Error: Division by zero" }],
424
434
  "isError": true
425
435
  }
426
436
  ```
@@ -435,6 +445,7 @@ NODE_ENV=production # Environment
435
445
  ## TypeScript Support
436
446
 
437
447
  **Key Points:**
448
+
438
449
  - Input schema is defined via `inputClass` in the decorator
439
450
  - Output type is inferred from the return type
440
451
  - For tools with no input, omit `inputClass`
package/dist/index.d.mts CHANGED
@@ -101,7 +101,7 @@ interface HTTPServerAuthOptions {
101
101
  issuer?: string;
102
102
  /** Access token TTL in seconds (default: 3600) */
103
103
  tokenTTL?: number;
104
- /** Enable Dynamic Client Registration (DCR) */
104
+ /** Enable Dynamic Client Registration (for ChatGPT etc.) */
105
105
  enableDCR?: boolean;
106
106
  /** Upstream OAuth provider configuration */
107
107
  upstreamProvider?: {
@@ -551,6 +551,8 @@ interface MCPServerConstructorOptions {
551
551
  };
552
552
  sessionTimeout?: number;
553
553
  stateless?: boolean;
554
+ dashboard?: boolean;
555
+ /** OAuth/Auth configuration (MCP authorization spec) - passed to HTTPServerOptions */
554
556
  auth?: HTTPServerAuthOptions;
555
557
  }
556
558
  interface RegisteredTool {
@@ -671,16 +673,10 @@ declare class MCPServer {
671
673
  method: string;
672
674
  params?: {
673
675
  [x: string]: unknown;
674
- task?: {
675
- [x: string]: unknown;
676
- ttl?: number | null | undefined;
677
- pollInterval?: number | undefined;
678
- } | undefined;
679
676
  _meta?: {
680
677
  [x: string]: unknown;
681
678
  progressToken?: string | number | undefined;
682
679
  "io.modelcontextprotocol/related-task"?: {
683
- [x: string]: unknown;
684
680
  taskId: string;
685
681
  } | undefined;
686
682
  } | undefined;
@@ -691,8 +687,8 @@ declare class MCPServer {
691
687
  [x: string]: unknown;
692
688
  _meta?: {
693
689
  [x: string]: unknown;
690
+ progressToken?: string | number | undefined;
694
691
  "io.modelcontextprotocol/related-task"?: {
695
- [x: string]: unknown;
696
692
  taskId: string;
697
693
  } | undefined;
698
694
  } | undefined;
@@ -701,8 +697,8 @@ declare class MCPServer {
701
697
  [x: string]: unknown;
702
698
  _meta?: {
703
699
  [x: string]: unknown;
700
+ progressToken?: string | number | undefined;
704
701
  "io.modelcontextprotocol/related-task"?: {
705
- [x: string]: unknown;
706
702
  taskId: string;
707
703
  } | undefined;
708
704
  } | undefined;
@@ -732,16 +728,10 @@ declare class MCPServerRuntime {
732
728
  method: string;
733
729
  params?: {
734
730
  [x: string]: unknown;
735
- task?: {
736
- [x: string]: unknown;
737
- ttl?: number | null | undefined;
738
- pollInterval?: number | undefined;
739
- } | undefined;
740
731
  _meta?: {
741
732
  [x: string]: unknown;
742
733
  progressToken?: string | number | undefined;
743
734
  "io.modelcontextprotocol/related-task"?: {
744
- [x: string]: unknown;
745
735
  taskId: string;
746
736
  } | undefined;
747
737
  } | undefined;
@@ -752,8 +742,8 @@ declare class MCPServerRuntime {
752
742
  [x: string]: unknown;
753
743
  _meta?: {
754
744
  [x: string]: unknown;
745
+ progressToken?: string | number | undefined;
755
746
  "io.modelcontextprotocol/related-task"?: {
756
- [x: string]: unknown;
757
747
  taskId: string;
758
748
  } | undefined;
759
749
  } | undefined;
@@ -762,8 +752,8 @@ declare class MCPServerRuntime {
762
752
  [x: string]: unknown;
763
753
  _meta?: {
764
754
  [x: string]: unknown;
755
+ progressToken?: string | number | undefined;
765
756
  "io.modelcontextprotocol/related-task"?: {
766
- [x: string]: unknown;
767
757
  taskId: string;
768
758
  } | undefined;
769
759
  } | undefined;
package/dist/index.d.ts CHANGED
@@ -101,7 +101,7 @@ interface HTTPServerAuthOptions {
101
101
  issuer?: string;
102
102
  /** Access token TTL in seconds (default: 3600) */
103
103
  tokenTTL?: number;
104
- /** Enable Dynamic Client Registration (DCR) */
104
+ /** Enable Dynamic Client Registration (for ChatGPT etc.) */
105
105
  enableDCR?: boolean;
106
106
  /** Upstream OAuth provider configuration */
107
107
  upstreamProvider?: {
@@ -551,6 +551,8 @@ interface MCPServerConstructorOptions {
551
551
  };
552
552
  sessionTimeout?: number;
553
553
  stateless?: boolean;
554
+ dashboard?: boolean;
555
+ /** OAuth/Auth configuration (MCP authorization spec) - passed to HTTPServerOptions */
554
556
  auth?: HTTPServerAuthOptions;
555
557
  }
556
558
  interface RegisteredTool {
@@ -671,16 +673,10 @@ declare class MCPServer {
671
673
  method: string;
672
674
  params?: {
673
675
  [x: string]: unknown;
674
- task?: {
675
- [x: string]: unknown;
676
- ttl?: number | null | undefined;
677
- pollInterval?: number | undefined;
678
- } | undefined;
679
676
  _meta?: {
680
677
  [x: string]: unknown;
681
678
  progressToken?: string | number | undefined;
682
679
  "io.modelcontextprotocol/related-task"?: {
683
- [x: string]: unknown;
684
680
  taskId: string;
685
681
  } | undefined;
686
682
  } | undefined;
@@ -691,8 +687,8 @@ declare class MCPServer {
691
687
  [x: string]: unknown;
692
688
  _meta?: {
693
689
  [x: string]: unknown;
690
+ progressToken?: string | number | undefined;
694
691
  "io.modelcontextprotocol/related-task"?: {
695
- [x: string]: unknown;
696
692
  taskId: string;
697
693
  } | undefined;
698
694
  } | undefined;
@@ -701,8 +697,8 @@ declare class MCPServer {
701
697
  [x: string]: unknown;
702
698
  _meta?: {
703
699
  [x: string]: unknown;
700
+ progressToken?: string | number | undefined;
704
701
  "io.modelcontextprotocol/related-task"?: {
705
- [x: string]: unknown;
706
702
  taskId: string;
707
703
  } | undefined;
708
704
  } | undefined;
@@ -732,16 +728,10 @@ declare class MCPServerRuntime {
732
728
  method: string;
733
729
  params?: {
734
730
  [x: string]: unknown;
735
- task?: {
736
- [x: string]: unknown;
737
- ttl?: number | null | undefined;
738
- pollInterval?: number | undefined;
739
- } | undefined;
740
731
  _meta?: {
741
732
  [x: string]: unknown;
742
733
  progressToken?: string | number | undefined;
743
734
  "io.modelcontextprotocol/related-task"?: {
744
- [x: string]: unknown;
745
735
  taskId: string;
746
736
  } | undefined;
747
737
  } | undefined;
@@ -752,8 +742,8 @@ declare class MCPServerRuntime {
752
742
  [x: string]: unknown;
753
743
  _meta?: {
754
744
  [x: string]: unknown;
745
+ progressToken?: string | number | undefined;
755
746
  "io.modelcontextprotocol/related-task"?: {
756
- [x: string]: unknown;
757
747
  taskId: string;
758
748
  } | undefined;
759
749
  } | undefined;
@@ -762,8 +752,8 @@ declare class MCPServerRuntime {
762
752
  [x: string]: unknown;
763
753
  _meta?: {
764
754
  [x: string]: unknown;
755
+ progressToken?: string | number | undefined;
765
756
  "io.modelcontextprotocol/related-task"?: {
766
- [x: string]: unknown;
767
757
  taskId: string;
768
758
  } | undefined;
769
759
  } | undefined;
package/dist/index.js CHANGED
@@ -1454,14 +1454,14 @@ var init_index = __esm({
1454
1454
  /**
1455
1455
  * Auto-register all services from the mcp directory
1456
1456
  * Scans the directory recursively and registers all exported classes
1457
- *
1457
+ *
1458
1458
  * @param mcpDir - Path to the mcp directory containing service files
1459
1459
  * @param serviceFactories - Optional map of service class names to factory functions for dependency injection
1460
- *
1460
+ *
1461
1461
  * @example
1462
1462
  * // Auto-register services with no dependencies
1463
1463
  * await server.autoRegisterServices('./mcp');
1464
- *
1464
+ *
1465
1465
  * @example
1466
1466
  * // Auto-register with dependency injection
1467
1467
  * await server.autoRegisterServices('./mcp', {
@@ -1614,7 +1614,7 @@ var init_index = __esm({
1614
1614
  }
1615
1615
  /**
1616
1616
  * Watch UI manifest for changes and reload resources dynamically
1617
- *
1617
+ *
1618
1618
  * CRITICAL: Only for stateful mode. In stateless mode, each request
1619
1619
  * creates a fresh server that reads the manifest directly, making
1620
1620
  * watchers both unnecessary and a memory leak source.
package/dist/index.mjs CHANGED
@@ -1341,14 +1341,14 @@ var MCPServer = class {
1341
1341
  /**
1342
1342
  * Auto-register all services from the mcp directory
1343
1343
  * Scans the directory recursively and registers all exported classes
1344
- *
1344
+ *
1345
1345
  * @param mcpDir - Path to the mcp directory containing service files
1346
1346
  * @param serviceFactories - Optional map of service class names to factory functions for dependency injection
1347
- *
1347
+ *
1348
1348
  * @example
1349
1349
  * // Auto-register services with no dependencies
1350
1350
  * await server.autoRegisterServices('./mcp');
1351
- *
1351
+ *
1352
1352
  * @example
1353
1353
  * // Auto-register with dependency injection
1354
1354
  * await server.autoRegisterServices('./mcp', {
@@ -1501,7 +1501,7 @@ var MCPServer = class {
1501
1501
  }
1502
1502
  /**
1503
1503
  * Watch UI manifest for changes and reload resources dynamically
1504
- *
1504
+ *
1505
1505
  * CRITICAL: Only for stateful mode. In stateless mode, each request
1506
1506
  * creates a fresh server that reads the manifest directly, making
1507
1507
  * watchers both unnecessary and a memory leak source.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@leanmcp/core",
3
- "version": "0.3.16",
3
+ "version": "0.3.18-alpha.6.6dae082",
4
4
  "description": "Core library implementing decorators, reflection, and MCP runtime server",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",
@@ -49,8 +49,7 @@
49
49
  "devDependencies": {
50
50
  "@types/cors": "^2.8.0",
51
51
  "@types/express": "^5.0.0",
52
- "@types/node": "^20.0.0",
53
- "@leanmcp/auth": "^0.4.0"
52
+ "@types/node": "^20.0.0"
54
53
  },
55
54
  "repository": {
56
55
  "type": "git",