@jrmc/adonis-mcp 1.0.0-alpha.7 → 1.0.0-alpha.8

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 (64) hide show
  1. package/README.md +5 -1
  2. package/build/commands/make/tool.js +2 -2
  3. package/build/providers/mcp_provider.d.ts.map +1 -1
  4. package/build/providers/mcp_provider.js +1 -1
  5. package/build/src/Transport/http_transport.js +2 -0
  6. package/build/src/context.d.ts +1 -0
  7. package/build/src/context.d.ts.map +1 -1
  8. package/build/src/context.js +3 -0
  9. package/build/src/enums/error.d.ts +16 -0
  10. package/build/src/enums/error.d.ts.map +1 -0
  11. package/build/src/enums/error.js +18 -0
  12. package/build/src/request.d.ts.map +1 -1
  13. package/build/src/response.d.ts +20 -20
  14. package/build/src/response.d.ts.map +1 -1
  15. package/build/src/response.js +17 -22
  16. package/build/src/server/methods/call_tool.d.ts +1 -3
  17. package/build/src/server/methods/call_tool.d.ts.map +1 -1
  18. package/build/src/server/methods/call_tool.js +13 -2
  19. package/build/src/server/methods/get_prompt.d.ts +1 -3
  20. package/build/src/server/methods/get_prompt.d.ts.map +1 -1
  21. package/build/src/server/methods/get_prompt.js +1 -1
  22. package/build/src/server/methods/initialize.d.ts +1 -3
  23. package/build/src/server/methods/initialize.d.ts.map +1 -1
  24. package/build/src/server/methods/initialize.js +2 -2
  25. package/build/src/server/methods/list_prompts.d.ts +1 -3
  26. package/build/src/server/methods/list_prompts.d.ts.map +1 -1
  27. package/build/src/server/methods/list_prompts.js +1 -1
  28. package/build/src/server/methods/list_resources.d.ts +1 -3
  29. package/build/src/server/methods/list_resources.d.ts.map +1 -1
  30. package/build/src/server/methods/list_resources.js +1 -1
  31. package/build/src/server/methods/list_tools.d.ts +1 -3
  32. package/build/src/server/methods/list_tools.d.ts.map +1 -1
  33. package/build/src/server/methods/list_tools.js +27 -14
  34. package/build/src/server/methods/ping.d.ts +1 -3
  35. package/build/src/server/methods/ping.d.ts.map +1 -1
  36. package/build/src/server/methods/ping.js +1 -1
  37. package/build/src/server/methods/read_resource.d.ts +1 -3
  38. package/build/src/server/methods/read_resource.d.ts.map +1 -1
  39. package/build/src/server/methods/read_resource.js +1 -1
  40. package/build/src/server/pagination/cursor_paginator.d.ts +12 -0
  41. package/build/src/server/pagination/cursor_paginator.d.ts.map +1 -0
  42. package/build/src/server/pagination/cursor_paginator.js +48 -0
  43. package/build/src/server/tool.d.ts +2 -4
  44. package/build/src/server/tool.d.ts.map +1 -1
  45. package/build/src/server.d.ts +1 -3
  46. package/build/src/server.d.ts.map +1 -1
  47. package/build/src/server.js +10 -4
  48. package/build/src/types/config.d.ts +2 -0
  49. package/build/src/types/config.d.ts.map +1 -1
  50. package/build/src/types/context.d.ts +2 -1
  51. package/build/src/types/context.d.ts.map +1 -1
  52. package/build/src/types/method.d.ts +8 -8
  53. package/build/src/types/method.d.ts.map +1 -1
  54. package/build/src/types/notification.d.ts +14 -0
  55. package/build/src/types/notification.d.ts.map +1 -0
  56. package/build/src/types/notification.js +7 -0
  57. package/build/src/types/request.d.ts +9 -4
  58. package/build/src/types/request.d.ts.map +1 -1
  59. package/build/src/types/response.d.ts +37 -1
  60. package/build/src/types/response.d.ts.map +1 -1
  61. package/build/stubs/config.ts.stub +1 -1
  62. package/build/stubs/make/mcp/tools/main.ts.stub +2 -1
  63. package/build/tsconfig.tsbuildinfo +1 -1
  64. package/package.json +1 -1
package/README.md CHANGED
@@ -11,7 +11,7 @@ AdonisJS MCP - Server MCP for your AdonisJS applications.
11
11
  - [ ] MCP resources support
12
12
  - [ ] MCP prompts support
13
13
  - [ ] Alternative transports support (SSE, stdio)
14
- - [ ] Advanced pagination support
14
+ - [x] Advanced pagination support
15
15
  - [ ] Automatic schema validation with Vine ??
16
16
 
17
17
  ## Installation & Configuration
@@ -276,6 +276,10 @@ export default class AddBookmarkTool implements Tool<Schema> {
276
276
  }
277
277
  ```
278
278
 
279
+ ### Pagination
280
+
281
+ The `tools/list` method supports cursor-based pagination to handle large numbers of tools efficiently. This is particularly useful when you have many tools registered in your application. [More information](https://modelcontextprotocol.io/specification/2025-06-18/server/utilities/pagination)
282
+
279
283
  ## Support
280
284
 
281
285
  For any questions or issues, please open an issue on the [GitHub repository](https://github.com/batosai/adonis-mcp).
@@ -24,8 +24,8 @@ export default class MakeTool extends BaseCommand {
24
24
  const codemods = await this.createCodemods();
25
25
  const stubPath = `make/mcp/tools/main.ts.stub`;
26
26
  await codemods.makeUsingStub(stubsRoot, stubPath, {
27
- className: `${string.pascalCase(this.name)}Tool`,
28
- basePath: config.path
27
+ name: string.pascalCase(this.name),
28
+ basePath: config.path,
29
29
  });
30
30
  this.logger.success(`Tool created successfully for: ${this.name}`);
31
31
  }
@@ -1 +1 @@
1
- {"version":3,"file":"mcp_provider.d.ts","sourceRoot":"","sources":["../../providers/mcp_provider.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAA;AAC9D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAA;AAKrD,OAAO,SAAS,MAAM,kBAAkB,CAAA;AAExC,MAAM,CAAC,OAAO,OAAO,WAAW;IAClB,SAAS,CAAC,GAAG,EAAE,kBAAkB;gBAAvB,GAAG,EAAE,kBAAkB;IAE7C,QAAQ;IAQF,KAAK;IAeL,aAAa;CA0CpB;AAED,OAAO,QAAQ,qBAAqB,CAAC;IACnC,UAAU,MAAM;QACd,GAAG,EAAE,CAAC,OAAO,CAAC,EAAE,MAAM,KAAK,UAAU,CAAA;KACtC;CACF;AAED,OAAO,QAAQ,sBAAsB,CAAC;IACpC,UAAU,iBAAiB;QACzB,UAAU,EAAE,SAAS,CAAA;KACtB;CACF"}
1
+ {"version":3,"file":"mcp_provider.d.ts","sourceRoot":"","sources":["../../providers/mcp_provider.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAA;AAC9D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAA;AAKrD,OAAO,SAAS,MAAM,kBAAkB,CAAA;AAExC,MAAM,CAAC,OAAO,OAAO,WAAW;IAClB,SAAS,CAAC,GAAG,EAAE,kBAAkB;gBAAvB,GAAG,EAAE,kBAAkB;IAE7C,QAAQ;IAQF,KAAK;IAeL,aAAa;CA4CpB;AAED,OAAO,QAAQ,qBAAqB,CAAC;IACnC,UAAU,MAAM;QACd,GAAG,EAAE,CAAC,OAAO,CAAC,EAAE,MAAM,KAAK,UAAU,CAAA;KACtC;CACF;AAED,OAAO,QAAQ,sBAAsB,CAAC;IACpC,UAAU,iBAAiB;QACzB,UAAU,EAAE,SAAS,CAAA;KACtB;CACF"}
@@ -34,7 +34,7 @@ export default class McpProvider {
34
34
  const server = await this.app.container.make('jrmc.mcp');
35
35
  const path = this.app.makePath(server.config.path);
36
36
  const files = await fsReadAll(path, {
37
- filter: (filePath) => filePath.includes('_tool.ts')
37
+ filter: (filePath) => filePath.includes('_tool.ts'),
38
38
  });
39
39
  await Promise.all(files.map(async (file) => {
40
40
  const path = this.app.makePath(server.config.path, file);
@@ -11,11 +11,13 @@ export default class HttpTransport {
11
11
  }
12
12
  bindBouncer(mcpContext) {
13
13
  if ('bouncer' in this.ctx) {
14
+ ;
14
15
  mcpContext.bouncer = this.ctx.bouncer;
15
16
  }
16
17
  }
17
18
  bindAuth(mcpContext) {
18
19
  if ('auth' in this.ctx) {
20
+ ;
19
21
  mcpContext.auth = this.ctx.auth;
20
22
  }
21
23
  }
@@ -22,5 +22,6 @@ export default class ServerContext implements McpContext {
22
22
  request: McpRequest;
23
23
  response: McpResponse;
24
24
  constructor(options: ServerContextOptions);
25
+ getPerPage(requestedPerPage?: number): number;
25
26
  }
26
27
  //# sourceMappingURL=context.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../src/context.ts"],"names":[],"mappings":"AACA;;;;;GAKG;AACH,OAAO,KAAK,EAAE,UAAU,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAA;AAC1E,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAA;AACpD,OAAO,KAAK,EAAE,QAAQ,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAA;AAE3E,OAAO,WAAW,MAAM,eAAe,CAAA;AAEvC,MAAM,CAAC,OAAO,OAAO,aAAc,YAAW,UAAU;IACtD,yBAAyB,EAAE,MAAM,EAAE,CAAA;IACnC,kBAAkB,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;IACvC,UAAU,EAAE,MAAM,CAAA;IAClB,aAAa,EAAE,MAAM,CAAA;IACrB,YAAY,EAAE,MAAM,CAAA;IACpB,mBAAmB,EAAE,MAAM,CAAA;IAC3B,uBAAuB,EAAE,MAAM,CAAA;IAC/B,KAAK,EAAE,QAAQ,CAAA;IACf,SAAS,EAAE,YAAY,CAAA;IACvB,OAAO,EAAE,UAAU,CAAA;IACnB,OAAO,EAAE,UAAU,CAAA;IACnB,QAAQ,EAAE,WAAW,CAAA;gBAET,OAAO,EAAE,oBAAoB;CAc1C"}
1
+ {"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../src/context.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,KAAK,EAAE,UAAU,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAA;AAC1E,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAA;AACpD,OAAO,KAAK,EAAE,QAAQ,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAA;AAE3E,OAAO,WAAW,MAAM,eAAe,CAAA;AAEvC,MAAM,CAAC,OAAO,OAAO,aAAc,YAAW,UAAU;IACtD,yBAAyB,EAAE,MAAM,EAAE,CAAA;IACnC,kBAAkB,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;IACvC,UAAU,EAAE,MAAM,CAAA;IAClB,aAAa,EAAE,MAAM,CAAA;IACrB,YAAY,EAAE,MAAM,CAAA;IACpB,mBAAmB,EAAE,MAAM,CAAA;IAC3B,uBAAuB,EAAE,MAAM,CAAA;IAC/B,KAAK,EAAE,QAAQ,CAAA;IACf,SAAS,EAAE,YAAY,CAAA;IACvB,OAAO,EAAE,UAAU,CAAA;IACnB,OAAO,EAAE,UAAU,CAAA;IACnB,QAAQ,EAAE,WAAW,CAAA;gBAET,OAAO,EAAE,oBAAoB;IAelC,UAAU,CAAC,gBAAgB,CAAC,EAAE,MAAM,GAAG,MAAM;CAGrD"}
@@ -26,4 +26,7 @@ export default class ServerContext {
26
26
  this.request = options.request;
27
27
  this.response = new McpResponse();
28
28
  }
29
+ getPerPage(requestedPerPage) {
30
+ return Math.min(requestedPerPage ?? this.defaultPaginationLength, this.maxPaginationLength);
31
+ }
29
32
  }
@@ -0,0 +1,16 @@
1
+ /**
2
+ * @jrmc/adonis-mcp
3
+ *
4
+ * @license MIT
5
+ * @copyright Jeremy Chaufourier <jeremy@chaufourier.fr>
6
+ */
7
+ export declare enum ErrorCode {
8
+ ConnectionClosed = -32000,
9
+ RequestTimeout = -32001,
10
+ ParseError = -32700,
11
+ InvalidRequest = -32600,
12
+ MethodNotFound = -32601,
13
+ InvalidParams = -32602,
14
+ InternalError = -32603
15
+ }
16
+ //# sourceMappingURL=error.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"error.d.ts","sourceRoot":"","sources":["../../../src/enums/error.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,oBAAY,SAAS;IAEnB,gBAAgB,SAAS;IACzB,cAAc,SAAS;IAGvB,UAAU,SAAS;IACnB,cAAc,SAAS;IACvB,cAAc,SAAS;IACvB,aAAa,SAAS;IACtB,aAAa,SAAS;CACvB"}
@@ -0,0 +1,18 @@
1
+ /**
2
+ * @jrmc/adonis-mcp
3
+ *
4
+ * @license MIT
5
+ * @copyright Jeremy Chaufourier <jeremy@chaufourier.fr>
6
+ */
7
+ export var ErrorCode;
8
+ (function (ErrorCode) {
9
+ // SDK error codes
10
+ ErrorCode[ErrorCode["ConnectionClosed"] = -32000] = "ConnectionClosed";
11
+ ErrorCode[ErrorCode["RequestTimeout"] = -32001] = "RequestTimeout";
12
+ // Standard JSON-RPC error codes
13
+ ErrorCode[ErrorCode["ParseError"] = -32700] = "ParseError";
14
+ ErrorCode[ErrorCode["InvalidRequest"] = -32600] = "InvalidRequest";
15
+ ErrorCode[ErrorCode["MethodNotFound"] = -32601] = "MethodNotFound";
16
+ ErrorCode[ErrorCode["InvalidParams"] = -32602] = "InvalidParams";
17
+ ErrorCode[ErrorCode["InternalError"] = -32603] = "InternalError";
18
+ })(ErrorCode || (ErrorCode = {}));
@@ -1 +1 @@
1
- {"version":3,"file":"request.d.ts","sourceRoot":"","sources":["../../src/request.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,MAAM,CAAC,OAAO,OAAO,OAAO;CAE3B"}
1
+ {"version":3,"file":"request.d.ts","sourceRoot":"","sources":["../../src/request.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,MAAM,CAAC,OAAO,OAAO,OAAO;CAAG"}
@@ -4,29 +4,29 @@
4
4
  * @license MIT
5
5
  * @copyright Jeremy Chaufourier <jeremy@chaufourier.fr>
6
6
  */
7
- export default class Response {
8
- static notification(_method: string, _params: Record<string, any>): void;
7
+ import type { JsonRpcResponse, McpResponse } from './types/response.js';
8
+ export default class Response implements McpResponse {
9
9
  text(text: string): {
10
- content: {
11
- type: "text";
12
- text: string;
13
- }[];
10
+ type: "text";
11
+ text: string;
14
12
  };
15
- static json(_content: Record<string, any>): void;
16
- static blob(_content: string): void;
17
- static error(_text: string): void;
18
- content(): void;
19
- static audio(): void;
20
- static image(): void;
21
- asAssistant(): void;
22
- isNotification(): void;
23
- isError(): void;
24
- role(): void;
25
- static result(id: number | string, result: Record<string, any>): {
26
- readonly jsonrpc: "2.0";
13
+ image(data: string, mimeType: string, _meta?: Record<string, unknown>): {
14
+ type: "image";
15
+ data: string;
16
+ mimeType: string;
17
+ _meta: Record<string, unknown> | undefined;
27
18
  };
28
- static resultRpc(result: Record<string, any>): {
29
- readonly jsonrpc: "2.0";
19
+ audio(data: string, mimeType: string, _meta?: Record<string, unknown>): {
20
+ type: "audio";
21
+ data: string;
22
+ mimeType: string;
23
+ _meta: Record<string, unknown> | undefined;
30
24
  };
25
+ error(message: string, code?: number, data?: Record<string, unknown>): {
26
+ message: string;
27
+ code: number;
28
+ data: Record<string, unknown> | undefined;
29
+ };
30
+ static toJsonRpc({ id, result, error }: Omit<JsonRpcResponse, 'jsonrpc'>): JsonRpcResponse;
31
31
  }
32
32
  //# sourceMappingURL=response.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"response.d.ts","sourceRoot":"","sources":["../../src/response.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,MAAM,CAAC,OAAO,OAAO,QAAQ;IAI3B,MAAM,CAAC,YAAY,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC;IAEjE,IAAI,CAAC,IAAI,EAAE,MAAM;;;;;;IAMjB,MAAM,CAAC,IAAI,CAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC;IAEzC,MAAM,CAAC,IAAI,CAAC,QAAQ,EAAE,MAAM;IAE5B,MAAM,CAAC,KAAK,CAAC,KAAK,EAAE,MAAM;IAE1B,OAAO;IAEP,MAAM,CAAC,KAAK;IAEZ,MAAM,CAAC,KAAK;IAEZ,WAAW;IAEX,cAAc;IAEd,OAAO;IAEP,IAAI;IAEJ,MAAM,CAAC,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC;;;IAO9D,MAAM,CAAC,SAAS,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC;;;CAM7C"}
1
+ {"version":3,"file":"response.d.ts","sourceRoot":"","sources":["../../src/response.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAA;AAEvE,MAAM,CAAC,OAAO,OAAO,QAAS,YAAW,WAAW;IAClD,IAAI,CAAC,IAAI,EAAE,MAAM;;;;IAIjB,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;;;;;;IAIrE,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;;;;;;IAIrE,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;;;;;IAQpE,MAAM,CAAC,SAAS,CAAC,EAAE,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,EAAE,IAAI,CAAC,eAAe,EAAE,SAAS,CAAC,GAAG,eAAe;CAQ3F"}
@@ -4,35 +4,30 @@
4
4
  * @license MIT
5
5
  * @copyright Jeremy Chaufourier <jeremy@chaufourier.fr>
6
6
  */
7
- // import Role from './enums/role.js'
7
+ import { ErrorCode } from './enums/error.js';
8
8
  export default class Response {
9
- // constructor(_content: string, _role: Role = Role.USER) {}
10
- static notification(_method, _params) { }
11
9
  text(text) {
10
+ return { type: 'text', text };
11
+ }
12
+ image(data, mimeType, _meta) {
13
+ return { type: 'image', data, mimeType, _meta };
14
+ }
15
+ audio(data, mimeType, _meta) {
16
+ return { type: 'audio', data, mimeType, _meta };
17
+ }
18
+ error(message, code, data) {
12
19
  return {
13
- content: [{ type: 'text', text }],
20
+ message,
21
+ code: code ?? ErrorCode.InternalError,
22
+ data,
14
23
  };
15
24
  }
16
- static json(_content) { }
17
- static blob(_content) { }
18
- static error(_text) { }
19
- content() { }
20
- static audio() { }
21
- static image() { }
22
- asAssistant() { }
23
- isNotification() { }
24
- isError() { }
25
- role() { }
26
- static result(id, result) {
27
- return this.resultRpc({
28
- id,
29
- result,
30
- });
31
- }
32
- static resultRpc(result) {
25
+ static toJsonRpc({ id, result, error }) {
33
26
  return {
34
27
  jsonrpc: '2.0',
35
- ...result,
28
+ id,
29
+ result,
30
+ error,
36
31
  };
37
32
  }
38
33
  }
@@ -7,8 +7,6 @@
7
7
  import type { Method } from '../../types/method.js';
8
8
  import type { McpContext } from '../../types/context.js';
9
9
  export default class CallTool implements Method {
10
- handle(ctx: McpContext): Promise<{
11
- readonly jsonrpc: "2.0";
12
- }>;
10
+ handle(ctx: McpContext): Promise<import("../../types/response.js").JsonRpcResponse>;
13
11
  }
14
12
  //# sourceMappingURL=call_tool.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"call_tool.d.ts","sourceRoot":"","sources":["../../../../src/server/methods/call_tool.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAA;AACnD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAA;AAKxD,MAAM,CAAC,OAAO,OAAO,QAAS,YAAW,MAAM;IACvC,MAAM,CAAC,GAAG,EAAE,UAAU;;;CAuC7B"}
1
+ {"version":3,"file":"call_tool.d.ts","sourceRoot":"","sources":["../../../../src/server/methods/call_tool.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAA;AACnD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAA;AAKxD,MAAM,CAAC,OAAO,OAAO,QAAS,YAAW,MAAM;IACvC,MAAM,CAAC,GAAG,EAAE,UAAU;CAyC7B"}
@@ -22,7 +22,18 @@ export default class CallTool {
22
22
  const { default: Tool } = await import(ctx.tools[item]);
23
23
  ctx.args = params.arguments ?? {};
24
24
  const tool = new Tool(ctx);
25
- const content = await tool.handle(ctx);
26
- return Response.result(ctx.request.id, content);
25
+ const data = await tool.handle(ctx);
26
+ let result;
27
+ let error;
28
+ if (Array.isArray(data)) {
29
+ result = { content: data };
30
+ }
31
+ else if (data.code) {
32
+ error = data;
33
+ }
34
+ else {
35
+ result = { content: [data] };
36
+ }
37
+ return Response.toJsonRpc({ id: ctx.request.id, result, error });
27
38
  }
28
39
  }
@@ -7,8 +7,6 @@
7
7
  import type { Method } from '../../types/method.js';
8
8
  import type { McpContext } from '../../types/context.js';
9
9
  export default class GetPrompt implements Method {
10
- handle(ctx: McpContext): {
11
- readonly jsonrpc: "2.0";
12
- };
10
+ handle(ctx: McpContext): import("../../types/response.js").JsonRpcResponse;
13
11
  }
14
12
  //# sourceMappingURL=get_prompt.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"get_prompt.d.ts","sourceRoot":"","sources":["../../../../src/server/methods/get_prompt.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAA;AACnD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAA;AAIxD,MAAM,CAAC,OAAO,OAAO,SAAU,YAAW,MAAM;IAC9C,MAAM,CAAC,GAAG,EAAE,UAAU;;;CAGvB"}
1
+ {"version":3,"file":"get_prompt.d.ts","sourceRoot":"","sources":["../../../../src/server/methods/get_prompt.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAA;AACnD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAA;AAIxD,MAAM,CAAC,OAAO,OAAO,SAAU,YAAW,MAAM;IAC9C,MAAM,CAAC,GAAG,EAAE,UAAU;CAGvB"}
@@ -7,6 +7,6 @@
7
7
  import Response from '../../response.js';
8
8
  export default class GetPrompt {
9
9
  handle(ctx) {
10
- return Response.result(ctx.request.id, {});
10
+ return Response.toJsonRpc({ id: ctx.request.id });
11
11
  }
12
12
  }
@@ -7,8 +7,6 @@
7
7
  import type { Method } from '../../types/method.js';
8
8
  import type { McpContext } from '../../types/context.js';
9
9
  export default class Initialize implements Method {
10
- handle(ctx: McpContext): {
11
- readonly jsonrpc: "2.0";
12
- };
10
+ handle(ctx: McpContext): import("../../types/response.js").JsonRpcResponse;
13
11
  }
14
12
  //# sourceMappingURL=initialize.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"initialize.d.ts","sourceRoot":"","sources":["../../../../src/server/methods/initialize.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAA;AACnD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAA;AAKxD,MAAM,CAAC,OAAO,OAAO,UAAW,YAAW,MAAM;IAC/C,MAAM,CAAC,GAAG,EAAE,UAAU;;;CAyBvB"}
1
+ {"version":3,"file":"initialize.d.ts","sourceRoot":"","sources":["../../../../src/server/methods/initialize.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAA;AACnD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAA;AAKxD,MAAM,CAAC,OAAO,OAAO,UAAW,YAAW,MAAM;IAC/C,MAAM,CAAC,GAAG,EAAE,UAAU;CA4BvB"}
@@ -16,7 +16,7 @@ export default class Initialize {
16
16
  throw createError('Unsupported protocol version', 'E_JSON_RPC_ERROR', -32000);
17
17
  }
18
18
  const protocolVersion = requestedVersion ?? ctx.supportedProtocolVersions[0];
19
- const initResult = {
19
+ const result = {
20
20
  protocolVersion,
21
21
  capabilities: ctx.serverCapabilities,
22
22
  serverInfo: {
@@ -25,6 +25,6 @@ export default class Initialize {
25
25
  },
26
26
  instructions: ctx.instructions,
27
27
  };
28
- return Response.result(ctx.request.id, initResult);
28
+ return Response.toJsonRpc({ id: ctx.request.id, result });
29
29
  }
30
30
  }
@@ -7,8 +7,6 @@
7
7
  import type { Method } from '../../types/method.js';
8
8
  import type { McpContext } from '../../types/context.js';
9
9
  export default class ListPrompts implements Method {
10
- handle(ctx: McpContext): {
11
- readonly jsonrpc: "2.0";
12
- };
10
+ handle(ctx: McpContext): import("../../types/response.js").JsonRpcResponse;
13
11
  }
14
12
  //# sourceMappingURL=list_prompts.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"list_prompts.d.ts","sourceRoot":"","sources":["../../../../src/server/methods/list_prompts.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAA;AACnD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAA;AAIxD,MAAM,CAAC,OAAO,OAAO,WAAY,YAAW,MAAM;IAChD,MAAM,CAAC,GAAG,EAAE,UAAU;;;CAGvB"}
1
+ {"version":3,"file":"list_prompts.d.ts","sourceRoot":"","sources":["../../../../src/server/methods/list_prompts.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAA;AACnD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAA;AAIxD,MAAM,CAAC,OAAO,OAAO,WAAY,YAAW,MAAM;IAChD,MAAM,CAAC,GAAG,EAAE,UAAU;CAGvB"}
@@ -7,6 +7,6 @@
7
7
  import Response from '../../response.js';
8
8
  export default class ListPrompts {
9
9
  handle(ctx) {
10
- return Response.result(ctx.request.id, { prompts: ctx.prompts });
10
+ return Response.toJsonRpc({ id: ctx.request.id, result: { prompts: ctx.prompts } });
11
11
  }
12
12
  }
@@ -7,8 +7,6 @@
7
7
  import type { Method } from '../../types/method.js';
8
8
  import type { McpContext } from '../../types/context.js';
9
9
  export default class ListResources implements Method {
10
- handle(ctx: McpContext): {
11
- readonly jsonrpc: "2.0";
12
- };
10
+ handle(ctx: McpContext): import("../../types/response.js").JsonRpcResponse;
13
11
  }
14
12
  //# sourceMappingURL=list_resources.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"list_resources.d.ts","sourceRoot":"","sources":["../../../../src/server/methods/list_resources.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAA;AACnD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAA;AAIxD,MAAM,CAAC,OAAO,OAAO,aAAc,YAAW,MAAM;IAClD,MAAM,CAAC,GAAG,EAAE,UAAU;;;CAGvB"}
1
+ {"version":3,"file":"list_resources.d.ts","sourceRoot":"","sources":["../../../../src/server/methods/list_resources.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAA;AACnD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAA;AAIxD,MAAM,CAAC,OAAO,OAAO,aAAc,YAAW,MAAM;IAClD,MAAM,CAAC,GAAG,EAAE,UAAU;CAGvB"}
@@ -7,6 +7,6 @@
7
7
  import Response from '../../response.js';
8
8
  export default class ListResources {
9
9
  handle(ctx) {
10
- return Response.result(ctx.request.id, { resources: ctx.resources });
10
+ return Response.toJsonRpc({ id: ctx.request.id, result: { resources: ctx.resources } });
11
11
  }
12
12
  }
@@ -7,8 +7,6 @@
7
7
  import type { Method } from '../../types/method.js';
8
8
  import type { McpContext } from '../../types/context.js';
9
9
  export default class ListTools implements Method {
10
- handle(ctx: McpContext): Promise<{
11
- readonly jsonrpc: "2.0";
12
- }>;
10
+ handle(ctx: McpContext): Promise<import("../../types/response.js").JsonRpcResponse>;
13
11
  }
14
12
  //# sourceMappingURL=list_tools.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"list_tools.d.ts","sourceRoot":"","sources":["../../../../src/server/methods/list_tools.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAA;AACnD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAA;AAKxD,MAAM,CAAC,OAAO,OAAO,SAAU,YAAW,MAAM;IACxC,MAAM,CAAC,GAAG,EAAE,UAAU;;;CAmC7B"}
1
+ {"version":3,"file":"list_tools.d.ts","sourceRoot":"","sources":["../../../../src/server/methods/list_tools.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAA;AACnD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAA;AAKxD,MAAM,CAAC,OAAO,OAAO,SAAU,YAAW,MAAM;IACxC,MAAM,CAAC,GAAG,EAAE,UAAU;CAwD7B"}
@@ -4,18 +4,24 @@
4
4
  * @license MIT
5
5
  * @copyright Jeremy Chaufourier <jeremy@chaufourier.fr>
6
6
  */
7
- // import { createError } from '@adonisjs/core/exceptions'
7
+ import { CursorPaginator } from '../pagination/cursor_paginator.js';
8
8
  import Response from '../../response.js';
9
9
  export default class ListTools {
10
10
  async handle(ctx) {
11
- const tools = await Promise.all(Object.values(ctx.tools).map(async (filepath) => {
11
+ let error = false;
12
+ let nextCursor;
13
+ const paginator = new CursorPaginator(Object.values(ctx.tools), ctx.getPerPage(), ctx.request.params?.cursor);
14
+ const paginatedTools = paginator.paginate('tools');
15
+ const tools = await Promise.all(paginatedTools['tools'].map(async (filepath) => {
12
16
  try {
13
17
  const { default: Tool } = await import(filepath);
14
18
  const tool = new Tool();
15
- const schema = tool.schema() ?? {
16
- type: 'object',
17
- properties: {},
18
- };
19
+ const schema = tool.schema
20
+ ? tool.schema()
21
+ : {
22
+ type: 'object',
23
+ properties: {},
24
+ };
19
25
  return {
20
26
  name: tool.name,
21
27
  title: tool.title,
@@ -24,18 +30,25 @@ export default class ListTools {
24
30
  type: schema.type,
25
31
  properties: schema.properties,
26
32
  required: schema.required ?? [],
27
- }
33
+ },
28
34
  };
29
35
  }
30
36
  catch (error) {
31
- console.error(error);
32
- // throw createError(
33
- // `Error listing tool ${tool.name}`,
34
- // 'E_LIST_TOOLS_ERROR',
35
- // -32601,
36
- // )
37
+ error = true;
37
38
  }
38
39
  }));
39
- return Response.result(ctx.request.id, { tools });
40
+ if (error) {
41
+ return Response.toJsonRpc({
42
+ id: ctx.request.id,
43
+ error: {
44
+ code: -32601,
45
+ message: `Error listing tool`,
46
+ },
47
+ });
48
+ }
49
+ if (paginatedTools.nextCursor) {
50
+ nextCursor = paginatedTools.nextCursor;
51
+ }
52
+ return Response.toJsonRpc({ id: ctx.request.id, result: { tools, nextCursor } });
40
53
  }
41
54
  }
@@ -7,8 +7,6 @@
7
7
  import type { Method } from '../../types/method.js';
8
8
  import type { McpContext } from '../../types/context.js';
9
9
  export default class Ping implements Method {
10
- handle(ctx: McpContext): {
11
- readonly jsonrpc: "2.0";
12
- };
10
+ handle(ctx: McpContext): import("../../types/response.js").JsonRpcResponse;
13
11
  }
14
12
  //# sourceMappingURL=ping.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"ping.d.ts","sourceRoot":"","sources":["../../../../src/server/methods/ping.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAA;AACnD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAA;AAIxD,MAAM,CAAC,OAAO,OAAO,IAAK,YAAW,MAAM;IACzC,MAAM,CAAC,GAAG,EAAE,UAAU;;;CAGvB"}
1
+ {"version":3,"file":"ping.d.ts","sourceRoot":"","sources":["../../../../src/server/methods/ping.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAA;AACnD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAA;AAIxD,MAAM,CAAC,OAAO,OAAO,IAAK,YAAW,MAAM;IACzC,MAAM,CAAC,GAAG,EAAE,UAAU;CAGvB"}
@@ -7,6 +7,6 @@
7
7
  import Response from '../../response.js';
8
8
  export default class Ping {
9
9
  handle(ctx) {
10
- return Response.result(ctx.request.id, {});
10
+ return Response.toJsonRpc({ id: ctx.request.id });
11
11
  }
12
12
  }
@@ -7,8 +7,6 @@
7
7
  import type { Method } from '../../types/method.js';
8
8
  import type { McpContext } from '../../types/context.js';
9
9
  export default class ReadResource implements Method {
10
- handle(ctx: McpContext): {
11
- readonly jsonrpc: "2.0";
12
- };
10
+ handle(ctx: McpContext): import("../../types/response.js").JsonRpcResponse;
13
11
  }
14
12
  //# sourceMappingURL=read_resource.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"read_resource.d.ts","sourceRoot":"","sources":["../../../../src/server/methods/read_resource.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAA;AACnD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAA;AAIxD,MAAM,CAAC,OAAO,OAAO,YAAa,YAAW,MAAM;IACjD,MAAM,CAAC,GAAG,EAAE,UAAU;;;CAGvB"}
1
+ {"version":3,"file":"read_resource.d.ts","sourceRoot":"","sources":["../../../../src/server/methods/read_resource.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAA;AACnD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAA;AAIxD,MAAM,CAAC,OAAO,OAAO,YAAa,YAAW,MAAM;IACjD,MAAM,CAAC,GAAG,EAAE,UAAU;CAGvB"}
@@ -7,6 +7,6 @@
7
7
  import Response from '../../response.js';
8
8
  export default class ReadResource {
9
9
  handle(ctx) {
10
- return Response.result(ctx.request.id, {});
10
+ return Response.toJsonRpc({ id: ctx.request.id });
11
11
  }
12
12
  }
@@ -0,0 +1,12 @@
1
+ export declare class CursorPaginator {
2
+ private items;
3
+ private perPage;
4
+ private cursor?;
5
+ constructor(items: unknown[], perPage: number, cursor?: string | undefined);
6
+ paginate(key?: string): {
7
+ [key: string]: unknown;
8
+ };
9
+ protected getStartOffsetFromCursor(): number;
10
+ protected createCursor(offset: number): string;
11
+ }
12
+ //# sourceMappingURL=cursor_paginator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cursor_paginator.d.ts","sourceRoot":"","sources":["../../../../src/server/pagination/cursor_paginator.ts"],"names":[],"mappings":"AAAA,qBAAa,eAAe;IAExB,OAAO,CAAC,KAAK;IACb,OAAO,CAAC,OAAO;IACf,OAAO,CAAC,MAAM,CAAC;gBAFP,KAAK,EAAE,OAAO,EAAE,EAChB,OAAO,EAAE,MAAM,EACf,MAAM,CAAC,EAAE,MAAM,YAAA;IAGlB,QAAQ,CAAC,GAAG,GAAE,MAAgB,GAAG;QAAE,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;KAAE;IAmBlE,SAAS,CAAC,wBAAwB;IA0BlC,SAAS,CAAC,YAAY,CAAC,MAAM,EAAE,MAAM;CAGtC"}
@@ -0,0 +1,48 @@
1
+ export class CursorPaginator {
2
+ items;
3
+ perPage;
4
+ cursor;
5
+ constructor(items, perPage, cursor) {
6
+ this.items = items;
7
+ this.perPage = perPage;
8
+ this.cursor = cursor;
9
+ }
10
+ paginate(key = 'items') {
11
+ const startOffset = this.getStartOffsetFromCursor();
12
+ console.log('startOffset', startOffset);
13
+ const paginatedItems = this.items.slice(startOffset, startOffset + this.perPage);
14
+ const hasMorePages = this.items.length > startOffset + this.perPage;
15
+ console.log('hasMorePages', hasMorePages);
16
+ console.log('paginatedItems', paginatedItems.length);
17
+ const result = {
18
+ [key]: paginatedItems,
19
+ };
20
+ if (hasMorePages) {
21
+ result.nextCursor = this.createCursor(startOffset + this.perPage);
22
+ }
23
+ return result;
24
+ }
25
+ getStartOffsetFromCursor() {
26
+ if (!this.cursor) {
27
+ return 0;
28
+ }
29
+ try {
30
+ const decodedCursor = Buffer.from(this.cursor, 'base64').toString('utf-8');
31
+ if (!decodedCursor) {
32
+ return 0;
33
+ }
34
+ const cursorData = JSON.parse(decodedCursor);
35
+ if (!cursorData.hasOwnProperty('offset')) {
36
+ return 0;
37
+ }
38
+ return parseInt(cursorData.offset);
39
+ }
40
+ catch (error) {
41
+ //
42
+ }
43
+ return 0;
44
+ }
45
+ createCursor(offset) {
46
+ return Buffer.from(JSON.stringify({ offset })).toString('base64');
47
+ }
48
+ }
@@ -10,11 +10,9 @@ export declare abstract class Tool<S extends JSONSchema> {
10
10
  abstract name: string;
11
11
  abstract title?: string;
12
12
  abstract description?: string;
13
- /** Schema retourné par la classe */
14
- abstract schema(): S;
15
- /** handle typé automatiquement depuis le schema */
13
+ abstract schema?(): S;
16
14
  abstract handle(ctx?: McpContext & {
17
15
  args: InferJSONSchema<S>;
18
- }): Record<string, unknown> | Promise<Record<string, unknown>>;
16
+ }): Record<string, unknown> | Record<string, unknown>[] | Promise<Record<string, unknown> | Record<string, unknown>[]>;
19
17
  }
20
18
  //# sourceMappingURL=tool.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"tool.d.ts","sourceRoot":"","sources":["../../../src/server/tool.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAA;AACrE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAA;AAErD,8BAAsB,IAAI,CAAC,CAAC,SAAS,UAAU;IAC7C,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAA;IACvB,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAA;IAE7B,oCAAoC;IACpC,QAAQ,CAAC,MAAM,IAAI,CAAC;IAEpB,mDAAmD;IACnD,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,UAAU,GAAG;QAAE,IAAI,EAAE,eAAe,CAAC,CAAC,CAAC,CAAA;KAAE,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAC7H"}
1
+ {"version":3,"file":"tool.d.ts","sourceRoot":"","sources":["../../../src/server/tool.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAA;AACrE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAA;AAErD,8BAAsB,IAAI,CAAC,CAAC,SAAS,UAAU;IAC7C,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAA;IACvB,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAA;IAE7B,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC;IAErB,QAAQ,CAAC,MAAM,CACb,GAAG,CAAC,EAAE,UAAU,GAAG;QAAE,IAAI,EAAE,eAAe,CAAC,CAAC,CAAC,CAAA;KAAE,GAE7C,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GACvB,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,GACzB,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAC;CACjE"}