easy-mcp-nest 0.1.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.
Files changed (82) hide show
  1. package/LICENSE +22 -0
  2. package/README.md +417 -0
  3. package/dist/EasyMCP.d.ts +8 -0
  4. package/dist/EasyMCP.js +105 -0
  5. package/dist/EasyMCP.js.map +1 -0
  6. package/dist/app.controller.d.ts +6 -0
  7. package/dist/app.controller.js +35 -0
  8. package/dist/app.controller.js.map +1 -0
  9. package/dist/app.module.d.ts +2 -0
  10. package/dist/app.module.js +34 -0
  11. package/dist/app.module.js.map +1 -0
  12. package/dist/app.service.d.ts +3 -0
  13. package/dist/app.service.js +20 -0
  14. package/dist/app.service.js.map +1 -0
  15. package/dist/config/config-holder.service.d.ts +6 -0
  16. package/dist/config/config-holder.service.js +32 -0
  17. package/dist/config/config-holder.service.js.map +1 -0
  18. package/dist/config/config-validator.d.ts +5 -0
  19. package/dist/config/config-validator.js +78 -0
  20. package/dist/config/config-validator.js.map +1 -0
  21. package/dist/config/constants.d.ts +4 -0
  22. package/dist/config/constants.js +8 -0
  23. package/dist/config/constants.js.map +1 -0
  24. package/dist/config/mcp-config.interface.d.ts +18 -0
  25. package/dist/config/mcp-config.interface.js +3 -0
  26. package/dist/config/mcp-config.interface.js.map +1 -0
  27. package/dist/config/version.d.ts +4 -0
  28. package/dist/config/version.js +41 -0
  29. package/dist/config/version.js.map +1 -0
  30. package/dist/core/core.module.d.ts +2 -0
  31. package/dist/core/core.module.js +24 -0
  32. package/dist/core/core.module.js.map +1 -0
  33. package/dist/core/errors/easy-mcp-error.d.ts +14 -0
  34. package/dist/core/errors/easy-mcp-error.js +39 -0
  35. package/dist/core/errors/easy-mcp-error.js.map +1 -0
  36. package/dist/core/mcp-server/mcp-server.service.d.ts +22 -0
  37. package/dist/core/mcp-server/mcp-server.service.js +285 -0
  38. package/dist/core/mcp-server/mcp-server.service.js.map +1 -0
  39. package/dist/core/utils/logger.util.d.ts +26 -0
  40. package/dist/core/utils/logger.util.js +44 -0
  41. package/dist/core/utils/logger.util.js.map +1 -0
  42. package/dist/core/utils/nestjs-stderr-logger.d.ts +9 -0
  43. package/dist/core/utils/nestjs-stderr-logger.js +123 -0
  44. package/dist/core/utils/nestjs-stderr-logger.js.map +1 -0
  45. package/dist/core/utils/sanitize.util.d.ts +6 -0
  46. package/dist/core/utils/sanitize.util.js +111 -0
  47. package/dist/core/utils/sanitize.util.js.map +1 -0
  48. package/dist/core/utils/schema-validator.d.ts +2 -0
  49. package/dist/core/utils/schema-validator.js +62 -0
  50. package/dist/core/utils/schema-validator.js.map +1 -0
  51. package/dist/index.d.ts +11 -0
  52. package/dist/index.js +22 -0
  53. package/dist/index.js.map +1 -0
  54. package/dist/interface/interface.interface.d.ts +4 -0
  55. package/dist/interface/interface.interface.js +3 -0
  56. package/dist/interface/interface.interface.js.map +1 -0
  57. package/dist/interface/interface.module.d.ts +2 -0
  58. package/dist/interface/interface.module.js +29 -0
  59. package/dist/interface/interface.module.js.map +1 -0
  60. package/dist/interface/jsonrpc.interface.d.ts +27 -0
  61. package/dist/interface/jsonrpc.interface.js +42 -0
  62. package/dist/interface/jsonrpc.interface.js.map +1 -0
  63. package/dist/interface/mcp-protocol.interface.d.ts +58 -0
  64. package/dist/interface/mcp-protocol.interface.js +13 -0
  65. package/dist/interface/mcp-protocol.interface.js.map +1 -0
  66. package/dist/interface/mcp.interface.d.ts +44 -0
  67. package/dist/interface/mcp.interface.js +3 -0
  68. package/dist/interface/mcp.interface.js.map +1 -0
  69. package/dist/interface/stdio-gateway.service.d.ts +20 -0
  70. package/dist/interface/stdio-gateway.service.js +373 -0
  71. package/dist/interface/stdio-gateway.service.js.map +1 -0
  72. package/dist/main.d.ts +1 -0
  73. package/dist/main.js +17 -0
  74. package/dist/main.js.map +1 -0
  75. package/dist/tooling/tool-registry/tool-registry.service.d.ts +23 -0
  76. package/dist/tooling/tool-registry/tool-registry.service.js +122 -0
  77. package/dist/tooling/tool-registry/tool-registry.service.js.map +1 -0
  78. package/dist/tooling/tool.interface.d.ts +13 -0
  79. package/dist/tooling/tool.interface.js +3 -0
  80. package/dist/tooling/tool.interface.js.map +1 -0
  81. package/dist/tsconfig.build.tsbuildinfo +1 -0
  82. package/package.json +104 -0
package/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Nir Arazi
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
22
+
package/README.md ADDED
@@ -0,0 +1,417 @@
1
+ # EasyMCP Framework
2
+
3
+ A NestJS-based framework for building standard Model Context Protocol (MCP) servers with tool execution via JSON-RPC 2.0.
4
+
5
+ ## Description
6
+
7
+ EasyMCP simplifies the creation of MCP (Model Context Protocol) servers by providing a clean, type-safe framework that:
8
+
9
+ - **Standard MCP Protocol**: Implements the Model Context Protocol specification with JSON-RPC 2.0 over stdio
10
+ - **Tool Execution**: Register and execute tools that external LLM agents can discover and call
11
+ - **Type Safety**: Full TypeScript support with comprehensive type definitions
12
+ - **Simple Configuration**: Minimal setup required - just define your tools and run
13
+
14
+ ## Installation
15
+
16
+ ```bash
17
+ npm install easy-mcp-framework
18
+ # or
19
+ pnpm add easy-mcp-framework
20
+ # or
21
+ yarn add easy-mcp-framework
22
+ ```
23
+
24
+ ### Peer Dependencies
25
+
26
+ EasyMCP requires the following peer dependencies to be installed:
27
+
28
+ - `@nestjs/common` ^11.0.1
29
+ - `@nestjs/core` ^11.0.1
30
+ - `@nestjs/platform-express` ^11.0.1
31
+
32
+ Install them with:
33
+
34
+ ```bash
35
+ npm install @nestjs/common@^11.0.1 @nestjs/core@^11.0.1 @nestjs/platform-express@^11.0.1
36
+ ```
37
+
38
+ ## Quick Start
39
+
40
+ ```typescript
41
+ import { EasyMCP, McpConfig } from 'easy-mcp-framework';
42
+
43
+ // Define your tools
44
+ async function getUser(args: { userId: string }): Promise<string> {
45
+ // Your tool logic here
46
+ const user = await fetchUser(args.userId);
47
+ return JSON.stringify(user);
48
+ }
49
+
50
+ // Configure EasyMCP
51
+ const config: McpConfig = {
52
+ tools: [
53
+ {
54
+ name: 'getUser',
55
+ description: 'Retrieves user details by ID',
56
+ function: getUser,
57
+ inputSchema: {
58
+ type: 'OBJECT',
59
+ properties: {
60
+ userId: {
61
+ type: 'STRING',
62
+ description: 'The unique ID of the user',
63
+ },
64
+ },
65
+ required: ['userId'],
66
+ },
67
+ },
68
+ ],
69
+ };
70
+
71
+ // Initialize and run
72
+ async function bootstrap() {
73
+ await EasyMCP.initialize(config);
74
+ await EasyMCP.run();
75
+ }
76
+
77
+ bootstrap();
78
+ ```
79
+
80
+ ## Configuration
81
+
82
+ ### McpConfig
83
+
84
+ The main configuration object passed to `EasyMCP.initialize()`:
85
+
86
+ ```typescript
87
+ interface McpConfig {
88
+ tools: ToolRegistrationInput[];
89
+ serverInfo?: ServerInfo;
90
+ }
91
+ ```
92
+
93
+ ### ToolRegistrationInput
94
+
95
+ Each tool must implement:
96
+
97
+ ```typescript
98
+ interface ToolRegistrationInput {
99
+ name: string;
100
+ description: string;
101
+ function: (args: Record<string, any>) => Promise<any>;
102
+ inputSchema: {
103
+ type: 'OBJECT';
104
+ properties: Record<string, {
105
+ type: 'STRING' | 'NUMBER' | 'INTEGER' | 'BOOLEAN' | 'ARRAY' | 'OBJECT';
106
+ description: string;
107
+ enum?: string[];
108
+ }>;
109
+ required?: string[];
110
+ };
111
+ }
112
+ ```
113
+
114
+ ### ServerInfo (Optional)
115
+
116
+ Optional server information for MCP initialize response:
117
+
118
+ ```typescript
119
+ interface ServerInfo {
120
+ name: string;
121
+ version: string;
122
+ }
123
+ ```
124
+
125
+ ### Example Tool
126
+
127
+ ```typescript
128
+ async function searchDatabase(args: { query: string; limit?: number }): Promise<string> {
129
+ const results = await db.search(args.query, args.limit || 10);
130
+ return JSON.stringify(results);
131
+ }
132
+
133
+ const searchTool: ToolRegistrationInput = {
134
+ name: 'searchDatabase',
135
+ description: 'Searches the database for matching records',
136
+ function: searchDatabase,
137
+ inputSchema: {
138
+ type: 'OBJECT',
139
+ properties: {
140
+ query: {
141
+ type: 'STRING',
142
+ description: 'The search query',
143
+ },
144
+ limit: {
145
+ type: 'INTEGER',
146
+ description: 'Maximum number of results to return',
147
+ },
148
+ },
149
+ required: ['query'],
150
+ },
151
+ };
152
+ ```
153
+
154
+ ## API Reference
155
+
156
+ ### EasyMCP Class
157
+
158
+ #### `static initialize(config: McpConfig): Promise<void>`
159
+
160
+ Initializes the EasyMCP framework with the provided configuration. Must be called before `run()`.
161
+
162
+ #### `static run(): Promise<void>`
163
+
164
+ Starts the EasyMCP server and begins listening for JSON-RPC requests via stdio.
165
+
166
+ #### `static getService<T>(token: string | symbol): T`
167
+
168
+ Retrieves a service from the NestJS application context. Useful for advanced use cases.
169
+
170
+ #### `static shutdown(): Promise<void>`
171
+
172
+ Gracefully shuts down the EasyMCP framework, closing the NestJS application context and cleaning up resources. Should be called when the application is terminating (e.g., on SIGTERM, SIGINT signals).
173
+
174
+ ```typescript
175
+ // Example: Handle graceful shutdown
176
+ process.on('SIGTERM', async () => {
177
+ await EasyMCP.shutdown();
178
+ process.exit(0);
179
+ });
180
+
181
+ process.on('SIGINT', async () => {
182
+ await EasyMCP.shutdown();
183
+ process.exit(0);
184
+ });
185
+ ```
186
+
187
+ ### Types
188
+
189
+ - `McpConfig` - Main configuration interface
190
+ - `ToolRegistrationInput` - Tool definition interface
191
+ - `ServerInfo` - Optional server information
192
+ - `JsonRpcRequest`, `JsonRpcResponse` - JSON-RPC 2.0 types
193
+ - `InitializeParams`, `InitializeResult` - MCP initialize types
194
+ - `ListToolsResult`, `McpTool` - MCP tools types
195
+ - `CallToolParams`, `CallToolResult` - MCP tool call types
196
+ - `ToolDefinition`, `ToolParameter`, `ToolFunction` - Tool interfaces
197
+ - `IInterfaceLayer` - Interface layer interface
198
+
199
+ ## Architecture
200
+
201
+ EasyMCP uses a simplified architecture for standard MCP servers:
202
+
203
+ 1. **Interface Layer**: Handles JSON-RPC 2.0 communication over stdio
204
+ 2. **Core Layer**: Implements MCP protocol methods (initialize, tools/list, tools/call)
205
+ 3. **Tool Registry**: Manages tool registration and execution
206
+
207
+ ### Architecture Diagram
208
+
209
+ ```mermaid
210
+ graph TB
211
+ MCPClient[MCP Client<br/>Claude Desktop, Cline, etc.] -->|stdio JSON-RPC| Interface[Interface Layer<br/>StdioGatewayService]
212
+ Interface -->|JsonRpcRequest| Core[McpServerService<br/>Core Orchestrator]
213
+ Core -->|getTools| Registry[ToolRegistryService]
214
+ Core -->|executeTool| Tools[User Tools]
215
+ Core -->|JsonRpcResponse| Interface
216
+ Interface -->|Response| MCPClient
217
+ ```
218
+
219
+ ## MCP Protocol Compliance
220
+
221
+ EasyMCP implements the standard Model Context Protocol (MCP) specification version **2024-11-05**.
222
+
223
+ ### Protocol Version
224
+
225
+ - **Supported Version**: `2024-11-05`
226
+ - **Validation**: The framework validates that clients use the supported protocol version during initialization
227
+ - **Error Handling**: Unsupported protocol versions are rejected with a clear error message
228
+
229
+ ### Supported Methods
230
+
231
+ EasyMCP implements the following MCP protocol methods:
232
+
233
+ - **`initialize`** - Server/client handshake, returns server capabilities and protocol version
234
+ - Validates client protocol version
235
+ - Returns server capabilities (currently supports tools)
236
+ - Returns server information (name and version)
237
+
238
+ - **`tools/list`** - Returns all registered tools with their JSON Schema definitions
239
+ - Returns array of tool definitions in MCP format
240
+ - Each tool includes name, description, and inputSchema
241
+
242
+ - **`tools/call`** - Executes a tool with provided arguments and returns the result
243
+ - Validates tool arguments against schema
244
+ - Executes tool function
245
+ - Returns result in MCP content format
246
+ - Handles errors according to MCP error code specification
247
+
248
+ ### Error Codes
249
+
250
+ EasyMCP uses standard JSON-RPC 2.0 and MCP error codes:
251
+
252
+ - `-32700` - Parse error
253
+ - `-32600` - Invalid request
254
+ - `-32601` - Method not found
255
+ - `-32602` - Invalid params
256
+ - `-32603` - Internal error
257
+ - `-32001` - Tool not found (MCP-specific)
258
+ - `-32002` - Tool execution error (MCP-specific)
259
+
260
+ ### Transport
261
+
262
+ The server communicates via JSON-RPC 2.0 over stdio (standard input/output), which is the standard transport for MCP servers. This allows the server to be used with MCP clients like Claude Desktop, Cursor, Cline, and other MCP-compatible tools.
263
+
264
+ **Default Mode: Newline-Delimited JSON**
265
+
266
+ By default, the server uses newline-delimited JSON (one JSON-RPC message per line) for maximum compatibility with MCP clients. This mode works seamlessly with Cursor, Claude Desktop, and other popular MCP clients.
267
+
268
+ **Content-Length Framing Mode (Optional)**
269
+
270
+ For strict MCP protocol compliance with Content-Length framing, set the environment variable:
271
+ ```bash
272
+ MCP_USE_CONTENT_LENGTH=1
273
+ ```
274
+
275
+ This enables the MCP-specified Content-Length header format, which some clients may not parse correctly.
276
+
277
+ ### Limitations
278
+
279
+ - **Transport**: Currently only stdio transport is supported. WebSocket and HTTP transports are not available.
280
+ - **Capabilities**: Only tools capability is implemented. Resources and prompts capabilities are not yet supported.
281
+ - **Protocol Version**: Only protocol version 2024-11-05 is supported. Older or newer versions will be rejected.
282
+
283
+ For more information on testing EasyMCP with real MCP clients, see [Integration Testing Guide](docs/INTEGRATION_TESTING.md).
284
+
285
+ ## Error Handling
286
+
287
+ EasyMCP provides comprehensive error handling with custom error classes and clear error messages.
288
+
289
+ ### Error Classes
290
+
291
+ - **`EasyMcpError`** - Base error class for all framework errors
292
+ - **`ConfigurationError`** - Configuration validation errors (thrown during `initialize()`)
293
+ - **`ToolExecutionError`** - Tool execution failures (wrapped and returned as MCP error)
294
+ - **`ToolNotFoundError`** - Tool not found in registry (returned as MCP error code -32001)
295
+
296
+ ### Error Handling Examples
297
+
298
+ ```typescript
299
+ import {
300
+ EasyMCP,
301
+ ConfigurationError,
302
+ ToolExecutionError,
303
+ ToolNotFoundError
304
+ } from 'easy-mcp-framework';
305
+
306
+ // Configuration errors - caught during initialization
307
+ try {
308
+ await EasyMCP.initialize(config);
309
+ } catch (error) {
310
+ if (error instanceof ConfigurationError) {
311
+ console.error('Configuration error:', error.message);
312
+ // Example: "Tool 'myTool': name must be a non-empty string"
313
+ }
314
+ }
315
+
316
+ // Tool execution errors - handled automatically by MCP protocol
317
+ // When a tool throws an error, it's automatically converted to an MCP error response
318
+ // The error is logged to stderr and returned to the client with error code -32002
319
+ ```
320
+
321
+ ### Common Error Scenarios
322
+
323
+ **Configuration Errors:**
324
+ - Missing required fields (tools array, tool name, description, etc.)
325
+ - Invalid tool schemas (unsupported types, missing properties)
326
+ - Invalid serverInfo format
327
+
328
+ **Tool Execution Errors:**
329
+ - Tool function throws an exception → Returns MCP error code -32002
330
+ - Tool not found → Returns MCP error code -32001
331
+ - Invalid tool arguments → Returns JSON-RPC error code -32602 (Invalid Params)
332
+
333
+ **Protocol Errors:**
334
+ - Unsupported protocol version → Returns error code -32602 with clear message
335
+ - Invalid JSON-RPC request → Returns error code -32600 (Invalid Request)
336
+ - Unknown method → Returns error code -32601 (Method Not Found)
337
+
338
+ ### Error Message Format
339
+
340
+ All error messages are designed to be helpful for debugging:
341
+ - Include the context (tool name, parameter name, etc.)
342
+ - Provide suggestions when possible
343
+ - Never expose internal implementation details to clients
344
+
345
+ Example error messages:
346
+ - `"Tool 'getUser': property 'userId' must have a description"`
347
+ - `"Unsupported protocol version: 2024-10-01. Supported version: 2024-11-05"`
348
+ - `"Missing required parameter: userId"`
349
+
350
+ ## Troubleshooting
351
+
352
+ ### Tools Not Executing
353
+
354
+ If tools are registered but not being called:
355
+
356
+ 1. **Check Tool Registration**: Verify tools appear in console log during initialization
357
+ 2. **Tool Schema**: Ensure `inputSchema` matches JSON Schema format
358
+ 3. **Tool Description**: Make tool descriptions clear so LLM agents know when to use them
359
+ 4. **MCP Client**: Verify your MCP client (Claude Desktop, etc.) is properly configured
360
+ 5. **Enable Debug Logging**: Set `DEBUG=1` environment variable to see detailed protocol messages
361
+
362
+ ### Build/Import Issues
363
+
364
+ If you encounter TypeScript or import errors:
365
+
366
+ 1. **Peer Dependencies**: Ensure all peer dependencies are installed (see Installation section)
367
+ 2. **Type Exports**: Verify you're importing from the main package: `import { EasyMCP } from 'easy-mcp-framework'`
368
+ 3. **Build Output**: Check that `dist/index.js` and `dist/index.d.ts` exist after building
369
+ 4. **Module Resolution**: Ensure your `tsconfig.json` has proper module resolution settings
370
+
371
+ ### Protocol Version Errors
372
+
373
+ If you see "Unsupported protocol version" errors:
374
+
375
+ 1. **Check Client Version**: Ensure your MCP client uses protocol version `2024-11-05`
376
+ 2. **Update Client**: Update your MCP client to the latest version
377
+ 3. **Debug Mode**: Set `DEBUG=1` to see detailed protocol version information
378
+
379
+ ### Integration Issues
380
+
381
+ If your server doesn't work with MCP clients:
382
+
383
+ 1. **Check Configuration**: Verify your MCP client configuration is correct
384
+ 2. **Test Server**: Run your server script directly to verify it starts correctly
385
+ 3. **Review Logs**: Check stderr output for initialization and error messages
386
+ 4. **Integration Guide**: See [Integration Testing Guide](docs/INTEGRATION_TESTING.md) for detailed setup instructions
387
+ 5. **Examples**: Check [examples/claude-desktop-integration](examples/claude-desktop-integration) and [examples/cursor-integration](examples/cursor-integration) for client-specific setup
388
+
389
+ ### Debug Mode
390
+
391
+ Enable debug logging to troubleshoot issues:
392
+
393
+ ```bash
394
+ DEBUG=1 node your-server.js
395
+ ```
396
+
397
+ Debug mode provides detailed information about:
398
+ - Protocol message flow
399
+ - Tool execution details
400
+ - Protocol version validation
401
+ - Argument validation
402
+
403
+ ## Examples
404
+
405
+ See the `examples/` directory for complete working examples.
406
+
407
+ ## Contributing
408
+
409
+ Contributions are welcome! Please feel free to submit a Pull Request.
410
+
411
+ ## License
412
+
413
+ MIT License - see [LICENSE](LICENSE) file for details.
414
+
415
+ ## Support
416
+
417
+ For issues and questions, please open an issue on [GitHub](https://github.com/nirarazi/easy-mcp).
@@ -0,0 +1,8 @@
1
+ import { McpConfig } from "./config/mcp-config.interface";
2
+ export declare class EasyMCP {
3
+ private static app;
4
+ static initialize(config: McpConfig): Promise<void>;
5
+ static run(): Promise<void>;
6
+ static getService<T>(token: string | symbol): T;
7
+ static shutdown(): Promise<void>;
8
+ }
@@ -0,0 +1,105 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.EasyMCP = void 0;
4
+ const core_1 = require("@nestjs/core");
5
+ const app_module_1 = require("./app.module");
6
+ const constants_1 = require("./config/constants");
7
+ const mcp_server_service_1 = require("./core/mcp-server/mcp-server.service");
8
+ const config_validator_1 = require("./config/config-validator");
9
+ const tool_registry_service_1 = require("./tooling/tool-registry/tool-registry.service");
10
+ const logger_util_1 = require("./core/utils/logger.util");
11
+ const sanitize_util_1 = require("./core/utils/sanitize.util");
12
+ const nestjs_stderr_logger_1 = require("./core/utils/nestjs-stderr-logger");
13
+ class EasyMCP {
14
+ static app;
15
+ static async initialize(config) {
16
+ if (this.app) {
17
+ logger_util_1.logger.warn("EasyMCP", "EasyMCP is already initialized", {
18
+ component: "EasyMCP",
19
+ });
20
+ return;
21
+ }
22
+ config_validator_1.ConfigValidator.validate(config);
23
+ const moduleRef = await core_1.NestFactory.createApplicationContext(app_module_1.AppModule, {
24
+ logger: new nestjs_stderr_logger_1.NestjsStderrLogger(),
25
+ });
26
+ this.app = moduleRef;
27
+ const configHolder = moduleRef.get(constants_1.CONFIG_TOKEN);
28
+ configHolder.setConfig(config);
29
+ if (config.tools && config.tools.length > 0) {
30
+ const toolRegistry = moduleRef.get(tool_registry_service_1.ToolRegistryService);
31
+ for (const tool of config.tools) {
32
+ try {
33
+ toolRegistry.registerToolFromConfig(tool);
34
+ }
35
+ catch (error) {
36
+ const errorMessage = error instanceof Error ? error.message : String(error);
37
+ throw new Error(`Failed to register tool '${tool.name}': ${errorMessage}`);
38
+ }
39
+ }
40
+ logger_util_1.logger.info("EasyMCP", `Registered ${config.tools.length} tool(s) from configuration`, {
41
+ component: "EasyMCP",
42
+ toolCount: config.tools.length,
43
+ });
44
+ }
45
+ logger_util_1.logger.info("EasyMCP", "EasyMCP Framework initialized successfully", {
46
+ component: "EasyMCP",
47
+ });
48
+ }
49
+ static async run() {
50
+ if (!this.app) {
51
+ throw new Error("EasyMCP is not initialized. Call EasyMCP.initialize() first.");
52
+ }
53
+ logger_util_1.logger.info("EasyMCP", "Starting EasyMCP core services", {
54
+ component: "EasyMCP",
55
+ });
56
+ try {
57
+ const mcpServer = this.app.get(mcp_server_service_1.McpServerService);
58
+ await mcpServer.startListening();
59
+ logger_util_1.logger.info("EasyMCP", "EasyMCP core services are now running and listening for JSON-RPC requests via stdio", {
60
+ component: "EasyMCP",
61
+ });
62
+ }
63
+ catch (error) {
64
+ logger_util_1.logger.error("EasyMCP", "Failed to start EasyMCP core services", {
65
+ component: "EasyMCP",
66
+ error: (0, sanitize_util_1.sanitizeErrorMessage)(error),
67
+ });
68
+ await this.app.close();
69
+ throw error;
70
+ }
71
+ }
72
+ static getService(token) {
73
+ if (!this.app) {
74
+ throw new Error("EasyMCP is not initialized.");
75
+ }
76
+ return this.app.get(token);
77
+ }
78
+ static async shutdown() {
79
+ if (!this.app) {
80
+ logger_util_1.logger.warn("EasyMCP", "EasyMCP is not initialized. Nothing to shutdown", {
81
+ component: "EasyMCP",
82
+ });
83
+ return;
84
+ }
85
+ logger_util_1.logger.info("EasyMCP", "Shutting down EasyMCP framework", {
86
+ component: "EasyMCP",
87
+ });
88
+ try {
89
+ await this.app.close();
90
+ this.app = null;
91
+ logger_util_1.logger.info("EasyMCP", "EasyMCP framework shut down successfully", {
92
+ component: "EasyMCP",
93
+ });
94
+ }
95
+ catch (error) {
96
+ logger_util_1.logger.error("EasyMCP", "Error during EasyMCP shutdown", {
97
+ component: "EasyMCP",
98
+ error: (0, sanitize_util_1.sanitizeErrorMessage)(error),
99
+ });
100
+ throw error;
101
+ }
102
+ }
103
+ }
104
+ exports.EasyMCP = EasyMCP;
105
+ //# sourceMappingURL=EasyMCP.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"EasyMCP.js","sourceRoot":"","sources":["../src/EasyMCP.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ import { AppService } from "./app.service";
2
+ export declare class AppController {
3
+ private readonly appService;
4
+ constructor(appService: AppService);
5
+ getHello(): string;
6
+ }
@@ -0,0 +1,35 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ var __metadata = (this && this.__metadata) || function (k, v) {
9
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.AppController = void 0;
13
+ const common_1 = require("@nestjs/common");
14
+ const app_service_1 = require("./app.service");
15
+ let AppController = class AppController {
16
+ appService;
17
+ constructor(appService) {
18
+ this.appService = appService;
19
+ }
20
+ getHello() {
21
+ return this.appService.getHello();
22
+ }
23
+ };
24
+ exports.AppController = AppController;
25
+ __decorate([
26
+ (0, common_1.Get)(),
27
+ __metadata("design:type", Function),
28
+ __metadata("design:paramtypes", []),
29
+ __metadata("design:returntype", String)
30
+ ], AppController.prototype, "getHello", null);
31
+ exports.AppController = AppController = __decorate([
32
+ (0, common_1.Controller)(),
33
+ __metadata("design:paramtypes", [app_service_1.AppService])
34
+ ], AppController);
35
+ //# sourceMappingURL=app.controller.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"app.controller.js","sourceRoot":"","sources":["../src/app.controller.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,2CAAiD;AACjD,+CAA2C;AAGpC,IAAM,aAAa,GAAnB,MAAM,aAAa;IACK;IAA7B,YAA6B,UAAsB;QAAtB,eAAU,GAAV,UAAU,CAAY;IAAG,CAAC;IAGvD,QAAQ;QACN,OAAO,IAAI,CAAC,UAAU,CAAC,QAAQ,EAAE,CAAC;IACpC,CAAC;CACF,CAAA;AAPY,sCAAa;AAIxB;IADC,IAAA,YAAG,GAAE;;;;6CAGL;wBANU,aAAa;IADzB,IAAA,mBAAU,GAAE;qCAE8B,wBAAU;GADxC,aAAa,CAOzB"}
@@ -0,0 +1,2 @@
1
+ export declare class AppModule {
2
+ }
@@ -0,0 +1,34 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.AppModule = void 0;
10
+ const common_1 = require("@nestjs/common");
11
+ const mcp_server_service_1 = require("./core/mcp-server/mcp-server.service");
12
+ const tool_registry_service_1 = require("./tooling/tool-registry/tool-registry.service");
13
+ const config_holder_service_1 = require("./config/config-holder.service");
14
+ const constants_1 = require("./config/constants");
15
+ const interface_module_1 = require("./interface/interface.module");
16
+ let AppModule = class AppModule {
17
+ };
18
+ exports.AppModule = AppModule;
19
+ exports.AppModule = AppModule = __decorate([
20
+ (0, common_1.Module)({
21
+ imports: [interface_module_1.InterfaceModule],
22
+ providers: [
23
+ mcp_server_service_1.McpServerService,
24
+ tool_registry_service_1.ToolRegistryService,
25
+ config_holder_service_1.ConfigHolderService,
26
+ {
27
+ provide: constants_1.CONFIG_TOKEN,
28
+ useExisting: config_holder_service_1.ConfigHolderService,
29
+ },
30
+ ],
31
+ exports: [mcp_server_service_1.McpServerService],
32
+ })
33
+ ], AppModule);
34
+ //# sourceMappingURL=app.module.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"app.module.js","sourceRoot":"","sources":["../src/app.module.ts"],"names":[],"mappings":";;;;;;;;;AAEA,2CAAwC;AACxC,6EAAwE;AACxE,yFAAoF;AACpF,0EAAqE;AACrE,kDAAkD;AAClD,mEAA+D;AAsBxD,IAAM,SAAS,GAAf,MAAM,SAAS;CAAG,CAAA;AAAZ,8BAAS;oBAAT,SAAS;IAhBrB,IAAA,eAAM,EAAC;QACN,OAAO,EAAE,CAAC,kCAAe,CAAC;QAC1B,SAAS,EAAE;YAET,qCAAgB;YAEhB,2CAAmB;YACnB,2CAAmB;YAEnB;gBACE,OAAO,EAAE,wBAAY;gBACrB,WAAW,EAAE,2CAAmB;aACjC;SACF;QACD,OAAO,EAAE,CAAC,qCAAgB,CAAC;KAC5B,CAAC;GACW,SAAS,CAAG"}
@@ -0,0 +1,3 @@
1
+ export declare class AppService {
2
+ getHello(): string;
3
+ }
@@ -0,0 +1,20 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.AppService = void 0;
10
+ const common_1 = require("@nestjs/common");
11
+ let AppService = class AppService {
12
+ getHello() {
13
+ return "Hello World!";
14
+ }
15
+ };
16
+ exports.AppService = AppService;
17
+ exports.AppService = AppService = __decorate([
18
+ (0, common_1.Injectable)()
19
+ ], AppService);
20
+ //# sourceMappingURL=app.service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"app.service.js","sourceRoot":"","sources":["../src/app.service.ts"],"names":[],"mappings":";;;;;;;;;AAAA,2CAA4C;AAGrC,IAAM,UAAU,GAAhB,MAAM,UAAU;IACrB,QAAQ;QACN,OAAO,cAAc,CAAC;IACxB,CAAC;CACF,CAAA;AAJY,gCAAU;qBAAV,UAAU;IADtB,IAAA,mBAAU,GAAE;GACA,UAAU,CAItB"}