easy-mcp-nest 0.2.1 → 0.4.0
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 +342 -8
- package/dist/EasyMCP.js +0 -3
- package/dist/EasyMCP.js.map +1 -1
- package/dist/adapters/express/express-adapter.d.ts +3 -0
- package/dist/adapters/express/express-adapter.js +135 -0
- package/dist/adapters/express/express-adapter.js.map +1 -0
- package/dist/adapters/express/http-gateway.service.d.ts +13 -0
- package/dist/adapters/express/http-gateway.service.js +102 -0
- package/dist/adapters/express/http-gateway.service.js.map +1 -0
- package/dist/adapters/express/index.d.ts +3 -0
- package/dist/adapters/express/index.js +8 -0
- package/dist/adapters/express/index.js.map +1 -0
- package/dist/adapters/express/types.d.ts +15 -0
- package/dist/adapters/express/types.js +3 -0
- package/dist/adapters/express/types.js.map +1 -0
- package/dist/app.module.js +2 -0
- package/dist/app.module.js.map +1 -1
- package/dist/auth/oauth/index.d.ts +3 -0
- package/dist/auth/oauth/index.js +8 -0
- package/dist/auth/oauth/index.js.map +1 -0
- package/dist/auth/oauth/oauth-config.interface.d.ts +12 -0
- package/dist/auth/oauth/oauth-config.interface.js +3 -0
- package/dist/auth/oauth/oauth-config.interface.js.map +1 -0
- package/dist/auth/oauth/oauth-middleware.d.ts +3 -0
- package/dist/auth/oauth/oauth-middleware.js +54 -0
- package/dist/auth/oauth/oauth-middleware.js.map +1 -0
- package/dist/auth/oauth/oauth-provider.service.d.ts +8 -0
- package/dist/auth/oauth/oauth-provider.service.js +63 -0
- package/dist/auth/oauth/oauth-provider.service.js.map +1 -0
- package/dist/config/mcp-config.interface.d.ts +1 -1
- package/dist/core/batch/batch-executor.service.d.ts +21 -0
- package/dist/core/batch/batch-executor.service.js +101 -0
- package/dist/core/batch/batch-executor.service.js.map +1 -0
- package/dist/core/context/context-provider.service.d.ts +8 -0
- package/dist/core/context/context-provider.service.js +55 -0
- package/dist/core/context/context-provider.service.js.map +1 -0
- package/dist/core/context/mcp-context.interface.d.ts +12 -0
- package/dist/core/context/mcp-context.interface.js +3 -0
- package/dist/core/context/mcp-context.interface.js.map +1 -0
- package/dist/core/documentation/openapi-generator.service.d.ts +13 -0
- package/dist/core/documentation/openapi-generator.service.js +116 -0
- package/dist/core/documentation/openapi-generator.service.js.map +1 -0
- package/dist/core/errors/error-handler.interface.d.ts +11 -0
- package/dist/core/errors/error-handler.interface.js +3 -0
- package/dist/core/errors/error-handler.interface.js.map +1 -0
- package/dist/core/health/health-check.service.d.ts +33 -0
- package/dist/core/health/health-check.service.js +71 -0
- package/dist/core/health/health-check.service.js.map +1 -0
- package/dist/core/mcp-server/mcp-server.service.d.ts +16 -1
- package/dist/core/mcp-server/mcp-server.service.js +201 -3
- package/dist/core/mcp-server/mcp-server.service.js.map +1 -1
- package/dist/core/middleware/middleware-executor.service.d.ts +8 -0
- package/dist/core/middleware/middleware-executor.service.js +46 -0
- package/dist/core/middleware/middleware-executor.service.js.map +1 -0
- package/dist/core/middleware/middleware.interface.d.ts +6 -0
- package/dist/core/middleware/middleware.interface.js +3 -0
- package/dist/core/middleware/middleware.interface.js.map +1 -0
- package/dist/core/observability/metrics.service.d.ts +29 -0
- package/dist/core/observability/metrics.service.js +124 -0
- package/dist/core/observability/metrics.service.js.map +1 -0
- package/dist/core/observability/tracing.service.d.ts +12 -0
- package/dist/core/observability/tracing.service.js +88 -0
- package/dist/core/observability/tracing.service.js.map +1 -0
- package/dist/core/progress/progress-notifier.service.d.ts +16 -0
- package/dist/core/progress/progress-notifier.service.js +96 -0
- package/dist/core/progress/progress-notifier.service.js.map +1 -0
- package/dist/core/rate-limiting/rate-limit.interface.d.ts +11 -0
- package/dist/core/rate-limiting/rate-limit.interface.js +3 -0
- package/dist/core/rate-limiting/rate-limit.interface.js.map +1 -0
- package/dist/core/rate-limiting/rate-limiter.service.d.ts +13 -0
- package/dist/core/rate-limiting/rate-limiter.service.js +147 -0
- package/dist/core/rate-limiting/rate-limiter.service.js.map +1 -0
- package/dist/core/resilience/circuit-breaker.interface.d.ts +15 -0
- package/dist/core/resilience/circuit-breaker.interface.js +3 -0
- package/dist/core/resilience/circuit-breaker.interface.js.map +1 -0
- package/dist/core/resilience/circuit-breaker.service.d.ts +11 -0
- package/dist/core/resilience/circuit-breaker.service.js +117 -0
- package/dist/core/resilience/circuit-breaker.service.js.map +1 -0
- package/dist/core/resilience/retry.service.d.ts +6 -0
- package/dist/core/resilience/retry.service.js +66 -0
- package/dist/core/resilience/retry.service.js.map +1 -0
- package/dist/core/utils/decorator-scanner.d.ts +4 -0
- package/dist/core/utils/decorator-scanner.js +112 -0
- package/dist/core/utils/decorator-scanner.js.map +1 -0
- package/dist/core/utils/sanitize.util.d.ts +2 -0
- package/dist/core/utils/sanitize.util.js +48 -0
- package/dist/core/utils/sanitize.util.js.map +1 -1
- package/dist/decorators/factory-provider.d.ts +2 -0
- package/dist/decorators/factory-provider.js +20 -0
- package/dist/decorators/factory-provider.js.map +1 -0
- package/dist/decorators/index.d.ts +7 -0
- package/dist/decorators/index.js +28 -0
- package/dist/decorators/index.js.map +1 -0
- package/dist/decorators/mcp-context.decorator.d.ts +3 -0
- package/dist/decorators/mcp-context.decorator.js +20 -0
- package/dist/decorators/mcp-context.decorator.js.map +1 -0
- package/dist/decorators/mcp-error-handler.decorator.d.ts +4 -0
- package/dist/decorators/mcp-error-handler.decorator.js +15 -0
- package/dist/decorators/mcp-error-handler.decorator.js.map +1 -0
- package/dist/decorators/mcp-middleware.decorator.d.ts +4 -0
- package/dist/decorators/mcp-middleware.decorator.js +17 -0
- package/dist/decorators/mcp-middleware.decorator.js.map +1 -0
- package/dist/decorators/mcp-param.decorator.d.ts +10 -0
- package/dist/decorators/mcp-param.decorator.js +41 -0
- package/dist/decorators/mcp-param.decorator.js.map +1 -0
- package/dist/decorators/mcp-service.decorator.d.ts +6 -0
- package/dist/decorators/mcp-service.decorator.js +27 -0
- package/dist/decorators/mcp-service.decorator.js.map +1 -0
- package/dist/decorators/mcp-tool.decorator.d.ts +28 -0
- package/dist/decorators/mcp-tool.decorator.js +36 -0
- package/dist/decorators/mcp-tool.decorator.js.map +1 -0
- package/dist/index.d.ts +12 -1
- package/dist/index.js +30 -1
- package/dist/index.js.map +1 -1
- package/dist/interface/interface.interface.d.ts +2 -0
- package/dist/interface/jsonrpc.interface.d.ts +8 -0
- package/dist/interface/jsonrpc.interface.js.map +1 -1
- package/dist/interface/mcp-protocol.interface.d.ts +14 -0
- package/dist/interface/mcp-protocol.interface.js.map +1 -1
- package/dist/standalone/core-services.d.ts +29 -0
- package/dist/standalone/core-services.js +94 -0
- package/dist/standalone/core-services.js.map +1 -0
- package/dist/standalone/index.d.ts +3 -0
- package/dist/standalone/index.js +11 -0
- package/dist/standalone/index.js.map +1 -0
- package/dist/standalone/standalone-server.d.ts +23 -0
- package/dist/standalone/standalone-server.js +366 -0
- package/dist/standalone/standalone-server.js.map +1 -0
- package/dist/standalone/types.d.ts +14 -0
- package/dist/standalone/types.js +3 -0
- package/dist/standalone/types.js.map +1 -0
- package/dist/testing/index.d.ts +3 -0
- package/dist/testing/index.js +14 -0
- package/dist/testing/index.js.map +1 -0
- package/dist/testing/mock-context.d.ts +2 -0
- package/dist/testing/mock-context.js +17 -0
- package/dist/testing/mock-context.js.map +1 -0
- package/dist/testing/test-app.factory.d.ts +15 -0
- package/dist/testing/test-app.factory.js +37 -0
- package/dist/testing/test-app.factory.js.map +1 -0
- package/dist/testing/test-helpers.d.ts +10 -0
- package/dist/testing/test-helpers.js +46 -0
- package/dist/testing/test-helpers.js.map +1 -0
- package/dist/tooling/tool-registry/tool-registry.service.d.ts +7 -1
- package/dist/tooling/tool-registry/tool-registry.service.js +40 -3
- package/dist/tooling/tool-registry/tool-registry.service.js.map +1 -1
- package/dist/tooling/tool.interface.d.ts +9 -2
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/dist/validation/index.d.ts +1 -0
- package/dist/validation/index.js +8 -0
- package/dist/validation/index.js.map +1 -0
- package/dist/validation/zod-integration.d.ts +11 -0
- package/dist/validation/zod-integration.js +148 -0
- package/dist/validation/zod-integration.js.map +1 -0
- package/package.json +4 -2
package/README.md
CHANGED
|
@@ -29,12 +29,26 @@ EasyMCP requires the following peer dependencies to be installed:
|
|
|
29
29
|
- `@nestjs/core` ^11.0.1
|
|
30
30
|
- `@nestjs/platform-express` ^11.0.1
|
|
31
31
|
|
|
32
|
-
|
|
32
|
+
**Optional peer dependencies** (for specific features):
|
|
33
|
+
- `express` ^4.18.0 (for Express adapter)
|
|
34
|
+
- `zod` ^3.22.0 (for TypeScript-first validation)
|
|
35
|
+
|
|
36
|
+
Install required dependencies with:
|
|
33
37
|
|
|
34
38
|
```bash
|
|
35
39
|
npm install @nestjs/common@^11.0.1 @nestjs/core@^11.0.1 @nestjs/platform-express@^11.0.1
|
|
36
40
|
```
|
|
37
41
|
|
|
42
|
+
Install optional dependencies as needed:
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
# For Express adapter
|
|
46
|
+
npm install express@^4.18.0
|
|
47
|
+
|
|
48
|
+
# For Zod validation
|
|
49
|
+
npm install zod@^3.22.0
|
|
50
|
+
```
|
|
51
|
+
|
|
38
52
|
## Quick Start
|
|
39
53
|
|
|
40
54
|
```typescript
|
|
@@ -193,6 +207,7 @@ process.on('SIGINT', async () => {
|
|
|
193
207
|
|
|
194
208
|
### Types
|
|
195
209
|
|
|
210
|
+
**Core Types:**
|
|
196
211
|
- `McpConfig` - Main configuration interface
|
|
197
212
|
- `ToolRegistrationInput` - Tool definition interface
|
|
198
213
|
- `ServerInfo` - Optional server information
|
|
@@ -207,6 +222,13 @@ process.on('SIGINT', async () => {
|
|
|
207
222
|
- `VERSION`, `PACKAGE_NAME`, `getVersion()`, `getPackageName()` - Version information utilities
|
|
208
223
|
- `INTERFACE_LAYER_TOKEN` - Token for accessing the interface layer (advanced use cases)
|
|
209
224
|
|
|
225
|
+
**New Feature Types:**
|
|
226
|
+
- `McpContext` - Context interface for user information
|
|
227
|
+
- `CreateMcpExpressRouterOptions` - Express adapter options
|
|
228
|
+
- `OAuthProviderConfig`, `OAuthConfig` - OAuth configuration
|
|
229
|
+
- `CreateMcpServerOptions` - Standalone server options
|
|
230
|
+
- `StandaloneTransport` - Transport type ('stdio' | 'http')
|
|
231
|
+
|
|
210
232
|
## Architecture
|
|
211
233
|
|
|
212
234
|
EasyMCP uses a simplified architecture for standard MCP servers:
|
|
@@ -245,11 +267,11 @@ EasyMCP implements the following MCP protocol methods:
|
|
|
245
267
|
- Validates client protocol version
|
|
246
268
|
- Returns server capabilities (currently supports tools)
|
|
247
269
|
- Returns server information (name and version)
|
|
248
|
-
|
|
270
|
+
|
|
249
271
|
- **`tools/list`** - Returns all registered tools with their JSON Schema 2020-12 definitions
|
|
250
272
|
- Returns array of tool definitions in MCP format
|
|
251
273
|
- Each tool includes name, description, inputSchema, and optional icon
|
|
252
|
-
|
|
274
|
+
|
|
253
275
|
- **`tools/call`** - Executes a tool with provided arguments and returns the result
|
|
254
276
|
- Validates tool arguments against JSON Schema 2020-12
|
|
255
277
|
- Executes tool function
|
|
@@ -310,7 +332,7 @@ This enables the MCP-specified Content-Length header format, which some clients
|
|
|
310
332
|
|
|
311
333
|
### Limitations
|
|
312
334
|
|
|
313
|
-
- **Transport**:
|
|
335
|
+
- **Transport**: stdio transport is fully supported. HTTP transport is available via Express adapter. WebSocket transport is not available.
|
|
314
336
|
- **Protocol Version**: Only protocol version 2025-11-25 is supported. Older or newer versions will be rejected.
|
|
315
337
|
- **Resources Subscribe/Unsubscribe**: Basic resource subscription is not yet implemented (resources/list and resources/read are supported)
|
|
316
338
|
|
|
@@ -330,10 +352,10 @@ EasyMCP provides comprehensive error handling with custom error classes and clea
|
|
|
330
352
|
### Error Handling Examples
|
|
331
353
|
|
|
332
354
|
```typescript
|
|
333
|
-
import {
|
|
334
|
-
EasyMCP,
|
|
335
|
-
ConfigurationError,
|
|
336
|
-
ToolExecutionError,
|
|
355
|
+
import {
|
|
356
|
+
EasyMCP,
|
|
357
|
+
ConfigurationError,
|
|
358
|
+
ToolExecutionError,
|
|
337
359
|
ToolNotFoundError
|
|
338
360
|
} from 'easy-mcp-nest';
|
|
339
361
|
|
|
@@ -438,6 +460,318 @@ Debug mode provides detailed information about:
|
|
|
438
460
|
|
|
439
461
|
**Note**: The `DEBUG` environment variable accepts either `'1'` or `'true'` (case-sensitive) to enable debug logging.
|
|
440
462
|
|
|
463
|
+
## High-Value Framework Features
|
|
464
|
+
|
|
465
|
+
EasyMCP provides production-ready features out of the box:
|
|
466
|
+
|
|
467
|
+
### 1. Declarative Tool Registration with @McpTool
|
|
468
|
+
|
|
469
|
+
Define tools using decorators for automatic discovery and registration:
|
|
470
|
+
|
|
471
|
+
```typescript
|
|
472
|
+
import { McpTool, McpParam, McpContext } from 'easy-mcp-nest';
|
|
473
|
+
import { z } from 'zod';
|
|
474
|
+
|
|
475
|
+
const CreateBuildingSchema = z.object({
|
|
476
|
+
name: z.string(),
|
|
477
|
+
address: z.string(),
|
|
478
|
+
});
|
|
479
|
+
|
|
480
|
+
@McpTool({
|
|
481
|
+
name: 'create_building',
|
|
482
|
+
description: 'Creates a new building',
|
|
483
|
+
requiredScopes: ['building:write'],
|
|
484
|
+
rateLimit: { max: 10, window: '1m' },
|
|
485
|
+
retry: { maxAttempts: 3, backoff: 'exponential' }
|
|
486
|
+
})
|
|
487
|
+
async createBuilding(
|
|
488
|
+
@McpParam(CreateBuildingSchema) params: z.infer<typeof CreateBuildingSchema>,
|
|
489
|
+
@McpContext() context: McpContext
|
|
490
|
+
) {
|
|
491
|
+
return this.service.createBuilding(context.userId, params);
|
|
492
|
+
}
|
|
493
|
+
```
|
|
494
|
+
|
|
495
|
+
### 2. Automatic Scope Checking
|
|
496
|
+
|
|
497
|
+
Declarative scope validation - framework handles security automatically:
|
|
498
|
+
|
|
499
|
+
```typescript
|
|
500
|
+
@McpTool({
|
|
501
|
+
name: 'delete_building',
|
|
502
|
+
requiredScopes: ['building:write', 'building:delete']
|
|
503
|
+
})
|
|
504
|
+
```
|
|
505
|
+
|
|
506
|
+
### 3. Progress Notifications
|
|
507
|
+
|
|
508
|
+
Report progress for long-running operations:
|
|
509
|
+
|
|
510
|
+
```typescript
|
|
511
|
+
@McpTool({ name: 'analyze_debts' })
|
|
512
|
+
async analyzeDebts(
|
|
513
|
+
args: any,
|
|
514
|
+
cancellationToken?: CancellationToken,
|
|
515
|
+
context?: McpContext,
|
|
516
|
+
progress?: ProgressCallback
|
|
517
|
+
) {
|
|
518
|
+
progress?.({ progress: 0.1, message: 'Fetching payment data...' });
|
|
519
|
+
// ... work ...
|
|
520
|
+
progress?.({ progress: 0.5, message: 'Processing 5/10 apartments...' });
|
|
521
|
+
// ... work ...
|
|
522
|
+
progress?.({ progress: 1.0, message: 'Complete!' });
|
|
523
|
+
}
|
|
524
|
+
```
|
|
525
|
+
|
|
526
|
+
### 4. Built-in Observability
|
|
527
|
+
|
|
528
|
+
Automatic metrics collection and Prometheus-compatible endpoints:
|
|
529
|
+
|
|
530
|
+
- Tool execution count
|
|
531
|
+
- Average execution time
|
|
532
|
+
- Error rate by tool
|
|
533
|
+
- Request tracing
|
|
534
|
+
- Performance monitoring
|
|
535
|
+
|
|
536
|
+
Access metrics at `/metrics` endpoint (Prometheus format).
|
|
537
|
+
|
|
538
|
+
### 5. Rate Limiting
|
|
539
|
+
|
|
540
|
+
Per-tool rate limiting with configurable limits:
|
|
541
|
+
|
|
542
|
+
```typescript
|
|
543
|
+
@McpTool({
|
|
544
|
+
name: 'create_building',
|
|
545
|
+
rateLimit: { max: 10, window: '1m' } // 10 requests per minute
|
|
546
|
+
})
|
|
547
|
+
```
|
|
548
|
+
|
|
549
|
+
### 6. Retry Logic
|
|
550
|
+
|
|
551
|
+
Automatic retry with exponential backoff:
|
|
552
|
+
|
|
553
|
+
```typescript
|
|
554
|
+
@McpTool({
|
|
555
|
+
name: 'create_building',
|
|
556
|
+
retry: {
|
|
557
|
+
maxAttempts: 3,
|
|
558
|
+
backoff: 'exponential',
|
|
559
|
+
initialDelay: 100,
|
|
560
|
+
maxDelay: 10000
|
|
561
|
+
}
|
|
562
|
+
})
|
|
563
|
+
```
|
|
564
|
+
|
|
565
|
+
### 7. Circuit Breaker
|
|
566
|
+
|
|
567
|
+
Automatic circuit breaking when error rate exceeds threshold:
|
|
568
|
+
|
|
569
|
+
- Prevents overwhelming system during outages
|
|
570
|
+
- Automatic recovery with half-open state
|
|
571
|
+
- Per-tool circuit breakers
|
|
572
|
+
|
|
573
|
+
### 8. Error Handling Hooks
|
|
574
|
+
|
|
575
|
+
Centralized error handling with decorators:
|
|
576
|
+
|
|
577
|
+
```typescript
|
|
578
|
+
@McpErrorHandler((error, context) => {
|
|
579
|
+
logErrorSecurely('MCP error', error, context);
|
|
580
|
+
return sanitizeError(error);
|
|
581
|
+
})
|
|
582
|
+
export class MyErrorHandler {}
|
|
583
|
+
```
|
|
584
|
+
|
|
585
|
+
### 9. Middleware System
|
|
586
|
+
|
|
587
|
+
Pre/post execution hooks for cross-cutting concerns:
|
|
588
|
+
|
|
589
|
+
```typescript
|
|
590
|
+
@McpMiddleware(async (req, context, next) => {
|
|
591
|
+
const start = Date.now();
|
|
592
|
+
const result = await next();
|
|
593
|
+
logPerformance(req.method, Date.now() - start);
|
|
594
|
+
return result;
|
|
595
|
+
})
|
|
596
|
+
export class PerformanceMiddleware {}
|
|
597
|
+
```
|
|
598
|
+
|
|
599
|
+
### 10. Batch Tool Execution
|
|
600
|
+
|
|
601
|
+
Execute multiple tools in parallel:
|
|
602
|
+
|
|
603
|
+
```typescript
|
|
604
|
+
// JSON-RPC request
|
|
605
|
+
{
|
|
606
|
+
"jsonrpc": "2.0",
|
|
607
|
+
"method": "tools/batch",
|
|
608
|
+
"params": {
|
|
609
|
+
"tools": [
|
|
610
|
+
{ "name": "create_building", "arguments": {...} },
|
|
611
|
+
{ "name": "add_apartment", "arguments": {...} }
|
|
612
|
+
]
|
|
613
|
+
}
|
|
614
|
+
}
|
|
615
|
+
```
|
|
616
|
+
|
|
617
|
+
### 11. Health Check Endpoints
|
|
618
|
+
|
|
619
|
+
Production-ready health checks:
|
|
620
|
+
|
|
621
|
+
- `GET /health` - Basic health check
|
|
622
|
+
- `GET /health/ready` - Readiness probe
|
|
623
|
+
- `GET /health/live` - Liveness probe
|
|
624
|
+
- `GET /metrics` - Prometheus metrics
|
|
625
|
+
|
|
626
|
+
### 12. Testing Utilities
|
|
627
|
+
|
|
628
|
+
Easy testing with test helpers:
|
|
629
|
+
|
|
630
|
+
```typescript
|
|
631
|
+
import { createMcpTestApp, mockMcpContext } from 'easy-mcp-nest';
|
|
632
|
+
|
|
633
|
+
const app = await createMcpTestApp([BuildingTools]);
|
|
634
|
+
const context = mockMcpContext({ userId: '123', scopes: ['read', 'write'] });
|
|
635
|
+
const result = await app.callTool('create_building', params, context);
|
|
636
|
+
await app.close();
|
|
637
|
+
```
|
|
638
|
+
|
|
639
|
+
## New Features
|
|
640
|
+
|
|
641
|
+
### Express Adapter
|
|
642
|
+
|
|
643
|
+
Use EasyMCP in Express applications without requiring NestJS for the HTTP layer:
|
|
644
|
+
|
|
645
|
+
```typescript
|
|
646
|
+
import express from 'express';
|
|
647
|
+
import { createMcpExpressRouter } from 'easy-mcp-nest';
|
|
648
|
+
|
|
649
|
+
const app = express();
|
|
650
|
+
app.use(express.json());
|
|
651
|
+
|
|
652
|
+
const mcpRouter = createMcpExpressRouter({
|
|
653
|
+
tools: [BuildingTools, PaymentTools],
|
|
654
|
+
resources: [BuildingResources],
|
|
655
|
+
auth: mcpAuthMiddleware, // Optional
|
|
656
|
+
});
|
|
657
|
+
|
|
658
|
+
app.use('/mcp', mcpRouter);
|
|
659
|
+
app.listen(3000);
|
|
660
|
+
```
|
|
661
|
+
|
|
662
|
+
### Context Injection
|
|
663
|
+
|
|
664
|
+
Inject user context into tools using the `@McpContext()` decorator:
|
|
665
|
+
|
|
666
|
+
```typescript
|
|
667
|
+
import { McpContext, McpContextDecorator } from 'easy-mcp-nest';
|
|
668
|
+
|
|
669
|
+
@McpTool({ name: 'create_building' })
|
|
670
|
+
async createBuilding(
|
|
671
|
+
@McpParam() params: CreateBuildingDto,
|
|
672
|
+
@McpContextDecorator() context: McpContext
|
|
673
|
+
) {
|
|
674
|
+
return this.service.createBuilding(context.userId, params);
|
|
675
|
+
}
|
|
676
|
+
```
|
|
677
|
+
|
|
678
|
+
### Factory Pattern Support
|
|
679
|
+
|
|
680
|
+
Use factory functions instead of dependency injection:
|
|
681
|
+
|
|
682
|
+
```typescript
|
|
683
|
+
import { McpService } from 'easy-mcp-nest';
|
|
684
|
+
|
|
685
|
+
@McpTool({ name: 'create_building' })
|
|
686
|
+
export class BuildingTools {
|
|
687
|
+
constructor(
|
|
688
|
+
@McpService(() => getBuildingService())
|
|
689
|
+
private buildingService: BuildingService
|
|
690
|
+
) {}
|
|
691
|
+
}
|
|
692
|
+
```
|
|
693
|
+
|
|
694
|
+
### OAuth Integration
|
|
695
|
+
|
|
696
|
+
Standardize OAuth integration across MCP servers:
|
|
697
|
+
|
|
698
|
+
```typescript
|
|
699
|
+
import { createOAuthMiddleware, OAuthProviderConfig } from 'easy-mcp-nest';
|
|
700
|
+
|
|
701
|
+
const oauthConfig: OAuthProviderConfig = {
|
|
702
|
+
provider: 'custom',
|
|
703
|
+
validateToken: async (token) => {
|
|
704
|
+
// Validate token and return payload
|
|
705
|
+
return jwt.verify(token, secret);
|
|
706
|
+
},
|
|
707
|
+
extractContext: (payload) => ({
|
|
708
|
+
userId: payload.sub,
|
|
709
|
+
scopes: payload.scopes,
|
|
710
|
+
buildingIds: payload.buildingIds,
|
|
711
|
+
}),
|
|
712
|
+
};
|
|
713
|
+
|
|
714
|
+
const oauthMiddleware = createOAuthMiddleware(oauthProviderService);
|
|
715
|
+
app.use('/mcp', oauthMiddleware, mcpRouter);
|
|
716
|
+
```
|
|
717
|
+
|
|
718
|
+
### TypeScript-First Validation with Zod
|
|
719
|
+
|
|
720
|
+
Use Zod schemas for type-safe validation:
|
|
721
|
+
|
|
722
|
+
```typescript
|
|
723
|
+
import { z } from 'zod';
|
|
724
|
+
import { McpParam } from 'easy-mcp-nest';
|
|
725
|
+
|
|
726
|
+
const CreateBuildingSchema = z.object({
|
|
727
|
+
name: z.string(),
|
|
728
|
+
address: z.string(),
|
|
729
|
+
floors: z.number().int().min(1).max(100),
|
|
730
|
+
});
|
|
731
|
+
|
|
732
|
+
@McpTool({ name: 'create_building' })
|
|
733
|
+
async createBuilding(
|
|
734
|
+
@McpParam(CreateBuildingSchema) params: z.infer<typeof CreateBuildingSchema>
|
|
735
|
+
) {
|
|
736
|
+
// params is fully typed and validated
|
|
737
|
+
return this.service.createBuilding(params);
|
|
738
|
+
}
|
|
739
|
+
```
|
|
740
|
+
|
|
741
|
+
### Standalone Mode
|
|
742
|
+
|
|
743
|
+
Use EasyMCP without NestJS:
|
|
744
|
+
|
|
745
|
+
```typescript
|
|
746
|
+
import { createMcpServer } from 'easy-mcp-nest';
|
|
747
|
+
|
|
748
|
+
const server = createMcpServer({
|
|
749
|
+
tools: [BuildingTools, PaymentTools],
|
|
750
|
+
resources: [BuildingResources],
|
|
751
|
+
transport: 'http', // or 'stdio'
|
|
752
|
+
auth: validateMcpToken, // Optional
|
|
753
|
+
port: 3000,
|
|
754
|
+
});
|
|
755
|
+
|
|
756
|
+
await server.start();
|
|
757
|
+
```
|
|
758
|
+
|
|
759
|
+
### Testing Utilities
|
|
760
|
+
|
|
761
|
+
Test MCP tools easily:
|
|
762
|
+
|
|
763
|
+
```typescript
|
|
764
|
+
import { createMcpTestApp, mockMcpContext } from 'easy-mcp-nest';
|
|
765
|
+
|
|
766
|
+
const app = await createMcpTestApp([BuildingTools]);
|
|
767
|
+
const context = mockMcpContext({
|
|
768
|
+
userId: '123',
|
|
769
|
+
scopes: ['read', 'write'],
|
|
770
|
+
});
|
|
771
|
+
const result = await app.callTool('create_building', params, context);
|
|
772
|
+
await app.close();
|
|
773
|
+
```
|
|
774
|
+
|
|
441
775
|
## Examples
|
|
442
776
|
|
|
443
777
|
See the `examples/` directory for complete working examples.
|
package/dist/EasyMCP.js
CHANGED
|
@@ -35,7 +35,6 @@ class EasyMCP {
|
|
|
35
35
|
toolRegistry.registerToolFromConfig(tool);
|
|
36
36
|
}
|
|
37
37
|
catch (error) {
|
|
38
|
-
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
39
38
|
const sanitizedToolName = (0, sanitize_util_1.sanitizeName)(tool.name);
|
|
40
39
|
logger_util_1.logger.error("EasyMCP", "Failed to register tool", {
|
|
41
40
|
component: "EasyMCP",
|
|
@@ -57,7 +56,6 @@ class EasyMCP {
|
|
|
57
56
|
resourceRegistry.registerResourceFromConfig(resource);
|
|
58
57
|
}
|
|
59
58
|
catch (error) {
|
|
60
|
-
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
61
59
|
const sanitizedUri = (0, sanitize_util_1.sanitizeUri)(resource.uri);
|
|
62
60
|
logger_util_1.logger.error("EasyMCP", "Failed to register resource", {
|
|
63
61
|
component: "EasyMCP",
|
|
@@ -79,7 +77,6 @@ class EasyMCP {
|
|
|
79
77
|
promptRegistry.registerPromptFromConfig(prompt);
|
|
80
78
|
}
|
|
81
79
|
catch (error) {
|
|
82
|
-
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
83
80
|
const sanitizedPromptName = (0, sanitize_util_1.sanitizeName)(prompt.name);
|
|
84
81
|
logger_util_1.logger.error("EasyMCP", "Failed to register prompt", {
|
|
85
82
|
component: "EasyMCP",
|
package/dist/EasyMCP.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"EasyMCP.js","sourceRoot":"","sources":["../src/EasyMCP.ts"],"names":[],"mappings":";;;AAAA,uCAA2C;AAE3C,6CAAyC;AAEzC,kDAAkD;AAClD,6EAAwE;AAExE,gEAA4D;AAC5D,yFAAoF;AACpF,qFAAgF;AAChF,+EAA0E;AAC1E,0DAAkD;AAClD,8DAA6F;AAC7F,4EAAuE;AAIvE,MAAa,OAAO;IACV,MAAM,CAAC,GAAG,CAA0B;IAOrC,MAAM,CAAC,KAAK,CAAC,UAAU,CAAC,MAAiB;QAC9C,IAAI,IAAI,CAAC,GAAG,EAAE,CAAC;YACb,oBAAM,CAAC,IAAI,CAAC,SAAS,EAAE,gCAAgC,EAAE;gBACvD,SAAS,EAAE,SAAS;aACrB,CAAC,CAAC;YACH,OAAO;QACT,CAAC;QAGD,kCAAe,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;QAKjC,MAAM,SAAS,GAAG,MAAM,kBAAW,CAAC,wBAAwB,CAAC,sBAAS,EAAE;YACtE,MAAM,EAAE,IAAI,yCAAkB,EAAE;SACjC,CAAC,CAAC;QACH,IAAI,CAAC,GAAG,GAAG,SAAS,CAAC;QAIrB,MAAM,YAAY,GAAG,SAAS,CAAC,GAAG,CAAsB,wBAAY,CAAC,CAAC;QACtE,YAAY,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;QAG/B,IAAI,MAAM,CAAC,KAAK,IAAI,MAAM,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC5C,MAAM,YAAY,GAAG,SAAS,CAAC,GAAG,CAAsB,2CAAmB,CAAC,CAAC;YAC7E,KAAK,MAAM,IAAI,IAAI,MAAM,CAAC,KAAK,EAAE,CAAC;gBAChC,IAAI,CAAC;oBACH,YAAY,CAAC,sBAAsB,CAAC,IAAI,CAAC,CAAC;gBAC5C,CAAC;gBAAC,OAAO,KAAK,EAAE,CAAC;oBACf,MAAM,
|
|
1
|
+
{"version":3,"file":"EasyMCP.js","sourceRoot":"","sources":["../src/EasyMCP.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createMcpExpressRouter = createMcpExpressRouter;
|
|
4
|
+
const express_1 = require("express");
|
|
5
|
+
const constants_1 = require("../../config/constants");
|
|
6
|
+
const EasyMCP_1 = require("../../EasyMCP");
|
|
7
|
+
const http_gateway_service_1 = require("./http-gateway.service");
|
|
8
|
+
const logger_util_1 = require("../../core/utils/logger.util");
|
|
9
|
+
const sanitize_util_1 = require("../../core/utils/sanitize.util");
|
|
10
|
+
const mcp_server_service_1 = require("../../core/mcp-server/mcp-server.service");
|
|
11
|
+
const oauth_provider_service_1 = require("../../auth/oauth/oauth-provider.service");
|
|
12
|
+
const oauth_middleware_1 = require("../../auth/oauth/oauth-middleware");
|
|
13
|
+
function createMcpExpressRouter(options) {
|
|
14
|
+
const router = (0, express_1.Router)();
|
|
15
|
+
const pathPrefix = options.pathPrefix || "/mcp";
|
|
16
|
+
const tools = (options.tools || []).map((tool) => {
|
|
17
|
+
if (tool && typeof tool === "object" && "name" in tool && "function" in tool) {
|
|
18
|
+
return tool;
|
|
19
|
+
}
|
|
20
|
+
if (typeof tool === "function") {
|
|
21
|
+
throw new Error("Class-based tools are not directly supported in createMcpExpressRouter. Please convert them to ToolRegistrationInput format or register them via NestJS modules.");
|
|
22
|
+
}
|
|
23
|
+
throw new Error("Tools must be in ToolRegistrationInput format or a class constructor. Use the config-based or decorator-based approach.");
|
|
24
|
+
});
|
|
25
|
+
const config = {
|
|
26
|
+
tools,
|
|
27
|
+
resources: options.resources || [],
|
|
28
|
+
prompts: options.prompts || [],
|
|
29
|
+
serverInfo: options.serverInfo,
|
|
30
|
+
};
|
|
31
|
+
let mcpServerService = null;
|
|
32
|
+
let httpGateway = null;
|
|
33
|
+
const initPromise = (async () => {
|
|
34
|
+
await EasyMCP_1.EasyMCP.initialize(config);
|
|
35
|
+
const appContext = EasyMCP_1.EasyMCP.app;
|
|
36
|
+
mcpServerService = appContext.get(mcp_server_service_1.McpServerService);
|
|
37
|
+
httpGateway = new http_gateway_service_1.HttpGatewayService();
|
|
38
|
+
if (mcpServerService) {
|
|
39
|
+
httpGateway.setMcpServerService(mcpServerService);
|
|
40
|
+
}
|
|
41
|
+
})();
|
|
42
|
+
router.use(async (req, res, next) => {
|
|
43
|
+
try {
|
|
44
|
+
await initPromise;
|
|
45
|
+
next();
|
|
46
|
+
}
|
|
47
|
+
catch (error) {
|
|
48
|
+
logger_util_1.logger.error("ExpressAdapter", "Failed to initialize EasyMCP", {
|
|
49
|
+
error: (0, sanitize_util_1.sanitizeErrorMessage)(error),
|
|
50
|
+
});
|
|
51
|
+
res.status(500).json({
|
|
52
|
+
jsonrpc: "2.0",
|
|
53
|
+
id: null,
|
|
54
|
+
error: {
|
|
55
|
+
code: -32603,
|
|
56
|
+
message: "Internal error",
|
|
57
|
+
},
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
});
|
|
61
|
+
if (options.auth) {
|
|
62
|
+
router.use(options.auth);
|
|
63
|
+
}
|
|
64
|
+
else if (options.oauth) {
|
|
65
|
+
const oauthProvider = new oauth_provider_service_1.OAuthProviderService();
|
|
66
|
+
oauthProvider.setConfig(options.oauth);
|
|
67
|
+
router.use((0, oauth_middleware_1.createOAuthMiddleware)(oauthProvider));
|
|
68
|
+
}
|
|
69
|
+
const extractContext = (req) => {
|
|
70
|
+
if (req.mcpContext) {
|
|
71
|
+
return req.mcpContext;
|
|
72
|
+
}
|
|
73
|
+
if (options.auth || options.oauth) {
|
|
74
|
+
return undefined;
|
|
75
|
+
}
|
|
76
|
+
const context = {};
|
|
77
|
+
if (req.headers["x-user-id"]) {
|
|
78
|
+
context.userId = String(req.headers["x-user-id"]);
|
|
79
|
+
}
|
|
80
|
+
if (req.headers["x-scopes"]) {
|
|
81
|
+
const scopes = req.headers["x-scopes"];
|
|
82
|
+
context.scopes = Array.isArray(scopes)
|
|
83
|
+
? scopes.map(String)
|
|
84
|
+
: String(scopes).split(",").map(s => s.trim());
|
|
85
|
+
}
|
|
86
|
+
if (req.headers["x-building-ids"]) {
|
|
87
|
+
const buildingIds = req.headers["x-building-ids"];
|
|
88
|
+
context.buildingIds = Array.isArray(buildingIds)
|
|
89
|
+
? buildingIds.map(String)
|
|
90
|
+
: String(buildingIds).split(",").map(s => s.trim());
|
|
91
|
+
}
|
|
92
|
+
if (Object.keys(context).length > 0) {
|
|
93
|
+
logger_util_1.logger.warn("ExpressAdapter", "Using unauthenticated headers for context extraction", {
|
|
94
|
+
component: "ExpressAdapter",
|
|
95
|
+
warning: "Headers are not authenticated and can be spoofed. Use auth middleware in production.",
|
|
96
|
+
});
|
|
97
|
+
return context;
|
|
98
|
+
}
|
|
99
|
+
return undefined;
|
|
100
|
+
};
|
|
101
|
+
router.post("/", (0, express_1.json)({ limit: constants_1.MAX_MESSAGE_SIZE_BYTES }), async (req, res) => {
|
|
102
|
+
if (!httpGateway || !mcpServerService) {
|
|
103
|
+
res.status(500).json({
|
|
104
|
+
jsonrpc: "2.0",
|
|
105
|
+
id: null,
|
|
106
|
+
error: {
|
|
107
|
+
code: -32603,
|
|
108
|
+
message: "Internal error",
|
|
109
|
+
},
|
|
110
|
+
});
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
113
|
+
const context = extractContext(req);
|
|
114
|
+
await httpGateway.handleHttpRequest(req, res, context);
|
|
115
|
+
});
|
|
116
|
+
router.get(`${pathPrefix}/health`, (req, res) => {
|
|
117
|
+
res.json({
|
|
118
|
+
status: "ok",
|
|
119
|
+
service: "mcp-server",
|
|
120
|
+
version: config.serverInfo?.version || "unknown",
|
|
121
|
+
});
|
|
122
|
+
});
|
|
123
|
+
router.get(`${pathPrefix}/health/ready`, (req, res) => {
|
|
124
|
+
const ready = tools.length > 0;
|
|
125
|
+
res.status(ready ? 200 : 503).json({ ready });
|
|
126
|
+
});
|
|
127
|
+
router.get(`${pathPrefix}/health/live`, (req, res) => {
|
|
128
|
+
res.status(200).json({ alive: true });
|
|
129
|
+
});
|
|
130
|
+
router.get(`${pathPrefix}/metrics`, (req, res) => {
|
|
131
|
+
res.status(200).set("Content-Type", "text/plain").send("# Metrics endpoint - implement with MetricsService");
|
|
132
|
+
});
|
|
133
|
+
return router;
|
|
134
|
+
}
|
|
135
|
+
//# sourceMappingURL=express-adapter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"express-adapter.js","sourceRoot":"","sources":["../../../src/adapters/express/express-adapter.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { Request, Response } from "express";
|
|
2
|
+
import { IInterfaceLayer } from "../../interface/interface.interface";
|
|
3
|
+
import { McpServerService } from "../../core/mcp-server/mcp-server.service";
|
|
4
|
+
import { McpContext } from "../../core/context/mcp-context.interface";
|
|
5
|
+
export declare class HttpGatewayService implements IInterfaceLayer {
|
|
6
|
+
private mcpServerService;
|
|
7
|
+
private requestContextMap;
|
|
8
|
+
constructor();
|
|
9
|
+
setMcpServerService(service: McpServerService): void;
|
|
10
|
+
start(): Promise<void>;
|
|
11
|
+
sendMessage(sessionId: string, output: unknown): Promise<void>;
|
|
12
|
+
handleHttpRequest(req: Request, res: Response, context?: McpContext): Promise<void>;
|
|
13
|
+
}
|