fa-mcp-sdk 0.4.141 → 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
package/dist/core/web/cors.js
CHANGED
|
@@ -2,21 +2,42 @@ import cors from 'cors';
|
|
|
2
2
|
import { config } from '../bootstrap/init-config.js';
|
|
3
3
|
const { originHosts } = config.webServer;
|
|
4
4
|
const originTestRe = new RegExp(`https?:\\/\\/(${originHosts.join('|')})(:\\d+)?`, 'i');
|
|
5
|
+
/**
|
|
6
|
+
* CORS guard (standard §6). Requests carrying an `Origin` header that is NOT covered by
|
|
7
|
+
* `webServer.originHosts` are rejected with HTTP 403 + a JSON-RPC error body. Same-origin
|
|
8
|
+
* requests (no `Origin` header) and tools (curl, MCP test clients) pass through.
|
|
9
|
+
*
|
|
10
|
+
* Production-time refusal of the "allow everything" configuration is enforced in
|
|
11
|
+
* `validateProductionWebServerConfig()` so the server never starts in that state.
|
|
12
|
+
*/
|
|
5
13
|
export const applyCors = (app) => {
|
|
6
14
|
const corsOptions = {
|
|
7
|
-
// https://www.npmjs.com/package/cors#configuring-cors
|
|
8
|
-
// origin: /https?:\/\/(localhost|any-service.corp.com)(:\d+)?/
|
|
9
15
|
origin(origin, callback) {
|
|
10
|
-
if (originTestRe.test(origin)
|
|
16
|
+
if (!origin || originTestRe.test(origin)) {
|
|
11
17
|
callback(null, true);
|
|
12
18
|
}
|
|
13
19
|
else {
|
|
14
|
-
callback(
|
|
15
|
-
// callback(new Error('Not allowed by CORS'));
|
|
20
|
+
callback(new Error('CORS_ORIGIN_NOT_ALLOWED'));
|
|
16
21
|
}
|
|
17
22
|
},
|
|
18
23
|
};
|
|
19
24
|
app.use(cors(corsOptions));
|
|
25
|
+
// Convert the CORS rejection into a 403 with a structured JSON-RPC error instead of letting
|
|
26
|
+
// Express fall through to the generic 500 handler.
|
|
27
|
+
app.use((err, _req, res, next) => {
|
|
28
|
+
if (err && err.message === 'CORS_ORIGIN_NOT_ALLOWED') {
|
|
29
|
+
return res.status(403).json({
|
|
30
|
+
jsonrpc: '2.0',
|
|
31
|
+
id: null,
|
|
32
|
+
error: {
|
|
33
|
+
code: -32600,
|
|
34
|
+
message: 'Origin not allowed by CORS policy',
|
|
35
|
+
data: { reason: 'origin_not_allowed' },
|
|
36
|
+
},
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
return next(err);
|
|
40
|
+
});
|
|
20
41
|
return corsOptions;
|
|
21
42
|
};
|
|
22
43
|
//# sourceMappingURL=cors.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cors.js","sourceRoot":"","sources":["../../../src/core/web/cors.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,MAAM,CAAC;AAGxB,OAAO,EAAE,MAAM,EAAE,MAAM,6BAA6B,CAAC;AAErD,MAAM,EAAE,WAAW,EAAE,GAAG,MAAM,CAAC,SAAS,CAAC;AAEzC,MAAM,YAAY,GAAG,IAAI,MAAM,CAAC,iBAAiB,WAAW,CAAC,IAAI,CAAC,GAAG,CAAC,WAAW,EAAE,GAAG,CAAC,CAAC;AAExF,MAAM,CAAC,MAAM,SAAS,GAAG,CAAC,GAAY,EAAE,EAAE;IACxC,MAAM,WAAW,GAAG;QAClB,
|
|
1
|
+
{"version":3,"file":"cors.js","sourceRoot":"","sources":["../../../src/core/web/cors.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,MAAM,CAAC;AAGxB,OAAO,EAAE,MAAM,EAAE,MAAM,6BAA6B,CAAC;AAErD,MAAM,EAAE,WAAW,EAAE,GAAG,MAAM,CAAC,SAAS,CAAC;AAEzC,MAAM,YAAY,GAAG,IAAI,MAAM,CAAC,iBAAiB,WAAW,CAAC,IAAI,CAAC,GAAG,CAAC,WAAW,EAAE,GAAG,CAAC,CAAC;AAExF;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,SAAS,GAAG,CAAC,GAAY,EAAE,EAAE;IACxC,MAAM,WAAW,GAAG;QAClB,MAAM,CAAC,MAAW,EAAE,QAAsD;YACxE,IAAI,CAAC,MAAM,IAAI,YAAY,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;gBACzC,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;YACvB,CAAC;iBAAM,CAAC;gBACN,QAAQ,CAAC,IAAI,KAAK,CAAC,yBAAyB,CAAC,CAAC,CAAC;YACjD,CAAC;QACH,CAAC;KACF,CAAC;IAEF,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC;IAE3B,4FAA4F;IAC5F,mDAAmD;IACnD,GAAG,CAAC,GAAG,CAAC,CAAC,GAAQ,EAAE,IAAa,EAAE,GAAa,EAAE,IAAkB,EAAE,EAAE;QACrE,IAAI,GAAG,IAAI,GAAG,CAAC,OAAO,KAAK,yBAAyB,EAAE,CAAC;YACrD,OAAO,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;gBAC1B,OAAO,EAAE,KAAK;gBACd,EAAE,EAAE,IAAI;gBACR,KAAK,EAAE;oBACL,IAAI,EAAE,CAAC,KAAK;oBACZ,OAAO,EAAE,mCAAmC;oBAC5C,IAAI,EAAE,EAAE,MAAM,EAAE,oBAAoB,EAAE;iBACvC;aACF,CAAC,CAAC;QACL,CAAC;QACD,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC;IACnB,CAAC,CAAC,CAAC;IAEH,OAAO,WAAW,CAAC;AACrB,CAAC,CAAC"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Standard §6 (MAY) — in-memory EventStore for Streamable HTTP SSE resumability.
|
|
3
|
+
*
|
|
4
|
+
* When a client reconnects to `GET /mcp` carrying a `Last-Event-ID` header, the SDK transport
|
|
5
|
+
* calls {@link InMemoryEventStore.replayEventsAfter} to re-send the messages the client missed.
|
|
6
|
+
* This implementation keeps a bounded ring buffer of the most recent events in process memory:
|
|
7
|
+
* it survives only within a single running server instance and is lost on restart. For
|
|
8
|
+
* multi-instance deployments a shared/persistent store (Redis etc.) would be required — that
|
|
9
|
+
* is intentionally out of scope here.
|
|
10
|
+
*/
|
|
11
|
+
import { JSONRPCMessage } from '@modelcontextprotocol/sdk/types.js';
|
|
12
|
+
import type { EventStore, EventId, StreamId } from '@modelcontextprotocol/sdk/server/streamableHttp.js';
|
|
13
|
+
/**
|
|
14
|
+
* Ring-buffer EventStore. Event ids are `<streamId>_<paddedSeq>` where `seq` is a process-global
|
|
15
|
+
* monotonic counter, zero-padded so lexicographic ordering matches insertion order (the SDK
|
|
16
|
+
* compares ids as strings during replay). Once the buffer exceeds `maxStoredEvents`, the oldest
|
|
17
|
+
* event is evicted; a `Last-Event-ID` pointing past the retained window yields no replay (the
|
|
18
|
+
* client simply resumes from the current moment, without error).
|
|
19
|
+
*/
|
|
20
|
+
export declare class InMemoryEventStore implements EventStore {
|
|
21
|
+
private readonly events;
|
|
22
|
+
private readonly maxStoredEvents;
|
|
23
|
+
private seq;
|
|
24
|
+
constructor(maxStoredEvents?: number);
|
|
25
|
+
private nextEventId;
|
|
26
|
+
private static streamIdFromEventId;
|
|
27
|
+
storeEvent(streamId: StreamId, message: JSONRPCMessage): Promise<EventId>;
|
|
28
|
+
getStreamIdForEventId(eventId: EventId): Promise<StreamId | undefined>;
|
|
29
|
+
replayEventsAfter(lastEventId: EventId, { send }: {
|
|
30
|
+
send: (eventId: EventId, message: JSONRPCMessage) => Promise<void>;
|
|
31
|
+
}): Promise<StreamId>;
|
|
32
|
+
}
|
|
33
|
+
//# sourceMappingURL=event-store.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"event-store.d.ts","sourceRoot":"","sources":["../../../src/core/web/event-store.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,OAAO,EAAE,cAAc,EAAE,MAAM,oCAAoC,CAAC;AACpE,OAAO,KAAK,EAAE,UAAU,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,oDAAoD,CAAC;AASxG;;;;;;GAMG;AACH,qBAAa,kBAAmB,YAAW,UAAU;IACnD,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAoC;IAE3D,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAS;IAEzC,OAAO,CAAC,GAAG,CAAK;gBAEJ,eAAe,GAAE,MAA2B;IAIxD,OAAO,CAAC,WAAW;IAMnB,OAAO,CAAC,MAAM,CAAC,mBAAmB;IAK5B,UAAU,CAAC,QAAQ,EAAE,QAAQ,EAAE,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,OAAO,CAAC;IAczE,qBAAqB,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,QAAQ,GAAG,SAAS,CAAC;IAKtE,iBAAiB,CACrB,WAAW,EAAE,OAAO,EACpB,EAAE,IAAI,EAAE,EAAE;QAAE,IAAI,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,cAAc,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;KAAE,GAC/E,OAAO,CAAC,QAAQ,CAAC;CAsBrB"}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
const DEFAULT_MAX_EVENTS = 1000;
|
|
2
|
+
/**
|
|
3
|
+
* Ring-buffer EventStore. Event ids are `<streamId>_<paddedSeq>` where `seq` is a process-global
|
|
4
|
+
* monotonic counter, zero-padded so lexicographic ordering matches insertion order (the SDK
|
|
5
|
+
* compares ids as strings during replay). Once the buffer exceeds `maxStoredEvents`, the oldest
|
|
6
|
+
* event is evicted; a `Last-Event-ID` pointing past the retained window yields no replay (the
|
|
7
|
+
* client simply resumes from the current moment, without error).
|
|
8
|
+
*/
|
|
9
|
+
export class InMemoryEventStore {
|
|
10
|
+
events = new Map();
|
|
11
|
+
maxStoredEvents;
|
|
12
|
+
seq = 0;
|
|
13
|
+
constructor(maxStoredEvents = DEFAULT_MAX_EVENTS) {
|
|
14
|
+
this.maxStoredEvents = maxStoredEvents > 0 ? maxStoredEvents : DEFAULT_MAX_EVENTS;
|
|
15
|
+
}
|
|
16
|
+
nextEventId(streamId) {
|
|
17
|
+
// 16-digit zero-padded counter keeps ids lexicographically ordered for the lifetime of the process.
|
|
18
|
+
const padded = String(this.seq++).padStart(16, '0');
|
|
19
|
+
return `${streamId}_${padded}`;
|
|
20
|
+
}
|
|
21
|
+
static streamIdFromEventId(eventId) {
|
|
22
|
+
const idx = eventId.lastIndexOf('_');
|
|
23
|
+
return idx === -1 ? '' : eventId.slice(0, idx);
|
|
24
|
+
}
|
|
25
|
+
async storeEvent(streamId, message) {
|
|
26
|
+
const eventId = this.nextEventId(streamId);
|
|
27
|
+
this.events.set(eventId, { streamId, message });
|
|
28
|
+
// FIFO eviction via Map insertion order keeps the buffer bounded.
|
|
29
|
+
while (this.events.size > this.maxStoredEvents) {
|
|
30
|
+
const oldest = this.events.keys().next().value;
|
|
31
|
+
if (oldest === undefined) {
|
|
32
|
+
break;
|
|
33
|
+
}
|
|
34
|
+
this.events.delete(oldest);
|
|
35
|
+
}
|
|
36
|
+
return eventId;
|
|
37
|
+
}
|
|
38
|
+
async getStreamIdForEventId(eventId) {
|
|
39
|
+
const stored = this.events.get(eventId);
|
|
40
|
+
return stored?.streamId;
|
|
41
|
+
}
|
|
42
|
+
async replayEventsAfter(lastEventId, { send }) {
|
|
43
|
+
// Unknown id (never stored or already evicted) → no replay; the transport starts a fresh stream.
|
|
44
|
+
if (!lastEventId || !this.events.has(lastEventId)) {
|
|
45
|
+
return '';
|
|
46
|
+
}
|
|
47
|
+
const streamId = InMemoryEventStore.streamIdFromEventId(lastEventId);
|
|
48
|
+
if (!streamId) {
|
|
49
|
+
return '';
|
|
50
|
+
}
|
|
51
|
+
let afterLast = false;
|
|
52
|
+
// Map iteration follows insertion order, which equals seq order — no sort needed.
|
|
53
|
+
for (const [eventId, stored] of this.events) {
|
|
54
|
+
if (eventId === lastEventId) {
|
|
55
|
+
afterLast = true;
|
|
56
|
+
continue;
|
|
57
|
+
}
|
|
58
|
+
if (afterLast && stored.streamId === streamId) {
|
|
59
|
+
await send(eventId, stored.message);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
return streamId;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
//# sourceMappingURL=event-store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"event-store.js","sourceRoot":"","sources":["../../../src/core/web/event-store.ts"],"names":[],"mappings":"AAkBA,MAAM,kBAAkB,GAAG,IAAI,CAAC;AAEhC;;;;;;GAMG;AACH,MAAM,OAAO,kBAAkB;IACZ,MAAM,GAAG,IAAI,GAAG,EAAyB,CAAC;IAE1C,eAAe,CAAS;IAEjC,GAAG,GAAG,CAAC,CAAC;IAEhB,YAAY,kBAA0B,kBAAkB;QACtD,IAAI,CAAC,eAAe,GAAG,eAAe,GAAG,CAAC,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,kBAAkB,CAAC;IACpF,CAAC;IAEO,WAAW,CAAC,QAAkB;QACpC,oGAAoG;QACpG,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,QAAQ,CAAC,EAAE,EAAE,GAAG,CAAC,CAAC;QACpD,OAAO,GAAG,QAAQ,IAAI,MAAM,EAAE,CAAC;IACjC,CAAC;IAEO,MAAM,CAAC,mBAAmB,CAAC,OAAgB;QACjD,MAAM,GAAG,GAAG,OAAO,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;QACrC,OAAO,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;IACjD,CAAC;IAED,KAAK,CAAC,UAAU,CAAC,QAAkB,EAAE,OAAuB;QAC1D,MAAM,OAAO,GAAG,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC;QAC3C,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,OAAO,EAAE,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC,CAAC;QAChD,kEAAkE;QAClE,OAAO,IAAI,CAAC,MAAM,CAAC,IAAI,GAAG,IAAI,CAAC,eAAe,EAAE,CAAC;YAC/C,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC;YAC/C,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;gBACzB,MAAM;YACR,CAAC;YACD,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QAC7B,CAAC;QACD,OAAO,OAAO,CAAC;IACjB,CAAC;IAED,KAAK,CAAC,qBAAqB,CAAC,OAAgB;QAC1C,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QACxC,OAAO,MAAM,EAAE,QAAQ,CAAC;IAC1B,CAAC;IAED,KAAK,CAAC,iBAAiB,CACrB,WAAoB,EACpB,EAAE,IAAI,EAA0E;QAEhF,iGAAiG;QACjG,IAAI,CAAC,WAAW,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,WAAW,CAAC,EAAE,CAAC;YAClD,OAAO,EAAE,CAAC;QACZ,CAAC;QACD,MAAM,QAAQ,GAAG,kBAAkB,CAAC,mBAAmB,CAAC,WAAW,CAAC,CAAC;QACrE,IAAI,CAAC,QAAQ,EAAE,CAAC;YACd,OAAO,EAAE,CAAC;QACZ,CAAC;QACD,IAAI,SAAS,GAAG,KAAK,CAAC;QACtB,kFAAkF;QAClF,KAAK,MAAM,CAAC,OAAO,EAAE,MAAM,CAAC,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;YAC5C,IAAI,OAAO,KAAK,WAAW,EAAE,CAAC;gBAC5B,SAAS,GAAG,IAAI,CAAC;gBACjB,SAAS;YACX,CAAC;YACD,IAAI,SAAS,IAAI,MAAM,CAAC,QAAQ,KAAK,QAAQ,EAAE,CAAC;gBAC9C,MAAM,IAAI,CAAC,OAAO,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC;YACtC,CAAC;QACH,CAAC;QACD,OAAO,QAAQ,CAAC;IAClB,CAAC;CACF"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OAuth / OIDC discovery + token endpoints for fa-mcp-sdk.
|
|
3
|
+
*
|
|
4
|
+
* Mounted only when jwtToken.mode !== 'legacyAesCtr'.
|
|
5
|
+
*
|
|
6
|
+
* Endpoints:
|
|
7
|
+
* GET /.well-known/oauth-protected-resource (always, any non-legacy mode)
|
|
8
|
+
* GET /.well-known/openid-configuration (only mode=embedded)
|
|
9
|
+
* GET /.well-known/jwks.json (only mode=embedded; also mode=localKey)
|
|
10
|
+
* POST /oauth/token (only when KeyResolver canSign())
|
|
11
|
+
*
|
|
12
|
+
* The flow:
|
|
13
|
+
* - Resource servers ALWAYS expose /.well-known/oauth-protected-resource so MCP-aware
|
|
14
|
+
* clients can discover where to obtain tokens (per the MCP Authorization spec).
|
|
15
|
+
* - Embedded mode additionally exposes a full local IdP (jwks + openid-configuration +
|
|
16
|
+
* /oauth/token grant_type=password). The token endpoint reuses the configured
|
|
17
|
+
* Basic-auth credentials as the password store — no separate user DB.
|
|
18
|
+
*/
|
|
19
|
+
import { Request, Router } from 'express';
|
|
20
|
+
/**
|
|
21
|
+
* Build the express router with discovery + token endpoints.
|
|
22
|
+
*/
|
|
23
|
+
export declare function createOAuthRouter(): Router;
|
|
24
|
+
/**
|
|
25
|
+
* Build the `WWW-Authenticate: Bearer ...` header advertised on 401 responses.
|
|
26
|
+
*
|
|
27
|
+
* Compliance:
|
|
28
|
+
* - Standard §7.4: realm="<service>" is REQUIRED in every challenge.
|
|
29
|
+
* - `error="invalid_token"` is added only when the verifier could read the token
|
|
30
|
+
* (signature OK, claims invalid/expired) — distinguishes "no creds" vs "bad creds".
|
|
31
|
+
* - In non-legacy modes the MCP Authorization spec mandates resource_metadata=...
|
|
32
|
+
*/
|
|
33
|
+
export declare function buildWwwAuthenticateHeader(req: Request, ctx?: {
|
|
34
|
+
errorReason?: string | undefined;
|
|
35
|
+
isTokenDecrypted?: boolean | undefined;
|
|
36
|
+
} | string): string;
|
|
37
|
+
//# sourceMappingURL=oauth-router.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"oauth-router.d.ts","sourceRoot":"","sources":["../../../src/core/web/oauth-router.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAGH,OAAO,EAAE,OAAO,EAAY,MAAM,EAAE,MAAM,SAAS,CAAC;AA+CpD;;GAEG;AACH,wBAAgB,iBAAiB,IAAI,MAAM,CA4H1C;AAED;;;;;;;;GAQG;AACH,wBAAgB,0BAA0B,CACxC,GAAG,EAAE,OAAO,EACZ,GAAG,GAAE;IAAE,WAAW,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAAC,gBAAgB,CAAC,EAAE,OAAO,GAAG,SAAS,CAAA;CAAE,GAAG,MAAW,GAC9F,MAAM,CAmBR"}
|
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OAuth / OIDC discovery + token endpoints for fa-mcp-sdk.
|
|
3
|
+
*
|
|
4
|
+
* Mounted only when jwtToken.mode !== 'legacyAesCtr'.
|
|
5
|
+
*
|
|
6
|
+
* Endpoints:
|
|
7
|
+
* GET /.well-known/oauth-protected-resource (always, any non-legacy mode)
|
|
8
|
+
* GET /.well-known/openid-configuration (only mode=embedded)
|
|
9
|
+
* GET /.well-known/jwks.json (only mode=embedded; also mode=localKey)
|
|
10
|
+
* POST /oauth/token (only when KeyResolver canSign())
|
|
11
|
+
*
|
|
12
|
+
* The flow:
|
|
13
|
+
* - Resource servers ALWAYS expose /.well-known/oauth-protected-resource so MCP-aware
|
|
14
|
+
* clients can discover where to obtain tokens (per the MCP Authorization spec).
|
|
15
|
+
* - Embedded mode additionally exposes a full local IdP (jwks + openid-configuration +
|
|
16
|
+
* /oauth/token grant_type=password). The token endpoint reuses the configured
|
|
17
|
+
* Basic-auth credentials as the password store — no separate user DB.
|
|
18
|
+
*/
|
|
19
|
+
import chalk from 'chalk';
|
|
20
|
+
import { Router } from 'express';
|
|
21
|
+
import { appConfig } from '../bootstrap/init-config.js';
|
|
22
|
+
import { logger as lgr } from '../logger.js';
|
|
23
|
+
import { checkBasicAuth } from '../auth/basic.js';
|
|
24
|
+
import { generateToken } from '../auth/jwt.js';
|
|
25
|
+
import { buildLocalJwks, getJwtRuntimeConfig, getKeyResolver } from '../auth/key-resolver.js';
|
|
26
|
+
const logger = lgr.getSubLogger({ name: chalk.bgYellow('oauth-router') });
|
|
27
|
+
/**
|
|
28
|
+
* Compose the canonical issuer URL for embedded mode. Resolution order:
|
|
29
|
+
* 1. expectedIssuer (config) — explicit, wins always
|
|
30
|
+
* 2. Public webServer.host + port (if usable)
|
|
31
|
+
* 3. http://localhost:<port>
|
|
32
|
+
*/
|
|
33
|
+
function getEmbeddedIssuer(req) {
|
|
34
|
+
const { expectedIssuer } = getJwtRuntimeConfig();
|
|
35
|
+
if (expectedIssuer) {
|
|
36
|
+
return expectedIssuer;
|
|
37
|
+
}
|
|
38
|
+
if (req) {
|
|
39
|
+
const protocol = req.protocol || 'http';
|
|
40
|
+
const host = req.get('host');
|
|
41
|
+
if (host) {
|
|
42
|
+
return `${protocol}://${host}`;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
const port = appConfig.webServer?.port;
|
|
46
|
+
return `http://localhost:${port}`;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Public URL of THIS resource server (used as `resource` in protected-resource metadata).
|
|
50
|
+
*/
|
|
51
|
+
function getResourceUrl(req) {
|
|
52
|
+
const protocol = req.protocol || 'http';
|
|
53
|
+
const host = req.get('host');
|
|
54
|
+
if (host) {
|
|
55
|
+
return `${protocol}://${host}`;
|
|
56
|
+
}
|
|
57
|
+
return `http://localhost:${appConfig.webServer?.port}`;
|
|
58
|
+
}
|
|
59
|
+
const TTL_MULTIPLIERS = { s: 1, m: 60, d: 86400, y: 31536000 };
|
|
60
|
+
/**
|
|
61
|
+
* Build the express router with discovery + token endpoints.
|
|
62
|
+
*/
|
|
63
|
+
export function createOAuthRouter() {
|
|
64
|
+
const router = Router();
|
|
65
|
+
const { mode } = getJwtRuntimeConfig();
|
|
66
|
+
// ──────────────────────────────────────────────────────────────────────
|
|
67
|
+
// RFC 9728 — Protected Resource Metadata (any non-legacy mode)
|
|
68
|
+
// ──────────────────────────────────────────────────────────────────────
|
|
69
|
+
router.get('/.well-known/oauth-protected-resource', (req, res) => {
|
|
70
|
+
const resource = getResourceUrl(req);
|
|
71
|
+
const issuer = getEmbeddedIssuer(req);
|
|
72
|
+
res.json({
|
|
73
|
+
resource,
|
|
74
|
+
authorization_servers: [issuer],
|
|
75
|
+
bearer_methods_supported: ['header'],
|
|
76
|
+
scopes_supported: ['mcp:read', 'mcp:write'],
|
|
77
|
+
resource_documentation: `${resource}/docs`,
|
|
78
|
+
});
|
|
79
|
+
});
|
|
80
|
+
// ──────────────────────────────────────────────────────────────────────
|
|
81
|
+
// OIDC discovery + JWKS (embedded / localKey when keys are available)
|
|
82
|
+
// ──────────────────────────────────────────────────────────────────────
|
|
83
|
+
if (mode === 'embedded' || mode === 'localKey') {
|
|
84
|
+
router.get('/.well-known/openid-configuration', (req, res) => {
|
|
85
|
+
const issuer = getEmbeddedIssuer(req);
|
|
86
|
+
res.json({
|
|
87
|
+
issuer,
|
|
88
|
+
jwks_uri: `${issuer}/.well-known/jwks.json`,
|
|
89
|
+
token_endpoint: `${issuer}/oauth/token`,
|
|
90
|
+
response_types_supported: ['token'],
|
|
91
|
+
grant_types_supported: ['password'],
|
|
92
|
+
token_endpoint_auth_methods_supported: ['client_secret_basic', 'none'],
|
|
93
|
+
id_token_signing_alg_values_supported: [getJwtRuntimeConfig().algorithm],
|
|
94
|
+
subject_types_supported: ['public'],
|
|
95
|
+
scopes_supported: ['mcp:read', 'mcp:write'],
|
|
96
|
+
});
|
|
97
|
+
});
|
|
98
|
+
router.get('/.well-known/jwks.json', async (_req, res) => {
|
|
99
|
+
try {
|
|
100
|
+
const jwks = await buildLocalJwks();
|
|
101
|
+
res.json(jwks);
|
|
102
|
+
}
|
|
103
|
+
catch (error) {
|
|
104
|
+
logger.error('Failed to build JWKS', error);
|
|
105
|
+
res.status(500).json({ error: 'jwks_unavailable', error_description: error?.message });
|
|
106
|
+
}
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
// ──────────────────────────────────────────────────────────────────────
|
|
110
|
+
// POST /oauth/token (grant_type=password) — embedded / localKey with privateKey
|
|
111
|
+
// ──────────────────────────────────────────────────────────────────────
|
|
112
|
+
router.post('/oauth/token', async (req, res) => {
|
|
113
|
+
try {
|
|
114
|
+
const resolver = await getKeyResolver();
|
|
115
|
+
if (!resolver || !resolver.canSign()) {
|
|
116
|
+
return res.status(400).json({
|
|
117
|
+
error: 'unsupported_grant_type',
|
|
118
|
+
error_description: 'This server does not issue tokens. Obtain a token from the configured IdP.',
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
const grantType = (req.body?.grant_type ?? req.query?.grant_type ?? '').toString();
|
|
122
|
+
if (grantType !== 'password') {
|
|
123
|
+
return res.status(400).json({
|
|
124
|
+
error: 'unsupported_grant_type',
|
|
125
|
+
error_description: `Only grant_type=password is supported (got "${grantType}")`,
|
|
126
|
+
});
|
|
127
|
+
}
|
|
128
|
+
const username = (req.body?.username ?? '').toString().trim();
|
|
129
|
+
const password = (req.body?.password ?? '').toString();
|
|
130
|
+
if (!username || !password) {
|
|
131
|
+
return res.status(400).json({
|
|
132
|
+
error: 'invalid_request',
|
|
133
|
+
error_description: 'username and password are required',
|
|
134
|
+
});
|
|
135
|
+
}
|
|
136
|
+
const encoded = Buffer.from(`${username}:${password}`).toString('base64');
|
|
137
|
+
const auth = checkBasicAuth(encoded);
|
|
138
|
+
if (!auth.success) {
|
|
139
|
+
return res.status(401).json({
|
|
140
|
+
error: 'invalid_grant',
|
|
141
|
+
error_description: auth.error || 'Invalid credentials',
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
const scope = (req.body?.scope ?? '').toString().trim() || undefined;
|
|
145
|
+
const requestedTtl = (req.body?.ttl ?? '').toString().trim();
|
|
146
|
+
let liveTimeSec = getJwtRuntimeConfig().defaultTtl;
|
|
147
|
+
if (requestedTtl) {
|
|
148
|
+
const match = /^(\d+)([smdy])$/.exec(requestedTtl);
|
|
149
|
+
if (!match) {
|
|
150
|
+
return res.status(400).json({
|
|
151
|
+
error: 'invalid_request',
|
|
152
|
+
error_description: `Invalid ttl "${requestedTtl}". Format: <N>s | <N>m | <N>d | <N>y`,
|
|
153
|
+
});
|
|
154
|
+
}
|
|
155
|
+
liveTimeSec = parseInt(match[1], 10) * TTL_MULTIPLIERS[match[2]];
|
|
156
|
+
}
|
|
157
|
+
const payload = {};
|
|
158
|
+
if (scope) {
|
|
159
|
+
payload.scope = scope;
|
|
160
|
+
}
|
|
161
|
+
const token = await generateToken(username, liveTimeSec, payload);
|
|
162
|
+
return res.json({
|
|
163
|
+
access_token: token,
|
|
164
|
+
token_type: 'Bearer',
|
|
165
|
+
expires_in: liveTimeSec,
|
|
166
|
+
...(scope ? { scope } : {}),
|
|
167
|
+
});
|
|
168
|
+
}
|
|
169
|
+
catch (error) {
|
|
170
|
+
logger.error('oauth/token failed', error);
|
|
171
|
+
return res.status(500).json({
|
|
172
|
+
error: 'server_error',
|
|
173
|
+
error_description: error?.message ?? 'unknown error',
|
|
174
|
+
});
|
|
175
|
+
}
|
|
176
|
+
});
|
|
177
|
+
return router;
|
|
178
|
+
}
|
|
179
|
+
/**
|
|
180
|
+
* Build the `WWW-Authenticate: Bearer ...` header advertised on 401 responses.
|
|
181
|
+
*
|
|
182
|
+
* Compliance:
|
|
183
|
+
* - Standard §7.4: realm="<service>" is REQUIRED in every challenge.
|
|
184
|
+
* - `error="invalid_token"` is added only when the verifier could read the token
|
|
185
|
+
* (signature OK, claims invalid/expired) — distinguishes "no creds" vs "bad creds".
|
|
186
|
+
* - In non-legacy modes the MCP Authorization spec mandates resource_metadata=...
|
|
187
|
+
*/
|
|
188
|
+
export function buildWwwAuthenticateHeader(req, ctx = {}) {
|
|
189
|
+
const opts = typeof ctx === 'string' ? { errorReason: ctx, isTokenDecrypted: true } : ctx;
|
|
190
|
+
const { mode } = getJwtRuntimeConfig();
|
|
191
|
+
const realm = appConfig.name || 'mcp';
|
|
192
|
+
const errParts = [];
|
|
193
|
+
if (opts.isTokenDecrypted && opts.errorReason) {
|
|
194
|
+
errParts.push(`error="invalid_token"`);
|
|
195
|
+
errParts.push(`error_description="${String(opts.errorReason).replace(/"/g, '')}"`);
|
|
196
|
+
}
|
|
197
|
+
if (mode === 'legacyAesCtr') {
|
|
198
|
+
return [`Bearer realm="${realm}"`, ...errParts].join(', ');
|
|
199
|
+
}
|
|
200
|
+
const resource = getResourceUrl(req);
|
|
201
|
+
return [
|
|
202
|
+
`Bearer realm="${realm}"`,
|
|
203
|
+
`resource_metadata="${resource}/.well-known/oauth-protected-resource"`,
|
|
204
|
+
...errParts,
|
|
205
|
+
].join(', ');
|
|
206
|
+
}
|
|
207
|
+
//# sourceMappingURL=oauth-router.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"oauth-router.js","sourceRoot":"","sources":["../../../src/core/web/oauth-router.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { AsyncLocalStorage } from 'node:async_hooks';
|
|
2
|
+
import { RequestHandler } from 'express';
|
|
3
|
+
/**
|
|
4
|
+
* Standard §15.1 — sticky correlation id for every request, plus optional W3C
|
|
5
|
+
* trace context. The middleware stores them in {@link AsyncLocalStorage} so the
|
|
6
|
+
* rest of the call chain (logger, JSON-RPC error serializer, debug-trace) can
|
|
7
|
+
* pick them up without explicit plumbing.
|
|
8
|
+
*/
|
|
9
|
+
export interface ITraceContext {
|
|
10
|
+
/** 32 hex chars (W3C trace-id). */
|
|
11
|
+
traceId: string;
|
|
12
|
+
/** 16 hex chars (W3C parent-id / span-id of the incoming span). */
|
|
13
|
+
parentId: string;
|
|
14
|
+
/** 2 hex chars (W3C trace flags). */
|
|
15
|
+
flags: string;
|
|
16
|
+
}
|
|
17
|
+
export interface IRequestContext {
|
|
18
|
+
/** Sticky id propagated end-to-end (HTTP `X-Request-Id` or stdio-generated). */
|
|
19
|
+
requestId: string;
|
|
20
|
+
/** Echoed verbatim to downstream services in `tracestate` (W3C). */
|
|
21
|
+
tracestate?: string;
|
|
22
|
+
/** Populated only when a valid W3C `traceparent` header was supplied. */
|
|
23
|
+
traceContext?: ITraceContext;
|
|
24
|
+
/** JSON-RPC id of the incoming message (stdio path) — never the same as `requestId`. */
|
|
25
|
+
jsonRpcId?: string | number | null;
|
|
26
|
+
}
|
|
27
|
+
declare const requestIdStorage: AsyncLocalStorage<IRequestContext>;
|
|
28
|
+
/**
|
|
29
|
+
* Express middleware that materialises {@link IRequestContext} for the lifetime
|
|
30
|
+
* of a request. Always sets the `X-Request-Id` response header (BEHAVIOUR
|
|
31
|
+
* change introduced in 0.8.0) and echoes a valid `tracestate` back unchanged.
|
|
32
|
+
*/
|
|
33
|
+
export declare function requestIdMW(): RequestHandler;
|
|
34
|
+
/**
|
|
35
|
+
* Run a callback with an explicit request context. Used by the stdio bootstrap
|
|
36
|
+
* to wrap every incoming JSON-RPC message.
|
|
37
|
+
*/
|
|
38
|
+
export declare function runWithRequestContext<T>(ctx: IRequestContext, fn: () => T): T;
|
|
39
|
+
export declare function getCurrentRequestContext(): IRequestContext | undefined;
|
|
40
|
+
export declare function getCurrentRequestId(): string | undefined;
|
|
41
|
+
export declare function getCurrentJsonRpcId(): string | number | null | undefined;
|
|
42
|
+
export declare function getCurrentTraceContext(): ITraceContext | undefined;
|
|
43
|
+
export { requestIdStorage };
|
|
44
|
+
//# sourceMappingURL=request-id.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"request-id.d.ts","sourceRoot":"","sources":["../../../src/core/web/request-id.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAGrD,OAAO,EAAyB,cAAc,EAAY,MAAM,SAAS,CAAC;AAE1E;;;;;GAKG;AACH,MAAM,WAAW,aAAa;IAC5B,mCAAmC;IACnC,OAAO,EAAE,MAAM,CAAC;IAChB,mEAAmE;IACnE,QAAQ,EAAE,MAAM,CAAC;IACjB,qCAAqC;IACrC,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,eAAe;IAC9B,gFAAgF;IAChF,SAAS,EAAE,MAAM,CAAC;IAClB,oEAAoE;IACpE,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,yEAAyE;IACzE,YAAY,CAAC,EAAE,aAAa,CAAC;IAC7B,wFAAwF;IACxF,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAC;CACpC;AAED,QAAA,MAAM,gBAAgB,oCAA2C,CAAC;AAwClE;;;;GAIG;AACH,wBAAgB,WAAW,IAAI,cAAc,CAqB5C;AAED;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,CAAC,EAAE,GAAG,EAAE,eAAe,EAAE,EAAE,EAAE,MAAM,CAAC,GAAG,CAAC,CAE7E;AAED,wBAAgB,wBAAwB,IAAI,eAAe,GAAG,SAAS,CAEtE;AAED,wBAAgB,mBAAmB,IAAI,MAAM,GAAG,SAAS,CAExD;AAED,wBAAgB,mBAAmB,IAAI,MAAM,GAAG,MAAM,GAAG,IAAI,GAAG,SAAS,CAExE;AAED,wBAAgB,sBAAsB,IAAI,aAAa,GAAG,SAAS,CAElE;AAED,OAAO,EAAE,gBAAgB,EAAE,CAAC"}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { AsyncLocalStorage } from 'node:async_hooks';
|
|
2
|
+
import { randomUUID } from 'node:crypto';
|
|
3
|
+
const requestIdStorage = new AsyncLocalStorage();
|
|
4
|
+
const REQUEST_ID_REGEX = /^[A-Za-z0-9._-]{8,128}$/;
|
|
5
|
+
const TRACEPARENT_REGEX = /^00-([a-f0-9]{32})-([a-f0-9]{16})-([a-f0-9]{2})$/;
|
|
6
|
+
const TRACESTATE_MAX_LEN = 4096;
|
|
7
|
+
function sanitizeRequestId(value) {
|
|
8
|
+
if (typeof value !== 'string') {
|
|
9
|
+
return undefined;
|
|
10
|
+
}
|
|
11
|
+
const trimmed = value.trim();
|
|
12
|
+
return REQUEST_ID_REGEX.test(trimmed) ? trimmed : undefined;
|
|
13
|
+
}
|
|
14
|
+
function parseTraceparent(value) {
|
|
15
|
+
if (typeof value !== 'string') {
|
|
16
|
+
return undefined;
|
|
17
|
+
}
|
|
18
|
+
const match = TRACEPARENT_REGEX.exec(value.trim().toLowerCase());
|
|
19
|
+
if (!match) {
|
|
20
|
+
return undefined;
|
|
21
|
+
}
|
|
22
|
+
const [, traceId, parentId, flags] = match;
|
|
23
|
+
if (!traceId || !parentId || !flags || /^0+$/.test(traceId) || /^0+$/.test(parentId)) {
|
|
24
|
+
return undefined;
|
|
25
|
+
}
|
|
26
|
+
return { traceId, parentId, flags };
|
|
27
|
+
}
|
|
28
|
+
function sanitizeTracestate(value) {
|
|
29
|
+
if (typeof value !== 'string') {
|
|
30
|
+
return undefined;
|
|
31
|
+
}
|
|
32
|
+
const trimmed = value.trim();
|
|
33
|
+
if (!trimmed || trimmed.length > TRACESTATE_MAX_LEN) {
|
|
34
|
+
return undefined;
|
|
35
|
+
}
|
|
36
|
+
return trimmed;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Express middleware that materialises {@link IRequestContext} for the lifetime
|
|
40
|
+
* of a request. Always sets the `X-Request-Id` response header (BEHAVIOUR
|
|
41
|
+
* change introduced in 0.8.0) and echoes a valid `tracestate` back unchanged.
|
|
42
|
+
*/
|
|
43
|
+
export function requestIdMW() {
|
|
44
|
+
return (req, res, next) => {
|
|
45
|
+
const requestId = sanitizeRequestId(req.headers['x-request-id']) ?? randomUUID();
|
|
46
|
+
const traceContext = parseTraceparent(req.headers['traceparent']);
|
|
47
|
+
const tracestate = sanitizeTracestate(req.headers['tracestate']);
|
|
48
|
+
const ctx = { requestId };
|
|
49
|
+
if (traceContext) {
|
|
50
|
+
ctx.traceContext = traceContext;
|
|
51
|
+
}
|
|
52
|
+
if (tracestate) {
|
|
53
|
+
ctx.tracestate = tracestate;
|
|
54
|
+
}
|
|
55
|
+
res.setHeader('X-Request-Id', requestId);
|
|
56
|
+
if (tracestate) {
|
|
57
|
+
res.setHeader('tracestate', tracestate);
|
|
58
|
+
}
|
|
59
|
+
requestIdStorage.run(ctx, () => next());
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Run a callback with an explicit request context. Used by the stdio bootstrap
|
|
64
|
+
* to wrap every incoming JSON-RPC message.
|
|
65
|
+
*/
|
|
66
|
+
export function runWithRequestContext(ctx, fn) {
|
|
67
|
+
return requestIdStorage.run(ctx, fn);
|
|
68
|
+
}
|
|
69
|
+
export function getCurrentRequestContext() {
|
|
70
|
+
return requestIdStorage.getStore();
|
|
71
|
+
}
|
|
72
|
+
export function getCurrentRequestId() {
|
|
73
|
+
return requestIdStorage.getStore()?.requestId;
|
|
74
|
+
}
|
|
75
|
+
export function getCurrentJsonRpcId() {
|
|
76
|
+
return requestIdStorage.getStore()?.jsonRpcId;
|
|
77
|
+
}
|
|
78
|
+
export function getCurrentTraceContext() {
|
|
79
|
+
return requestIdStorage.getStore()?.traceContext;
|
|
80
|
+
}
|
|
81
|
+
export { requestIdStorage };
|
|
82
|
+
//# sourceMappingURL=request-id.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"request-id.js","sourceRoot":"","sources":["../../../src/core/web/request-id.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":"
|
|
1
|
+
{"version":3,"file":"server-http.d.ts","sourceRoot":"","sources":["../../../src/core/web/server-http.ts"],"names":[],"mappings":"AA+DA,eAAO,MAAM,cAAc,SAAyC,CAAC;AA6DrE;;GAEG;AACH,wBAAsB,eAAe,IAAI,OAAO,CAAC,IAAI,CAAC,CA4wBrD"}
|