fa-mcp-sdk 0.4.124 → 0.4.134

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 (71) hide show
  1. package/cli-template/AGENTS.md +1 -1
  2. package/cli-template/FA-MCP-SDK-DOC/00-FA-MCP-SDK-index.md +19 -5
  3. package/cli-template/FA-MCP-SDK-DOC/02-1-tools-and-api.md +63 -0
  4. package/cli-template/FA-MCP-SDK-DOC/06-utilities.md +133 -5
  5. package/cli-template/FA-MCP-SDK-DOC/07-testing-and-operations.md +85 -0
  6. package/cli-template/FA-MCP-SDK-DOC/08-agent-tester-and-headless-api.md +284 -0
  7. package/cli-template/FA-MCP-SDK-DOC/10-mcp-apps.md +90 -0
  8. package/cli-template/examples/mcp-apps-canonical/README.md +62 -0
  9. package/cli-template/examples/mcp-apps-canonical/server.ts +95 -0
  10. package/cli-template/examples/mcp-apps-canonical/widget/index.html +147 -0
  11. package/cli-template/package.json +2 -1
  12. package/config/_local.yaml +6 -0
  13. package/config/custom-environment-variables.yaml +5 -0
  14. package/config/default.yaml +15 -0
  15. package/dist/core/_types_/config.d.ts +20 -0
  16. package/dist/core/_types_/config.d.ts.map +1 -1
  17. package/dist/core/_types_/types.d.ts +13 -0
  18. package/dist/core/_types_/types.d.ts.map +1 -1
  19. package/dist/core/agent-tester/agent-tester-router.d.ts.map +1 -1
  20. package/dist/core/agent-tester/agent-tester-router.js +79 -2
  21. package/dist/core/agent-tester/agent-tester-router.js.map +1 -1
  22. package/dist/core/agent-tester/services/TesterAgentService.d.ts +14 -0
  23. package/dist/core/agent-tester/services/TesterAgentService.d.ts.map +1 -1
  24. package/dist/core/agent-tester/services/TesterAgentService.js +101 -1
  25. package/dist/core/agent-tester/services/TesterAgentService.js.map +1 -1
  26. package/dist/core/agent-tester/services/TesterMcpClientService.d.ts +1 -0
  27. package/dist/core/agent-tester/services/TesterMcpClientService.d.ts.map +1 -1
  28. package/dist/core/agent-tester/services/TesterMcpClientService.js +46 -19
  29. package/dist/core/agent-tester/services/TesterMcpClientService.js.map +1 -1
  30. package/dist/core/agent-tester/services/mcp-apps-utils.d.ts +22 -0
  31. package/dist/core/agent-tester/services/mcp-apps-utils.d.ts.map +1 -0
  32. package/dist/core/agent-tester/services/mcp-apps-utils.js +77 -0
  33. package/dist/core/agent-tester/services/mcp-apps-utils.js.map +1 -0
  34. package/dist/core/agent-tester/types.d.ts +65 -0
  35. package/dist/core/agent-tester/types.d.ts.map +1 -1
  36. package/dist/core/index.d.ts +4 -1
  37. package/dist/core/index.d.ts.map +1 -1
  38. package/dist/core/index.js +4 -1
  39. package/dist/core/index.js.map +1 -1
  40. package/dist/core/init-mcp-server.d.ts.map +1 -1
  41. package/dist/core/init-mcp-server.js +46 -5
  42. package/dist/core/init-mcp-server.js.map +1 -1
  43. package/dist/core/mcp/builtin-debug-tools.d.ts +41 -0
  44. package/dist/core/mcp/builtin-debug-tools.d.ts.map +1 -0
  45. package/dist/core/mcp/builtin-debug-tools.js +75 -0
  46. package/dist/core/mcp/builtin-debug-tools.js.map +1 -0
  47. package/dist/core/mcp/debug-trace.d.ts +26 -0
  48. package/dist/core/mcp/debug-trace.d.ts.map +1 -0
  49. package/dist/core/mcp/debug-trace.js +79 -0
  50. package/dist/core/mcp/debug-trace.js.map +1 -0
  51. package/dist/core/mcp/prompts.d.ts.map +1 -1
  52. package/dist/core/mcp/prompts.js +11 -0
  53. package/dist/core/mcp/prompts.js.map +1 -1
  54. package/dist/core/mcp/resources.d.ts.map +1 -1
  55. package/dist/core/mcp/resources.js +11 -0
  56. package/dist/core/mcp/resources.js.map +1 -1
  57. package/dist/core/utils/formatToolResult.d.ts +39 -0
  58. package/dist/core/utils/formatToolResult.d.ts.map +1 -1
  59. package/dist/core/utils/formatToolResult.js +58 -0
  60. package/dist/core/utils/formatToolResult.js.map +1 -1
  61. package/dist/core/utils/testing/debug-tool.d.ts +35 -0
  62. package/dist/core/utils/testing/debug-tool.d.ts.map +1 -0
  63. package/dist/core/utils/testing/debug-tool.js +146 -0
  64. package/dist/core/utils/testing/debug-tool.js.map +1 -0
  65. package/dist/core/web/server-http.d.ts.map +1 -1
  66. package/dist/core/web/server-http.js +26 -1
  67. package/dist/core/web/server-http.js.map +1 -1
  68. package/dist/core/web/static/agent-tester/index.html +55 -0
  69. package/dist/core/web/static/agent-tester/script.js +986 -9
  70. package/dist/core/web/static/agent-tester/styles.css +416 -0
  71. package/package.json +1 -1
@@ -0,0 +1,79 @@
1
+ /**
2
+ * JSON-lines debug sink for MCP server traffic.
3
+ *
4
+ * Stderr output via `DEBUG=mcp:*` (`af-tools-ts/Debug`) is great for live
5
+ * development but useless for post-mortem analysis: ANSI colors, multi-process
6
+ * interleaving, no structured fields. This module mirrors every `debugMcp*`
7
+ * stream into a single newline-delimited JSON file when `mcp.debug.logFile`
8
+ * is configured. Stderr behavior is unchanged — the sink is purely additive.
9
+ *
10
+ * Activation:
11
+ * - via `appConfig.mcp.debug.logFile` (absolute path) — set the file path
12
+ * at startup and call {@link initDebugTraceFromConfig}; or
13
+ * - via {@link configureDebugSink} for programmatic control (tests).
14
+ *
15
+ * Each event is one line like:
16
+ * {"ts":"2026-05-19T12:34:56.124Z","ch":"mcp:tool","kind":"req","name":"get_rate","corr":"a3f1",...}
17
+ *
18
+ * No-op when no sink is configured — call sites are cheap (one `if`).
19
+ */
20
+ import { appendFile, mkdir } from 'node:fs/promises';
21
+ import * as path from 'node:path';
22
+ import { appConfig } from '../bootstrap/init-config.js';
23
+ let sink = null;
24
+ /**
25
+ * Configure (or disable) the JSON-lines sink.
26
+ *
27
+ * @param logFile Absolute path to the .jsonl file. Empty / undefined disables the sink.
28
+ *
29
+ * Writes are fire-and-forget: failures (permission, disk full) are swallowed
30
+ * so debug logging never breaks the server. The parent directory is created
31
+ * lazily on the first event.
32
+ */
33
+ export function configureDebugSink(logFile) {
34
+ if (!logFile || typeof logFile !== 'string' || logFile.trim() === '') {
35
+ sink = null;
36
+ return;
37
+ }
38
+ const resolved = path.resolve(logFile.trim());
39
+ let dirEnsured = false;
40
+ sink = (event) => {
41
+ const line = JSON.stringify(event) + '\n';
42
+ const write = () => appendFile(resolved, line, 'utf-8').catch(() => { });
43
+ if (dirEnsured) {
44
+ void write();
45
+ return;
46
+ }
47
+ void mkdir(path.dirname(resolved), { recursive: true })
48
+ .catch(() => { })
49
+ .then(() => {
50
+ dirEnsured = true;
51
+ return write();
52
+ });
53
+ };
54
+ }
55
+ /**
56
+ * Emit a single trace event. Always adds `ts` (ISO timestamp) and `ch` (channel).
57
+ * No-op when the sink is not configured.
58
+ */
59
+ export function emitTrace(channel, event) {
60
+ if (!sink) {
61
+ return;
62
+ }
63
+ sink({ ts: new Date().toISOString(), ch: channel, ...event });
64
+ }
65
+ /**
66
+ * Generate a short correlation ID for matching req/res/err events of a single call.
67
+ * 8 hex chars — collision-resistant enough for human reading; not cryptographic.
68
+ */
69
+ export function makeCorr() {
70
+ return Math.random().toString(16).slice(2, 10).padStart(8, '0');
71
+ }
72
+ /**
73
+ * Initialize the sink from `appConfig.mcp.debug.logFile`. Called once at server
74
+ * startup; safe to call again to apply config changes during tests.
75
+ */
76
+ export function initDebugTraceFromConfig() {
77
+ configureDebugSink(appConfig.mcp?.debug?.logFile);
78
+ }
79
+ //# sourceMappingURL=debug-trace.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"debug-trace.js","sourceRoot":"","sources":["../../../src/core/mcp/debug-trace.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AACH,OAAO,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAElC,OAAO,EAAE,SAAS,EAAE,MAAM,6BAA6B,CAAC;AAIxD,IAAI,IAAI,GAAgB,IAAI,CAAC;AAE7B;;;;;;;;GAQG;AACH,MAAM,UAAU,kBAAkB,CAAC,OAAkC;IACnE,IAAI,CAAC,OAAO,IAAI,OAAO,OAAO,KAAK,QAAQ,IAAI,OAAO,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;QACrE,IAAI,GAAG,IAAI,CAAC;QACZ,OAAO;IACT,CAAC;IACD,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC;IAC9C,IAAI,UAAU,GAAG,KAAK,CAAC;IACvB,IAAI,GAAG,CAAC,KAAK,EAAE,EAAE;QACf,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC;QAC1C,MAAM,KAAK,GAAG,GAAG,EAAE,CAAC,UAAU,CAAC,QAAQ,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;QACxE,IAAI,UAAU,EAAE,CAAC;YACf,KAAK,KAAK,EAAE,CAAC;YACb,OAAO;QACT,CAAC;QACD,KAAK,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC;aACpD,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC;aACf,IAAI,CAAC,GAAG,EAAE;YACT,UAAU,GAAG,IAAI,CAAC;YAClB,OAAO,KAAK,EAAE,CAAC;QACjB,CAAC,CAAC,CAAC;IACP,CAAC,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,SAAS,CAAC,OAAe,EAAE,KAA8B;IACvE,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,OAAO;IACT,CAAC;IACD,IAAI,CAAC,EAAE,EAAE,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,EAAE,EAAE,EAAE,OAAO,EAAE,GAAG,KAAK,EAAE,CAAC,CAAC;AAChE,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,QAAQ;IACtB,OAAO,IAAI,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;AAClE,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,wBAAwB;IACtC,kBAAkB,CAAC,SAAS,CAAC,GAAG,EAAE,KAAK,EAAE,OAAO,CAAC,CAAC;AACpD,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"prompts.d.ts","sourceRoot":"","sources":["../../../src/core/mcp/prompts.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,EAAE,iBAAiB,EAAE,iBAAiB,EAA+B,MAAM,qBAAqB,CAAC;AAgDxG,wBAAsB,cAAc,CAAC,IAAI,EAAE,iBAAiB;;;;;;;GAU3D;AAED,eAAO,MAAM,SAAS,GAAU,SAAS,iBAAiB,EAAE,MAAM,iBAAiB,KAAG,OAAO,CAAC,GAAG,CAmChG,CAAC"}
1
+ {"version":3,"file":"prompts.d.ts","sourceRoot":"","sources":["../../../src/core/mcp/prompts.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,EAAE,iBAAiB,EAAE,iBAAiB,EAA+B,MAAM,qBAAqB,CAAC;AAiDxG,wBAAsB,cAAc,CAAC,IAAI,EAAE,iBAAiB;;;;;;;GAc3D;AAED,eAAO,MAAM,SAAS,GAAU,SAAS,iBAAiB,EAAE,MAAM,iBAAiB,KAAG,OAAO,CAAC,GAAG,CAyChG,CAAC"}
@@ -1,5 +1,6 @@
1
1
  import { getProjectData } from '../bootstrap/init-config.js';
2
2
  import { debugMcpPrompt } from '../debug.js';
3
+ import { emitTrace } from './debug-trace.js';
3
4
  async function getPrompts(args) {
4
5
  const projectData = getProjectData();
5
6
  if (!projectData) {
@@ -41,24 +42,31 @@ async function getPrompts(args) {
41
42
  ];
42
43
  }
43
44
  export async function getPromptsList(args) {
45
+ const startedAt = Date.now();
44
46
  if (debugMcpPrompt.enabled) {
45
47
  debugMcpPrompt('→ prompts/list');
46
48
  }
49
+ emitTrace('mcp:prompt', { kind: 'list-req' });
47
50
  const prompts = await getPrompts(args);
48
51
  const result = { prompts: prompts.map(({ content, ...rest }) => ({ ...rest })) };
52
+ const ms = Date.now() - startedAt;
49
53
  if (debugMcpPrompt.enabled) {
50
54
  debugMcpPrompt(`← prompts/list (${result.prompts.length})\n${JSON.stringify(result, null, 2)}`);
51
55
  }
56
+ emitTrace('mcp:prompt', { kind: 'list-res', count: result.prompts.length, ms });
52
57
  return result;
53
58
  }
54
59
  export const getPrompt = async (request, args) => {
55
60
  const { name } = request.params;
61
+ const startedAt = Date.now();
56
62
  if (debugMcpPrompt.enabled) {
57
63
  debugMcpPrompt(`→ prompts/get ${name}\n${JSON.stringify(request.params ?? {}, null, 2)}`);
58
64
  }
65
+ emitTrace('mcp:prompt', { kind: 'get-req', name });
59
66
  const prompts = await getPrompts(args);
60
67
  // Check if prompts are available
61
68
  if (!prompts || prompts.length === 0) {
69
+ emitTrace('mcp:prompt', { kind: 'get-err', name, ms: Date.now() - startedAt, error: 'no-prompts' });
62
70
  throw new Error('No prompts available. Project data may not be properly initialized.');
63
71
  }
64
72
  let content = prompts.filter((p) => p.name === name).map((p) => p.content)[0] || null;
@@ -66,6 +74,7 @@ export const getPrompt = async (request, args) => {
66
74
  content = await content(request);
67
75
  }
68
76
  if (!content) {
77
+ emitTrace('mcp:prompt', { kind: 'get-err', name, ms: Date.now() - startedAt, error: 'unknown-prompt' });
69
78
  throw new Error(`Unknown prompt: ${name}`);
70
79
  }
71
80
  const result = {
@@ -79,9 +88,11 @@ export const getPrompt = async (request, args) => {
79
88
  },
80
89
  ],
81
90
  };
91
+ const ms = Date.now() - startedAt;
82
92
  if (debugMcpPrompt.enabled) {
83
93
  debugMcpPrompt(`← prompts/get ${name}\n${content}`);
84
94
  }
95
+ emitTrace('mcp:prompt', { kind: 'get-res', name, ms });
85
96
  return result;
86
97
  };
87
98
  //# sourceMappingURL=prompts.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"prompts.js","sourceRoot":"","sources":["../../../src/core/mcp/prompts.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"prompts.js","sourceRoot":"","sources":["../../../src/core/mcp/prompts.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"resources.d.ts","sourceRoot":"","sources":["../../../src/core/mcp/resources.ts"],"names":[],"mappings":"AAAA;;GAEG;AAKH,OAAO,EAAmB,SAAS,EAAiB,aAAa,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAyElH,eAAO,MAAM,gBAAgB,GAAU,MAAM,iBAAiB,KAAG,OAAO,CAAC;IAAE,SAAS,EAAE,aAAa,EAAE,CAAA;CAAE,CAUtG,CAAC;AAEF,eAAO,MAAM,WAAW,GAAU,KAAK,MAAM,EAAE,MAAM,iBAAiB,KAAG,OAAO,CAAC,SAAS,CA+BzF,CAAC"}
1
+ {"version":3,"file":"resources.d.ts","sourceRoot":"","sources":["../../../src/core/mcp/resources.ts"],"names":[],"mappings":"AAAA;;GAEG;AAKH,OAAO,EAAmB,SAAS,EAAiB,aAAa,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AA0ElH,eAAO,MAAM,gBAAgB,GAAU,MAAM,iBAAiB,KAAG,OAAO,CAAC;IAAE,SAAS,EAAE,aAAa,EAAE,CAAA;CAAE,CActG,CAAC;AAEF,eAAO,MAAM,WAAW,GAAU,KAAK,MAAM,EAAE,MAAM,iBAAiB,KAAG,OAAO,CAAC,SAAS,CAqCzF,CAAC"}
@@ -6,6 +6,7 @@ import * as path from 'node:path';
6
6
  import { appConfig, getProjectData } from '../bootstrap/init-config.js';
7
7
  import { ROOT_PROJECT_DIR } from '../constants.js';
8
8
  import { debugMcpResource } from '../debug.js';
9
+ import { emitTrace } from './debug-trace.js';
9
10
  import { assembleReadmeWithSatellites } from './readme-assembler.js';
10
11
  let readme = assembleReadmeWithSatellites(ROOT_PROJECT_DIR);
11
12
  let packageJson;
@@ -72,23 +73,30 @@ This information is used by searching for this MCP server and its information in
72
73
  return [...resources, ...resolvedCustomResources];
73
74
  };
74
75
  export const getResourcesList = async (args) => {
76
+ const startedAt = Date.now();
75
77
  if (debugMcpResource.enabled) {
76
78
  debugMcpResource('→ resources/list');
77
79
  }
80
+ emitTrace('mcp:resource', { kind: 'list-req' });
78
81
  const resources = await createResources(args);
79
82
  const result = { resources: resources.map(({ content, ...rest }) => ({ ...rest })) };
83
+ const ms = Date.now() - startedAt;
80
84
  if (debugMcpResource.enabled) {
81
85
  debugMcpResource(`← resources/list (${result.resources.length})\n${JSON.stringify(result, null, 2)}`);
82
86
  }
87
+ emitTrace('mcp:resource', { kind: 'list-res', count: result.resources.length, ms });
83
88
  return result;
84
89
  };
85
90
  export const getResource = async (uri, args) => {
91
+ const startedAt = Date.now();
86
92
  if (debugMcpResource.enabled) {
87
93
  debugMcpResource(`→ resources/read ${uri}`);
88
94
  }
95
+ emitTrace('mcp:resource', { kind: 'read-req', uri });
89
96
  const resources = await createResources(args);
90
97
  const resource = resources.find((r) => r.uri === uri);
91
98
  if (!resource) {
99
+ emitTrace('mcp:resource', { kind: 'read-err', uri, ms: Date.now() - startedAt, error: 'unknown-resource' });
92
100
  throw new Error(`Unknown resource: ${uri}`);
93
101
  }
94
102
  let { content } = resource;
@@ -96,6 +104,7 @@ export const getResource = async (uri, args) => {
96
104
  content = await content(uri);
97
105
  }
98
106
  if (!content) {
107
+ emitTrace('mcp:resource', { kind: 'read-err', uri, ms: Date.now() - startedAt, error: 'no-content' });
99
108
  throw new Error(`Can not get content of resource '${uri}' by custom handler`);
100
109
  }
101
110
  const result = {
@@ -108,10 +117,12 @@ export const getResource = async (uri, args) => {
108
117
  },
109
118
  ],
110
119
  };
120
+ const ms = Date.now() - startedAt;
111
121
  if (debugMcpResource.enabled) {
112
122
  const body = typeof content === 'string' ? content : JSON.stringify(content, null, 2);
113
123
  debugMcpResource(`← resources/read ${uri}\n${body}`);
114
124
  }
125
+ emitTrace('mcp:resource', { kind: 'read-res', uri, ms });
115
126
  return result;
116
127
  };
117
128
  //# sourceMappingURL=resources.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"resources.js","sourceRoot":"","sources":["../../../src/core/mcp/resources.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"resources.js","sourceRoot":"","sources":["../../../src/core/mcp/resources.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAC9B,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAGlC,OAAO,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,6BAA6B,CAAC;AACxE,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACnD,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAC/C,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC7C,OAAO,EAAE,4BAA4B,EAAE,MAAM,uBAAuB,CAAC;AAErE,IAAI,MAAM,GAAG,4BAA4B,CAAC,gBAAgB,CAAC,CAAC;AAC5D,IAAI,WAAgB,CAAC;AACrB,IAAI,CAAC;IACH,WAAW,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,gBAAgB,EAAE,gBAAgB,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC;IAClG,MAAM,GAAG,MAAM,CAAC,OAAO,CAAC,oCAAoC,EAAE,YAAY,WAAW,CAAC,OAAO,EAAE,CAAC,CAAC;AACnG,CAAC;AAAC,OAAO,GAAG,EAAE,CAAC;IACb,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;AACrB,CAAC;AAED,MAAM,eAAe,GAAG,KAAK,EAAE,IAAuB,EAA4B,EAAE;IAClF,MAAM,EAAE,eAAe,EAAE,eAAe,EAAE,kBAAkB,EAAE,GAAG,cAAc,EAAE,CAAC;IAElF,2DAA2D;IAC3D,IAAI,uBAAuB,GAAoB,EAAE,CAAC;IAClD,IAAI,eAAe,EAAE,CAAC;QACpB,IAAI,OAAO,eAAe,KAAK,UAAU,EAAE,CAAC;YAC1C,uBAAuB,GAAG,MAAM,eAAe,CAAC,IAAI,CAAC,CAAC;QACxD,CAAC;aAAM,CAAC;YACN,uBAAuB,GAAG,eAAe,CAAC;QAC5C,CAAC;IACH,CAAC;IAED,MAAM,SAAS,GAAoB;QACjC;YACE,GAAG,EAAE,cAAc;YACnB,IAAI,EAAE,YAAY;YAClB,WAAW,EAAE;;;oCAGiB;YAC9B,QAAQ,EAAE,YAAY;YACtB,OAAO,EAAE,SAAS,CAAC,IAAI;YACvB,WAAW,EAAE,KAAK;SACnB;QACD;YACE,GAAG,EAAE,gBAAgB;YACrB,IAAI,EAAE,cAAc;YACpB,WAAW,EAAE,+CAA+C;YAC5D,QAAQ,EAAE,YAAY;YACtB,OAAO,EAAE,SAAS,CAAC,WAAW;YAC9B,WAAW,EAAE,KAAK;SACnB;QACD;YACE,GAAG,EAAE,cAAc;YACnB,IAAI,EAAE,WAAW;YACjB,WAAW,EAAE,6BAA6B,SAAS,CAAC,WAAW;;;CAGpE;YACK,QAAQ,EAAE,eAAe;YACzB,OAAO,EAAE,MAAM;YACf,WAAW,EAAE,KAAK;SACnB;KACF,CAAC;IACF,MAAM,eAAe,GAAG,CAAC,kBAAkB,IAAI,EAAE,CAAsB,CAAC;IAExE,SAAS,CAAC,IAAI,CAAC;QACb,GAAG,EAAE,oBAAoB;QACzB,IAAI,EAAE,mBAAmB;QACzB,WAAW,EAAE,mBAAmB;QAChC,QAAQ,EAAE,kBAAkB;QAC5B,OAAO,EAAE,eAAe;QACxB,WAAW,EAAE,KAAK;KACnB,CAAC,CAAC;IACH,OAAO,CAAC,GAAG,SAAS,EAAE,GAAG,uBAAuB,CAAC,CAAC;AACpD,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,gBAAgB,GAAG,KAAK,EAAE,IAAuB,EAA2C,EAAE;IACzG,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IAC7B,IAAI,gBAAgB,CAAC,OAAO,EAAE,CAAC;QAC7B,gBAAgB,CAAC,kBAAkB,CAAC,CAAC;IACvC,CAAC;IACD,SAAS,CAAC,cAAc,EAAE,EAAE,IAAI,EAAE,UAAU,EAAE,CAAC,CAAC;IAChD,MAAM,SAAS,GAAoB,MAAM,eAAe,CAAC,IAAI,CAAC,CAAC;IAC/D,MAAM,MAAM,GAAG,EAAE,SAAS,EAAE,SAAS,CAAC,GAAG,CAAC,CAAC,EAAE,OAAO,EAAE,GAAG,IAAI,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC;IACrF,MAAM,EAAE,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,CAAC;IAClC,IAAI,gBAAgB,CAAC,OAAO,EAAE,CAAC;QAC7B,gBAAgB,CAAC,qBAAqB,MAAM,CAAC,SAAS,CAAC,MAAM,MAAM,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC;IACxG,CAAC;IACD,SAAS,CAAC,cAAc,EAAE,EAAE,IAAI,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,CAAC,SAAS,CAAC,MAAM,EAAE,EAAE,EAAE,CAAC,CAAC;IACpF,OAAO,MAAM,CAAC;AAChB,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,WAAW,GAAG,KAAK,EAAE,GAAW,EAAE,IAAuB,EAAsB,EAAE;IAC5F,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IAC7B,IAAI,gBAAgB,CAAC,OAAO,EAAE,CAAC;QAC7B,gBAAgB,CAAC,oBAAoB,GAAG,EAAE,CAAC,CAAC;IAC9C,CAAC;IACD,SAAS,CAAC,cAAc,EAAE,EAAE,IAAI,EAAE,UAAU,EAAE,GAAG,EAAE,CAAC,CAAC;IACrD,MAAM,SAAS,GAAG,MAAM,eAAe,CAAC,IAAI,CAAC,CAAC;IAC9C,MAAM,QAAQ,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,KAAK,GAAG,CAAC,CAAC;IACtD,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,SAAS,CAAC,cAAc,EAAE,EAAE,IAAI,EAAE,UAAU,EAAE,GAAG,EAAE,EAAE,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,EAAE,KAAK,EAAE,kBAAkB,EAAE,CAAC,CAAC;QAC5G,MAAM,IAAI,KAAK,CAAC,qBAAqB,GAAG,EAAE,CAAC,CAAC;IAC9C,CAAC;IACD,IAAI,EAAE,OAAO,EAAE,GAAG,QAAQ,CAAC;IAC3B,IAAI,OAAO,OAAO,KAAK,UAAU,EAAE,CAAC;QAClC,OAAO,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,CAAC;IAC/B,CAAC;IACD,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,SAAS,CAAC,cAAc,EAAE,EAAE,IAAI,EAAE,UAAU,EAAE,GAAG,EAAE,EAAE,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,EAAE,KAAK,EAAE,YAAY,EAAE,CAAC,CAAC;QACtG,MAAM,IAAI,KAAK,CAAC,oCAAoC,GAAG,qBAAqB,CAAC,CAAC;IAChF,CAAC;IACD,MAAM,MAAM,GAAc;QACxB,QAAQ,EAAE;YACR;gBACE,GAAG,EAAE,QAAQ,CAAC,GAAG;gBACjB,QAAQ,EAAE,QAAQ,CAAC,QAAQ;gBAC3B,IAAI,EAAE,OAAO;gBACb,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,QAAQ,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;aACrD;SACF;KACF,CAAC;IACF,MAAM,EAAE,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,CAAC;IAClC,IAAI,gBAAgB,CAAC,OAAO,EAAE,CAAC;QAC7B,MAAM,IAAI,GAAG,OAAO,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;QACtF,gBAAgB,CAAC,oBAAoB,GAAG,KAAK,IAAI,EAAE,CAAC,CAAC;IACvD,CAAC;IACD,SAAS,CAAC,cAAc,EAAE,EAAE,IAAI,EAAE,UAAU,EAAE,GAAG,EAAE,EAAE,EAAE,CAAC,CAAC;IACzD,OAAO,MAAM,CAAC;AAChB,CAAC,CAAC"}
@@ -14,5 +14,44 @@ export declare function asJson<T = any>(json: T): IToolHandlerStructuredResponse
14
14
  * Returns either structured content (JSON) or formatted text
15
15
  */
16
16
  export declare function formatToolResult<T = any>(json: T): TToolHandlerResponse<T>;
17
+ /**
18
+ * Text response with `isError: true`. Use for tool-level errors that the LLM
19
+ * should see and react to (resource not found, business validation failed,
20
+ * upstream API returned 404, etc.). Per MCP spec these MUST NOT be thrown as
21
+ * JSON-RPC errors — throwing turns them into protocol-level failures the LLM
22
+ * cannot self-correct from.
23
+ *
24
+ * @example
25
+ * if (!issue) {
26
+ * return asTextError(`Issue ${key} not found`);
27
+ * }
28
+ */
29
+ export declare function asTextError(text: string): IToolHandlerTextResponse;
30
+ /**
31
+ * Structured (`structuredContent`) response with `isError: true`. See
32
+ * {@link asTextError} for when to use error responses vs throwing.
33
+ */
34
+ export declare function asJsonError<T = any>(json: T): IToolHandlerStructuredResponse<T>;
35
+ /**
36
+ * Config-aware tool error formatter — mirror of {@link formatToolResult} but
37
+ * sets `isError: true`. Honors `appConfig.mcp.tools.answerAs` so error
38
+ * responses follow the same shape as success responses for the same MCP.
39
+ *
40
+ * Use this for tool-level errors the LLM should see (not-found, validation,
41
+ * upstream failure). Reserve `throw new ToolExecutionError(...)` for protocol
42
+ * issues: unknown tool, malformed call, missing transport feature.
43
+ *
44
+ * @example
45
+ * try {
46
+ * const data = await fetchIssue(key);
47
+ * return formatToolResult(data);
48
+ * } catch (err) {
49
+ * if (err.code === 'NOT_FOUND') {
50
+ * return formatToolError(`Issue ${key} not found`);
51
+ * }
52
+ * throw err; // genuine infra failure → JSON-RPC error is appropriate
53
+ * }
54
+ */
55
+ export declare function formatToolError<T = any>(json: T): TToolHandlerResponse<T>;
17
56
  export declare const getJsonFromResult: <T = any>(result: any) => T;
18
57
  //# sourceMappingURL=formatToolResult.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"formatToolResult.d.ts","sourceRoot":"","sources":["../../../src/core/utils/formatToolResult.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,8BAA8B,EAAE,wBAAwB,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AA+BrH;;;GAGG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,wBAAwB,CASpE;AAED;;;GAGG;AACH,wBAAgB,MAAM,CAAC,CAAC,GAAG,GAAG,EAAE,IAAI,EAAE,CAAC,GAAG,8BAA8B,CAAC,CAAC,CAAC,CAK1E;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,CAAC,GAAG,GAAG,EAAE,IAAI,EAAE,CAAC,GAAG,oBAAoB,CAAC,CAAC,CAAC,CAW1E;AAED,eAAO,MAAM,iBAAiB,GAAI,CAAC,GAAG,GAAG,EAAE,QAAQ,GAAG,KAAG,CAYxD,CAAC"}
1
+ {"version":3,"file":"formatToolResult.d.ts","sourceRoot":"","sources":["../../../src/core/utils/formatToolResult.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,8BAA8B,EAAE,wBAAwB,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AA+BrH;;;GAGG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,wBAAwB,CASpE;AAED;;;GAGG;AACH,wBAAgB,MAAM,CAAC,CAAC,GAAG,GAAG,EAAE,IAAI,EAAE,CAAC,GAAG,8BAA8B,CAAC,CAAC,CAAC,CAK1E;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,CAAC,GAAG,GAAG,EAAE,IAAI,EAAE,CAAC,GAAG,oBAAoB,CAAC,CAAC,CAAC,CAW1E;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,wBAAwB,CAKlE;AAED;;;GAGG;AACH,wBAAgB,WAAW,CAAC,CAAC,GAAG,GAAG,EAAE,IAAI,EAAE,CAAC,GAAG,8BAA8B,CAAC,CAAC,CAAC,CAK/E;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,eAAe,CAAC,CAAC,GAAG,GAAG,EAAE,IAAI,EAAE,CAAC,GAAG,oBAAoB,CAAC,CAAC,CAAC,CASzE;AAED,eAAO,MAAM,iBAAiB,GAAI,CAAC,GAAG,GAAG,EAAE,QAAQ,GAAG,KAAG,CAYxD,CAAC"}
@@ -69,6 +69,64 @@ export function formatToolResult(json) {
69
69
  }
70
70
  return asTextContent(ppj(json));
71
71
  }
72
+ /**
73
+ * Text response with `isError: true`. Use for tool-level errors that the LLM
74
+ * should see and react to (resource not found, business validation failed,
75
+ * upstream API returned 404, etc.). Per MCP spec these MUST NOT be thrown as
76
+ * JSON-RPC errors — throwing turns them into protocol-level failures the LLM
77
+ * cannot self-correct from.
78
+ *
79
+ * @example
80
+ * if (!issue) {
81
+ * return asTextError(`Issue ${key} not found`);
82
+ * }
83
+ */
84
+ export function asTextError(text) {
85
+ return {
86
+ content: [{ type: 'text', text }],
87
+ isError: true,
88
+ };
89
+ }
90
+ /**
91
+ * Structured (`structuredContent`) response with `isError: true`. See
92
+ * {@link asTextError} for when to use error responses vs throwing.
93
+ */
94
+ export function asJsonError(json) {
95
+ if (isObject(json)) {
96
+ cleanUndefinedDeep(json);
97
+ }
98
+ return { structuredContent: json, isError: true };
99
+ }
100
+ /**
101
+ * Config-aware tool error formatter — mirror of {@link formatToolResult} but
102
+ * sets `isError: true`. Honors `appConfig.mcp.tools.answerAs` so error
103
+ * responses follow the same shape as success responses for the same MCP.
104
+ *
105
+ * Use this for tool-level errors the LLM should see (not-found, validation,
106
+ * upstream failure). Reserve `throw new ToolExecutionError(...)` for protocol
107
+ * issues: unknown tool, malformed call, missing transport feature.
108
+ *
109
+ * @example
110
+ * try {
111
+ * const data = await fetchIssue(key);
112
+ * return formatToolResult(data);
113
+ * } catch (err) {
114
+ * if (err.code === 'NOT_FOUND') {
115
+ * return formatToolError(`Issue ${key} not found`);
116
+ * }
117
+ * throw err; // genuine infra failure → JSON-RPC error is appropriate
118
+ * }
119
+ */
120
+ export function formatToolError(json) {
121
+ if (appConfig.mcp.tools.answerAs === 'structuredContent') {
122
+ return asJsonError(json);
123
+ }
124
+ if (isObject(json)) {
125
+ cleanUndefinedDeep(json);
126
+ }
127
+ const text = typeof json === 'string' ? json : ppj(json);
128
+ return asTextError(text);
129
+ }
72
130
  export const getJsonFromResult = (result) => {
73
131
  if (appConfig.mcp.tools.answerAs === 'structuredContent') {
74
132
  return result?.structuredContent;
@@ -1 +1 @@
1
- {"version":3,"file":"formatToolResult.js","sourceRoot":"","sources":["../../../src/core/utils/formatToolResult.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"formatToolResult.js","sourceRoot":"","sources":["../../../src/core/utils/formatToolResult.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,6BAA6B,CAAC;AAExD,OAAO,EAAE,QAAQ,EAAE,GAAG,EAAE,MAAM,YAAY,CAAC;AAG3C,MAAM,kBAAkB,GAAG,CAAC,KAAU,EAAQ,EAAE;IAC9C,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;QACrB,OAAO;IACT,CAAC;IACD,oDAAoD;IACpD,IAAI,KAAK,YAAY,IAAI,EAAE,CAAC;QAC1B,OAAO;IACT,CAAC;IACD,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QACzB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YACtC,MAAM,EAAE,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;YACpB,IAAI,QAAQ,CAAC,EAAE,CAAC,EAAE,CAAC;gBACjB,kBAAkB,CAAC,EAAE,CAAC,CAAC;YACzB,CAAC;YACD,oFAAoF;QACtF,CAAC;QACD,OAAO;IACT,CAAC;IACD,oBAAoB;IACpB,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;QACrC,MAAM,CAAC,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC;QACrB,IAAI,CAAC,KAAK,SAAS,EAAE,CAAC;YACpB,OAAO,KAAK,CAAC,GAAG,CAAC,CAAC;QACpB,CAAC;aAAM,IAAI,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC;YACvB,kBAAkB,CAAC,CAAC,CAAC,CAAC;QACxB,CAAC;IACH,CAAC;AACH,CAAC,CAAC;AAEF;;;GAGG;AACH,MAAM,UAAU,aAAa,CAAC,IAAY;IACxC,OAAO;QACL,OAAO,EAAE;YACP;gBACE,IAAI,EAAE,MAAM;gBACZ,IAAI;aACL;SACF;KACF,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,MAAM,CAAU,IAAO;IACrC,IAAI,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;QACnB,kBAAkB,CAAC,IAAI,CAAC,CAAC;IAC3B,CAAC;IACD,OAAO,EAAE,iBAAiB,EAAE,IAAI,EAAE,CAAC;AACrC,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,gBAAgB,CAAU,IAAO;IAC/C,IAAI,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC,QAAQ,KAAK,mBAAmB,EAAE,CAAC;QACzD,OAAO,MAAM,CAAI,IAAI,CAAsC,CAAC;IAC9D,CAAC;IACD,IAAI,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;QACnB,kBAAkB,CAAC,IAAI,CAAC,CAAC;IAC3B,CAAC;IACD,IAAI,OAAO,IAAI,KAAK,QAAQ,EAAE,CAAC;QAC7B,OAAO,aAAa,CAAC,IAAI,CAA6B,CAAC;IACzD,CAAC;IACD,OAAO,aAAa,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC;AAClC,CAAC;AAED;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,WAAW,CAAC,IAAY;IACtC,OAAO;QACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;QACjC,OAAO,EAAE,IAAI;KACd,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,WAAW,CAAU,IAAO;IAC1C,IAAI,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;QACnB,kBAAkB,CAAC,IAAI,CAAC,CAAC;IAC3B,CAAC;IACD,OAAO,EAAE,iBAAiB,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;AACpD,CAAC;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,UAAU,eAAe,CAAU,IAAO;IAC9C,IAAI,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC,QAAQ,KAAK,mBAAmB,EAAE,CAAC;QACzD,OAAO,WAAW,CAAI,IAAI,CAAC,CAAC;IAC9B,CAAC;IACD,IAAI,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;QACnB,kBAAkB,CAAC,IAAI,CAAC,CAAC;IAC3B,CAAC;IACD,MAAM,IAAI,GAAG,OAAO,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IACzD,OAAO,WAAW,CAAC,IAAI,CAAC,CAAC;AAC3B,CAAC;AAED,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAU,MAAW,EAAK,EAAE;IAC3D,IAAI,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC,QAAQ,KAAK,mBAAmB,EAAE,CAAC;QACzD,OAAO,MAAM,EAAE,iBAAsB,CAAC;IACxC,CAAC;SAAM,CAAC;QACN,MAAM,IAAI,GAAG,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,IAAI,MAAM,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,IAAI,EAAE,CAAC;QACpF,IAAI,CAAC;YACH,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAM,CAAC;QAC/B,CAAC;QAAC,MAAM,CAAC;YACP,EAAE;QACJ,CAAC;IACH,CAAC;IACD,OAAO,SAAc,CAAC;AACxB,CAAC,CAAC"}
@@ -0,0 +1,35 @@
1
+ /**
2
+ * Universal `debug-tool` for integration testing of MCP clients (Agent Tester,
3
+ * custom hosts, CI smoke tests).
4
+ *
5
+ * One parameterised tool that can produce **any** variation of
6
+ * `CallToolResult`: every content-block type from the MCP spec, single vs.
7
+ * multiple blocks, `structuredContent` / `_meta` toggles, `isError: true`,
8
+ * delay simulation, and a `largeInput` knob for streaming / truncate tests.
9
+ *
10
+ * Activated together with the other built-ins via
11
+ * `appConfig.mcp.debug.builtinTools = true`. Test code can also import the
12
+ * tool descriptor + handler directly to spin up a stand-alone server.
13
+ *
14
+ * The constants for an image / audio block (`BLUE_PNG_1X1`, `SILENT_WAV`)
15
+ * are kept private to this file — never exported.
16
+ */
17
+ import { Tool } from '@modelcontextprotocol/sdk/types.js';
18
+ import { IToolHandlerParams, TToolHandlerResponse } from '../../_types_/types.js';
19
+ export declare const DEBUG_TOOL_NAME = "debug-tool";
20
+ /** `Tool` descriptor for the universal debug-tool. */
21
+ export declare const DEBUG_TOOL: Tool;
22
+ /** Execute the debug-tool. Returns a `CallToolResult`-shaped response. */
23
+ export declare function handleDebugTool(params: IToolHandlerParams): Promise<TToolHandlerResponse>;
24
+ /**
25
+ * Register the debug-tool against a `McpServer` from
26
+ * `@modelcontextprotocol/sdk/server/mcp.js`. Use this for stand-alone test
27
+ * servers that do not go through `initMcpServer()`.
28
+ *
29
+ * The signature deliberately uses a structural type so the SDK does not take
30
+ * a hard dependency on the high-level `McpServer` class.
31
+ */
32
+ export declare function registerDebugTool(server: {
33
+ registerTool: (name: string, def: any, handler: (args: any) => unknown) => void;
34
+ }): void;
35
+ //# sourceMappingURL=debug-tool.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"debug-tool.d.ts","sourceRoot":"","sources":["../../../../src/core/utils/testing/debug-tool.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AACH,OAAO,EAAE,IAAI,EAAE,MAAM,oCAAoC,CAAC;AAE1D,OAAO,EAAE,kBAAkB,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AAElF,eAAO,MAAM,eAAe,eAAe,CAAC;AAsB5C,sDAAsD;AACtD,eAAO,MAAM,UAAU,EAAE,IA4CxB,CAAC;AAmDF,0EAA0E;AAC1E,wBAAsB,eAAe,CAAC,MAAM,EAAE,kBAAkB,GAAG,OAAO,CAAC,oBAAoB,CAAC,CAgC/F;AAED;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE;IACxC,YAAY,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,GAAG,EAAE,OAAO,EAAE,CAAC,IAAI,EAAE,GAAG,KAAK,OAAO,KAAK,IAAI,CAAC;CACjF,GAAG,IAAI,CAgBP"}
@@ -0,0 +1,146 @@
1
+ export const DEBUG_TOOL_NAME = 'debug-tool';
2
+ // Minimal 1×1 blue PNG (base64). Private — keeps the public surface clean.
3
+ const BLUE_PNG_1X1 = 'iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNkYPj/HwADBwIAMCbHYQAAAABJRU5ErkJggg==';
4
+ // Minimal silent WAV (base64) — 44 byte header + 1 sample.
5
+ const SILENT_WAV = 'UklGRiYAAABXQVZFZm10IBAAAAABAAEARKwAAIhYAQACABAAZGF0YQIAAAAAAA==';
6
+ let callCounter = 0;
7
+ /** `Tool` descriptor for the universal debug-tool. */
8
+ export const DEBUG_TOOL = {
9
+ name: DEBUG_TOOL_NAME,
10
+ title: 'Debug tool',
11
+ description: 'App-only test helper. Produces any variation of CallToolResult (text/image/audio/resource/' +
12
+ 'resourceLink/mixed, single or multi-block, isError, delays, large payload) so MCP host tests ' +
13
+ 'can exercise every code path without standing up a bespoke fake server. Hidden from the LLM ' +
14
+ 'via _meta.ui.visibility=["app"].',
15
+ inputSchema: {
16
+ type: 'object',
17
+ properties: {
18
+ contentType: {
19
+ type: 'string',
20
+ enum: ['text', 'image', 'audio', 'resource', 'resourceLink', 'mixed'],
21
+ description: 'Which content-block type to emit. "mixed" returns one of each (ignores multipleBlocks).',
22
+ },
23
+ multipleBlocks: {
24
+ type: 'boolean',
25
+ description: 'When true, emit 3 blocks of the chosen type; otherwise emit 1. Default: true.',
26
+ },
27
+ includeStructuredContent: {
28
+ type: 'boolean',
29
+ description: 'Include result.structuredContent with config/timestamp/counter. Default: true.',
30
+ },
31
+ includeMeta: {
32
+ type: 'boolean',
33
+ description: 'Include result._meta with diagnostic fields. Default: true.',
34
+ },
35
+ largeInput: {
36
+ type: 'string',
37
+ description: 'Optional large payload — its length is echoed back in structuredContent.largeInputLength.',
38
+ },
39
+ simulateError: {
40
+ type: 'boolean',
41
+ description: 'When true, set result.isError = true (the call still resolves). Default: false.',
42
+ },
43
+ delayMs: {
44
+ type: 'number',
45
+ description: 'Optional artificial delay (ms) before responding — for timeout / loading-state tests.',
46
+ minimum: 0,
47
+ },
48
+ },
49
+ },
50
+ _meta: { ui: { visibility: ['app'] } },
51
+ };
52
+ function buildContent(args) {
53
+ const contentType = args.contentType ?? 'text';
54
+ const multiple = args.multipleBlocks !== false;
55
+ if (contentType === 'mixed') {
56
+ return [
57
+ { type: 'text', text: 'Mixed content: text block' },
58
+ { type: 'image', data: BLUE_PNG_1X1, mimeType: 'image/png' },
59
+ { type: 'audio', data: SILENT_WAV, mimeType: 'audio/wav' },
60
+ ];
61
+ }
62
+ const count = multiple ? 3 : 1;
63
+ const blocks = [];
64
+ for (let i = 0; i < count; i++) {
65
+ const suffix = multiple ? ` #${i + 1}` : '';
66
+ switch (contentType) {
67
+ case 'text':
68
+ blocks.push({ type: 'text', text: `Debug text content${suffix}` });
69
+ break;
70
+ case 'image':
71
+ blocks.push({ type: 'image', data: BLUE_PNG_1X1, mimeType: 'image/png' });
72
+ break;
73
+ case 'audio':
74
+ blocks.push({ type: 'audio', data: SILENT_WAV, mimeType: 'audio/wav' });
75
+ break;
76
+ case 'resource':
77
+ blocks.push({
78
+ type: 'resource',
79
+ resource: {
80
+ uri: `debug://embedded-resource${suffix.replace(/\s/g, '-')}`,
81
+ text: `Embedded resource content${suffix}`,
82
+ mimeType: 'text/plain',
83
+ },
84
+ });
85
+ break;
86
+ case 'resourceLink':
87
+ blocks.push({
88
+ type: 'resource_link',
89
+ uri: `debug://linked-resource${suffix.replace(/\s/g, '-')}`,
90
+ name: `Linked Resource${suffix}`,
91
+ mimeType: 'text/plain',
92
+ });
93
+ break;
94
+ }
95
+ }
96
+ return blocks;
97
+ }
98
+ /** Execute the debug-tool. Returns a `CallToolResult`-shaped response. */
99
+ export async function handleDebugTool(params) {
100
+ const args = (params.arguments ?? {});
101
+ if (typeof args.delayMs === 'number' && args.delayMs > 0) {
102
+ await new Promise((resolve) => setTimeout(resolve, args.delayMs));
103
+ }
104
+ const content = buildContent(args);
105
+ const result = { content };
106
+ if (args.includeStructuredContent !== false) {
107
+ result.structuredContent = {
108
+ config: args,
109
+ timestamp: new Date().toISOString(),
110
+ counter: ++callCounter,
111
+ ...(args.largeInput ? { largeInputLength: args.largeInput.length } : {}),
112
+ };
113
+ }
114
+ if (args.includeMeta !== false) {
115
+ result._meta = {
116
+ debugInfo: {
117
+ processedAt: Date.now(),
118
+ },
119
+ };
120
+ }
121
+ if (args.simulateError) {
122
+ result.isError = true;
123
+ }
124
+ return result;
125
+ }
126
+ /**
127
+ * Register the debug-tool against a `McpServer` from
128
+ * `@modelcontextprotocol/sdk/server/mcp.js`. Use this for stand-alone test
129
+ * servers that do not go through `initMcpServer()`.
130
+ *
131
+ * The signature deliberately uses a structural type so the SDK does not take
132
+ * a hard dependency on the high-level `McpServer` class.
133
+ */
134
+ export function registerDebugTool(server) {
135
+ server.registerTool(DEBUG_TOOL_NAME, {
136
+ title: DEBUG_TOOL.title,
137
+ description: DEBUG_TOOL.description,
138
+ inputSchema: DEBUG_TOOL.inputSchema,
139
+ _meta: DEBUG_TOOL._meta,
140
+ }, async (args) => handleDebugTool({
141
+ name: DEBUG_TOOL_NAME,
142
+ arguments: args,
143
+ transport: 'stdio',
144
+ }));
145
+ }
146
+ //# sourceMappingURL=debug-tool.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"debug-tool.js","sourceRoot":"","sources":["../../../../src/core/utils/testing/debug-tool.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"server-http.d.ts","sourceRoot":"","sources":["../../../src/core/web/server-http.ts"],"names":[],"mappings":"AAiDA,eAAO,MAAM,cAAc,SAAyC,CAAC;AAsCrE;;GAEG;AACH,wBAAsB,eAAe,IAAI,OAAO,CAAC,IAAI,CAAC,CA+mBrD"}
1
+ {"version":3,"file":"server-http.d.ts","sourceRoot":"","sources":["../../../src/core/web/server-http.ts"],"names":[],"mappings":"AAkDA,eAAO,MAAM,cAAc,SAAyC,CAAC;AAsCrE;;GAEG;AACH,wBAAsB,eAAe,IAAI,OAAO,CAAC,IAAI,CAAC,CA2oBrD"}
@@ -9,8 +9,9 @@ import { RateLimiterMemory } from 'rate-limiter-flexible';
9
9
  import { createAgentTesterRouter } from '../agent-tester/agent-tester-router.js';
10
10
  import { validateAdminAuthConfig } from '../auth/admin-auth.js';
11
11
  import { createAgentTesterSessionMW } from '../auth/agent-tester-auth.js';
12
- import { generateToken, MIN_ENCRYPT_KEY_LENGTH } from '../auth/jwt.js';
12
+ import { checkJwtToken, generateToken, MIN_ENCRYPT_KEY_LENGTH } from '../auth/jwt.js';
13
13
  import { createAuthMW } from '../auth/middleware.js';
14
+ import { checkPermanentToken } from '../auth/permanent.js';
14
15
  import { appConfig, getProjectData } from '../bootstrap/init-config.js';
15
16
  import { debugMcpNotification } from '../debug.js';
16
17
  import { getMainDBConnectionStatus } from '../db/pg-db.js';
@@ -113,6 +114,29 @@ export async function startHttpServer() {
113
114
  }
114
115
  res.json(health);
115
116
  });
117
+ // Token check endpoint: GET /ct?t=<token> or POST /ct {"t": "<token>"}
118
+ // Returns { success, type: 'permanent' | 'JWT', payload? } or { success: false, error }
119
+ const handleTokenCheck = (req, res) => {
120
+ const raw = req.method === 'GET' ? req.query.t : req.body?.t;
121
+ const token = typeof raw === 'string' ? raw.trim() : '';
122
+ if (!token) {
123
+ return res.status(400).json({ success: false, error: 'Token not provided. Pass via "t" query/body parameter' });
124
+ }
125
+ const { errorReason: permError } = checkPermanentToken(token);
126
+ if (!permError) {
127
+ return res.json({ success: true, type: 'permanent' });
128
+ }
129
+ const xff = req.headers['x-forwarded-for'];
130
+ const xffStr = (Array.isArray(xff) ? (xff[0] ?? '') : (xff ?? '')).split(',').shift() ?? '';
131
+ const clientIp = req.ip ?? (xffStr.trim() || (req.socket?.remoteAddress ?? ''));
132
+ const jwtResult = checkJwtToken({ token, clientIp });
133
+ if (!jwtResult.errorReason) {
134
+ return res.json({ success: true, type: 'JWT', payload: jwtResult.payload });
135
+ }
136
+ return res.status(401).json({ success: false, error: jwtResult.errorReason });
137
+ };
138
+ app.get('/ct', handleTokenCheck);
139
+ app.post('/ct', handleTokenCheck);
116
140
  // Public endpoint: returns used HTTP headers configured in the template (optional)
117
141
  app.get('/used-http-headers', (req, res) => {
118
142
  try {
@@ -550,6 +574,7 @@ export async function startHttpServer() {
550
574
  const availableEndpoints = {
551
575
  home: 'GET /',
552
576
  health: 'GET /health',
577
+ checkToken: 'GET /ct?t=<token>, POST /ct',
553
578
  sse: 'GET /sse, POST /sse',
554
579
  messages: 'POST /messages',
555
580
  mcp: 'POST /mcp',