mcpose 2.1.1 → 3.1.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 +461 -62
- package/dist/backendClient.d.ts +1 -1
- package/dist/backendClient.d.ts.map +1 -1
- package/dist/backendClient.js +6 -1
- package/dist/backendClient.js.map +1 -1
- package/dist/core.d.ts +309 -35
- package/dist/core.d.ts.map +1 -1
- package/dist/core.js +1023 -186
- package/dist/core.js.map +1 -1
- package/dist/delegation.d.ts +89 -0
- package/dist/delegation.d.ts.map +1 -0
- package/dist/delegation.js +175 -0
- package/dist/delegation.js.map +1 -0
- package/dist/eventStore.d.ts +12 -0
- package/dist/eventStore.d.ts.map +1 -1
- package/dist/eventStore.js +43 -5
- package/dist/eventStore.js.map +1 -1
- package/dist/hiddenTools.d.ts +42 -0
- package/dist/hiddenTools.d.ts.map +1 -0
- package/dist/hiddenTools.js +53 -0
- package/dist/hiddenTools.js.map +1 -0
- package/dist/index.d.ts +15 -6
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +7 -3
- package/dist/index.js.map +1 -1
- package/dist/mesh.d.ts +82 -0
- package/dist/mesh.d.ts.map +1 -0
- package/dist/mesh.js +141 -0
- package/dist/mesh.js.map +1 -0
- package/dist/middleware.d.ts +13 -0
- package/dist/middleware.d.ts.map +1 -1
- package/dist/middleware.js +27 -3
- package/dist/middleware.js.map +1 -1
- package/dist/proxyContext.d.ts +65 -5
- package/dist/proxyContext.d.ts.map +1 -1
- package/dist/proxyContext.js +39 -4
- package/dist/proxyContext.js.map +1 -1
- package/dist/rejection.d.ts +7 -1
- package/dist/rejection.d.ts.map +1 -1
- package/dist/rejection.js +24 -1
- package/dist/rejection.js.map +1 -1
- package/dist/sanitizeCatalog.d.ts +37 -0
- package/dist/sanitizeCatalog.d.ts.map +1 -0
- package/dist/sanitizeCatalog.js +92 -0
- package/dist/sanitizeCatalog.js.map +1 -0
- package/dist/sessionRegistry.d.ts +79 -0
- package/dist/sessionRegistry.d.ts.map +1 -0
- package/dist/sessionRegistry.js +83 -0
- package/dist/sessionRegistry.js.map +1 -0
- package/dist/telemetry.d.ts +29 -1
- package/dist/telemetry.d.ts.map +1 -1
- package/dist/testing.d.ts +18 -2
- package/dist/testing.d.ts.map +1 -1
- package/dist/testing.js +30 -8
- package/dist/testing.js.map +1 -1
- package/dist/version.d.ts +7 -0
- package/dist/version.d.ts.map +1 -0
- package/dist/version.js +7 -0
- package/dist/version.js.map +1 -0
- package/package.json +22 -8
- package/src/__tests__/_helpers.ts +64 -0
- package/src/__tests__/backendClient.test.ts +198 -0
- package/src/__tests__/core.delegation.test.ts +964 -0
- package/src/__tests__/core.edge.test.ts +314 -0
- package/src/__tests__/core.hiddenTools.predicate.test.ts +236 -0
- package/src/__tests__/core.localTools.test.ts +314 -0
- package/src/__tests__/core.mesh.test.ts +1182 -0
- package/src/__tests__/core.stripRequestMeta.test.ts +226 -0
- package/src/__tests__/core.stripResultMeta.test.ts +217 -0
- package/src/__tests__/core.test.ts +1105 -0
- package/src/__tests__/core.toolCallTelemetry.test.ts +157 -0
- package/src/__tests__/eventStore.test.ts +141 -0
- package/src/__tests__/hasToolContent.test.ts +63 -0
- package/src/__tests__/mapToolResult.test.ts +101 -0
- package/src/__tests__/middleware.edge.test.ts +126 -0
- package/src/__tests__/middleware.test.ts +233 -0
- package/src/__tests__/proxyContext.test.ts +140 -0
- package/src/__tests__/sanitizeCatalog.test.ts +380 -0
- package/src/__tests__/startHttpProxy.lifecycle.test.ts +675 -0
- package/src/__tests__/startHttpProxy.registry.test.ts +409 -0
- package/src/__tests__/startHttpProxy.replay.test.ts +116 -0
- package/src/__tests__/startHttpProxy.security.test.ts +288 -0
- package/src/__tests__/startHttpProxy.test.ts +1065 -0
- package/src/__tests__/testing.test.ts +250 -0
- package/src/__tests__/version.test.ts +12 -0
- package/src/backendClient.ts +83 -0
- package/src/core.ts +2129 -0
- package/src/delegation.ts +224 -0
- package/src/eventStore.ts +106 -0
- package/src/hiddenTools.ts +84 -0
- package/src/identity.ts +15 -0
- package/src/index.ts +63 -0
- package/src/mesh.ts +204 -0
- package/src/middleware.ts +101 -0
- package/src/proxyContext.ts +108 -0
- package/src/rejection.ts +62 -0
- package/src/sanitizeCatalog.ts +126 -0
- package/src/sessionRegistry.ts +142 -0
- package/src/telemetry.ts +46 -0
- package/src/testing.ts +174 -0
- package/src/version.ts +6 -0
package/dist/backendClient.d.ts
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* Backend MCP client factory.
|
|
3
3
|
* Modes: stdio (spawns child process) or HTTP/SSE (connects to running server).
|
|
4
4
|
*/
|
|
5
|
-
import { OAuthClientProvider } from '@modelcontextprotocol/sdk/client/auth';
|
|
5
|
+
import type { OAuthClientProvider } from '@modelcontextprotocol/sdk/client/auth.js';
|
|
6
6
|
import { Client } from '@modelcontextprotocol/sdk/client/index.js';
|
|
7
7
|
/** Backend connection config. */
|
|
8
8
|
export interface BackendConfig {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"backendClient.d.ts","sourceRoot":"","sources":["../src/backendClient.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,EAAE,mBAAmB,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"backendClient.d.ts","sourceRoot":"","sources":["../src/backendClient.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,0CAA0C,CAAC;AACpF,OAAO,EAAE,MAAM,EAAE,MAAM,2CAA2C,CAAC;AASnE,iCAAiC;AACjC,MAAM,WAAW,aAAa;IAC5B,4EAA4E;IAC5E,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,+DAA+D;IAC/D,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,oEAAoE;IACpE,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,gFAAgF;IAChF,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,+FAA+F;IAC/F,YAAY,CAAC,EAAE,mBAAmB,CAAC;CACpC;AAED,MAAM,MAAM,aAAa,GAAG,MAAM,CAAC;AAEnC;;;GAGG;AACH,wBAAsB,mBAAmB,CACvC,MAAM,EAAE,aAAa,GACpB,OAAO,CAAC,aAAa,CAAC,CAyBxB"}
|
package/dist/backendClient.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { Client } from '@modelcontextprotocol/sdk/client/index.js';
|
|
2
2
|
import { StdioClientTransport } from '@modelcontextprotocol/sdk/client/stdio.js';
|
|
3
3
|
import { StreamableHTTPClientTransport, } from '@modelcontextprotocol/sdk/client/streamableHttp.js';
|
|
4
|
+
import { VERSION } from './version.js';
|
|
4
5
|
/**
|
|
5
6
|
* Creates and connects an MCP client to the backend.
|
|
6
7
|
* @throws If neither `command` nor `url` provided, or connection fails.
|
|
@@ -9,13 +10,17 @@ export async function createBackendClient(config) {
|
|
|
9
10
|
if (!config.command && !config.url) {
|
|
10
11
|
throw new Error('mcpose: either command or url must be provided in BackendConfig');
|
|
11
12
|
}
|
|
12
|
-
const client = new Client({ name: 'mcpose-backend', version:
|
|
13
|
+
const client = new Client({ name: 'mcpose-backend', version: VERSION }, { capabilities: {} });
|
|
13
14
|
const transport = config.url
|
|
14
15
|
? getHttpTransport(config.url, config.headers, config.authProvider)
|
|
15
16
|
: new StdioClientTransport({
|
|
16
17
|
command: config.command,
|
|
17
18
|
args: config.args ?? [],
|
|
18
19
|
});
|
|
20
|
+
// The SDK's own transports are not assignable to its own `Transport`
|
|
21
|
+
// interface under `exactOptionalPropertyTypes` (the interface declares
|
|
22
|
+
// `sessionId?: string`, the implementations `sessionId: string | undefined`).
|
|
23
|
+
// Purely a declaration mismatch upstream — the value is a real Transport.
|
|
19
24
|
await client.connect(transport);
|
|
20
25
|
return client;
|
|
21
26
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"backendClient.js","sourceRoot":"","sources":["../src/backendClient.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,MAAM,EAAE,MAAM,2CAA2C,CAAC;AACnE,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AACjF,OAAO,EACL,6BAA6B,GAE9B,MAAM,oDAAoD,CAAC;
|
|
1
|
+
{"version":3,"file":"backendClient.js","sourceRoot":"","sources":["../src/backendClient.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,MAAM,EAAE,MAAM,2CAA2C,CAAC;AACnE,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AACjF,OAAO,EACL,6BAA6B,GAE9B,MAAM,oDAAoD,CAAC;AAE5D,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAkBvC;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,mBAAmB,CACvC,MAAqB;IAErB,IAAI,CAAC,MAAM,CAAC,OAAO,IAAI,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC;QACnC,MAAM,IAAI,KAAK,CACb,iEAAiE,CAClE,CAAC;IACJ,CAAC;IAED,MAAM,MAAM,GAAG,IAAI,MAAM,CACvB,EAAE,IAAI,EAAE,gBAAgB,EAAE,OAAO,EAAE,OAAO,EAAE,EAC5C,EAAE,YAAY,EAAE,EAAE,EAAE,CACrB,CAAC;IAEF,MAAM,SAAS,GAAG,MAAM,CAAC,GAAG;QAC1B,CAAC,CAAC,gBAAgB,CAAC,MAAM,CAAC,GAAG,EAAE,MAAM,CAAC,OAAO,EAAE,MAAM,CAAC,YAAY,CAAC;QACnE,CAAC,CAAC,IAAI,oBAAoB,CAAC;YACvB,OAAO,EAAE,MAAM,CAAC,OAAQ;YACxB,IAAI,EAAE,MAAM,CAAC,IAAI,IAAI,EAAE;SACxB,CAAC,CAAC;IAEP,qEAAqE;IACrE,uEAAuE;IACvE,8EAA8E;IAC9E,0EAA0E;IAC1E,MAAM,MAAM,CAAC,OAAO,CAAC,SAAsB,CAAC,CAAC;IAC7C,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,MAAM,gBAAgB,GAAG,CACvB,SAAiB,EACjB,OAAgC,EAChC,YAAkC,EAClC,EAAE;IACF,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,SAAS,CAAC,CAAC;IAC/B,IAAI,GAAG,CAAC,QAAQ,KAAK,OAAO,IAAI,GAAG,CAAC,QAAQ,KAAK,QAAQ,EAAE,CAAC;QAC1D,MAAM,IAAI,KAAK,CACb,qCAAqC,GAAG,CAAC,QAAQ,uCAAuC,CACzF,CAAC;IACJ,CAAC;IACD,MAAM,IAAI,GAAkD,EAAE,CAAC;IAC/D,IAAI,OAAO,EAAE,CAAC;QACZ,IAAI,CAAC,WAAW,GAAG,EAAE,OAAO,EAAE,CAAC;IACjC,CAAC;IACD,IAAI,YAAY,EAAE,CAAC;QACjB,IAAI,CAAC,YAAY,GAAG,YAAY,CAAC;IACnC,CAAC;IACD,OAAO,IAAI,6BAA6B,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;AACtD,CAAC,CAAC"}
|
package/dist/core.d.ts
CHANGED
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
import * as http from 'node:http';
|
|
2
2
|
import * as https from 'node:https';
|
|
3
3
|
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
|
|
4
|
-
import { type ListToolsRequest, type ListToolsResult, type CallToolRequest, type CallToolResult, type CompatibilityCallToolResult, type ReadResourceRequest, type ReadResourceResult } from '@modelcontextprotocol/sdk/types.js';
|
|
4
|
+
import { type ListToolsRequest, type ListToolsResult, type CallToolRequest, type CallToolRequestParams, type CallToolResult, type CompatibilityCallToolResult, type ContentBlock, type GetPromptRequest, type GetPromptResult, type TextContent, type ReadResourceRequest, type ReadResourceResult, type Tool } from '@modelcontextprotocol/sdk/types.js';
|
|
5
5
|
import { type Middleware } from './middleware.js';
|
|
6
|
-
import type {
|
|
6
|
+
import type { HiddenToolPredicate } from './hiddenTools.js';
|
|
7
|
+
import { type ProxyContext } from './proxyContext.js';
|
|
7
8
|
import type { Identity } from './identity.js';
|
|
8
9
|
import type { TelemetryEvent } from './telemetry.js';
|
|
10
|
+
import { type Backends } from './mesh.js';
|
|
11
|
+
import { type SessionRegistry } from './sessionRegistry.js';
|
|
9
12
|
import type { EventStore } from '@modelcontextprotocol/sdk/server/streamableHttp.js';
|
|
10
|
-
export type { ProxyContext } from './proxyContext.js';
|
|
11
13
|
/**
|
|
12
14
|
* Middleware for tool calls.
|
|
13
15
|
* Uses `CompatibilityCallToolResult` to cover legacy `{ toolResult }` shape
|
|
@@ -16,30 +18,122 @@ export type { ProxyContext } from './proxyContext.js';
|
|
|
16
18
|
export type ToolMiddleware = Middleware<CallToolRequest, CompatibilityCallToolResult>;
|
|
17
19
|
/** Middleware for resource reads. */
|
|
18
20
|
export type ResourceMiddleware = Middleware<ReadResourceRequest, ReadResourceResult>;
|
|
21
|
+
/** Middleware for prompt fetches (`prompts/get`). */
|
|
22
|
+
export type PromptMiddleware = Middleware<GetPromptRequest, GetPromptResult>;
|
|
19
23
|
/** Middleware for tool-list responses. */
|
|
20
24
|
export type ListToolsMiddleware = Middleware<ListToolsRequest, ListToolsResult>;
|
|
21
25
|
/**
|
|
22
|
-
*
|
|
23
|
-
*
|
|
26
|
+
* The result channels of a `CallToolResult` — everything a redaction or
|
|
27
|
+
* transform middleware must account for:
|
|
28
|
+
*
|
|
29
|
+
* 1. `content` blocks (text, image, audio, resource link, embedded
|
|
30
|
+
* resource), each carrying its own block-level `_meta`,
|
|
31
|
+
* 2. `structuredContent`, the machine-readable mirror of the content,
|
|
32
|
+
* 3. result-level `_meta`,
|
|
33
|
+
* 4. `isError`,
|
|
34
|
+
* 5. unknown extra keys via the index signature.
|
|
35
|
+
*
|
|
36
|
+
* Redaction that maps only `.content` misses 2, 3, and the non-text
|
|
37
|
+
* members of 1. Use {@link mapToolResult} to cover every payload channel
|
|
38
|
+
* by construction; channel 3 is stripped at the proxy boundary by default
|
|
39
|
+
* via `ProxyOptions.stripResultMeta` (ADR-0009).
|
|
40
|
+
*
|
|
41
|
+
* This guard narrows `CompatibilityCallToolResult` to `CallToolResult`
|
|
42
|
+
* (has `.content` array). Both union members carry `[x: string]: unknown`,
|
|
43
|
+
* so this avoids unsafe casts.
|
|
44
|
+
*
|
|
45
|
+
* A guard, not an assertion: the union's two members are both objects, but a
|
|
46
|
+
* pipeline result is not the union. The legacy shape has no `.content`, and a
|
|
47
|
+
* handler that produced nothing at all (a local tool with a missing `return`,
|
|
48
|
+
* or a middleware that dropped the result) produces a nullish one, which has
|
|
49
|
+
* none either. Both answer `false` here. Throwing instead replaced whatever
|
|
50
|
+
* the pipeline produced with `TypeError: Cannot read properties of undefined
|
|
51
|
+
* (reading 'content')` — inside `mapToolResult`, and inside the `tools/call`
|
|
52
|
+
* handler's telemetry read of `result.isError`.
|
|
24
53
|
*/
|
|
25
54
|
export declare function hasToolContent(r: CompatibilityCallToolResult): r is CallToolResult;
|
|
55
|
+
/**
|
|
56
|
+
* Handlers for {@link mapToolResult}, one per payload channel. All three
|
|
57
|
+
* are required, so forgetting a channel is a compile error rather than a
|
|
58
|
+
* silent leak.
|
|
59
|
+
*/
|
|
60
|
+
export interface ToolResultHandlers {
|
|
61
|
+
/** Maps a text content block. Return `null` to drop the block. */
|
|
62
|
+
onText: (block: TextContent) => ContentBlock | null;
|
|
63
|
+
/**
|
|
64
|
+
* Maps a non-text content block (image, audio, resource link, embedded
|
|
65
|
+
* resource). Return `null` to drop the block.
|
|
66
|
+
*/
|
|
67
|
+
onOther: (block: Exclude<ContentBlock, TextContent>) => ContentBlock | null;
|
|
68
|
+
/**
|
|
69
|
+
* Maps `structuredContent`. Called only when the field is present.
|
|
70
|
+
* Return `undefined` to remove the field entirely.
|
|
71
|
+
*/
|
|
72
|
+
onStructured: (structured: Record<string, unknown>) => Record<string, unknown> | undefined;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Maps every payload channel of a tool result through the given handlers.
|
|
76
|
+
*
|
|
77
|
+
* The legacy `{ toolResult }` shape (protocol 2024-10-07) is returned
|
|
78
|
+
* untouched. `isError`, result-level `_meta`, and unknown extra keys are
|
|
79
|
+
* preserved by spread — result-level `_meta` needs no handler because the
|
|
80
|
+
* proxy strips it by default (`stripResultMeta`, ADR-0009); with
|
|
81
|
+
* `stripResultMeta: false` forwarding it is the consumer's explicit choice.
|
|
82
|
+
*/
|
|
83
|
+
export declare function mapToolResult(result: CompatibilityCallToolResult, handlers: ToolResultHandlers): CompatibilityCallToolResult;
|
|
26
84
|
/** HTTP transport options for {@link startHttpProxy}. */
|
|
27
85
|
export interface HttpProxyOptions {
|
|
28
86
|
/** Default: 3000 */
|
|
29
87
|
port?: number;
|
|
30
|
-
/**
|
|
88
|
+
/**
|
|
89
|
+
* Bind address. Default: `'127.0.0.1'` (loopback).
|
|
90
|
+
*
|
|
91
|
+
* Binding a non-loopback address (e.g. `'0.0.0.0'`) exposes an
|
|
92
|
+
* unauthenticated MCP proxy holding an authenticated upstream session to
|
|
93
|
+
* the network, so it is a deliberate opt-in; doing so without
|
|
94
|
+
* {@link resolveIdentity} reports a startup warning through {@link onError}.
|
|
95
|
+
*/
|
|
31
96
|
host?: string;
|
|
32
97
|
/** Default: '/mcp' */
|
|
33
98
|
path?: string;
|
|
34
|
-
/**
|
|
99
|
+
/**
|
|
100
|
+
* Called for every incoming request before MCP handling. Return false to
|
|
101
|
+
* block (caller writes its own response). Throw to get a 401, with the error
|
|
102
|
+
* reported through {@link onError}.
|
|
103
|
+
*/
|
|
35
104
|
onRequest?: (req: http.IncomingMessage, res: http.ServerResponse) => boolean | Promise<boolean>;
|
|
36
|
-
/**
|
|
37
|
-
|
|
38
|
-
|
|
105
|
+
/**
|
|
106
|
+
* Called on unhandled errors instead of console.error, and on every auth
|
|
107
|
+
* hook that throws: the request still fails closed, and the operator still
|
|
108
|
+
* sees why. If this hook itself throws or returns a rejected promise, the
|
|
109
|
+
* failure is contained and changes nothing the caller sees.
|
|
110
|
+
*/
|
|
111
|
+
onError?: (err: unknown) => unknown;
|
|
112
|
+
/**
|
|
113
|
+
* Maximum request body size in bytes. Excess POST bodies return 413.
|
|
114
|
+
* Default: 4 MB. Set to `Infinity` to opt out of the cap.
|
|
115
|
+
*
|
|
116
|
+
* `0` is a valid value and means "reject every POST body", so it is not the
|
|
117
|
+
* opt-out. The two shapes that are mistakes rather than choices throw at
|
|
118
|
+
* startup: a negative number returns 413 for every POST, and `NaN`, which is
|
|
119
|
+
* what `Number(process.env.MAX_BODY_BYTES)` returns for an unset key,
|
|
120
|
+
* compares false against every body size and so gates nothing at all.
|
|
121
|
+
*/
|
|
39
122
|
maxBodyBytes?: number;
|
|
40
|
-
/**
|
|
123
|
+
/**
|
|
124
|
+
* Maximum number of concurrent MCP sessions. Excess requests return 503.
|
|
125
|
+
* Default: 1000. Set to `Infinity` to opt out of the cap.
|
|
126
|
+
*
|
|
127
|
+
* `0` is a valid value and means "reject every session", so it is not the
|
|
128
|
+
* opt-out.
|
|
129
|
+
*/
|
|
41
130
|
maxSessions?: number;
|
|
42
|
-
/**
|
|
131
|
+
/**
|
|
132
|
+
* Session TTL in milliseconds. Sessions are closed after this duration,
|
|
133
|
+
* which fires {@link onSessionClosed}. Default: 30 minutes. Finite values
|
|
134
|
+
* must not exceed Node's maximum timer delay of 2,147,483,647 ms. Set to
|
|
135
|
+
* `Infinity` to opt out of the TTL.
|
|
136
|
+
*/
|
|
43
137
|
sessionTtlMs?: number;
|
|
44
138
|
/**
|
|
45
139
|
* Resolves caller identity from the initial session request.
|
|
@@ -48,7 +142,7 @@ export interface HttpProxyOptions {
|
|
|
48
142
|
*
|
|
49
143
|
* Supply a JWT extractor, mTLS cert reader, API-key lookup, or any async
|
|
50
144
|
* function returning an {@link Identity}. Errors thrown here abort the
|
|
51
|
-
* session with a 401.
|
|
145
|
+
* session with a 401 and are reported through {@link onError}.
|
|
52
146
|
*
|
|
53
147
|
* @example
|
|
54
148
|
* resolveIdentity: extractJwtIdentity({ jwksUri: '...' })
|
|
@@ -73,27 +167,112 @@ export interface HttpProxyOptions {
|
|
|
73
167
|
* (suitable for single-instance deployments). For multi-instance / HA
|
|
74
168
|
* deployments, supply a Redis or Postgres-backed implementation.
|
|
75
169
|
*
|
|
170
|
+
* Stream ids reach the store namespaced as `<sessionId>:<streamId>`, so
|
|
171
|
+
* one store serves every session without their replay histories mixing.
|
|
172
|
+
*
|
|
76
173
|
* Set to `null` to disable reconnect replay entirely.
|
|
77
174
|
*/
|
|
78
175
|
eventStore?: EventStore | null;
|
|
79
176
|
/**
|
|
80
|
-
*
|
|
81
|
-
*
|
|
82
|
-
*
|
|
177
|
+
* Shared record of live sessions, so a client can resume after a proxy
|
|
178
|
+
* restart or on another instance behind a load balancer. Without one,
|
|
179
|
+
* sessions live only in this process and a resume against a fresh process
|
|
180
|
+
* is a 404.
|
|
181
|
+
*
|
|
182
|
+
* A record is written before the initialize response goes out and read
|
|
183
|
+
* only for an `mcp-session-id` this instance does not hold; the resumed
|
|
184
|
+
* session negotiates what the original did, keeps its identity, and dies
|
|
185
|
+
* at the original deadline. Client DELETE and TTL expiry delete the
|
|
186
|
+
* record, server shutdown keeps it. Pair it with the matching
|
|
187
|
+
* {@link eventStore} adapter, or a resumed session has no replay history.
|
|
188
|
+
*
|
|
189
|
+
* @example
|
|
190
|
+
* sessionRegistry: createRedisSessionRegistry(redis),
|
|
191
|
+
* eventStore: createRedisEventStore(redis),
|
|
192
|
+
*/
|
|
193
|
+
sessionRegistry?: SessionRegistry;
|
|
194
|
+
/**
|
|
195
|
+
* Called when a session is closed (client DELETE, TTL expiry, or server
|
|
196
|
+
* shutdown). Wire {@link AuditMiddlewareHandle.closeSession} here to flush
|
|
197
|
+
* the ReplayManifest for the session.
|
|
198
|
+
*
|
|
199
|
+
* A returned promise is awaited: `server.close()` does not complete until
|
|
200
|
+
* every session's hook has settled, so a host that exits in the close
|
|
201
|
+
* callback never loses a final manifest. A throw or a rejection is routed
|
|
202
|
+
* to {@link onError} and never breaks teardown.
|
|
83
203
|
*
|
|
84
204
|
* @example
|
|
85
205
|
* onSessionClosed: (sessionId) => auditHandle.closeSession(sessionId)
|
|
86
206
|
*/
|
|
87
|
-
onSessionClosed?: (sessionId: string) =>
|
|
207
|
+
onSessionClosed?: (sessionId: string) => unknown;
|
|
208
|
+
/**
|
|
209
|
+
* Re-validates an existing session on every routed request. Return `false`
|
|
210
|
+
* (or throw, which is reported through {@link onError}) to reject with 401.
|
|
211
|
+
* Use to bind sessions to their original credential — e.g. re-check the
|
|
212
|
+
* bearer token — so a leaked `mcp-session-id` alone cannot take over a
|
|
213
|
+
* session.
|
|
214
|
+
*/
|
|
215
|
+
validateSession?: (req: http.IncomingMessage, session: {
|
|
216
|
+
sessionId: string;
|
|
217
|
+
identity?: Identity;
|
|
218
|
+
}) => boolean | Promise<boolean>;
|
|
219
|
+
/**
|
|
220
|
+
* Hosts allowed in the `Host` header when
|
|
221
|
+
* {@link enableDnsRebindingProtection} is on. Forwarded to the SDK
|
|
222
|
+
* transport, which only validates against a non-empty list.
|
|
223
|
+
*
|
|
224
|
+
* Default: for a loopback bind, derived from the effective bind address
|
|
225
|
+
* and the real listening port (`127.0.0.1:<port>`, `localhost:<port>`,
|
|
226
|
+
* `[::1]:<port>`). An explicit value is used verbatim, never merged with
|
|
227
|
+
* the derived list. No list is derived for a non-loopback bind.
|
|
228
|
+
*/
|
|
229
|
+
allowedHosts?: string[];
|
|
230
|
+
/**
|
|
231
|
+
* Origins allowed in the `Origin` header. Forwarded to the SDK transport,
|
|
232
|
+
* which only validates against a non-empty list.
|
|
233
|
+
*
|
|
234
|
+
* Default: for a loopback bind, the derived {@link allowedHosts} entries
|
|
235
|
+
* as origins (`http://` or `https://` matching {@link tlsOptions}). An
|
|
236
|
+
* explicit value is used verbatim, never merged.
|
|
237
|
+
*/
|
|
238
|
+
allowedOrigins?: string[];
|
|
239
|
+
/**
|
|
240
|
+
* Enables the SDK transport's DNS-rebinding protection (Host/Origin
|
|
241
|
+
* checks). Default: `true` when the effective bind address is loopback,
|
|
242
|
+
* `false` otherwise (a non-loopback bind usually sits behind a gateway
|
|
243
|
+
* that rewrites `Host`).
|
|
244
|
+
*
|
|
245
|
+
* Enabling this on a non-loopback bind without explicit
|
|
246
|
+
* {@link allowedHosts} / {@link allowedOrigins} validates nothing and
|
|
247
|
+
* reports a startup warning through {@link onError}.
|
|
248
|
+
*/
|
|
249
|
+
enableDnsRebindingProtection?: boolean;
|
|
250
|
+
}
|
|
251
|
+
/**
|
|
252
|
+
* A tool the proxy implements itself, instead of forwarding to the
|
|
253
|
+
* upstream. See ADR-0007.
|
|
254
|
+
*/
|
|
255
|
+
export interface LocalTool {
|
|
256
|
+
/** The tool definition advertised in `tools/list`. */
|
|
257
|
+
tool: Tool;
|
|
258
|
+
/**
|
|
259
|
+
* Runs instead of the upstream call, from inside the innermost `next`,
|
|
260
|
+
* so the whole `toolMiddleware` pipeline (audit, redaction) still
|
|
261
|
+
* applies.
|
|
262
|
+
*/
|
|
263
|
+
handler: (params: CallToolRequestParams, context: ProxyContext) => Promise<CallToolResult>;
|
|
88
264
|
}
|
|
89
265
|
/** Proxy server options. */
|
|
90
266
|
export interface ProxyOptions {
|
|
91
267
|
/**
|
|
92
|
-
* Human-readable name for this proxy instance.
|
|
93
|
-
*
|
|
94
|
-
*
|
|
268
|
+
* Human-readable name for this proxy instance. Required, and rejected at
|
|
269
|
+
* construction when empty or whitespace-only.
|
|
270
|
+
*
|
|
271
|
+
* It is stamped onto every `ProxyContext`, every audit event, and the
|
|
272
|
+
* `ReplayManifest` as provenance (ADR-0012), so a default would record a
|
|
273
|
+
* whole fleet under one name: attribution in appearance only (#122).
|
|
95
274
|
*/
|
|
96
|
-
name
|
|
275
|
+
name: string;
|
|
97
276
|
/**
|
|
98
277
|
* Version of this proxy server (yours, not the mcpose library). MCP clients see
|
|
99
278
|
* it in the `initialize` response. Defaults to the mcpose library version when
|
|
@@ -107,43 +286,138 @@ export interface ProxyOptions {
|
|
|
107
286
|
toolMiddleware?: ReadonlyArray<ToolMiddleware>;
|
|
108
287
|
/** Resource middleware in response-processing order (first = innermost). */
|
|
109
288
|
resourceMiddleware?: ReadonlyArray<ResourceMiddleware>;
|
|
289
|
+
/**
|
|
290
|
+
* Prompt middleware in response-processing order (first = innermost),
|
|
291
|
+
* per ADR-0002. Runs around every `prompts/get`, in both 1:1 and mesh
|
|
292
|
+
* mode.
|
|
293
|
+
*
|
|
294
|
+
* Mesh routing and the `BACKEND_UNROUTABLE` rejection for an unroutable
|
|
295
|
+
* prompt name happen inside the innermost `next` (the ADR-0007 pattern),
|
|
296
|
+
* so an observing middleware such as audit records every prompt call
|
|
297
|
+
* including the rejected ones.
|
|
298
|
+
*
|
|
299
|
+
* `prompts/list` has no pipeline yet; hiding and pass-through for prompts
|
|
300
|
+
* are deferred with it (ADR-0014).
|
|
301
|
+
*/
|
|
302
|
+
promptMiddleware?: ReadonlyArray<PromptMiddleware>;
|
|
110
303
|
/** Tool-list middleware in response-processing order (first = innermost). */
|
|
111
304
|
listToolsMiddleware?: ReadonlyArray<ListToolsMiddleware>;
|
|
112
|
-
/**
|
|
305
|
+
/**
|
|
306
|
+
* Tools that skip transforming middleware — upstream response forwarded
|
|
307
|
+
* as-is. Middleware wrapped in `markPassThroughObserver()` (e.g. audit)
|
|
308
|
+
* still runs for these tools.
|
|
309
|
+
*/
|
|
113
310
|
passThroughTools?: ReadonlyArray<string>;
|
|
114
|
-
/**
|
|
311
|
+
/**
|
|
312
|
+
* Resources that skip middleware — upstream response forwarded as-is.
|
|
313
|
+
* Matched against the URI the client sees, which in mesh mode is
|
|
314
|
+
* `mcpose://<backendKey>/<uri>` (ADR-0022).
|
|
315
|
+
*/
|
|
115
316
|
passThroughResources?: ReadonlyArray<string>;
|
|
116
|
-
/**
|
|
117
|
-
|
|
118
|
-
|
|
317
|
+
/**
|
|
318
|
+
* Tools hidden from list_tools and rejected at runtime with
|
|
319
|
+
* MethodNotFound. Precedence: a tool listed here AND in
|
|
320
|
+
* `passThroughTools` stays hidden. Hidden filtering is applied both
|
|
321
|
+
* before and after `listToolsMiddleware`, so list middleware cannot
|
|
322
|
+
* re-expose a hidden tool.
|
|
323
|
+
*
|
|
324
|
+
* A name array cannot see through a dispatcher (meta-tool) that takes
|
|
325
|
+
* the real tool name as an argument. Pass a {@link HiddenToolPredicate}
|
|
326
|
+
* (e.g. {@link dispatcherAwareBlock}) to close that bypass: it receives
|
|
327
|
+
* `undefined` args during list filtering and always an object at call
|
|
328
|
+
* time. See ADR-0006.
|
|
329
|
+
*/
|
|
330
|
+
hiddenTools?: ReadonlyArray<string> | HiddenToolPredicate;
|
|
331
|
+
/**
|
|
332
|
+
* Resources hidden from list_resources and rejected at runtime with
|
|
333
|
+
* InvalidRequest. Matched against the URI the client sees, which in mesh
|
|
334
|
+
* mode is `mcpose://<backendKey>/<uri>` (ADR-0022).
|
|
335
|
+
*/
|
|
119
336
|
hiddenResources?: ReadonlyArray<string>;
|
|
120
337
|
/**
|
|
121
|
-
*
|
|
122
|
-
*
|
|
123
|
-
*
|
|
338
|
+
* Strips `params._meta` from every request the proxy forwards (tool
|
|
339
|
+
* calls, resource reads, list and prompt calls). Default: `true`.
|
|
340
|
+
*
|
|
341
|
+
* MCP clients put correlation identifiers there (VS Code sends
|
|
342
|
+
* `progressToken`, a W3C `traceparent`, and `vscode/conversationId`),
|
|
343
|
+
* and the upstream is frequently a third party. The strip happens at the
|
|
344
|
+
* proxy boundary, before the pipeline, so middleware sees the stripped
|
|
345
|
+
* request and can still add its own `_meta` deliberately. Progress relay
|
|
346
|
+
* is unaffected: the proxy reads the client's progress token from the
|
|
347
|
+
* server-side request `extra`, and the SDK client stamps its own token
|
|
348
|
+
* on the upstream request.
|
|
349
|
+
*
|
|
350
|
+
* Applies to `passThroughTools` too; disable only globally with `false`
|
|
351
|
+
* for upstreams that read other `_meta` keys. See ADR-0008.
|
|
352
|
+
*/
|
|
353
|
+
stripRequestMeta?: boolean;
|
|
354
|
+
/**
|
|
355
|
+
* Strips top-level `_meta` from every result the proxy returns from the
|
|
356
|
+
* upstream (tool calls, resource reads, list and prompt calls).
|
|
357
|
+
* Default: `true`.
|
|
358
|
+
*
|
|
359
|
+
* The response-direction mirror of {@link stripRequestMeta}: upstreams
|
|
360
|
+
* stamp correlation identifiers there (the SDK stamps
|
|
361
|
+
* `io.modelcontextprotocol/related-task`), and the client is a third
|
|
362
|
+
* party to them. The strip happens at the upstream boundary, inside the
|
|
363
|
+
* innermost `next`, so middleware sees the stripped result and any
|
|
364
|
+
* `_meta` middleware adds deliberately still reaches the client.
|
|
365
|
+
*
|
|
366
|
+
* Local tool results are not stripped (they have no upstream), and
|
|
367
|
+
* nested `_meta` (per-tool in `tools[]`, per-block in `content`) is
|
|
368
|
+
* untouched. Applies to pass-through tools and resources too; disable
|
|
369
|
+
* only globally with `false`. See ADR-0009.
|
|
370
|
+
*/
|
|
371
|
+
stripResultMeta?: boolean;
|
|
372
|
+
/**
|
|
373
|
+
* Tools the proxy implements itself. Local tools appear in `tools/list`
|
|
374
|
+
* (first page only, so pagination does not duplicate them) and route to
|
|
375
|
+
* their handler instead of the upstream, from inside the innermost
|
|
376
|
+
* `next`, so the full `toolMiddleware` pipeline still runs.
|
|
377
|
+
*
|
|
378
|
+
* Precedence: `hiddenTools` beats a local tool; a local tool beats (and
|
|
379
|
+
* shadows) an upstream tool of the same name; `passThroughTools` has no
|
|
380
|
+
* effect on a local tool, because pass-through means "forward the
|
|
381
|
+
* upstream response as-is" and a local tool has no upstream.
|
|
382
|
+
*
|
|
383
|
+
* The proxy advertises the `tools` capability when this is non-empty
|
|
384
|
+
* even if the upstream has none. A duplicate local tool name throws at
|
|
385
|
+
* {@link createProxyServer}. See ADR-0007.
|
|
386
|
+
*/
|
|
387
|
+
localTools?: ReadonlyArray<LocalTool>;
|
|
388
|
+
/**
|
|
389
|
+
* Called after every tool call with timing and outcome data. Wire to any
|
|
390
|
+
* custom telemetry sink, or to `createOtelTelemetry` from `@mcpose/otel`
|
|
391
|
+
* for OpenTelemetry spans.
|
|
392
|
+
* A sink that throws, or whose returned promise rejects, is logged and never
|
|
393
|
+
* fails the tool call. The sink is not awaited, so a slow one does not delay
|
|
394
|
+
* the call either.
|
|
124
395
|
*/
|
|
125
|
-
onTelemetry?: (event: TelemetryEvent) =>
|
|
396
|
+
onTelemetry?: (event: TelemetryEvent) => unknown;
|
|
126
397
|
}
|
|
127
398
|
/**
|
|
128
399
|
* Creates a proxy MCP server without connecting it to a transport.
|
|
129
400
|
*
|
|
130
401
|
* Mirrors upstream tool/resource/prompt lists and routes requests through
|
|
131
|
-
* middleware pipelines.
|
|
402
|
+
* middleware pipelines. `prompts/list` is forwarded as-is; `prompts/get`
|
|
403
|
+
* runs `promptMiddleware` (ADR-0014).
|
|
132
404
|
*
|
|
133
405
|
* Uses low-level `Server` (not `McpServer`) — transparent proxying requires
|
|
134
406
|
* generic list interception; `McpServer.tool()` needs names upfront.
|
|
135
407
|
*
|
|
136
|
-
* @param
|
|
408
|
+
* @param backends - Connected (or mock) upstream MCP client for a 1:1 proxy,
|
|
409
|
+
* or a record of named backends for mesh mode (ADR-0013), where every
|
|
410
|
+
* upstream tool and prompt is exposed as `<backendKey>__<name>`.
|
|
137
411
|
* @param options - Middleware stacks, hidden/passthrough sets.
|
|
138
412
|
* @returns Configured {@link Server} ready to connect.
|
|
139
413
|
*/
|
|
140
|
-
export declare function createProxyServer(
|
|
414
|
+
export declare function createProxyServer(backends: Backends, options: ProxyOptions): Server;
|
|
141
415
|
/**
|
|
142
416
|
* Starts the proxy on stdio.
|
|
143
417
|
* Calls {@link createProxyServer} then connects to `StdioServerTransport`.
|
|
144
418
|
* Use `createProxyServer` directly for testable access to the server.
|
|
145
419
|
*/
|
|
146
|
-
export declare function startProxy(
|
|
420
|
+
export declare function startProxy(backends: Backends, options: ProxyOptions): Promise<void>;
|
|
147
421
|
/**
|
|
148
422
|
* Starts the proxy over Streamable HTTP with stateful sessions.
|
|
149
423
|
*
|
|
@@ -155,5 +429,5 @@ export declare function startProxy(backend: BackendClient, options?: ProxyOption
|
|
|
155
429
|
* @returns Promise resolving to the listening `http.Server` (or `https.Server`
|
|
156
430
|
* when `tlsOptions` is supplied).
|
|
157
431
|
*/
|
|
158
|
-
export declare function startHttpProxy(
|
|
432
|
+
export declare function startHttpProxy(backends: Backends, options: ProxyOptions, httpOptions?: HttpProxyOptions): Promise<http.Server>;
|
|
159
433
|
//# sourceMappingURL=core.d.ts.map
|
package/dist/core.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"core.d.ts","sourceRoot":"","sources":["../src/core.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAClC,OAAO,KAAK,KAAK,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"core.d.ts","sourceRoot":"","sources":["../src/core.ts"],"names":[],"mappings":"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"}
|