apcore-mcp 0.6.0 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +181 -13
- package/dist/auth/index.d.ts +8 -0
- package/dist/auth/index.d.ts.map +1 -0
- package/dist/auth/index.js +6 -0
- package/dist/auth/index.js.map +1 -0
- package/dist/auth/jwt.d.ts +59 -0
- package/dist/auth/jwt.d.ts.map +1 -0
- package/dist/auth/jwt.js +95 -0
- package/dist/auth/jwt.js.map +1 -0
- package/dist/auth/storage.d.ts +18 -0
- package/dist/auth/storage.d.ts.map +1 -0
- package/dist/auth/storage.js +19 -0
- package/dist/auth/storage.js.map +1 -0
- package/dist/auth/types.d.ts +21 -0
- package/dist/auth/types.d.ts.map +1 -0
- package/dist/auth/types.js +8 -0
- package/dist/auth/types.js.map +1 -0
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +37 -2
- package/dist/cli.js.map +1 -1
- package/dist/explorer/handler.d.ts +10 -1
- package/dist/explorer/handler.d.ts.map +1 -1
- package/dist/explorer/handler.js +47 -21
- package/dist/explorer/handler.js.map +1 -1
- package/dist/explorer/html.d.ts +2 -2
- package/dist/explorer/html.d.ts.map +1 -1
- package/dist/explorer/html.js +126 -47
- package/dist/explorer/html.js.map +1 -1
- package/dist/index.d.ts +10 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +15 -5
- package/dist/index.js.map +1 -1
- package/dist/server/context.d.ts +5 -2
- package/dist/server/context.d.ts.map +1 -1
- package/dist/server/context.js +7 -5
- package/dist/server/context.js.map +1 -1
- package/dist/server/router.d.ts.map +1 -1
- package/dist/server/router.js +4 -2
- package/dist/server/router.js.map +1 -1
- package/dist/server/transport.d.ts +34 -1
- package/dist/server/transport.d.ts.map +1 -1
- package/dist/server/transport.js +149 -60
- package/dist/server/transport.js.map +1 -1
- package/package.json +6 -11
package/dist/index.d.ts
CHANGED
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
import type { ConvertRegistryOptions } from "./converters/openai.js";
|
|
9
9
|
import type { MetricsExporter } from "./server/transport.js";
|
|
10
10
|
import type { RegistryOrExecutor, Registry, Executor, OpenAIToolDef } from "./types.js";
|
|
11
|
+
import type { Authenticator } from "./auth/types.js";
|
|
11
12
|
export declare const VERSION: string;
|
|
12
13
|
export type { Registry, Executor, RegistryOrExecutor, OpenAIToolDef } from "./types.js";
|
|
13
14
|
export type { ModuleDescriptor, ModuleAnnotations, JsonSchema, ModuleError, McpAnnotationsDict, McpErrorResponse, TextContentDict, } from "./types.js";
|
|
@@ -16,6 +17,10 @@ export { reportProgress, elicit, MCP_PROGRESS_KEY, MCP_ELICIT_KEY } from "./help
|
|
|
16
17
|
export type { ElicitResult } from "./helpers.js";
|
|
17
18
|
export { createBridgeContext } from "./server/context.js";
|
|
18
19
|
export type { BridgeContext } from "./server/context.js";
|
|
20
|
+
export { JWTAuthenticator } from "./auth/jwt.js";
|
|
21
|
+
export type { ClaimMapping, JWTAuthenticatorOptions } from "./auth/jwt.js";
|
|
22
|
+
export type { Authenticator, Identity } from "./auth/types.js";
|
|
23
|
+
export { identityStorage, getCurrentIdentity } from "./auth/storage.js";
|
|
19
24
|
export { MCPServerFactory } from "./server/factory.js";
|
|
20
25
|
export { ExecutionRouter } from "./server/router.js";
|
|
21
26
|
export type { CallResult, HandleCallExtra, ExecutionRouterOptions } from "./server/router.js";
|
|
@@ -47,7 +52,7 @@ export declare function resolveRegistry(registryOrExecutor: RegistryOrExecutor):
|
|
|
47
52
|
*
|
|
48
53
|
* @throws {Error} If the argument is a Registry and apcore-js is not installed.
|
|
49
54
|
*/
|
|
50
|
-
export declare function resolveExecutor(registryOrExecutor: RegistryOrExecutor): Executor
|
|
55
|
+
export declare function resolveExecutor(registryOrExecutor: RegistryOrExecutor): Promise<Executor>;
|
|
51
56
|
/** Options for serve() */
|
|
52
57
|
export interface ServeOptions {
|
|
53
58
|
/** Transport type. Default: "stdio" */
|
|
@@ -82,6 +87,10 @@ export interface ServeOptions {
|
|
|
82
87
|
explorerPrefix?: string;
|
|
83
88
|
/** Allow tool execution from the explorer UI. Default: false */
|
|
84
89
|
allowExecute?: boolean;
|
|
90
|
+
/** Optional authenticator for request authentication (HTTP transports only). */
|
|
91
|
+
authenticator?: Authenticator;
|
|
92
|
+
/** Custom paths exempt from authentication. Default: ["/health", "/metrics"] */
|
|
93
|
+
exemptPaths?: string[];
|
|
85
94
|
}
|
|
86
95
|
/**
|
|
87
96
|
* Launch an MCP Server that exposes all apcore modules as tools.
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAIH,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,wBAAwB,CAAC;AAIrE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAE7D,OAAO,KAAK,EACV,kBAAkB,EAClB,QAAQ,EACR,QAAQ,EACR,aAAa,EACd,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -18,6 +18,9 @@ export { REGISTRY_EVENTS, ErrorCodes, MODULE_ID_PATTERN } from "./types.js";
|
|
|
18
18
|
// ─── Extension Helpers ───────────────────────────────────────────────────────
|
|
19
19
|
export { reportProgress, elicit, MCP_PROGRESS_KEY, MCP_ELICIT_KEY } from "./helpers.js";
|
|
20
20
|
export { createBridgeContext } from "./server/context.js";
|
|
21
|
+
// ─── Auth Exports ────────────────────────────────────────────────────────────
|
|
22
|
+
export { JWTAuthenticator } from "./auth/jwt.js";
|
|
23
|
+
export { identityStorage, getCurrentIdentity } from "./auth/storage.js";
|
|
21
24
|
// ─── Building Block Exports ──────────────────────────────────────────────────
|
|
22
25
|
export { MCPServerFactory } from "./server/factory.js";
|
|
23
26
|
export { ExecutionRouter } from "./server/router.js";
|
|
@@ -52,15 +55,15 @@ export function resolveRegistry(registryOrExecutor) {
|
|
|
52
55
|
*
|
|
53
56
|
* @throws {Error} If the argument is a Registry and apcore-js is not installed.
|
|
54
57
|
*/
|
|
55
|
-
export function resolveExecutor(registryOrExecutor) {
|
|
58
|
+
export async function resolveExecutor(registryOrExecutor) {
|
|
56
59
|
if ("call" in registryOrExecutor || "callAsync" in registryOrExecutor) {
|
|
57
60
|
// Already an Executor
|
|
58
61
|
return registryOrExecutor;
|
|
59
62
|
}
|
|
60
63
|
// It's a bare Registry — create a default Executor
|
|
61
64
|
try {
|
|
62
|
-
// eslint-disable-next-line @typescript-eslint/no-
|
|
63
|
-
const apcore =
|
|
65
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
66
|
+
const apcore = await import("apcore-js");
|
|
64
67
|
const ExecutorClass = apcore.Executor ?? apcore.default?.Executor;
|
|
65
68
|
if (ExecutorClass) {
|
|
66
69
|
return new ExecutorClass({ registry: registryOrExecutor });
|
|
@@ -78,7 +81,7 @@ export function resolveExecutor(registryOrExecutor) {
|
|
|
78
81
|
* @param options - Server configuration options.
|
|
79
82
|
*/
|
|
80
83
|
export async function serve(registryOrExecutor, options = {}) {
|
|
81
|
-
const { transport = "stdio", host = "127.0.0.1", port = 8000, name = "apcore-mcp", version = VERSION, validateInputs, tags, prefix, logLevel, onStartup, onShutdown, metricsCollector, explorer = false, explorerPrefix = "/explorer", allowExecute = false, } = options;
|
|
84
|
+
const { transport = "stdio", host = "127.0.0.1", port = 8000, name = "apcore-mcp", version = VERSION, validateInputs, tags, prefix, logLevel, onStartup, onShutdown, metricsCollector, explorer = false, explorerPrefix = "/explorer", allowExecute = false, authenticator, exemptPaths, } = options;
|
|
82
85
|
// Input validation (matching Python's checks)
|
|
83
86
|
if (!name || name.length === 0) {
|
|
84
87
|
throw new Error("name must not be empty");
|
|
@@ -118,7 +121,7 @@ export async function serve(registryOrExecutor, options = {}) {
|
|
|
118
121
|
console.error = () => { };
|
|
119
122
|
}
|
|
120
123
|
const registry = resolveRegistry(registryOrExecutor);
|
|
121
|
-
const executor = resolveExecutor(registryOrExecutor);
|
|
124
|
+
const executor = await resolveExecutor(registryOrExecutor);
|
|
122
125
|
// Build MCP server components
|
|
123
126
|
const factory = new MCPServerFactory();
|
|
124
127
|
const server = factory.createServer(name, version);
|
|
@@ -135,12 +138,19 @@ export async function serve(registryOrExecutor, options = {}) {
|
|
|
135
138
|
if (metricsCollector) {
|
|
136
139
|
transportManager.setMetricsCollector(metricsCollector);
|
|
137
140
|
}
|
|
141
|
+
if (authenticator) {
|
|
142
|
+
transportManager.setAuthenticator(authenticator);
|
|
143
|
+
}
|
|
144
|
+
if (exemptPaths) {
|
|
145
|
+
transportManager.setExemptPaths(exemptPaths);
|
|
146
|
+
}
|
|
138
147
|
// Mount explorer for HTTP transports only
|
|
139
148
|
const transportLower = transport.toLowerCase();
|
|
140
149
|
if (explorer && (transportLower === "streamable-http" || transportLower === "sse")) {
|
|
141
150
|
const explorerHandler = new ExplorerHandler(tools, router, {
|
|
142
151
|
allowExecute,
|
|
143
152
|
prefix: explorerPrefix,
|
|
153
|
+
authenticator,
|
|
144
154
|
});
|
|
145
155
|
transportManager.setExplorerHandler(explorerHandler);
|
|
146
156
|
origInfo(`Tool Explorer enabled at ${explorerPrefix}`);
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAEzD,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AACvD,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AACrD,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAEzD,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/server/context.d.ts
CHANGED
|
@@ -10,13 +10,15 @@
|
|
|
10
10
|
* The key requirement: child() returns a new context that shares the same
|
|
11
11
|
* `data` reference so MCP callbacks remain accessible throughout the call chain.
|
|
12
12
|
*/
|
|
13
|
+
import type { Identity } from "../auth/types.js";
|
|
13
14
|
/** Shape of the bridge context object. */
|
|
14
15
|
export interface BridgeContext {
|
|
15
16
|
readonly traceId: string;
|
|
16
17
|
readonly callerId: string | null;
|
|
17
18
|
readonly callChain: readonly string[];
|
|
18
19
|
readonly executor: unknown;
|
|
19
|
-
readonly identity:
|
|
20
|
+
readonly identity: Identity | null;
|
|
21
|
+
readonly cancelToken: null;
|
|
20
22
|
redactedInputs: Record<string, unknown> | null;
|
|
21
23
|
readonly data: Record<string, unknown>;
|
|
22
24
|
child(moduleId: string): BridgeContext;
|
|
@@ -25,7 +27,8 @@ export interface BridgeContext {
|
|
|
25
27
|
* Create a minimal bridge context that carries `data` through executor call chains.
|
|
26
28
|
*
|
|
27
29
|
* @param data - Shared data dict (MCP callbacks are injected here)
|
|
30
|
+
* @param identity - Authenticated identity, if any
|
|
28
31
|
* @returns A BridgeContext with a working child() method
|
|
29
32
|
*/
|
|
30
|
-
export declare function createBridgeContext(data: Record<string, unknown
|
|
33
|
+
export declare function createBridgeContext(data: Record<string, unknown>, identity?: Identity | null): BridgeContext;
|
|
31
34
|
//# sourceMappingURL=context.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../src/server/context.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;
|
|
1
|
+
{"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../src/server/context.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAGH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAEjD,0CAA0C;AAC1C,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,QAAQ,CAAC,SAAS,EAAE,SAAS,MAAM,EAAE,CAAC;IACtC,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;IAC3B,QAAQ,CAAC,QAAQ,EAAE,QAAQ,GAAG,IAAI,CAAC;IACnC,QAAQ,CAAC,WAAW,EAAE,IAAI,CAAC;IAC3B,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;IAC/C,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACvC,KAAK,CAAC,QAAQ,EAAE,MAAM,GAAG,aAAa,CAAC;CACxC;AAED;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CACjC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC7B,QAAQ,CAAC,EAAE,QAAQ,GAAG,IAAI,GACzB,aAAa,CAEf"}
|
package/dist/server/context.js
CHANGED
|
@@ -15,24 +15,26 @@ import { randomUUID } from "node:crypto";
|
|
|
15
15
|
* Create a minimal bridge context that carries `data` through executor call chains.
|
|
16
16
|
*
|
|
17
17
|
* @param data - Shared data dict (MCP callbacks are injected here)
|
|
18
|
+
* @param identity - Authenticated identity, if any
|
|
18
19
|
* @returns A BridgeContext with a working child() method
|
|
19
20
|
*/
|
|
20
|
-
export function createBridgeContext(data) {
|
|
21
|
-
return _buildContext(data, randomUUID(), null, []);
|
|
21
|
+
export function createBridgeContext(data, identity) {
|
|
22
|
+
return _buildContext(data, randomUUID(), null, [], identity ?? null);
|
|
22
23
|
}
|
|
23
|
-
function _buildContext(data, traceId, callerId, callChain) {
|
|
24
|
+
function _buildContext(data, traceId, callerId, callChain, identity) {
|
|
24
25
|
return {
|
|
25
26
|
traceId,
|
|
26
27
|
callerId,
|
|
27
28
|
callChain,
|
|
28
29
|
executor: null,
|
|
29
|
-
identity
|
|
30
|
+
identity,
|
|
31
|
+
cancelToken: null,
|
|
30
32
|
redactedInputs: null,
|
|
31
33
|
data,
|
|
32
34
|
child(moduleId) {
|
|
33
35
|
// Match real Context.child(): callerId = last element of current callChain
|
|
34
36
|
const newCallerId = callChain.length > 0 ? callChain[callChain.length - 1] : null;
|
|
35
|
-
return _buildContext(data, traceId, newCallerId, [...callChain, moduleId]);
|
|
37
|
+
return _buildContext(data, traceId, newCallerId, [...callChain, moduleId], identity);
|
|
36
38
|
},
|
|
37
39
|
};
|
|
38
40
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"context.js","sourceRoot":"","sources":["../../src/server/context.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"context.js","sourceRoot":"","sources":["../../src/server/context.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAgBzC;;;;;;GAMG;AACH,MAAM,UAAU,mBAAmB,CACjC,IAA6B,EAC7B,QAA0B;IAE1B,OAAO,aAAa,CAAC,IAAI,EAAE,UAAU,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,QAAQ,IAAI,IAAI,CAAC,CAAC;AACvE,CAAC;AAED,SAAS,aAAa,CACpB,IAA6B,EAC7B,OAAe,EACf,QAAuB,EACvB,SAAmB,EACnB,QAAyB;IAEzB,OAAO;QACL,OAAO;QACP,QAAQ;QACR,SAAS;QACT,QAAQ,EAAE,IAAI;QACd,QAAQ;QACR,WAAW,EAAE,IAAI;QACjB,cAAc,EAAE,IAAI;QACpB,IAAI;QACJ,KAAK,CAAC,QAAgB;YACpB,2EAA2E;YAC3E,MAAM,WAAW,GAAG,SAAS,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,SAAS,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;YAClF,OAAO,aAAa,CAAC,IAAI,EAAE,OAAO,EAAE,WAAW,EAAE,CAAC,GAAG,SAAS,EAAE,QAAQ,CAAC,EAAE,QAAQ,CAAC,CAAC;QACvF,CAAC;KACF,CAAC;AACJ,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"router.d.ts","sourceRoot":"","sources":["../../src/server/router.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAGH,OAAO,KAAK,EAAE,QAAQ,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"router.d.ts","sourceRoot":"","sources":["../../src/server/router.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAGH,OAAO,KAAK,EAAE,QAAQ,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAM7D,gFAAgF;AAChF,MAAM,MAAM,UAAU,GAAG,CAAC,eAAe,EAAE,EAAE,OAAO,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC;AAE1E;;;;;;;GAOG;AACH,MAAM,WAAW,eAAe;IAC9B,gBAAgB,CAAC,EAAE,CAAC,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5E,WAAW,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,YAAY,EAAE,OAAO,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IAC5F,KAAK,CAAC,EAAE;QAAE,aAAa,CAAC,EAAE,MAAM,GAAG,MAAM,CAAA;KAAE,CAAC;CAC7C;AAED,mDAAmD;AACnD,MAAM,WAAW,sBAAsB;IACrC,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B;AAED,qBAAa,eAAe;IAC1B,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAW;IACrC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAc;IAC3C,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAU;IAE1C;;;;;OAKG;gBACS,QAAQ,EAAE,QAAQ,EAAE,OAAO,CAAC,EAAE,sBAAsB;IAMhE;;;;;;;;;;;;;;;OAeG;IACG,UAAU,CACd,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC7B,KAAK,CAAC,EAAE,eAAe,GACtB,OAAO,CAAC,UAAU,CAAC;CAwKvB"}
|
package/dist/server/router.js
CHANGED
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
import { ErrorMapper } from "../adapters/errors.js";
|
|
12
12
|
import { createBridgeContext } from "./context.js";
|
|
13
13
|
import { MCP_PROGRESS_KEY, MCP_ELICIT_KEY } from "../helpers.js";
|
|
14
|
+
import { getCurrentIdentity } from "../auth/storage.js";
|
|
14
15
|
export class ExecutionRouter {
|
|
15
16
|
_executor;
|
|
16
17
|
_errorMapper;
|
|
@@ -79,8 +80,9 @@ export class ExecutionRouter {
|
|
|
79
80
|
return result ?? null;
|
|
80
81
|
};
|
|
81
82
|
}
|
|
82
|
-
const
|
|
83
|
-
|
|
83
|
+
const identity = getCurrentIdentity();
|
|
84
|
+
const context = (hasCallbacks || identity)
|
|
85
|
+
? createBridgeContext(contextData, identity)
|
|
84
86
|
: undefined;
|
|
85
87
|
// ── Pre-execution validation ────────────────────────────────────
|
|
86
88
|
if (this._validateInputs && this._executor.validate) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"router.js","sourceRoot":"","sources":["../../src/server/router.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAEpD,OAAO,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AACnD,OAAO,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"router.js","sourceRoot":"","sources":["../../src/server/router.ts"],"names":[],"mappings":"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"}
|
|
@@ -6,9 +6,10 @@
|
|
|
6
6
|
* - streamableHttp: Streamable HTTP with SSE support
|
|
7
7
|
* - sse: Legacy Server-Sent Events transport
|
|
8
8
|
*/
|
|
9
|
-
import { type IncomingMessage, type Server as HttpServer } from "node:http";
|
|
9
|
+
import { type IncomingMessage, type Server as HttpServer, type ServerResponse } from "node:http";
|
|
10
10
|
import type { Server } from "@modelcontextprotocol/sdk/server/index.js";
|
|
11
11
|
import type { ExplorerHandler } from "../explorer/handler.js";
|
|
12
|
+
import type { Authenticator } from "../auth/types.js";
|
|
12
13
|
/** Options for HTTP-based transports. */
|
|
13
14
|
export interface HttpTransportOptions {
|
|
14
15
|
host: string;
|
|
@@ -38,12 +39,28 @@ export declare class TransportManager {
|
|
|
38
39
|
private _metricsCollector?;
|
|
39
40
|
/** Optional explorer handler for Tool Explorer UI. */
|
|
40
41
|
private _explorerHandler?;
|
|
42
|
+
/** Optional authenticator for request authentication. */
|
|
43
|
+
private _authenticator?;
|
|
44
|
+
/** Configurable set of paths exempt from authentication. */
|
|
45
|
+
private _exemptPaths;
|
|
41
46
|
/**
|
|
42
47
|
* Set the number of registered modules/tools.
|
|
43
48
|
*
|
|
44
49
|
* @param count - The number of modules
|
|
45
50
|
*/
|
|
46
51
|
setModuleCount(count: number): void;
|
|
52
|
+
/**
|
|
53
|
+
* Set the authenticator for request authentication.
|
|
54
|
+
*
|
|
55
|
+
* @param authenticator - An Authenticator instance (e.g. JWTAuthenticator)
|
|
56
|
+
*/
|
|
57
|
+
setAuthenticator(authenticator: Authenticator): void;
|
|
58
|
+
/**
|
|
59
|
+
* Set the paths that are exempt from authentication.
|
|
60
|
+
*
|
|
61
|
+
* @param paths - Array of path strings to exempt
|
|
62
|
+
*/
|
|
63
|
+
setExemptPaths(paths: string[]): void;
|
|
47
64
|
/**
|
|
48
65
|
* Set the metrics collector for Prometheus /metrics endpoint.
|
|
49
66
|
*
|
|
@@ -71,6 +88,22 @@ export declare class TransportManager {
|
|
|
71
88
|
* @returns true if the request was handled, false otherwise
|
|
72
89
|
*/
|
|
73
90
|
private _handleBuiltinRoute;
|
|
91
|
+
/**
|
|
92
|
+
* Check if a request path/method combination is exempt from authentication.
|
|
93
|
+
*
|
|
94
|
+
* Exempt routes: /health, /metrics (GET), and explorer GET routes.
|
|
95
|
+
*/
|
|
96
|
+
_isAuthExempt(pathname: string, method: string): boolean;
|
|
97
|
+
/**
|
|
98
|
+
* Authenticate an incoming request using the configured authenticator.
|
|
99
|
+
*
|
|
100
|
+
* Returns the Identity on success, or sends a 401 response and returns null.
|
|
101
|
+
* If no authenticator is set, returns null (no auth required).
|
|
102
|
+
*/
|
|
103
|
+
_authenticateRequest(req: IncomingMessage, res: ServerResponse, url: URL): Promise<{
|
|
104
|
+
identity: import("../auth/types.js").Identity | null;
|
|
105
|
+
blocked: boolean;
|
|
106
|
+
}>;
|
|
74
107
|
/**
|
|
75
108
|
* Run the server using stdio transport.
|
|
76
109
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"transport.d.ts","sourceRoot":"","sources":["../../src/server/transport.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAgB,KAAK,eAAe,EAAE,KAAK,MAAM,IAAI,UAAU,
|
|
1
|
+
{"version":3,"file":"transport.d.ts","sourceRoot":"","sources":["../../src/server/transport.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAgB,KAAK,eAAe,EAAE,KAAK,MAAM,IAAI,UAAU,EAAE,KAAK,cAAc,EAAE,MAAM,WAAW,CAAC;AAC/G,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,2CAA2C,CAAC;AAIxE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAC9D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAGtD,yCAAyC;AACzC,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,oFAAoF;AACpF,MAAM,WAAW,eAAe;IAC9B,gBAAgB,IAAI,MAAM,CAAC;CAC5B;AAiBD;;;;;;GAMG;AACH,wBAAgB,QAAQ,CAAC,GAAG,EAAE,eAAe,EAAE,QAAQ,GAAE,MAAuB,GAAG,OAAO,CAAC,MAAM,CAAC,CAwBjG;AAED,qBAAa,gBAAgB;IAC3B,wEAAwE;IACxE,UAAU,CAAC,EAAE,UAAU,CAAC;IAExB,iFAAiF;IACjF,OAAO,CAAC,UAAU,CAAsB;IAExC,0CAA0C;IAC1C,OAAO,CAAC,YAAY,CAAa;IAEjC,mEAAmE;IACnE,OAAO,CAAC,iBAAiB,CAAC,CAAkB;IAE5C,sDAAsD;IACtD,OAAO,CAAC,gBAAgB,CAAC,CAAkB;IAE3C,yDAAyD;IACzD,OAAO,CAAC,cAAc,CAAC,CAAgB;IAEvC,4DAA4D;IAC5D,OAAO,CAAC,YAAY,CAAoC;IAExD;;;;OAIG;IACH,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAInC;;;;OAIG;IACH,gBAAgB,CAAC,aAAa,EAAE,aAAa,GAAG,IAAI;IAIpD;;;;OAIG;IACH,cAAc,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,IAAI;IAIrC;;;;OAIG;IACH,mBAAmB,CAAC,SAAS,EAAE,eAAe,GAAG,IAAI;IAIrD;;;;OAIG;IACH,kBAAkB,CAAC,OAAO,EAAE,eAAe,GAAG,IAAI;IAIlD;;;;OAIG;IACH,OAAO,CAAC,oBAAoB;IAQ5B;;;;;;;OAOG;IACH,OAAO,CAAC,mBAAmB;IAyB3B;;;;OAIG;IACH,aAAa,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO;IAYxD;;;;;OAKG;IACG,oBAAoB,CAAC,GAAG,EAAE,eAAe,EAAE,GAAG,EAAE,cAAc,EAAE,GAAG,EAAE,GAAG,GAAG,OAAO,CAAC;QAAE,QAAQ,EAAE,OAAO,kBAAkB,EAAE,QAAQ,GAAG,IAAI,CAAC;QAAC,OAAO,EAAE,OAAO,CAAA;KAAE,CAAC;IAuBpK;;;;;;;OAOG;IACG,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAK7C;;;;;;;;OAQG;IACG,iBAAiB,CACrB,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,oBAAoB,GAC5B,OAAO,CAAC,IAAI,CAAC;IAqFhB;;;;;;;;;OASG;IACG,MAAM,CACV,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,oBAAoB,GAC5B,OAAO,CAAC,IAAI,CAAC;IAqGhB;;OAEG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAQ5B;;;;;;OAMG;IACH,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI;CAcpD"}
|
package/dist/server/transport.js
CHANGED
|
@@ -10,6 +10,7 @@ import { createServer } from "node:http";
|
|
|
10
10
|
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
11
11
|
import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
|
|
12
12
|
import { SSEServerTransport } from "@modelcontextprotocol/sdk/server/sse.js";
|
|
13
|
+
import { identityStorage } from "../auth/storage.js";
|
|
13
14
|
/** Default maximum request body size in bytes (4MB). */
|
|
14
15
|
const DEFAULT_MAX_BODY_BYTES = 4 * 1024 * 1024;
|
|
15
16
|
/** Prometheus exposition format content-type. */
|
|
@@ -70,6 +71,10 @@ export class TransportManager {
|
|
|
70
71
|
_metricsCollector;
|
|
71
72
|
/** Optional explorer handler for Tool Explorer UI. */
|
|
72
73
|
_explorerHandler;
|
|
74
|
+
/** Optional authenticator for request authentication. */
|
|
75
|
+
_authenticator;
|
|
76
|
+
/** Configurable set of paths exempt from authentication. */
|
|
77
|
+
_exemptPaths = new Set(["/health", "/metrics"]);
|
|
73
78
|
/**
|
|
74
79
|
* Set the number of registered modules/tools.
|
|
75
80
|
*
|
|
@@ -78,6 +83,22 @@ export class TransportManager {
|
|
|
78
83
|
setModuleCount(count) {
|
|
79
84
|
this._moduleCount = count;
|
|
80
85
|
}
|
|
86
|
+
/**
|
|
87
|
+
* Set the authenticator for request authentication.
|
|
88
|
+
*
|
|
89
|
+
* @param authenticator - An Authenticator instance (e.g. JWTAuthenticator)
|
|
90
|
+
*/
|
|
91
|
+
setAuthenticator(authenticator) {
|
|
92
|
+
this._authenticator = authenticator;
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Set the paths that are exempt from authentication.
|
|
96
|
+
*
|
|
97
|
+
* @param paths - Array of path strings to exempt
|
|
98
|
+
*/
|
|
99
|
+
setExemptPaths(paths) {
|
|
100
|
+
this._exemptPaths = new Set(paths);
|
|
101
|
+
}
|
|
81
102
|
/**
|
|
82
103
|
* Set the metrics collector for Prometheus /metrics endpoint.
|
|
83
104
|
*
|
|
@@ -139,6 +160,48 @@ export class TransportManager {
|
|
|
139
160
|
}
|
|
140
161
|
return false;
|
|
141
162
|
}
|
|
163
|
+
/**
|
|
164
|
+
* Check if a request path/method combination is exempt from authentication.
|
|
165
|
+
*
|
|
166
|
+
* Exempt routes: /health, /metrics (GET), and explorer GET routes.
|
|
167
|
+
*/
|
|
168
|
+
_isAuthExempt(pathname, method) {
|
|
169
|
+
if (method === "GET" && this._exemptPaths.has(pathname))
|
|
170
|
+
return true;
|
|
171
|
+
// Explorer GET routes are exempt (browsing the UI)
|
|
172
|
+
if (this._explorerHandler && method === "GET") {
|
|
173
|
+
const prefix = this._explorerHandler.prefix;
|
|
174
|
+
if (pathname === prefix || pathname === prefix + "/" || pathname.startsWith(prefix + "/")) {
|
|
175
|
+
return true;
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
return false;
|
|
179
|
+
}
|
|
180
|
+
/**
|
|
181
|
+
* Authenticate an incoming request using the configured authenticator.
|
|
182
|
+
*
|
|
183
|
+
* Returns the Identity on success, or sends a 401 response and returns null.
|
|
184
|
+
* If no authenticator is set, returns null (no auth required).
|
|
185
|
+
*/
|
|
186
|
+
async _authenticateRequest(req, res, url) {
|
|
187
|
+
if (!this._authenticator) {
|
|
188
|
+
return { identity: null, blocked: false };
|
|
189
|
+
}
|
|
190
|
+
if (this._isAuthExempt(url.pathname, req.method ?? "GET")) {
|
|
191
|
+
return { identity: null, blocked: false };
|
|
192
|
+
}
|
|
193
|
+
const identity = await this._authenticator.authenticate(req);
|
|
194
|
+
if (!identity) {
|
|
195
|
+
const requireAuth = this._authenticator.requireAuth ?? true;
|
|
196
|
+
if (!requireAuth) {
|
|
197
|
+
return { identity: null, blocked: false };
|
|
198
|
+
}
|
|
199
|
+
res.writeHead(401, { "Content-Type": "application/json", "WWW-Authenticate": "Bearer" });
|
|
200
|
+
res.end(JSON.stringify({ error: "Authentication required" }));
|
|
201
|
+
return { identity: null, blocked: true };
|
|
202
|
+
}
|
|
203
|
+
return { identity, blocked: false };
|
|
204
|
+
}
|
|
142
205
|
/**
|
|
143
206
|
* Run the server using stdio transport.
|
|
144
207
|
*
|
|
@@ -172,10 +235,14 @@ export class TransportManager {
|
|
|
172
235
|
const url = new URL(req.url ?? "/", `http://${options.host}:${options.port}`);
|
|
173
236
|
if (this._handleBuiltinRoute(req, res, url))
|
|
174
237
|
return;
|
|
238
|
+
// Authenticate non-exempt requests
|
|
239
|
+
const { identity, blocked } = await this._authenticateRequest(req, res, url);
|
|
240
|
+
if (blocked)
|
|
241
|
+
return;
|
|
175
242
|
// Check explorer routes before MCP transport
|
|
176
243
|
if (explorerHandler) {
|
|
177
244
|
try {
|
|
178
|
-
const handled = await explorerHandler.handleRequest(req, res, url);
|
|
245
|
+
const handled = await explorerHandler.handleRequest(req, res, url, identity);
|
|
179
246
|
if (handled)
|
|
180
247
|
return;
|
|
181
248
|
}
|
|
@@ -190,29 +257,38 @@ export class TransportManager {
|
|
|
190
257
|
res.writeHead(404).end("Not Found");
|
|
191
258
|
return;
|
|
192
259
|
}
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
else {
|
|
200
|
-
await transport.handleRequest(req, res);
|
|
201
|
-
}
|
|
202
|
-
}
|
|
203
|
-
catch (err) {
|
|
204
|
-
if (!res.headersSent) {
|
|
205
|
-
const message = err instanceof Error ? err.message : "";
|
|
206
|
-
if (message === "Request body too large") {
|
|
207
|
-
res.writeHead(413).end("Request Entity Too Large");
|
|
208
|
-
}
|
|
209
|
-
else if (err instanceof SyntaxError) {
|
|
210
|
-
res.writeHead(400).end("Bad Request");
|
|
260
|
+
const handleMcp = async () => {
|
|
261
|
+
try {
|
|
262
|
+
if (req.method === "POST" || req.method === "DELETE") {
|
|
263
|
+
const body = await readBody(req);
|
|
264
|
+
const parsed = body ? JSON.parse(body) : undefined;
|
|
265
|
+
await transport.handleRequest(req, res, parsed);
|
|
211
266
|
}
|
|
212
267
|
else {
|
|
213
|
-
|
|
268
|
+
await transport.handleRequest(req, res);
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
catch (err) {
|
|
272
|
+
if (!res.headersSent) {
|
|
273
|
+
const message = err instanceof Error ? err.message : "";
|
|
274
|
+
if (message === "Request body too large") {
|
|
275
|
+
res.writeHead(413).end("Request Entity Too Large");
|
|
276
|
+
}
|
|
277
|
+
else if (err instanceof SyntaxError) {
|
|
278
|
+
res.writeHead(400).end("Bad Request");
|
|
279
|
+
}
|
|
280
|
+
else {
|
|
281
|
+
res.writeHead(500).end("Internal Server Error");
|
|
282
|
+
}
|
|
214
283
|
}
|
|
215
284
|
}
|
|
285
|
+
};
|
|
286
|
+
// Wrap in identityStorage so getCurrentIdentity() works in the call chain
|
|
287
|
+
if (identity) {
|
|
288
|
+
await identityStorage.run(identity, handleMcp);
|
|
289
|
+
}
|
|
290
|
+
else {
|
|
291
|
+
await handleMcp();
|
|
216
292
|
}
|
|
217
293
|
});
|
|
218
294
|
this.httpServer = httpServer;
|
|
@@ -245,10 +321,14 @@ export class TransportManager {
|
|
|
245
321
|
const url = new URL(req.url ?? "/", `http://${options.host}:${options.port}`);
|
|
246
322
|
if (this._handleBuiltinRoute(req, res, url))
|
|
247
323
|
return;
|
|
324
|
+
// Authenticate non-exempt requests
|
|
325
|
+
const { identity, blocked } = await this._authenticateRequest(req, res, url);
|
|
326
|
+
if (blocked)
|
|
327
|
+
return;
|
|
248
328
|
// Check explorer routes before SSE transport
|
|
249
329
|
if (explorerHandler) {
|
|
250
330
|
try {
|
|
251
|
-
const handled = await explorerHandler.handleRequest(req, res, url);
|
|
331
|
+
const handled = await explorerHandler.handleRequest(req, res, url, identity);
|
|
252
332
|
if (handled)
|
|
253
333
|
return;
|
|
254
334
|
}
|
|
@@ -259,51 +339,60 @@ export class TransportManager {
|
|
|
259
339
|
return;
|
|
260
340
|
}
|
|
261
341
|
}
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
else if (url.pathname === messagesEndpoint && req.method === "POST") {
|
|
274
|
-
// Route message to the correct session transport
|
|
275
|
-
const sessionId = url.searchParams.get("sessionId");
|
|
276
|
-
if (!sessionId) {
|
|
277
|
-
res.writeHead(400).end("Missing sessionId parameter");
|
|
278
|
-
return;
|
|
279
|
-
}
|
|
280
|
-
const transport = transports.get(sessionId);
|
|
281
|
-
if (!transport) {
|
|
282
|
-
res.writeHead(400).end("Unknown session");
|
|
283
|
-
return;
|
|
284
|
-
}
|
|
285
|
-
try {
|
|
286
|
-
const body = await readBody(req);
|
|
287
|
-
const parsed = body ? JSON.parse(body) : undefined;
|
|
288
|
-
await transport.handlePostMessage(req, res, parsed);
|
|
342
|
+
const handleSse = async () => {
|
|
343
|
+
if (url.pathname === endpoint && req.method === "GET") {
|
|
344
|
+
// Establish SSE connection
|
|
345
|
+
const transport = new SSEServerTransport(messagesEndpoint, res);
|
|
346
|
+
const sessionId = transport.sessionId;
|
|
347
|
+
transports.set(sessionId, transport);
|
|
348
|
+
transport.onclose = () => {
|
|
349
|
+
transports.delete(sessionId);
|
|
350
|
+
};
|
|
351
|
+
await server.connect(transport);
|
|
352
|
+
await transport.start();
|
|
289
353
|
}
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
354
|
+
else if (url.pathname === messagesEndpoint && req.method === "POST") {
|
|
355
|
+
// Route message to the correct session transport
|
|
356
|
+
const sessionId = url.searchParams.get("sessionId");
|
|
357
|
+
if (!sessionId) {
|
|
358
|
+
res.writeHead(400).end("Missing sessionId parameter");
|
|
359
|
+
return;
|
|
360
|
+
}
|
|
361
|
+
const transport = transports.get(sessionId);
|
|
362
|
+
if (!transport) {
|
|
363
|
+
res.writeHead(400).end("Unknown session");
|
|
364
|
+
return;
|
|
365
|
+
}
|
|
366
|
+
try {
|
|
367
|
+
const body = await readBody(req);
|
|
368
|
+
const parsed = body ? JSON.parse(body) : undefined;
|
|
369
|
+
await transport.handlePostMessage(req, res, parsed);
|
|
370
|
+
}
|
|
371
|
+
catch (err) {
|
|
372
|
+
if (!res.headersSent) {
|
|
373
|
+
const message = err instanceof Error ? err.message : "";
|
|
374
|
+
if (message === "Request body too large") {
|
|
375
|
+
res.writeHead(413).end("Request Entity Too Large");
|
|
376
|
+
}
|
|
377
|
+
else if (err instanceof SyntaxError) {
|
|
378
|
+
res.writeHead(400).end("Bad Request");
|
|
379
|
+
}
|
|
380
|
+
else {
|
|
381
|
+
res.writeHead(500).end("Internal Server Error");
|
|
382
|
+
}
|
|
301
383
|
}
|
|
302
384
|
}
|
|
303
385
|
}
|
|
386
|
+
else {
|
|
387
|
+
res.writeHead(404).end("Not Found");
|
|
388
|
+
}
|
|
389
|
+
};
|
|
390
|
+
// Wrap in identityStorage so getCurrentIdentity() works in the call chain
|
|
391
|
+
if (identity) {
|
|
392
|
+
await identityStorage.run(identity, handleSse);
|
|
304
393
|
}
|
|
305
394
|
else {
|
|
306
|
-
|
|
395
|
+
await handleSse();
|
|
307
396
|
}
|
|
308
397
|
});
|
|
309
398
|
this.httpServer = httpServer;
|