fa-mcp-sdk 0.4.142 → 0.11.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +5 -0
- package/cli-template/.dockerignore +16 -0
- package/cli-template/.gitlab-ci.yml +135 -0
- package/cli-template/AGENTS.md +1 -0
- package/cli-template/CHANGELOG.md +64 -0
- package/cli-template/FA-MCP-SDK-DOC/00-FA-MCP-SDK-index.md +27 -4
- package/cli-template/FA-MCP-SDK-DOC/02-1-tools-and-api.md +195 -0
- package/cli-template/FA-MCP-SDK-DOC/02-2-prompts-and-resources.md +172 -9
- package/cli-template/FA-MCP-SDK-DOC/03-configuration.md +170 -12
- package/cli-template/FA-MCP-SDK-DOC/04-authentication.md +158 -8
- package/cli-template/FA-MCP-SDK-DOC/06-utilities.md +67 -6
- package/cli-template/FA-MCP-SDK-DOC/07-testing-and-operations.md +31 -15
- package/cli-template/FA-MCP-SDK-DOC/10-mcp-apps.md +1 -1
- package/cli-template/FA-MCP-SDK-DOC/11-public-contract.md +342 -0
- package/cli-template/README.md +37 -0
- package/cli-template/deploy/docker/.env.example +10 -0
- package/cli-template/deploy/docker/Dockerfile +44 -0
- package/cli-template/deploy/docker/Dockerfile.local +29 -0
- package/cli-template/deploy/docker/README.md +94 -0
- package/cli-template/deploy/docker/config/local.docker.yaml +14 -0
- package/cli-template/deploy/docker/docker-compose.yml +31 -0
- package/cli-template/deploy/gitlab-runner/.env.example +16 -0
- package/cli-template/deploy/gitlab-runner/README.md +65 -0
- package/cli-template/deploy/gitlab-runner/config/config.toml.template +26 -0
- package/cli-template/deploy/gitlab-runner/docker-compose.yml +39 -0
- package/cli-template/deploy/gitlab-runner/entrypoint.sh +27 -0
- package/cli-template/deploy/gitlab-runner/start.sh +47 -0
- package/cli-template/gitignore +96 -95
- package/cli-template/package.json +1 -1
- package/config/_local.yaml +73 -11
- package/config/custom-environment-variables.yaml +102 -0
- package/config/default.yaml +164 -11
- package/config/local.yaml +20 -19
- package/dist/core/_types_/config.d.ts +119 -0
- package/dist/core/_types_/config.d.ts.map +1 -1
- package/dist/core/_types_/types.d.ts +137 -4
- package/dist/core/_types_/types.d.ts.map +1 -1
- package/dist/core/agent-tester/agent-tester-router.d.ts.map +1 -1
- package/dist/core/agent-tester/agent-tester-router.js +25 -11
- package/dist/core/agent-tester/agent-tester-router.js.map +1 -1
- package/dist/core/agent-tester/services/TesterMcpClientService.d.ts.map +1 -1
- package/dist/core/agent-tester/services/TesterMcpClientService.js +6 -4
- package/dist/core/agent-tester/services/TesterMcpClientService.js.map +1 -1
- package/dist/core/auth/admin-auth.js +4 -4
- package/dist/core/auth/admin-auth.js.map +1 -1
- package/dist/core/auth/agent-tester-auth.d.ts +1 -1
- package/dist/core/auth/agent-tester-auth.d.ts.map +1 -1
- package/dist/core/auth/agent-tester-auth.js +8 -4
- package/dist/core/auth/agent-tester-auth.js.map +1 -1
- package/dist/core/auth/auth-profile.d.ts +38 -0
- package/dist/core/auth/auth-profile.d.ts.map +1 -0
- package/dist/core/auth/auth-profile.js +101 -0
- package/dist/core/auth/auth-profile.js.map +1 -0
- package/dist/core/auth/jwt-v2.d.ts +27 -0
- package/dist/core/auth/jwt-v2.d.ts.map +1 -0
- package/dist/core/auth/jwt-v2.js +180 -0
- package/dist/core/auth/jwt-v2.js.map +1 -0
- package/dist/core/auth/jwt.d.ts +27 -13
- package/dist/core/auth/jwt.d.ts.map +1 -1
- package/dist/core/auth/jwt.js +36 -13
- package/dist/core/auth/jwt.js.map +1 -1
- package/dist/core/auth/key-resolver.d.ts +74 -0
- package/dist/core/auth/key-resolver.d.ts.map +1 -0
- package/dist/core/auth/key-resolver.js +330 -0
- package/dist/core/auth/key-resolver.js.map +1 -0
- package/dist/core/auth/middleware.d.ts.map +1 -1
- package/dist/core/auth/middleware.js +66 -0
- package/dist/core/auth/middleware.js.map +1 -1
- package/dist/core/auth/multi-auth.d.ts +1 -1
- package/dist/core/auth/multi-auth.d.ts.map +1 -1
- package/dist/core/auth/multi-auth.js +7 -7
- package/dist/core/auth/multi-auth.js.map +1 -1
- package/dist/core/auth/token-generator/server.js +4 -4
- package/dist/core/auth/token-generator/server.js.map +1 -1
- package/dist/core/auth/types.d.ts +5 -0
- package/dist/core/auth/types.d.ts.map +1 -1
- package/dist/core/db/pg-db.d.ts +7 -0
- package/dist/core/db/pg-db.d.ts.map +1 -1
- package/dist/core/db/pg-db.js +54 -3
- package/dist/core/db/pg-db.js.map +1 -1
- package/dist/core/errors/BaseMcpError.d.ts +21 -1
- package/dist/core/errors/BaseMcpError.d.ts.map +1 -1
- package/dist/core/errors/BaseMcpError.js +20 -1
- package/dist/core/errors/BaseMcpError.js.map +1 -1
- package/dist/core/errors/ValidationError.d.ts +5 -0
- package/dist/core/errors/ValidationError.d.ts.map +1 -1
- package/dist/core/errors/ValidationError.js +6 -1
- package/dist/core/errors/ValidationError.js.map +1 -1
- package/dist/core/errors/errors.d.ts +31 -3
- package/dist/core/errors/errors.d.ts.map +1 -1
- package/dist/core/errors/errors.js +86 -6
- package/dist/core/errors/errors.js.map +1 -1
- package/dist/core/errors/specific-errors.d.ts +54 -0
- package/dist/core/errors/specific-errors.d.ts.map +1 -0
- package/dist/core/errors/specific-errors.js +82 -0
- package/dist/core/errors/specific-errors.js.map +1 -0
- package/dist/core/index.d.ts +10 -2
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/index.js +9 -1
- package/dist/core/index.js.map +1 -1
- package/dist/core/init-mcp-server.d.ts.map +1 -1
- package/dist/core/init-mcp-server.js +39 -0
- package/dist/core/init-mcp-server.js.map +1 -1
- package/dist/core/mcp/create-mcp-server.d.ts +12 -6
- package/dist/core/mcp/create-mcp-server.d.ts.map +1 -1
- package/dist/core/mcp/create-mcp-server.js +592 -33
- package/dist/core/mcp/create-mcp-server.js.map +1 -1
- package/dist/core/mcp/debug-trace.d.ts +3 -1
- package/dist/core/mcp/debug-trace.d.ts.map +1 -1
- package/dist/core/mcp/debug-trace.js +17 -2
- package/dist/core/mcp/debug-trace.js.map +1 -1
- package/dist/core/mcp/deprecation.d.ts +31 -0
- package/dist/core/mcp/deprecation.d.ts.map +1 -0
- package/dist/core/mcp/deprecation.js +96 -0
- package/dist/core/mcp/deprecation.js.map +1 -0
- package/dist/core/mcp/mcp-logging.d.ts +32 -0
- package/dist/core/mcp/mcp-logging.d.ts.map +1 -0
- package/dist/core/mcp/mcp-logging.js +97 -0
- package/dist/core/mcp/mcp-logging.js.map +1 -0
- package/dist/core/mcp/pagination.d.ts +13 -0
- package/dist/core/mcp/pagination.d.ts.map +1 -0
- package/dist/core/mcp/pagination.js +50 -0
- package/dist/core/mcp/pagination.js.map +1 -0
- package/dist/core/mcp/prompts.d.ts +5 -1
- package/dist/core/mcp/prompts.d.ts.map +1 -1
- package/dist/core/mcp/prompts.js +3 -1
- package/dist/core/mcp/prompts.js.map +1 -1
- package/dist/core/mcp/resources.d.ts +9 -0
- package/dist/core/mcp/resources.d.ts.map +1 -1
- package/dist/core/mcp/resources.js +158 -11
- package/dist/core/mcp/resources.js.map +1 -1
- package/dist/core/mcp/server-stdio.d.ts +7 -1
- package/dist/core/mcp/server-stdio.d.ts.map +1 -1
- package/dist/core/mcp/server-stdio.js +8 -3
- package/dist/core/mcp/server-stdio.js.map +1 -1
- package/dist/core/mcp/task-store.d.ts +97 -0
- package/dist/core/mcp/task-store.d.ts.map +1 -0
- package/dist/core/mcp/task-store.js +175 -0
- package/dist/core/mcp/task-store.js.map +1 -0
- package/dist/core/mcp/tool-limits.d.ts +22 -0
- package/dist/core/mcp/tool-limits.d.ts.map +1 -0
- package/dist/core/mcp/tool-limits.js +115 -0
- package/dist/core/mcp/tool-limits.js.map +1 -0
- package/dist/core/mcp/validate-tool-args.d.ts +16 -0
- package/dist/core/mcp/validate-tool-args.d.ts.map +1 -0
- package/dist/core/mcp/validate-tool-args.js +67 -0
- package/dist/core/mcp/validate-tool-args.js.map +1 -0
- package/dist/core/mcp/validate-tool-names.d.ts +11 -0
- package/dist/core/mcp/validate-tool-names.d.ts.map +1 -0
- package/dist/core/mcp/validate-tool-names.js +23 -0
- package/dist/core/mcp/validate-tool-names.js.map +1 -0
- package/dist/core/metrics/metrics.d.ts +45 -0
- package/dist/core/metrics/metrics.d.ts.map +1 -0
- package/dist/core/metrics/metrics.js +119 -0
- package/dist/core/metrics/metrics.js.map +1 -0
- package/dist/core/utils/mask-sensitive.d.ts +44 -0
- package/dist/core/utils/mask-sensitive.d.ts.map +1 -0
- package/dist/core/utils/mask-sensitive.js +64 -0
- package/dist/core/utils/mask-sensitive.js.map +1 -0
- package/dist/core/utils/testing/McpHttpClient.d.ts +8 -33
- package/dist/core/utils/testing/McpHttpClient.d.ts.map +1 -1
- package/dist/core/utils/testing/McpHttpClient.js +8 -74
- package/dist/core/utils/testing/McpHttpClient.js.map +1 -1
- package/dist/core/utils/testing/McpStreamableHttpClient.d.ts +24 -30
- package/dist/core/utils/testing/McpStreamableHttpClient.d.ts.map +1 -1
- package/dist/core/utils/testing/McpStreamableHttpClient.js +36 -198
- package/dist/core/utils/testing/McpStreamableHttpClient.js.map +1 -1
- package/dist/core/utils/utils.d.ts.map +1 -1
- package/dist/core/utils/utils.js +2 -0
- package/dist/core/utils/utils.js.map +1 -1
- package/dist/core/web/admin-router.js +3 -3
- package/dist/core/web/admin-router.js.map +1 -1
- package/dist/core/web/cors.d.ts +9 -1
- package/dist/core/web/cors.d.ts.map +1 -1
- package/dist/core/web/cors.js +26 -5
- package/dist/core/web/cors.js.map +1 -1
- package/dist/core/web/event-store.d.ts +33 -0
- package/dist/core/web/event-store.d.ts.map +1 -0
- package/dist/core/web/event-store.js +65 -0
- package/dist/core/web/event-store.js.map +1 -0
- package/dist/core/web/oauth-router.d.ts +37 -0
- package/dist/core/web/oauth-router.d.ts.map +1 -0
- package/dist/core/web/oauth-router.js +207 -0
- package/dist/core/web/oauth-router.js.map +1 -0
- package/dist/core/web/request-id.d.ts +44 -0
- package/dist/core/web/request-id.d.ts.map +1 -0
- package/dist/core/web/request-id.js +82 -0
- package/dist/core/web/request-id.js.map +1 -0
- package/dist/core/web/server-http.d.ts.map +1 -1
- package/dist/core/web/server-http.js +322 -182
- package/dist/core/web/server-http.js.map +1 -1
- package/package.json +15 -2
- package/scripts/claude-2-agents-symlink.js +10 -1
- package/scripts/generate-jwt.js +129 -51
- package/src/template/custom-resources.ts +14 -0
- package/src/template/prompts/custom-prompts.ts +4 -0
- package/src/template/tools/handle-tool-call.ts +59 -3
- package/src/template/tools/tools.ts +92 -31
- package/src/tests/mcp/test-http.js +1 -1
- package/src/tests/mcp/test-sse.js +1 -1
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import { McpError } from '@modelcontextprotocol/sdk/types.js';
|
|
2
|
+
import { appConfig } from '../bootstrap/init-config.js';
|
|
3
|
+
import { MCP_ERROR_CODES } from '../errors/specific-errors.js';
|
|
4
|
+
/**
|
|
5
|
+
* Race a tool invocation against `mcp.limits.toolTimeoutMs`. On expiry the returned promise
|
|
6
|
+
* rejects with an SDK `McpError` carrying code `-32004` (standard §14 / Appendix B). The
|
|
7
|
+
* pending tool promise is left running — Node.js cannot synchronously abort user code —
|
|
8
|
+
* but the server-side timer is cleared so we don't leak handles. The HTTP-level transport
|
|
9
|
+
* layer in `server-http.ts` runs its own race so the response status becomes 504.
|
|
10
|
+
*/
|
|
11
|
+
export async function withToolTimeout(toolName, exec) {
|
|
12
|
+
const timeoutMs = appConfig.mcp.limits.toolTimeoutMs;
|
|
13
|
+
let timer;
|
|
14
|
+
const timeoutPromise = new Promise((_resolve, reject) => {
|
|
15
|
+
timer = setTimeout(() => {
|
|
16
|
+
reject(new McpError(MCP_ERROR_CODES.TIMEOUT, `Tool '${toolName}' exceeded ${timeoutMs} ms timeout`, {
|
|
17
|
+
reason: 'tool_timeout',
|
|
18
|
+
retryAfter: 0,
|
|
19
|
+
}));
|
|
20
|
+
}, timeoutMs);
|
|
21
|
+
if (typeof timer.unref === 'function') {
|
|
22
|
+
timer.unref();
|
|
23
|
+
}
|
|
24
|
+
});
|
|
25
|
+
try {
|
|
26
|
+
return await Promise.race([exec(), timeoutPromise]);
|
|
27
|
+
}
|
|
28
|
+
finally {
|
|
29
|
+
if (timer) {
|
|
30
|
+
clearTimeout(timer);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
const TRUNCATION_TAIL = '\n…[truncated]';
|
|
35
|
+
/**
|
|
36
|
+
* Trim a tool response so its serialized payload stays under `mcp.limits.maxToolResultBytes`
|
|
37
|
+
* (standard §12.2 / §14). Truncation is signalled BOTH in the textual content and in the
|
|
38
|
+
* structured payload so the client cannot silently miss it.
|
|
39
|
+
*
|
|
40
|
+
* - For `content[].text` entries: the offending entry is cut to fit the budget and suffixed
|
|
41
|
+
* with an explicit `…[truncated]` marker.
|
|
42
|
+
* - For `structuredContent`: a sibling `truncated: true` field is set when the JSON exceeds
|
|
43
|
+
* the budget, and the payload is replaced with a minimal sentinel object so the response
|
|
44
|
+
* still fits the wire frame.
|
|
45
|
+
*/
|
|
46
|
+
export function truncateToolResponse(response) {
|
|
47
|
+
const maxBytes = appConfig.mcp.limits.maxToolResultBytes;
|
|
48
|
+
if (!response || maxBytes <= 0) {
|
|
49
|
+
return response;
|
|
50
|
+
}
|
|
51
|
+
// Structured response branch.
|
|
52
|
+
if ('structuredContent' in response) {
|
|
53
|
+
const structured = response;
|
|
54
|
+
let serialized;
|
|
55
|
+
try {
|
|
56
|
+
serialized = JSON.stringify(structured.structuredContent ?? null);
|
|
57
|
+
}
|
|
58
|
+
catch {
|
|
59
|
+
return response;
|
|
60
|
+
}
|
|
61
|
+
if (Buffer.byteLength(serialized, 'utf8') <= maxBytes) {
|
|
62
|
+
return response;
|
|
63
|
+
}
|
|
64
|
+
const replacement = {
|
|
65
|
+
truncated: true,
|
|
66
|
+
reason: 'max_tool_result_bytes_exceeded',
|
|
67
|
+
maxBytes,
|
|
68
|
+
originalBytes: Buffer.byteLength(serialized, 'utf8'),
|
|
69
|
+
};
|
|
70
|
+
return {
|
|
71
|
+
...structured,
|
|
72
|
+
structuredContent: replacement,
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
// Text content branch.
|
|
76
|
+
if ('content' in response && Array.isArray(response.content)) {
|
|
77
|
+
const sizes = response.content.map((p) => (p && p.type === 'text' ? Buffer.byteLength(p.text ?? '', 'utf8') : 0));
|
|
78
|
+
const total = sizes.reduce((a, b) => a + b, 0);
|
|
79
|
+
if (total <= maxBytes) {
|
|
80
|
+
return response;
|
|
81
|
+
}
|
|
82
|
+
let budget = maxBytes;
|
|
83
|
+
const newContent = [];
|
|
84
|
+
let truncatedFlag = false;
|
|
85
|
+
for (const part of response.content) {
|
|
86
|
+
if (!part || part.type !== 'text') {
|
|
87
|
+
newContent.push(part);
|
|
88
|
+
continue;
|
|
89
|
+
}
|
|
90
|
+
const bytes = Buffer.byteLength(part.text ?? '', 'utf8');
|
|
91
|
+
if (bytes <= budget) {
|
|
92
|
+
newContent.push(part);
|
|
93
|
+
budget -= bytes;
|
|
94
|
+
continue;
|
|
95
|
+
}
|
|
96
|
+
truncatedFlag = true;
|
|
97
|
+
const sliceBytes = Math.max(0, budget - Buffer.byteLength(TRUNCATION_TAIL, 'utf8'));
|
|
98
|
+
const buf = Buffer.from(part.text ?? '', 'utf8')
|
|
99
|
+
.subarray(0, sliceBytes)
|
|
100
|
+
.toString('utf8');
|
|
101
|
+
newContent.push({ type: 'text', text: `${buf}${TRUNCATION_TAIL}` });
|
|
102
|
+
budget = 0;
|
|
103
|
+
}
|
|
104
|
+
if (truncatedFlag) {
|
|
105
|
+
return {
|
|
106
|
+
...response,
|
|
107
|
+
content: newContent,
|
|
108
|
+
structuredContent: { truncated: true, reason: 'max_tool_result_bytes_exceeded', maxBytes },
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
return { ...response, content: newContent };
|
|
112
|
+
}
|
|
113
|
+
return response;
|
|
114
|
+
}
|
|
115
|
+
//# sourceMappingURL=tool-limits.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tool-limits.js","sourceRoot":"","sources":["../../../src/core/mcp/tool-limits.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { Tool } from '@modelcontextprotocol/sdk/types.js';
|
|
2
|
+
export interface IValidationFailure {
|
|
3
|
+
field: string;
|
|
4
|
+
reason: string;
|
|
5
|
+
}
|
|
6
|
+
export declare function validateToolInput(tool: Tool, args: unknown): {
|
|
7
|
+
valid: true;
|
|
8
|
+
} | ({
|
|
9
|
+
valid: false;
|
|
10
|
+
} & IValidationFailure);
|
|
11
|
+
export declare function validateToolOutput(tool: Tool, structuredContent: unknown): {
|
|
12
|
+
valid: true;
|
|
13
|
+
} | ({
|
|
14
|
+
valid: false;
|
|
15
|
+
} & IValidationFailure);
|
|
16
|
+
//# sourceMappingURL=validate-tool-args.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validate-tool-args.d.ts","sourceRoot":"","sources":["../../../src/core/mcp/validate-tool-args.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,IAAI,EAAE,MAAM,oCAAoC,CAAC;AAyB1D,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;CAChB;AAiBD,wBAAgB,iBAAiB,CAC/B,IAAI,EAAE,IAAI,EACV,IAAI,EAAE,OAAO,GACZ;IAAE,KAAK,EAAE,IAAI,CAAA;CAAE,GAAG,CAAC;IAAE,KAAK,EAAE,KAAK,CAAA;CAAE,GAAG,kBAAkB,CAAC,CAc3D;AAED,wBAAgB,kBAAkB,CAChC,IAAI,EAAE,IAAI,EACV,iBAAiB,EAAE,OAAO,GACzB;IAAE,KAAK,EAAE,IAAI,CAAA;CAAE,GAAG,CAAC;IAAE,KAAK,EAAE,KAAK,CAAA;CAAE,GAAG,kBAAkB,CAAC,CAc3D"}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import Ajv2020 from 'ajv/dist/2020.js';
|
|
2
|
+
import addFormats from 'ajv-formats';
|
|
3
|
+
const ajv = new Ajv2020({ allErrors: false, strict: false, useDefaults: false });
|
|
4
|
+
addFormats(ajv);
|
|
5
|
+
const inputCache = new WeakMap();
|
|
6
|
+
const outputCache = new WeakMap();
|
|
7
|
+
function compile(schema, cache) {
|
|
8
|
+
if (!schema || typeof schema !== 'object') {
|
|
9
|
+
return undefined;
|
|
10
|
+
}
|
|
11
|
+
const cached = cache.get(schema);
|
|
12
|
+
if (cached) {
|
|
13
|
+
return cached;
|
|
14
|
+
}
|
|
15
|
+
try {
|
|
16
|
+
const validate = ajv.compile(schema);
|
|
17
|
+
cache.set(schema, validate);
|
|
18
|
+
return validate;
|
|
19
|
+
}
|
|
20
|
+
catch {
|
|
21
|
+
return undefined;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
function firstError(errors) {
|
|
25
|
+
const e = errors?.[0];
|
|
26
|
+
if (!e) {
|
|
27
|
+
return { field: '', reason: 'schema_violation' };
|
|
28
|
+
}
|
|
29
|
+
const fieldFromParams = e.params?.missingProperty ||
|
|
30
|
+
e.params?.additionalProperty ||
|
|
31
|
+
e.params?.propertyName ||
|
|
32
|
+
'';
|
|
33
|
+
const path = e.instancePath || '';
|
|
34
|
+
const field = fieldFromParams ? (path ? `${path}/${fieldFromParams}` : fieldFromParams) : path || 'root';
|
|
35
|
+
return { field, reason: e.message || e.keyword || 'schema_violation' };
|
|
36
|
+
}
|
|
37
|
+
export function validateToolInput(tool, args) {
|
|
38
|
+
const schema = tool.inputSchema;
|
|
39
|
+
if (!schema || typeof schema !== 'object') {
|
|
40
|
+
return { valid: true };
|
|
41
|
+
}
|
|
42
|
+
const validate = compile(schema, inputCache);
|
|
43
|
+
if (!validate) {
|
|
44
|
+
return { valid: true };
|
|
45
|
+
}
|
|
46
|
+
const ok = validate(args ?? {});
|
|
47
|
+
if (ok) {
|
|
48
|
+
return { valid: true };
|
|
49
|
+
}
|
|
50
|
+
return { valid: false, ...firstError(validate.errors) };
|
|
51
|
+
}
|
|
52
|
+
export function validateToolOutput(tool, structuredContent) {
|
|
53
|
+
const schema = tool.outputSchema;
|
|
54
|
+
if (!schema || typeof schema !== 'object') {
|
|
55
|
+
return { valid: true };
|
|
56
|
+
}
|
|
57
|
+
const validate = compile(schema, outputCache);
|
|
58
|
+
if (!validate) {
|
|
59
|
+
return { valid: true };
|
|
60
|
+
}
|
|
61
|
+
const ok = validate(structuredContent ?? null);
|
|
62
|
+
if (ok) {
|
|
63
|
+
return { valid: true };
|
|
64
|
+
}
|
|
65
|
+
return { valid: false, ...firstError(validate.errors) };
|
|
66
|
+
}
|
|
67
|
+
//# sourceMappingURL=validate-tool-args.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validate-tool-args.js","sourceRoot":"","sources":["../../../src/core/mcp/validate-tool-args.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { Tool } from '@modelcontextprotocol/sdk/types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Standard §9.1 — corporate rule: tool names are ASCII snake_case, 1..63 chars.
|
|
4
|
+
*/
|
|
5
|
+
export declare const TOOL_NAME_RE: RegExp;
|
|
6
|
+
/**
|
|
7
|
+
* Throws on the first name that violates the rule. Memoizes the validated array reference
|
|
8
|
+
* so static `tools` arrays pay the cost only once per process.
|
|
9
|
+
*/
|
|
10
|
+
export declare function assertToolNames(tools: Tool[]): void;
|
|
11
|
+
//# sourceMappingURL=validate-tool-names.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validate-tool-names.d.ts","sourceRoot":"","sources":["../../../src/core/mcp/validate-tool-names.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,oCAAoC,CAAC;AAE1D;;GAEG;AACH,eAAO,MAAM,YAAY,QAA2B,CAAC;AAIrD;;;GAGG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,IAAI,EAAE,GAAG,IAAI,CAcnD"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Standard §9.1 — corporate rule: tool names are ASCII snake_case, 1..63 chars.
|
|
3
|
+
*/
|
|
4
|
+
export const TOOL_NAME_RE = /^[a-z][a-z0-9_]{0,62}$/;
|
|
5
|
+
const validatedRefs = new WeakSet();
|
|
6
|
+
/**
|
|
7
|
+
* Throws on the first name that violates the rule. Memoizes the validated array reference
|
|
8
|
+
* so static `tools` arrays pay the cost only once per process.
|
|
9
|
+
*/
|
|
10
|
+
export function assertToolNames(tools) {
|
|
11
|
+
if (!Array.isArray(tools) || validatedRefs.has(tools)) {
|
|
12
|
+
return;
|
|
13
|
+
}
|
|
14
|
+
for (const tool of tools) {
|
|
15
|
+
const name = tool?.name;
|
|
16
|
+
if (typeof name !== 'string' || !TOOL_NAME_RE.test(name)) {
|
|
17
|
+
throw new Error(`Tool name "${name}" violates standard §9.1: ` +
|
|
18
|
+
`must match /^[a-z][a-z0-9_]{0,62}$/ (snake_case, ASCII, 1..63 chars).`);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
validatedRefs.add(tools);
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=validate-tool-names.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validate-tool-names.js","sourceRoot":"","sources":["../../../src/core/mcp/validate-tool-names.ts"],"names":[],"mappings":"AAEA;;GAEG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG,wBAAwB,CAAC;AAErD,MAAM,aAAa,GAAG,IAAI,OAAO,EAAU,CAAC;AAE5C;;;GAGG;AACH,MAAM,UAAU,eAAe,CAAC,KAAa;IAC3C,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,aAAa,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC;QACtD,OAAO;IACT,CAAC;IACD,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,MAAM,IAAI,GAAI,IAAY,EAAE,IAAI,CAAC;QACjC,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;YACzD,MAAM,IAAI,KAAK,CACb,cAAc,IAAI,4BAA4B;gBAC5C,uEAAuE,CAC1E,CAAC;QACJ,CAAC;IACH,CAAC;IACD,aAAa,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;AAC3B,CAAC"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Standard §15.3 — Prometheus exposition for MCP-server operability.
|
|
3
|
+
*
|
|
4
|
+
* Off by default; enabled via `webServer.metrics.enabled = true`. When active, a single
|
|
5
|
+
* `prom-client` registry holds every series the SDK emits. Process-level metrics (GC, heap,
|
|
6
|
+
* uptime) are added conditionally — they add ≈30 series, so projects scraping multiple SDK
|
|
7
|
+
* instances can shed them by setting `webServer.metrics.includeProcessMetrics = false`.
|
|
8
|
+
*
|
|
9
|
+
* All metrics use snake_case names; cardinality is bounded by tool name / scope so the
|
|
10
|
+
* SDK never explodes a Prometheus instance even when run with hundreds of tools.
|
|
11
|
+
*/
|
|
12
|
+
import { Counter, Gauge, Histogram, Registry } from 'prom-client';
|
|
13
|
+
export interface IMcpMetrics {
|
|
14
|
+
toolCalls: Counter<'tool' | 'status'>;
|
|
15
|
+
toolDuration: Histogram<'tool'>;
|
|
16
|
+
authFailures: Counter<'reason'>;
|
|
17
|
+
rateLimitHits: Counter<'scope'>;
|
|
18
|
+
httpRequests: Counter<'method' | 'path' | 'status'>;
|
|
19
|
+
concurrentCalls: Gauge<'subject'>;
|
|
20
|
+
payloadBytes: Histogram<never>;
|
|
21
|
+
resultBytes: Histogram<never>;
|
|
22
|
+
/** Standard §8.7 — task lifecycle transitions by status (created/completed/failed/cancelled). */
|
|
23
|
+
tasks: Counter<'status'>;
|
|
24
|
+
}
|
|
25
|
+
export type ToolCallStatus = 'ok' | 'error' | 'timeout' | 'rate_limited' | 'invalid_params' | 'internal_error';
|
|
26
|
+
export type RateLimitScope = 'subject' | 'ip' | 'concurrent';
|
|
27
|
+
/**
|
|
28
|
+
* Lazy initialization — `initMetrics` is called from `server-http.ts` only when metrics are
|
|
29
|
+
* enabled. Subsequent calls are no-ops, so tests can re-import without leaking series.
|
|
30
|
+
*/
|
|
31
|
+
export declare function initMetrics(): IMcpMetrics;
|
|
32
|
+
/**
|
|
33
|
+
* Safe accessor for places that may run before `initMetrics` (e.g. tool execution paths that
|
|
34
|
+
* run regardless of HTTP / stdio mode). Returns `undefined` when metrics are disabled — call
|
|
35
|
+
* sites should use optional chaining: `getMetrics()?.toolCalls.inc(...)`.
|
|
36
|
+
*/
|
|
37
|
+
export declare function getMetrics(): IMcpMetrics | undefined;
|
|
38
|
+
export declare function isMetricsEnabled(): boolean;
|
|
39
|
+
export declare function getMetricsRegistry(): Registry;
|
|
40
|
+
/**
|
|
41
|
+
* The default global `register` is left alone so apps that already export their own metrics
|
|
42
|
+
* via prom-client keep working. The SDK only writes to its private registry.
|
|
43
|
+
*/
|
|
44
|
+
export declare function getGlobalPromRegister(): Registry;
|
|
45
|
+
//# sourceMappingURL=metrics.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"metrics.d.ts","sourceRoot":"","sources":["../../../src/core/metrics/metrics.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,OAAO,EAAyB,OAAO,EAAE,KAAK,EAAE,SAAS,EAAY,QAAQ,EAAE,MAAM,aAAa,CAAC;AAOnG,MAAM,WAAW,WAAW;IAC1B,SAAS,EAAE,OAAO,CAAC,MAAM,GAAG,QAAQ,CAAC,CAAC;IACtC,YAAY,EAAE,SAAS,CAAC,MAAM,CAAC,CAAC;IAChC,YAAY,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC;IAChC,aAAa,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC;IAChC,YAAY,EAAE,OAAO,CAAC,QAAQ,GAAG,MAAM,GAAG,QAAQ,CAAC,CAAC;IACpD,eAAe,EAAE,KAAK,CAAC,SAAS,CAAC,CAAC;IAClC,YAAY,EAAE,SAAS,CAAC,KAAK,CAAC,CAAC;IAC/B,WAAW,EAAE,SAAS,CAAC,KAAK,CAAC,CAAC;IAC9B,iGAAiG;IACjG,KAAK,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC;CAC1B;AAOD,MAAM,MAAM,cAAc,GAAG,IAAI,GAAG,OAAO,GAAG,SAAS,GAAG,cAAc,GAAG,gBAAgB,GAAG,gBAAgB,CAAC;AAE/G,MAAM,MAAM,cAAc,GAAG,SAAS,GAAG,IAAI,GAAG,YAAY,CAAC;AAU7D;;;GAGG;AACH,wBAAgB,WAAW,IAAI,WAAW,CAqEzC;AAED;;;;GAIG;AACH,wBAAgB,UAAU,IAAI,WAAW,GAAG,SAAS,CAEpD;AAED,wBAAgB,gBAAgB,IAAI,OAAO,CAE1C;AAED,wBAAgB,kBAAkB,IAAI,QAAQ,CAE7C;AAED;;;GAGG;AACH,wBAAgB,qBAAqB,IAAI,QAAQ,CAEhD"}
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Standard §15.3 — Prometheus exposition for MCP-server operability.
|
|
3
|
+
*
|
|
4
|
+
* Off by default; enabled via `webServer.metrics.enabled = true`. When active, a single
|
|
5
|
+
* `prom-client` registry holds every series the SDK emits. Process-level metrics (GC, heap,
|
|
6
|
+
* uptime) are added conditionally — they add ≈30 series, so projects scraping multiple SDK
|
|
7
|
+
* instances can shed them by setting `webServer.metrics.includeProcessMetrics = false`.
|
|
8
|
+
*
|
|
9
|
+
* All metrics use snake_case names; cardinality is bounded by tool name / scope so the
|
|
10
|
+
* SDK never explodes a Prometheus instance even when run with hundreds of tools.
|
|
11
|
+
*/
|
|
12
|
+
import { collectDefaultMetrics, Counter, Gauge, Histogram, register, Registry } from 'prom-client';
|
|
13
|
+
import { appConfig } from '../bootstrap/init-config.js';
|
|
14
|
+
let registry;
|
|
15
|
+
let initialized = false;
|
|
16
|
+
let metrics;
|
|
17
|
+
const DURATION_BUCKETS = [0.05, 0.1, 0.25, 0.5, 1, 2.5, 5, 10, 30];
|
|
18
|
+
const BYTES_BUCKETS = [256, 1024, 4096, 16_384, 65_536, 262_144, 1_048_576, 10_485_760];
|
|
19
|
+
function ensureRegistry() {
|
|
20
|
+
if (registry) {
|
|
21
|
+
return registry;
|
|
22
|
+
}
|
|
23
|
+
registry = new Registry();
|
|
24
|
+
return registry;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Lazy initialization — `initMetrics` is called from `server-http.ts` only when metrics are
|
|
28
|
+
* enabled. Subsequent calls are no-ops, so tests can re-import without leaking series.
|
|
29
|
+
*/
|
|
30
|
+
export function initMetrics() {
|
|
31
|
+
if (metrics) {
|
|
32
|
+
return metrics;
|
|
33
|
+
}
|
|
34
|
+
const reg = ensureRegistry();
|
|
35
|
+
if (appConfig.webServer.metrics?.includeProcessMetrics !== false) {
|
|
36
|
+
collectDefaultMetrics({ register: reg });
|
|
37
|
+
}
|
|
38
|
+
metrics = {
|
|
39
|
+
toolCalls: new Counter({
|
|
40
|
+
name: 'mcp_tool_calls_total',
|
|
41
|
+
help: 'Number of MCP tools/call invocations by tool name and final status.',
|
|
42
|
+
labelNames: ['tool', 'status'],
|
|
43
|
+
registers: [reg],
|
|
44
|
+
}),
|
|
45
|
+
toolDuration: new Histogram({
|
|
46
|
+
name: 'mcp_tool_duration_seconds',
|
|
47
|
+
help: 'Wall-clock duration of MCP tools/call invocations.',
|
|
48
|
+
labelNames: ['tool'],
|
|
49
|
+
buckets: DURATION_BUCKETS,
|
|
50
|
+
registers: [reg],
|
|
51
|
+
}),
|
|
52
|
+
authFailures: new Counter({
|
|
53
|
+
name: 'mcp_auth_failures_total',
|
|
54
|
+
help: 'Number of authentication failures by reason.',
|
|
55
|
+
labelNames: ['reason'],
|
|
56
|
+
registers: [reg],
|
|
57
|
+
}),
|
|
58
|
+
rateLimitHits: new Counter({
|
|
59
|
+
name: 'mcp_rate_limit_hits_total',
|
|
60
|
+
help: 'Number of rate-limit rejections by enforcement scope.',
|
|
61
|
+
labelNames: ['scope'],
|
|
62
|
+
registers: [reg],
|
|
63
|
+
}),
|
|
64
|
+
httpRequests: new Counter({
|
|
65
|
+
name: 'mcp_http_requests_total',
|
|
66
|
+
help: 'Number of HTTP requests by method, route and final status code.',
|
|
67
|
+
labelNames: ['method', 'path', 'status'],
|
|
68
|
+
registers: [reg],
|
|
69
|
+
}),
|
|
70
|
+
concurrentCalls: new Gauge({
|
|
71
|
+
name: 'mcp_concurrent_calls',
|
|
72
|
+
help: 'In-flight MCP tools/call invocations by JWT subject.',
|
|
73
|
+
labelNames: ['subject'],
|
|
74
|
+
registers: [reg],
|
|
75
|
+
}),
|
|
76
|
+
payloadBytes: new Histogram({
|
|
77
|
+
name: 'mcp_payload_bytes',
|
|
78
|
+
help: 'Size of incoming MCP request payloads in bytes.',
|
|
79
|
+
buckets: BYTES_BUCKETS,
|
|
80
|
+
registers: [reg],
|
|
81
|
+
}),
|
|
82
|
+
resultBytes: new Histogram({
|
|
83
|
+
name: 'mcp_result_bytes',
|
|
84
|
+
help: 'Size of serialized MCP tool results in bytes.',
|
|
85
|
+
buckets: BYTES_BUCKETS,
|
|
86
|
+
registers: [reg],
|
|
87
|
+
}),
|
|
88
|
+
tasks: new Counter({
|
|
89
|
+
name: 'mcp_tasks_total',
|
|
90
|
+
help: 'Number of task lifecycle transitions by status.',
|
|
91
|
+
labelNames: ['status'],
|
|
92
|
+
registers: [reg],
|
|
93
|
+
}),
|
|
94
|
+
};
|
|
95
|
+
initialized = true;
|
|
96
|
+
return metrics;
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Safe accessor for places that may run before `initMetrics` (e.g. tool execution paths that
|
|
100
|
+
* run regardless of HTTP / stdio mode). Returns `undefined` when metrics are disabled — call
|
|
101
|
+
* sites should use optional chaining: `getMetrics()?.toolCalls.inc(...)`.
|
|
102
|
+
*/
|
|
103
|
+
export function getMetrics() {
|
|
104
|
+
return metrics;
|
|
105
|
+
}
|
|
106
|
+
export function isMetricsEnabled() {
|
|
107
|
+
return initialized && appConfig.webServer.metrics?.enabled === true;
|
|
108
|
+
}
|
|
109
|
+
export function getMetricsRegistry() {
|
|
110
|
+
return ensureRegistry();
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* The default global `register` is left alone so apps that already export their own metrics
|
|
114
|
+
* via prom-client keep working. The SDK only writes to its private registry.
|
|
115
|
+
*/
|
|
116
|
+
export function getGlobalPromRegister() {
|
|
117
|
+
return register;
|
|
118
|
+
}
|
|
119
|
+
//# sourceMappingURL=metrics.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"metrics.js","sourceRoot":"","sources":["../../../src/core/metrics/metrics.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Standard §12.2 — optional helper for masking personal / sensitive data in tool results.
|
|
3
|
+
*
|
|
4
|
+
* The standard requires that sensitive data be protected according to the domain policy
|
|
5
|
+
* (masking, filtering). That responsibility stays with the server: the SDK does not know the
|
|
6
|
+
* domain model and cannot decide what counts as sensitive. This utility is a reusable building
|
|
7
|
+
* block so a server need not re-implement masking from scratch — it is NOT wired into the
|
|
8
|
+
* `tools/call` path automatically. Call it explicitly inside a tool handler before returning.
|
|
9
|
+
*
|
|
10
|
+
* Masking is driven purely by explicit rules (field names, regular expressions). It performs no
|
|
11
|
+
* heuristic PII detection.
|
|
12
|
+
*/
|
|
13
|
+
export interface IMaskRules {
|
|
14
|
+
/**
|
|
15
|
+
* Field names whose values are fully masked wherever they occur in the object tree
|
|
16
|
+
* (e.g. `['password', 'token', 'ssn']`). Matched case-insensitively.
|
|
17
|
+
*/
|
|
18
|
+
fieldNames?: string[];
|
|
19
|
+
/**
|
|
20
|
+
* Regular expressions matched against string values at any depth. Every match is replaced
|
|
21
|
+
* (e.g. card numbers, e-mail addresses). Use a global flag to replace all occurrences within a
|
|
22
|
+
* single string; without it only the first occurrence is replaced.
|
|
23
|
+
*/
|
|
24
|
+
patterns?: RegExp[];
|
|
25
|
+
/**
|
|
26
|
+
* Replacement applied when a rule fires. A string replaces the whole matched value (for
|
|
27
|
+
* `fieldNames`) or the matched substring (for `patterns`); default `'***'`. A function receives
|
|
28
|
+
* the original value and returns the masked form — useful for partial masking such as
|
|
29
|
+
* `4111********1111`.
|
|
30
|
+
*/
|
|
31
|
+
replacement?: string | ((original: string) => string);
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Recursively masks sensitive data in `value` according to `rules`, returning a new value.
|
|
35
|
+
* The input is never mutated. Strings, arrays and plain objects are walked; other primitives
|
|
36
|
+
* (numbers, booleans, null, undefined) are returned as-is. Field-name masking replaces the entire
|
|
37
|
+
* value of a matching key regardless of its type.
|
|
38
|
+
*
|
|
39
|
+
* @example
|
|
40
|
+
* maskSensitive({ password: 'p', name: 'a' }, { fieldNames: ['password'] });
|
|
41
|
+
* // → { password: '***', name: 'a' }
|
|
42
|
+
*/
|
|
43
|
+
export declare function maskSensitive<T>(value: T, rules: IMaskRules): T;
|
|
44
|
+
//# sourceMappingURL=mask-sensitive.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mask-sensitive.d.ts","sourceRoot":"","sources":["../../../src/core/utils/mask-sensitive.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,MAAM,WAAW,UAAU;IACzB;;;OAGG;IACH,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB;;;;OAIG;IACH,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB;;;;;OAKG;IACH,WAAW,CAAC,EAAE,MAAM,GAAG,CAAC,CAAC,QAAQ,EAAE,MAAM,KAAK,MAAM,CAAC,CAAC;CACvD;AAmBD;;;;;;;;;GASG;AACH,wBAAgB,aAAa,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,KAAK,EAAE,UAAU,GAAG,CAAC,CA2B/D"}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Standard §12.2 — optional helper for masking personal / sensitive data in tool results.
|
|
3
|
+
*
|
|
4
|
+
* The standard requires that sensitive data be protected according to the domain policy
|
|
5
|
+
* (masking, filtering). That responsibility stays with the server: the SDK does not know the
|
|
6
|
+
* domain model and cannot decide what counts as sensitive. This utility is a reusable building
|
|
7
|
+
* block so a server need not re-implement masking from scratch — it is NOT wired into the
|
|
8
|
+
* `tools/call` path automatically. Call it explicitly inside a tool handler before returning.
|
|
9
|
+
*
|
|
10
|
+
* Masking is driven purely by explicit rules (field names, regular expressions). It performs no
|
|
11
|
+
* heuristic PII detection.
|
|
12
|
+
*/
|
|
13
|
+
const DEFAULT_REPLACEMENT = '***';
|
|
14
|
+
function applyReplacement(original, replacement) {
|
|
15
|
+
if (typeof replacement === 'function') {
|
|
16
|
+
return replacement(original);
|
|
17
|
+
}
|
|
18
|
+
return replacement ?? DEFAULT_REPLACEMENT;
|
|
19
|
+
}
|
|
20
|
+
function maskString(value, patterns, replacement) {
|
|
21
|
+
let out = value;
|
|
22
|
+
for (const re of patterns) {
|
|
23
|
+
out = out.replace(re, (match) => applyReplacement(match, replacement));
|
|
24
|
+
}
|
|
25
|
+
return out;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Recursively masks sensitive data in `value` according to `rules`, returning a new value.
|
|
29
|
+
* The input is never mutated. Strings, arrays and plain objects are walked; other primitives
|
|
30
|
+
* (numbers, booleans, null, undefined) are returned as-is. Field-name masking replaces the entire
|
|
31
|
+
* value of a matching key regardless of its type.
|
|
32
|
+
*
|
|
33
|
+
* @example
|
|
34
|
+
* maskSensitive({ password: 'p', name: 'a' }, { fieldNames: ['password'] });
|
|
35
|
+
* // → { password: '***', name: 'a' }
|
|
36
|
+
*/
|
|
37
|
+
export function maskSensitive(value, rules) {
|
|
38
|
+
const fieldNames = new Set((rules.fieldNames ?? []).map((n) => n.toLowerCase()));
|
|
39
|
+
const patterns = rules.patterns ?? [];
|
|
40
|
+
const { replacement } = rules;
|
|
41
|
+
const walk = (node) => {
|
|
42
|
+
if (typeof node === 'string') {
|
|
43
|
+
return patterns.length > 0 ? maskString(node, patterns, replacement) : node;
|
|
44
|
+
}
|
|
45
|
+
if (Array.isArray(node)) {
|
|
46
|
+
return node.map((item) => walk(item));
|
|
47
|
+
}
|
|
48
|
+
if (node && typeof node === 'object') {
|
|
49
|
+
const result = {};
|
|
50
|
+
for (const [key, val] of Object.entries(node)) {
|
|
51
|
+
if (fieldNames.has(key.toLowerCase())) {
|
|
52
|
+
result[key] = applyReplacement(typeof val === 'string' ? val : String(val), replacement);
|
|
53
|
+
}
|
|
54
|
+
else {
|
|
55
|
+
result[key] = walk(val);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
return result;
|
|
59
|
+
}
|
|
60
|
+
return node;
|
|
61
|
+
};
|
|
62
|
+
return walk(value);
|
|
63
|
+
}
|
|
64
|
+
//# sourceMappingURL=mask-sensitive.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mask-sensitive.js","sourceRoot":"","sources":["../../../src/core/utils/mask-sensitive.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAuBH,MAAM,mBAAmB,GAAG,KAAK,CAAC;AAElC,SAAS,gBAAgB,CAAC,QAAgB,EAAE,WAAsC;IAChF,IAAI,OAAO,WAAW,KAAK,UAAU,EAAE,CAAC;QACtC,OAAO,WAAW,CAAC,QAAQ,CAAC,CAAC;IAC/B,CAAC;IACD,OAAO,WAAW,IAAI,mBAAmB,CAAC;AAC5C,CAAC;AAED,SAAS,UAAU,CAAC,KAAa,EAAE,QAAkB,EAAE,WAAsC;IAC3F,IAAI,GAAG,GAAG,KAAK,CAAC;IAChB,KAAK,MAAM,EAAE,IAAI,QAAQ,EAAE,CAAC;QAC1B,GAAG,GAAG,GAAG,CAAC,OAAO,CAAC,EAAE,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,gBAAgB,CAAC,KAAK,EAAE,WAAW,CAAC,CAAC,CAAC;IACzE,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,UAAU,aAAa,CAAI,KAAQ,EAAE,KAAiB;IAC1D,MAAM,UAAU,GAAG,IAAI,GAAG,CAAC,CAAC,KAAK,CAAC,UAAU,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC;IACjF,MAAM,QAAQ,GAAG,KAAK,CAAC,QAAQ,IAAI,EAAE,CAAC;IACtC,MAAM,EAAE,WAAW,EAAE,GAAG,KAAK,CAAC;IAE9B,MAAM,IAAI,GAAG,CAAC,IAAa,EAAW,EAAE;QACtC,IAAI,OAAO,IAAI,KAAK,QAAQ,EAAE,CAAC;YAC7B,OAAO,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,IAAI,EAAE,QAAQ,EAAE,WAAW,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;QAC9E,CAAC;QACD,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;YACxB,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;QACxC,CAAC;QACD,IAAI,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ,EAAE,CAAC;YACrC,MAAM,MAAM,GAA4B,EAAE,CAAC;YAC3C,KAAK,MAAM,CAAC,GAAG,EAAE,GAAG,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;gBAC9C,IAAI,UAAU,CAAC,GAAG,CAAC,GAAG,CAAC,WAAW,EAAE,CAAC,EAAE,CAAC;oBACtC,MAAM,CAAC,GAAG,CAAC,GAAG,gBAAgB,CAAC,OAAO,GAAG,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,WAAW,CAAC,CAAC;gBAC3F,CAAC;qBAAM,CAAC;oBACN,MAAM,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC;gBAC1B,CAAC;YACH,CAAC;YACD,OAAO,MAAM,CAAC;QAChB,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC,CAAC;IAEF,OAAO,IAAI,CAAC,KAAK,CAAM,CAAC;AAC1B,CAAC"}
|
|
@@ -1,38 +1,13 @@
|
|
|
1
|
-
import {
|
|
2
|
-
type Json = any;
|
|
1
|
+
import { McpStreamableHttpClient } from './McpStreamableHttpClient.js';
|
|
3
2
|
/**
|
|
4
|
-
*
|
|
3
|
+
* @deprecated Use {@link McpStreamableHttpClient}.
|
|
5
4
|
*
|
|
6
|
-
*
|
|
7
|
-
* with the
|
|
5
|
+
* The original plain-POST client (one-shot `POST /mcp`, `Accept: application/json`, no session) is
|
|
6
|
+
* incompatible with the server's official `StreamableHTTPServerTransport`, which requires
|
|
7
|
+
* `Accept: application/json, text/event-stream` and an `Mcp-Session-Id` round-trip. This is now a
|
|
8
|
+
* thin alias over {@link McpStreamableHttpClient}, which speaks the correct protocol. The public
|
|
9
|
+
* API (`initialize`, `listTools`, `callTool`, …) is unchanged.
|
|
8
10
|
*/
|
|
9
|
-
export declare class McpHttpClient extends
|
|
10
|
-
private readonly baseURL;
|
|
11
|
-
private readonly endpointPath;
|
|
12
|
-
serverInfo?: {
|
|
13
|
-
name: string;
|
|
14
|
-
version: string;
|
|
15
|
-
};
|
|
16
|
-
capabilities?: any;
|
|
17
|
-
protocolVersion?: string;
|
|
18
|
-
constructor(baseURL: string, options?: {
|
|
19
|
-
endpointPath?: string;
|
|
20
|
-
headers?: Record<string, string>;
|
|
21
|
-
requestTimeoutMs?: number;
|
|
22
|
-
});
|
|
23
|
-
initialize(params?: {
|
|
24
|
-
protocolVersion?: string;
|
|
25
|
-
capabilities?: any;
|
|
26
|
-
clientInfo?: {
|
|
27
|
-
name: string;
|
|
28
|
-
version: string;
|
|
29
|
-
};
|
|
30
|
-
}): Promise<any>;
|
|
31
|
-
close(): Promise<void>;
|
|
32
|
-
private sendHttpRequest;
|
|
33
|
-
notify(method: string, params?: Json): void;
|
|
34
|
-
sendRpc<T = any>(method: string, params?: Json): Promise<T>;
|
|
35
|
-
protected sendRequest(method: string, params: any): Promise<any>;
|
|
11
|
+
export declare class McpHttpClient extends McpStreamableHttpClient {
|
|
36
12
|
}
|
|
37
|
-
export {};
|
|
38
13
|
//# sourceMappingURL=McpHttpClient.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"McpHttpClient.d.ts","sourceRoot":"","sources":["../../../../src/core/utils/testing/McpHttpClient.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"McpHttpClient.d.ts","sourceRoot":"","sources":["../../../../src/core/utils/testing/McpHttpClient.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,uBAAuB,EAAE,MAAM,8BAA8B,CAAC;AAEvE;;;;;;;;GAQG;AACH,qBAAa,aAAc,SAAQ,uBAAuB;CAAG"}
|