@malek0512/loopback4-mcp 1.0.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 (112) hide show
  1. package/README.md +124 -0
  2. package/dist/component.d.ts +8 -0
  3. package/dist/component.d.ts.map +1 -0
  4. package/dist/component.js +67 -0
  5. package/dist/component.js.map +1 -0
  6. package/dist/controllers/index.d.ts +2 -0
  7. package/dist/controllers/index.d.ts.map +1 -0
  8. package/dist/controllers/index.js +18 -0
  9. package/dist/controllers/index.js.map +1 -0
  10. package/dist/controllers/mcp.controller.d.ts +16 -0
  11. package/dist/controllers/mcp.controller.d.ts.map +1 -0
  12. package/dist/controllers/mcp.controller.js +66 -0
  13. package/dist/controllers/mcp.controller.js.map +1 -0
  14. package/dist/decorators/index.d.ts +2 -0
  15. package/dist/decorators/index.d.ts.map +1 -0
  16. package/dist/decorators/index.js +18 -0
  17. package/dist/decorators/index.js.map +1 -0
  18. package/dist/decorators/mcp-tool.decorator.d.ts +21 -0
  19. package/dist/decorators/mcp-tool.decorator.d.ts.map +1 -0
  20. package/dist/decorators/mcp-tool.decorator.js +30 -0
  21. package/dist/decorators/mcp-tool.decorator.js.map +1 -0
  22. package/dist/execution/context-manager.d.ts +14 -0
  23. package/dist/execution/context-manager.d.ts.map +1 -0
  24. package/dist/execution/context-manager.js +41 -0
  25. package/dist/execution/context-manager.js.map +1 -0
  26. package/dist/execution/index.d.ts +4 -0
  27. package/dist/execution/index.d.ts.map +1 -0
  28. package/dist/execution/index.js +20 -0
  29. package/dist/execution/index.js.map +1 -0
  30. package/dist/execution/result-formatter.d.ts +16 -0
  31. package/dist/execution/result-formatter.d.ts.map +1 -0
  32. package/dist/execution/result-formatter.js +102 -0
  33. package/dist/execution/result-formatter.js.map +1 -0
  34. package/dist/execution/tool-executor.d.ts +12 -0
  35. package/dist/execution/tool-executor.d.ts.map +1 -0
  36. package/dist/execution/tool-executor.js +72 -0
  37. package/dist/execution/tool-executor.js.map +1 -0
  38. package/dist/index.d.ts +6 -0
  39. package/dist/index.d.ts.map +1 -0
  40. package/dist/index.js +25 -0
  41. package/dist/index.js.map +1 -0
  42. package/dist/observers/index.d.ts +2 -0
  43. package/dist/observers/index.d.ts.map +1 -0
  44. package/dist/observers/index.js +18 -0
  45. package/dist/observers/index.js.map +1 -0
  46. package/dist/observers/mcp-boot.observer.d.ts +9 -0
  47. package/dist/observers/mcp-boot.observer.d.ts.map +1 -0
  48. package/dist/observers/mcp-boot.observer.js +36 -0
  49. package/dist/observers/mcp-boot.observer.js.map +1 -0
  50. package/dist/protocol/index.d.ts +4 -0
  51. package/dist/protocol/index.d.ts.map +1 -0
  52. package/dist/protocol/index.js +20 -0
  53. package/dist/protocol/index.js.map +1 -0
  54. package/dist/protocol/json-rpc.handler.d.ts +10 -0
  55. package/dist/protocol/json-rpc.handler.d.ts.map +1 -0
  56. package/dist/protocol/json-rpc.handler.js +63 -0
  57. package/dist/protocol/json-rpc.handler.js.map +1 -0
  58. package/dist/protocol/message-router.d.ts +18 -0
  59. package/dist/protocol/message-router.d.ts.map +1 -0
  60. package/dist/protocol/message-router.js +106 -0
  61. package/dist/protocol/message-router.js.map +1 -0
  62. package/dist/protocol/types.d.ts +227 -0
  63. package/dist/protocol/types.d.ts.map +1 -0
  64. package/dist/protocol/types.js +56 -0
  65. package/dist/protocol/types.js.map +1 -0
  66. package/dist/registry/index.d.ts +4 -0
  67. package/dist/registry/index.d.ts.map +1 -0
  68. package/dist/registry/index.js +20 -0
  69. package/dist/registry/index.js.map +1 -0
  70. package/dist/registry/metadata-scanner.d.ts +13 -0
  71. package/dist/registry/metadata-scanner.d.ts.map +1 -0
  72. package/dist/registry/metadata-scanner.js +101 -0
  73. package/dist/registry/metadata-scanner.js.map +1 -0
  74. package/dist/registry/schema-generator.d.ts +19 -0
  75. package/dist/registry/schema-generator.d.ts.map +1 -0
  76. package/dist/registry/schema-generator.js +90 -0
  77. package/dist/registry/schema-generator.js.map +1 -0
  78. package/dist/registry/tool-registry.d.ts +23 -0
  79. package/dist/registry/tool-registry.d.ts.map +1 -0
  80. package/dist/registry/tool-registry.js +58 -0
  81. package/dist/registry/tool-registry.js.map +1 -0
  82. package/dist/transport/index.d.ts +2 -0
  83. package/dist/transport/index.d.ts.map +1 -0
  84. package/dist/transport/index.js +18 -0
  85. package/dist/transport/index.js.map +1 -0
  86. package/dist/transport/sse.transport.d.ts +9 -0
  87. package/dist/transport/sse.transport.d.ts.map +1 -0
  88. package/dist/transport/sse.transport.js +67 -0
  89. package/dist/transport/sse.transport.js.map +1 -0
  90. package/package.json +26 -0
  91. package/src/component.ts +58 -0
  92. package/src/controllers/index.ts +1 -0
  93. package/src/controllers/mcp.controller.ts +42 -0
  94. package/src/decorators/index.ts +1 -0
  95. package/src/decorators/mcp-tool.decorator.ts +57 -0
  96. package/src/execution/context-manager.ts +44 -0
  97. package/src/execution/index.ts +3 -0
  98. package/src/execution/result-formatter.ts +104 -0
  99. package/src/execution/tool-executor.ts +61 -0
  100. package/src/index.ts +5 -0
  101. package/src/observers/index.ts +1 -0
  102. package/src/observers/mcp-boot.observer.ts +19 -0
  103. package/src/protocol/index.ts +3 -0
  104. package/src/protocol/json-rpc.handler.ts +77 -0
  105. package/src/protocol/message-router.ts +125 -0
  106. package/src/protocol/types.ts +309 -0
  107. package/src/registry/index.ts +3 -0
  108. package/src/registry/metadata-scanner.ts +105 -0
  109. package/src/registry/schema-generator.ts +82 -0
  110. package/src/registry/tool-registry.ts +57 -0
  111. package/src/transport/index.ts +1 -0
  112. package/src/transport/sse.transport.ts +56 -0
@@ -0,0 +1,57 @@
1
+ import {bind, BindingScope, inject} from '@loopback/core';
2
+ import {Tool, JsonSchema} from '../protocol/types';
3
+ import {SchemaGenerator} from './schema-generator';
4
+
5
+ export interface ToolDescriptor {
6
+ name: string;
7
+ description?: string;
8
+ inputSchema: JsonSchema;
9
+ controller: Object;
10
+ methodName: string;
11
+ handler: Function;
12
+ }
13
+
14
+ @bind({scope: BindingScope.SINGLETON})
15
+ export class ToolRegistry {
16
+ private tools = new Map<string, ToolDescriptor>();
17
+
18
+ constructor(
19
+ @inject('mcp.schemaGenerator')
20
+ private schemaGenerator: SchemaGenerator,
21
+ ) {}
22
+
23
+ register(descriptor: ToolDescriptor): void {
24
+ if (this.tools.has(descriptor.name)) {
25
+ throw new Error(`Tool '${descriptor.name}' is already registered`);
26
+ }
27
+ this.tools.set(descriptor.name, descriptor);
28
+ }
29
+
30
+ unregister(name: string): boolean {
31
+ return this.tools.delete(name);
32
+ }
33
+
34
+ get(name: string): ToolDescriptor | undefined {
35
+ return this.tools.get(name);
36
+ }
37
+
38
+ list(): Tool[] {
39
+ return Array.from(this.tools.values()).map(descriptor => ({
40
+ name: descriptor.name,
41
+ description: descriptor.description,
42
+ inputSchema: descriptor.inputSchema as any,
43
+ }));
44
+ }
45
+
46
+ has(name: string): boolean {
47
+ return this.tools.has(name);
48
+ }
49
+
50
+ clear(): void {
51
+ this.tools.clear();
52
+ }
53
+
54
+ get size(): number {
55
+ return this.tools.size;
56
+ }
57
+ }
@@ -0,0 +1 @@
1
+ export * from './sse.transport';
@@ -0,0 +1,56 @@
1
+ import {bind, BindingScope, inject} from '@loopback/core';
2
+ import {Request, Response} from '@loopback/rest';
3
+ import {MessageRouter} from '../protocol/message-router';
4
+ import {JsonRpcRequest} from '../protocol/types';
5
+
6
+ @bind({scope: BindingScope.SINGLETON})
7
+ export class SseTransport {
8
+ constructor(
9
+ @inject('mcp.messageRouter')
10
+ private messageRouter: MessageRouter,
11
+ ) {}
12
+
13
+ async handleConnection(req: Request, res: Response): Promise<void> {
14
+ // Set SSE headers
15
+ res.setHeader('Content-Type', 'text/event-stream');
16
+ res.setHeader('Cache-Control', 'no-cache');
17
+ res.setHeader('Connection', 'keep-alive');
18
+ res.setHeader('Access-Control-Allow-Origin', '*');
19
+
20
+ // Send initial connection event
21
+ this.sendEvent(res, 'connected', {message: 'MCP Server connected'});
22
+
23
+ // Handle incoming messages
24
+ req.on('data', async (chunk: Buffer) => {
25
+ try {
26
+ const message = JSON.parse(chunk.toString()) as JsonRpcRequest;
27
+ const response = await this.messageRouter.route(message);
28
+ this.sendEvent(res, 'message', response);
29
+ } catch (error) {
30
+ this.sendEvent(res, 'error', {
31
+ message: 'Failed to process message',
32
+ error: error instanceof Error ? error.message : String(error),
33
+ });
34
+ }
35
+ });
36
+
37
+ // Handle connection close
38
+ req.on('close', () => {
39
+ console.log('SSE connection closed');
40
+ });
41
+
42
+ // Keep connection alive
43
+ const keepAliveInterval = setInterval(() => {
44
+ this.sendEvent(res, 'ping', {timestamp: Date.now()});
45
+ }, 30000);
46
+
47
+ req.on('close', () => {
48
+ clearInterval(keepAliveInterval);
49
+ });
50
+ }
51
+
52
+ private sendEvent(res: Response, event: string, data: unknown): void {
53
+ res.write(`event: ${event}\n`);
54
+ res.write(`data: ${JSON.stringify(data)}\n\n`);
55
+ }
56
+ }