mcpose 1.1.0 → 1.2.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 +103 -17
- package/dist/backendClient.js +9 -2
- package/dist/backendClient.js.map +1 -1
- package/dist/core.d.ts +17 -4
- package/dist/core.d.ts.map +1 -1
- package/dist/core.js +241 -67
- package/dist/core.js.map +1 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/middleware.d.ts +9 -3
- package/dist/middleware.d.ts.map +1 -1
- package/dist/middleware.js +4 -3
- package/dist/middleware.js.map +1 -1
- package/dist/proxyContext.d.ts +11 -0
- package/dist/proxyContext.d.ts.map +1 -0
- package/dist/proxyContext.js +14 -0
- package/dist/proxyContext.js.map +1 -0
- package/dist/testing.d.ts +5 -2
- package/dist/testing.d.ts.map +1 -1
- package/dist/testing.js +12 -2
- package/dist/testing.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,7 +1,23 @@
|
|
|
1
|
+
<p align="center">
|
|
2
|
+
<img src="assets/logo.png" alt="mcpose logo" width="500" />
|
|
3
|
+
</p>
|
|
4
|
+
|
|
1
5
|
# mcpose
|
|
2
6
|
|
|
3
|
-
|
|
7
|
+
A transparent middleware proxy for MCP servers - intercept, transform, and govern tool calls and tool discovery through composable functional middleware.
|
|
8
|
+
|
|
9
|
+
You'll probably love it if you have enjoyed working with middleware functions or LEGO.
|
|
10
|
+
|
|
11
|
+
## New in 1.2.0
|
|
12
|
+
|
|
13
|
+
- `onRequest` hook — auth/request gating on HTTP proxy
|
|
14
|
+
- `onError` callback — custom error handler (replaces `console.error`)
|
|
15
|
+
- `maxBodyBytes` — body size cap, returns 413 (default 4 MB)
|
|
16
|
+
- `maxSessions` — concurrent session cap, excess returns 503
|
|
17
|
+
- `sessionTtlMs` — session TTL with auto-close
|
|
18
|
+
- `createProxyContext` exported for manual context construction
|
|
4
19
|
|
|
20
|
+
---
|
|
5
21
|
---
|
|
6
22
|
|
|
7
23
|
## Background
|
|
@@ -12,7 +28,7 @@ mcpose was extracted from [`financial-elastic-mcp-server`](https://github.com/am
|
|
|
12
28
|
|
|
13
29
|
## Concept
|
|
14
30
|
|
|
15
|
-
mcpose is a **transparent proxy
|
|
31
|
+
mcpose is a **transparent proxy** between an LLM client and an upstream MCP server. It mirrors the upstream MCP surface and routes supported calls through middleware. The client sees a normal MCP server; the upstream sees a normal MCP client.
|
|
16
32
|
|
|
17
33
|
---
|
|
18
34
|
|
|
@@ -68,7 +84,7 @@ await startProxy(backend, {
|
|
|
68
84
|
└──────────────┘ └────────────────────────────────┘ └────────────────────┘
|
|
69
85
|
```
|
|
70
86
|
|
|
71
|
-
For each tool or resource, mcpose picks one of three routing paths:
|
|
87
|
+
For each supported tool or resource, mcpose picks one of three routing paths:
|
|
72
88
|
|
|
73
89
|
| Path | Option | Behavior |
|
|
74
90
|
|---|---|---|
|
|
@@ -76,13 +92,21 @@ For each tool or resource, mcpose picks one of three routing paths:
|
|
|
76
92
|
| **Pass-through** | `passThroughTools` / `passThroughResources` | Forwarded raw to upstream — all middleware skipped |
|
|
77
93
|
| **Middleware** | everything else | Routed through the full `toolMiddleware` / `resourceMiddleware` pipeline |
|
|
78
94
|
|
|
79
|
-
Prompts are
|
|
95
|
+
Prompts are forwarded as-is when the upstream supports prompts.
|
|
96
|
+
|
|
97
|
+
The proxy preserves core request semantics end to end:
|
|
98
|
+
|
|
99
|
+
- advertised capabilities are mirrored from the upstream server
|
|
100
|
+
- abort signals are forwarded to upstream tool, resource, and prompt calls
|
|
101
|
+
- upstream progress updates are relayed back to the downstream client
|
|
102
|
+
- list-changed notifications are advertised and fanned out when the upstream supports them
|
|
103
|
+
- `list_tools` responses can be transformed through `listToolsMiddleware` without weakening local `hiddenTools` guarantees
|
|
80
104
|
|
|
81
105
|
---
|
|
82
106
|
|
|
83
107
|
## Middleware model
|
|
84
108
|
|
|
85
|
-
Middleware follows the **onion model**: outer layers run code before *and* after inner layers. Each middleware receives the request
|
|
109
|
+
Middleware follows the **onion model**: outer layers run code before *and* after inner layers. Each middleware receives the request, a `next` function to invoke the rest of the pipeline, and a normalized `ProxyContext`.
|
|
86
110
|
|
|
87
111
|
```
|
|
88
112
|
request ──►
|
|
@@ -114,34 +138,50 @@ toolMiddleware: [piiMW, auditMW]
|
|
|
114
138
|
|
|
115
139
|
`compose([outerMW, innerMW])` uses the **opposite** (outermost-first) convention — `ProxyOptions` arrays are **not** interchangeable with `compose()` arguments.
|
|
116
140
|
|
|
117
|
-
A middleware can **short-circuit** by returning without calling `next`, or **handle upstream errors** by wrapping `await next(req)` in a try/catch.
|
|
141
|
+
A middleware can **short-circuit** by returning without calling `next`, or **handle upstream errors** by wrapping `await next(req)` in a try/catch. Existing two-argument middleware keeps working unchanged; `mcpose` supplies `ProxyContext` as an optional third argument.
|
|
118
142
|
|
|
119
143
|
---
|
|
120
144
|
|
|
121
145
|
## API Reference
|
|
122
146
|
|
|
123
|
-
### `Middleware<Req, Res>` · `ToolMiddleware` · `ResourceMiddleware` · `compose()`
|
|
147
|
+
### `ProxyContext` · `Middleware<Req, Res>` · `ToolMiddleware` · `ResourceMiddleware` · `ListToolsMiddleware` · `compose()` · `createProxyContext()`
|
|
124
148
|
|
|
125
149
|
```ts
|
|
150
|
+
interface ProxyContext {
|
|
151
|
+
requestId: string;
|
|
152
|
+
transport: 'stdio' | 'http';
|
|
153
|
+
sessionId?: string;
|
|
154
|
+
headers?: Readonly<Record<string, string>>;
|
|
155
|
+
signal?: AbortSignal;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
// Builds a ProxyContext with a fresh requestId; useful in tests or custom orchestration:
|
|
159
|
+
function createProxyContext(overrides?: Partial<ProxyContext>): ProxyContext;
|
|
160
|
+
|
|
126
161
|
type Middleware<Req, Res> = (
|
|
127
162
|
req: Req,
|
|
128
163
|
next: (req: Req) => Promise<Res>,
|
|
164
|
+
context: ProxyContext,
|
|
129
165
|
) => Promise<Res>;
|
|
130
166
|
|
|
131
|
-
// Convenience aliases for the
|
|
167
|
+
// Convenience aliases for the three pipeline types:
|
|
132
168
|
type ToolMiddleware = Middleware<CallToolRequest, CompatibilityCallToolResult>;
|
|
133
169
|
type ResourceMiddleware = Middleware<ReadResourceRequest, ReadResourceResult>;
|
|
170
|
+
type ListToolsMiddleware = Middleware<ListToolsRequest, ListToolsResult>;
|
|
134
171
|
|
|
135
172
|
function compose<Req, Res>(
|
|
136
173
|
middlewares: ReadonlyArray<Middleware<Req, Res>>,
|
|
137
|
-
):
|
|
174
|
+
): {
|
|
175
|
+
(req: Req, next: (req: Req) => Promise<Res>): Promise<Res>;
|
|
176
|
+
(req: Req, next: (req: Req) => Promise<Res>, context: ProxyContext): Promise<Res>;
|
|
177
|
+
};
|
|
138
178
|
|
|
139
179
|
// Type guard — narrows CompatibilityCallToolResult to CallToolResult
|
|
140
180
|
// (safe access to .content and .isError without casts):
|
|
141
181
|
function hasToolContent(r: CompatibilityCallToolResult): r is CallToolResult;
|
|
142
182
|
```
|
|
143
183
|
|
|
144
|
-
`compose` takes an array in **outermost-first** order. Use `hasToolContent` in middleware implementations before accessing `.content` or `.isError`, since `CompatibilityCallToolResult` also covers the legacy `{ toolResult }` shape.
|
|
184
|
+
`compose` takes an array in **outermost-first** order. Use `hasToolContent` in middleware implementations before accessing `.content` or `.isError`, since `CompatibilityCallToolResult` also covers the legacy `{ toolResult }` shape. `ProxyContext.signal` carries the downstream abort signal when the transport provides one.
|
|
145
185
|
|
|
146
186
|
---
|
|
147
187
|
|
|
@@ -157,7 +197,7 @@ interface BackendConfig {
|
|
|
157
197
|
async function createBackendClient(config: BackendConfig): Promise<BackendClient>;
|
|
158
198
|
```
|
|
159
199
|
|
|
160
|
-
`BackendClient` is an alias for the SDK `Client`.
|
|
200
|
+
`BackendClient` is an alias for the SDK `Client`. It throws if neither `command` nor `url` is provided, or if the connection fails.
|
|
161
201
|
|
|
162
202
|
---
|
|
163
203
|
|
|
@@ -167,6 +207,7 @@ async function createBackendClient(config: BackendConfig): Promise<BackendClient
|
|
|
167
207
|
interface ProxyOptions {
|
|
168
208
|
toolMiddleware?: ReadonlyArray<ToolMiddleware>;
|
|
169
209
|
resourceMiddleware?: ReadonlyArray<ResourceMiddleware>;
|
|
210
|
+
listToolsMiddleware?: ReadonlyArray<ListToolsMiddleware>;
|
|
170
211
|
passThroughTools?: ReadonlyArray<string>;
|
|
171
212
|
passThroughResources?: ReadonlyArray<string>;
|
|
172
213
|
hiddenTools?: ReadonlyArray<string>;
|
|
@@ -181,11 +222,14 @@ function createProxyServer(backend: BackendClient, options?: ProxyOptions): Serv
|
|
|
181
222
|
|---|---|
|
|
182
223
|
| `toolMiddleware` | Middleware stack for tool calls, in response-processing order (first element processes response first). |
|
|
183
224
|
| `resourceMiddleware` | Middleware stack for resource reads, in response-processing order. |
|
|
225
|
+
| `listToolsMiddleware` | Middleware stack for `list_tools`, in response-processing order. Local `hiddenTools` filtering still runs before and after this pipeline. |
|
|
184
226
|
| `passThroughTools` | Tool names forwarded raw to upstream — middleware skipped entirely. |
|
|
185
227
|
| `passThroughResources` | Resource URIs forwarded raw to upstream — middleware skipped entirely. |
|
|
186
228
|
| `hiddenTools` | Tool names removed from `list_tools` **and** rejected at call time with `MethodNotFound`. |
|
|
187
229
|
| `hiddenResources` | Resource URIs removed from `list_resources` **and** rejected at call time with `InvalidRequest`. |
|
|
188
230
|
|
|
231
|
+
`createProxyServer` mirrors only the upstream capabilities exposed by `backend.getServerCapabilities()`. Unsupported prompt, resource, and tool endpoints are not advertised or registered.
|
|
232
|
+
|
|
189
233
|
`startProxy` connects the proxy to a `StdioServerTransport`. `createProxyServer` returns the configured `Server` without connecting — useful for testing request handlers without a live transport.
|
|
190
234
|
|
|
191
235
|
---
|
|
@@ -194,9 +238,14 @@ function createProxyServer(backend: BackendClient, options?: ProxyOptions): Serv
|
|
|
194
238
|
|
|
195
239
|
```ts
|
|
196
240
|
interface HttpProxyOptions {
|
|
197
|
-
port?: number;
|
|
198
|
-
host?: string;
|
|
199
|
-
path?: string;
|
|
241
|
+
port?: number; // Default: 3000
|
|
242
|
+
host?: string; // Default: all interfaces
|
|
243
|
+
path?: string; // Default: '/mcp'
|
|
244
|
+
onRequest?: (req: http.IncomingMessage, res: http.ServerResponse) => boolean | Promise<boolean>;
|
|
245
|
+
onError?: (err: unknown) => void;
|
|
246
|
+
maxBodyBytes?: number; // Default: 4 MB — returns 413 on excess
|
|
247
|
+
maxSessions?: number; // Excess requests return 503
|
|
248
|
+
sessionTtlMs?: number; // Sessions auto-close after this duration
|
|
200
249
|
}
|
|
201
250
|
|
|
202
251
|
function startHttpProxy(
|
|
@@ -206,7 +255,7 @@ function startHttpProxy(
|
|
|
206
255
|
): Promise<http.Server>;
|
|
207
256
|
```
|
|
208
257
|
|
|
209
|
-
Starts the proxy over Streamable HTTP with stateful sessions. Each client connection is assigned an `mcp-session-id
|
|
258
|
+
Starts the proxy over Streamable HTTP with stateful sessions. Each client connection is assigned an `mcp-session-id`. Upstream list-change notifications (`tools/list_changed`, `resources/list_changed`, `prompts/list_changed`) are fanned out to all active sessions when the upstream advertises them.
|
|
210
259
|
|
|
211
260
|
```ts
|
|
212
261
|
import { createBackendClient, startHttpProxy } from 'mcpose';
|
|
@@ -216,13 +265,50 @@ const server = await startHttpProxy(backend, { toolMiddleware: [loggingMW] }, {
|
|
|
216
265
|
// HTTP server is now listening on port 8080 at /mcp
|
|
217
266
|
```
|
|
218
267
|
|
|
268
|
+
On shutdown, active proxy sessions are closed before the underlying `http.Server` finishes closing.
|
|
269
|
+
|
|
219
270
|
**Limitations:**
|
|
220
|
-
- Two `startHttpProxy` calls sharing the same `backend` will overwrite each other's notification handlers (last call wins).
|
|
221
|
-
- Sessions are only cleaned up on `DELETE` or server close — there is no idle timeout.
|
|
222
271
|
- SSE reconnect replay is not supported (no `EventStore`).
|
|
223
272
|
|
|
224
273
|
---
|
|
225
274
|
|
|
275
|
+
### `mcpose/testing`
|
|
276
|
+
|
|
277
|
+
```ts
|
|
278
|
+
import { createMockBackendClient, runToolMiddleware } from 'mcpose/testing';
|
|
279
|
+
```
|
|
280
|
+
|
|
281
|
+
`createMockBackendClient()` returns an in-memory backend stub with capability lookup and notification hooks. It works with both `createProxyServer()` and `startHttpProxy()` tests.
|
|
282
|
+
|
|
283
|
+
---
|
|
284
|
+
|
|
285
|
+
## Recipe: list_tools rewriting
|
|
286
|
+
|
|
287
|
+
Use `listToolsMiddleware` when you want to rewrite the visible tool catalog without changing local routing guarantees:
|
|
288
|
+
|
|
289
|
+
```ts
|
|
290
|
+
import type { ListToolsMiddleware } from 'mcpose';
|
|
291
|
+
|
|
292
|
+
const enrichDescriptions: ListToolsMiddleware = async (req, next, context) => {
|
|
293
|
+
const result = await next(req);
|
|
294
|
+
return {
|
|
295
|
+
...result,
|
|
296
|
+
tools: result.tools.map((tool) =>
|
|
297
|
+
tool.name === 'wire_transfer'
|
|
298
|
+
? {
|
|
299
|
+
...tool,
|
|
300
|
+
description: `${tool.description ?? 'Wire transfer'} (approval required on ${context.transport})`,
|
|
301
|
+
}
|
|
302
|
+
: tool,
|
|
303
|
+
),
|
|
304
|
+
};
|
|
305
|
+
};
|
|
306
|
+
```
|
|
307
|
+
|
|
308
|
+
`hiddenTools` remains authoritative even if a `listToolsMiddleware` tries to add a hidden tool back into the response.
|
|
309
|
+
|
|
310
|
+
---
|
|
311
|
+
|
|
226
312
|
## Recipe: PII redaction
|
|
227
313
|
|
|
228
314
|
The origin use case for mcpose: a financial-grade MCP server where every Elasticsearch tool response must be scrubbed of PII before it reaches the LLM or the audit log.
|
package/dist/backendClient.js
CHANGED
|
@@ -13,9 +13,9 @@ export async function createBackendClient(config) {
|
|
|
13
13
|
if (!config.command && !config.url) {
|
|
14
14
|
throw new Error('mcpose: either command or url must be provided in BackendConfig');
|
|
15
15
|
}
|
|
16
|
-
const client = new Client({ name: 'mcpose-backend', version: '1.
|
|
16
|
+
const client = new Client({ name: 'mcpose-backend', version: '1.1.1' }, { capabilities: {} });
|
|
17
17
|
const transport = config.url
|
|
18
|
-
?
|
|
18
|
+
? getHttpTransport(config.url)
|
|
19
19
|
: new StdioClientTransport({
|
|
20
20
|
command: config.command,
|
|
21
21
|
args: config.args ?? [],
|
|
@@ -23,4 +23,11 @@ export async function createBackendClient(config) {
|
|
|
23
23
|
await client.connect(transport);
|
|
24
24
|
return client;
|
|
25
25
|
}
|
|
26
|
+
const getHttpTransport = (urlString) => {
|
|
27
|
+
const url = new URL(urlString);
|
|
28
|
+
if (url.protocol !== 'http:' && url.protocol !== 'https:') {
|
|
29
|
+
throw new Error(`mcpose: unsupported URL protocol "${url.protocol}" — only http: and https: are allowed`);
|
|
30
|
+
}
|
|
31
|
+
return new StreamableHTTPClientTransport(url);
|
|
32
|
+
};
|
|
26
33
|
//# sourceMappingURL=backendClient.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"backendClient.js","sourceRoot":"","sources":["../src/backendClient.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,EAAE,MAAM,EAAE,MAAM,2CAA2C,CAAC;AACnE,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AACjF,OAAO,EAAE,6BAA6B,EAAE,MAAM,oDAAoD,CAAC;AAcnG;;;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,
|
|
1
|
+
{"version":3,"file":"backendClient.js","sourceRoot":"","sources":["../src/backendClient.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,EAAE,MAAM,EAAE,MAAM,2CAA2C,CAAC;AACnE,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AACjF,OAAO,EAAE,6BAA6B,EAAE,MAAM,oDAAoD,CAAC;AAcnG;;;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,CAAC;QAC9B,CAAC,CAAC,IAAI,oBAAoB,CAAC;YACvB,OAAO,EAAE,MAAM,CAAC,OAAQ;YACxB,IAAI,EAAE,MAAM,CAAC,IAAI,IAAI,EAAE;SACxB,CAAC,CAAC;IAEP,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IAChC,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,MAAM,gBAAgB,GAAG,CAAC,SAAiB,EAAE,EAAE;IAC7C,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,OAAO,IAAI,6BAA6B,CAAC,GAAG,CAAC,CAAC;AAChD,CAAC,CAAC"}
|
package/dist/core.d.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
/** MCP proxy core: wires server→upstream through middleware pipelines. */
|
|
2
1
|
import * as http from 'node:http';
|
|
3
2
|
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
|
|
4
|
-
import { type CallToolRequest, type CallToolResult, type CompatibilityCallToolResult, type ReadResourceRequest, type ReadResourceResult } from '@modelcontextprotocol/sdk/types.js';
|
|
3
|
+
import { type ListToolsRequest, type ListToolsResult, type CallToolRequest, type CallToolResult, type CompatibilityCallToolResult, type ReadResourceRequest, type ReadResourceResult } from '@modelcontextprotocol/sdk/types.js';
|
|
5
4
|
import { type Middleware } from './middleware.js';
|
|
6
5
|
import type { BackendClient } from './backendClient.js';
|
|
6
|
+
export type { ProxyContext } from './proxyContext.js';
|
|
7
7
|
/**
|
|
8
8
|
* Middleware for tool calls.
|
|
9
9
|
* Uses `CompatibilityCallToolResult` to cover legacy `{ toolResult }` shape
|
|
@@ -12,6 +12,8 @@ import type { BackendClient } from './backendClient.js';
|
|
|
12
12
|
export type ToolMiddleware = Middleware<CallToolRequest, CompatibilityCallToolResult>;
|
|
13
13
|
/** Middleware for resource reads. */
|
|
14
14
|
export type ResourceMiddleware = Middleware<ReadResourceRequest, ReadResourceResult>;
|
|
15
|
+
/** Middleware for tool-list responses. */
|
|
16
|
+
export type ListToolsMiddleware = Middleware<ListToolsRequest, ListToolsResult>;
|
|
15
17
|
/**
|
|
16
18
|
* Narrows `CompatibilityCallToolResult` to `CallToolResult` (has `.content` array).
|
|
17
19
|
* Both union members carry `[x: string]: unknown`, so this avoids unsafe casts.
|
|
@@ -25,6 +27,16 @@ export interface HttpProxyOptions {
|
|
|
25
27
|
host?: string;
|
|
26
28
|
/** Default: '/mcp' */
|
|
27
29
|
path?: string;
|
|
30
|
+
/** Called for every incoming request before MCP handling. Return false to block (caller writes its own response). Throw to get a 401. */
|
|
31
|
+
onRequest?: (req: http.IncomingMessage, res: http.ServerResponse) => boolean | Promise<boolean>;
|
|
32
|
+
/** Called on unhandled errors instead of console.error. */
|
|
33
|
+
onError?: (err: unknown) => void;
|
|
34
|
+
/** Maximum request body size in bytes. Default: 4 MB. */
|
|
35
|
+
maxBodyBytes?: number;
|
|
36
|
+
/** Maximum number of concurrent MCP sessions. Excess requests return 503. */
|
|
37
|
+
maxSessions?: number;
|
|
38
|
+
/** Session TTL in milliseconds. Sessions are closed after this duration. */
|
|
39
|
+
sessionTtlMs?: number;
|
|
28
40
|
}
|
|
29
41
|
/** Proxy server options. */
|
|
30
42
|
export interface ProxyOptions {
|
|
@@ -35,6 +47,8 @@ export interface ProxyOptions {
|
|
|
35
47
|
toolMiddleware?: ReadonlyArray<ToolMiddleware>;
|
|
36
48
|
/** Resource middleware in response-processing order (first = innermost). */
|
|
37
49
|
resourceMiddleware?: ReadonlyArray<ResourceMiddleware>;
|
|
50
|
+
/** Tool-list middleware in response-processing order (first = innermost). */
|
|
51
|
+
listToolsMiddleware?: ReadonlyArray<ListToolsMiddleware>;
|
|
38
52
|
/** Tools that skip middleware — upstream response forwarded as-is. */
|
|
39
53
|
passThroughTools?: ReadonlyArray<string>;
|
|
40
54
|
/** Resources that skip middleware — upstream response forwarded as-is. */
|
|
@@ -71,8 +85,7 @@ export declare function startProxy(backend: BackendClient, options?: ProxyOption
|
|
|
71
85
|
* all active sessions via their GET SSE stream.
|
|
72
86
|
*
|
|
73
87
|
* **Limitations:**
|
|
74
|
-
* -
|
|
75
|
-
* - Sessions never expire — only cleaned up on DELETE or server close.
|
|
88
|
+
* - Sessions never expire.
|
|
76
89
|
* - No `EventStore` → SSE reconnect replay unsupported.
|
|
77
90
|
*
|
|
78
91
|
* @returns Promise resolving to the listening `http.Server`.
|
package/dist/core.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"core.d.ts","sourceRoot":"","sources":["../src/core.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"core.d.ts","sourceRoot":"","sources":["../src/core.ts"],"names":[],"mappings":"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"}
|
package/dist/core.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
/** MCP proxy core: wires server→upstream through middleware pipelines. */
|
|
2
|
+
import { AsyncLocalStorage } from 'node:async_hooks';
|
|
2
3
|
import * as http from 'node:http';
|
|
3
4
|
import { randomUUID } from 'node:crypto';
|
|
4
5
|
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
|
|
@@ -6,6 +7,7 @@ import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'
|
|
|
6
7
|
import { StreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/streamableHttp.js';
|
|
7
8
|
import { CallToolRequestSchema, ErrorCode, GetPromptRequestSchema, ListPromptsRequestSchema, ListResourcesRequestSchema, ListToolsRequestSchema, McpError, PromptListChangedNotificationSchema, ReadResourceRequestSchema, ResourceListChangedNotificationSchema, ToolListChangedNotificationSchema, } from '@modelcontextprotocol/sdk/types.js';
|
|
8
9
|
import { pipe } from './middleware.js';
|
|
10
|
+
import { createProxyContext } from './proxyContext.js';
|
|
9
11
|
/**
|
|
10
12
|
* Narrows `CompatibilityCallToolResult` to `CallToolResult` (has `.content` array).
|
|
11
13
|
* Both union members carry `[x: string]: unknown`, so this avoids unsafe casts.
|
|
@@ -13,6 +15,108 @@ import { pipe } from './middleware.js';
|
|
|
13
15
|
export function hasToolContent(r) {
|
|
14
16
|
return Array.isArray(r.content);
|
|
15
17
|
}
|
|
18
|
+
const listChangedBuses = new WeakMap();
|
|
19
|
+
const httpProxyContext = new AsyncLocalStorage();
|
|
20
|
+
function createProxyCapabilities(backend) {
|
|
21
|
+
const upstream = backend.getServerCapabilities();
|
|
22
|
+
return {
|
|
23
|
+
...(upstream?.tools
|
|
24
|
+
? { tools: upstream.tools.listChanged ? { listChanged: true } : {} }
|
|
25
|
+
: {}),
|
|
26
|
+
...(upstream?.resources
|
|
27
|
+
? { resources: upstream.resources.listChanged ? { listChanged: true } : {} }
|
|
28
|
+
: {}),
|
|
29
|
+
...(upstream?.prompts
|
|
30
|
+
? { prompts: upstream.prompts.listChanged ? { listChanged: true } : {} }
|
|
31
|
+
: {}),
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
function createRequestOptions(extra = {}) {
|
|
35
|
+
const progressToken = extra._meta?.progressToken;
|
|
36
|
+
const onprogress = progressToken && extra.sendNotification
|
|
37
|
+
? ({ progress, total, message, }) => {
|
|
38
|
+
void extra.sendNotification?.({
|
|
39
|
+
method: 'notifications/progress',
|
|
40
|
+
params: {
|
|
41
|
+
progressToken,
|
|
42
|
+
progress,
|
|
43
|
+
...(total === undefined ? {} : { total }),
|
|
44
|
+
...(message === undefined ? {} : { message }),
|
|
45
|
+
},
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
: undefined;
|
|
49
|
+
if (!extra.signal && !onprogress)
|
|
50
|
+
return undefined;
|
|
51
|
+
return {
|
|
52
|
+
...(extra.signal ? { signal: extra.signal } : {}),
|
|
53
|
+
...(onprogress ? { onprogress } : {}),
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
function normalizeHeaders(headers) {
|
|
57
|
+
const normalized = Object.entries(headers).reduce((acc, [key, value]) => {
|
|
58
|
+
if (typeof value === 'string') {
|
|
59
|
+
acc[key] = value;
|
|
60
|
+
return acc;
|
|
61
|
+
}
|
|
62
|
+
if (Array.isArray(value)) {
|
|
63
|
+
acc[key] = value.join(', ');
|
|
64
|
+
}
|
|
65
|
+
return acc;
|
|
66
|
+
}, {});
|
|
67
|
+
return Object.keys(normalized).length ? normalized : undefined;
|
|
68
|
+
}
|
|
69
|
+
function getMiddlewareContext(signal) {
|
|
70
|
+
return createProxyContext({
|
|
71
|
+
...httpProxyContext.getStore(),
|
|
72
|
+
...(signal === undefined ? {} : { signal }),
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
function filterHiddenTools(result, hiddenToolSet) {
|
|
76
|
+
if (!hiddenToolSet.size)
|
|
77
|
+
return result;
|
|
78
|
+
return {
|
|
79
|
+
...result,
|
|
80
|
+
tools: result.tools.filter((tool) => !hiddenToolSet.has(tool.name)),
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
function registerListChangedForwarders(backend, server, capabilities) {
|
|
84
|
+
if (!capabilities.tools?.listChanged &&
|
|
85
|
+
!capabilities.resources?.listChanged &&
|
|
86
|
+
!capabilities.prompts?.listChanged) {
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
89
|
+
let bus = listChangedBuses.get(backend);
|
|
90
|
+
if (!bus) {
|
|
91
|
+
const servers = new Set();
|
|
92
|
+
const fanOut = async (notify) => {
|
|
93
|
+
await Promise.allSettled([...servers].map((proxyServer) => notify(proxyServer)));
|
|
94
|
+
};
|
|
95
|
+
if (capabilities.tools?.listChanged) {
|
|
96
|
+
backend.setNotificationHandler(ToolListChangedNotificationSchema, () => fanOut((proxyServer) => proxyServer.sendToolListChanged()));
|
|
97
|
+
}
|
|
98
|
+
if (capabilities.prompts?.listChanged) {
|
|
99
|
+
backend.setNotificationHandler(PromptListChangedNotificationSchema, () => fanOut((proxyServer) => proxyServer.sendPromptListChanged()));
|
|
100
|
+
}
|
|
101
|
+
if (capabilities.resources?.listChanged) {
|
|
102
|
+
backend.setNotificationHandler(ResourceListChangedNotificationSchema, () => fanOut((proxyServer) => proxyServer.sendResourceListChanged()));
|
|
103
|
+
}
|
|
104
|
+
bus = { servers };
|
|
105
|
+
listChangedBuses.set(backend, bus);
|
|
106
|
+
}
|
|
107
|
+
bus.servers.add(server);
|
|
108
|
+
const prevOnClose = server.onclose;
|
|
109
|
+
let active = true;
|
|
110
|
+
server.onclose = () => {
|
|
111
|
+
if (!active)
|
|
112
|
+
return;
|
|
113
|
+
active = false;
|
|
114
|
+
bus.servers.delete(server);
|
|
115
|
+
if (!bus.servers.size)
|
|
116
|
+
listChangedBuses.delete(backend);
|
|
117
|
+
prevOnClose?.();
|
|
118
|
+
};
|
|
119
|
+
}
|
|
16
120
|
/**
|
|
17
121
|
* Creates a proxy MCP server without connecting it to a transport.
|
|
18
122
|
*
|
|
@@ -27,50 +131,63 @@ export function hasToolContent(r) {
|
|
|
27
131
|
* @returns Configured {@link Server} ready to connect.
|
|
28
132
|
*/
|
|
29
133
|
export function createProxyServer(backend, options = {}) {
|
|
134
|
+
const capabilities = createProxyCapabilities(backend);
|
|
30
135
|
const toolPipeline = pipe(options.toolMiddleware ?? []);
|
|
31
136
|
const resourcePipeline = pipe(options.resourceMiddleware ?? []);
|
|
137
|
+
const listToolsPipeline = pipe(options.listToolsMiddleware ?? []);
|
|
32
138
|
const hiddenToolSet = new Set(options.hiddenTools ?? []);
|
|
33
139
|
const passThroughToolSet = new Set(options.passThroughTools ?? []);
|
|
34
140
|
const hiddenResourceSet = new Set(options.hiddenResources ?? []);
|
|
35
141
|
const passThroughResourceSet = new Set(options.passThroughResources ?? []);
|
|
36
|
-
const server = new Server({ name: 'mcpose', version: '1.
|
|
142
|
+
const server = new Server({ name: 'mcpose', version: '1.1.1' }, { capabilities });
|
|
143
|
+
registerListChangedForwarders(backend, server, capabilities);
|
|
37
144
|
// ── Tool handlers ──────────────────────────────────────────────────────────
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
145
|
+
if (capabilities.tools) {
|
|
146
|
+
server.setRequestHandler(ListToolsRequestSchema, async (req, extra) => {
|
|
147
|
+
const requestOptions = createRequestOptions(extra);
|
|
148
|
+
const context = getMiddlewareContext(extra.signal);
|
|
149
|
+
const result = await listToolsPipeline(req, async (currentReq) => filterHiddenTools(await backend.listTools(currentReq.params, requestOptions), hiddenToolSet), context);
|
|
150
|
+
return filterHiddenTools(result, hiddenToolSet);
|
|
151
|
+
});
|
|
152
|
+
server.setRequestHandler(CallToolRequestSchema, (req, extra) => {
|
|
153
|
+
const name = req.params.name;
|
|
154
|
+
const requestOptions = createRequestOptions(extra);
|
|
155
|
+
const context = getMiddlewareContext(extra.signal);
|
|
156
|
+
if (hiddenToolSet.has(name)) {
|
|
157
|
+
throw new McpError(ErrorCode.MethodNotFound, `Tool not found: ${name}`);
|
|
158
|
+
}
|
|
159
|
+
if (passThroughToolSet.has(name)) {
|
|
160
|
+
return backend.callTool(req.params, undefined, requestOptions);
|
|
161
|
+
}
|
|
162
|
+
return toolPipeline(req, (r) => backend.callTool(r.params, undefined, requestOptions), context);
|
|
163
|
+
});
|
|
164
|
+
}
|
|
54
165
|
// ── Resource handlers ──────────────────────────────────────────────────────
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
166
|
+
if (capabilities.resources) {
|
|
167
|
+
server.setRequestHandler(ListResourcesRequestSchema, async (req, extra) => {
|
|
168
|
+
const result = await backend.listResources(req.params, createRequestOptions(extra));
|
|
169
|
+
if (!hiddenResourceSet.size)
|
|
170
|
+
return result;
|
|
171
|
+
return { ...result, resources: result.resources.filter((r) => !hiddenResourceSet.has(r.uri)) };
|
|
172
|
+
});
|
|
173
|
+
server.setRequestHandler(ReadResourceRequestSchema, (req, extra) => {
|
|
174
|
+
const uri = req.params.uri;
|
|
175
|
+
const requestOptions = createRequestOptions(extra);
|
|
176
|
+
const context = getMiddlewareContext(extra.signal);
|
|
177
|
+
if (hiddenResourceSet.has(uri)) {
|
|
178
|
+
throw new McpError(ErrorCode.InvalidRequest, `Resource not found: ${uri}`);
|
|
179
|
+
}
|
|
180
|
+
if (passThroughResourceSet.has(uri)) {
|
|
181
|
+
return backend.readResource(req.params, requestOptions);
|
|
182
|
+
}
|
|
183
|
+
return resourcePipeline(req, (r) => backend.readResource(r.params, requestOptions), context);
|
|
184
|
+
});
|
|
185
|
+
}
|
|
71
186
|
// ── Prompt handlers (pass-through) ────────────────────────────────────────
|
|
72
|
-
|
|
73
|
-
|
|
187
|
+
if (capabilities.prompts) {
|
|
188
|
+
server.setRequestHandler(ListPromptsRequestSchema, (req, extra) => backend.listPrompts(req.params, createRequestOptions(extra)));
|
|
189
|
+
server.setRequestHandler(GetPromptRequestSchema, (req, extra) => backend.getPrompt(req.params, createRequestOptions(extra)));
|
|
190
|
+
}
|
|
74
191
|
return server;
|
|
75
192
|
}
|
|
76
193
|
/**
|
|
@@ -82,6 +199,21 @@ export async function startProxy(backend, options = {}) {
|
|
|
82
199
|
const server = createProxyServer(backend, options);
|
|
83
200
|
await server.connect(new StdioServerTransport());
|
|
84
201
|
}
|
|
202
|
+
function applyBodySizeLimit(req, res, maxBodyBytes) {
|
|
203
|
+
let total = 0;
|
|
204
|
+
const originalPush = req.push.bind(req);
|
|
205
|
+
req.push = (chunk, enc) => {
|
|
206
|
+
if (chunk !== null && total + chunk.length > maxBodyBytes) {
|
|
207
|
+
if (!res.headersSent)
|
|
208
|
+
res.writeHead(413).end();
|
|
209
|
+
req.destroy(new Error('Request body too large'));
|
|
210
|
+
return false;
|
|
211
|
+
}
|
|
212
|
+
if (chunk !== null)
|
|
213
|
+
total += chunk.length;
|
|
214
|
+
return originalPush(chunk, enc);
|
|
215
|
+
};
|
|
216
|
+
}
|
|
85
217
|
/**
|
|
86
218
|
* Starts the proxy over Streamable HTTP with stateful sessions.
|
|
87
219
|
*
|
|
@@ -89,8 +221,7 @@ export async function startProxy(backend, options = {}) {
|
|
|
89
221
|
* all active sessions via their GET SSE stream.
|
|
90
222
|
*
|
|
91
223
|
* **Limitations:**
|
|
92
|
-
* -
|
|
93
|
-
* - Sessions never expire — only cleaned up on DELETE or server close.
|
|
224
|
+
* - Sessions never expire.
|
|
94
225
|
* - No `EventStore` → SSE reconnect replay unsupported.
|
|
95
226
|
*
|
|
96
227
|
* @returns Promise resolving to the listening `http.Server`.
|
|
@@ -101,51 +232,94 @@ export function startHttpProxy(backend, options = {}, httpOptions = {}) {
|
|
|
101
232
|
const host = httpOptions.host;
|
|
102
233
|
// session ID → { transport, proxyServer }
|
|
103
234
|
const sessions = new Map();
|
|
104
|
-
// Fan upstream notifications to all active sessions' SSE streams.
|
|
105
|
-
backend.setNotificationHandler(ToolListChangedNotificationSchema, async () => {
|
|
106
|
-
await Promise.all([...sessions.values()].map(({ proxyServer }) => proxyServer.sendToolListChanged()));
|
|
107
|
-
});
|
|
108
|
-
backend.setNotificationHandler(PromptListChangedNotificationSchema, async () => {
|
|
109
|
-
await Promise.all([...sessions.values()].map(({ proxyServer }) => proxyServer.sendPromptListChanged()));
|
|
110
|
-
});
|
|
111
|
-
backend.setNotificationHandler(ResourceListChangedNotificationSchema, async () => {
|
|
112
|
-
await Promise.all([...sessions.values()].map(({ proxyServer }) => proxyServer.sendResourceListChanged()));
|
|
113
|
-
});
|
|
114
235
|
const server = http.createServer((req, res) => {
|
|
115
236
|
const handle = async () => {
|
|
237
|
+
if (httpOptions.onRequest !== undefined) {
|
|
238
|
+
let allowed;
|
|
239
|
+
try {
|
|
240
|
+
allowed = await httpOptions.onRequest(req, res);
|
|
241
|
+
}
|
|
242
|
+
catch {
|
|
243
|
+
if (!res.headersSent)
|
|
244
|
+
res.writeHead(401).end();
|
|
245
|
+
return;
|
|
246
|
+
}
|
|
247
|
+
if (!allowed)
|
|
248
|
+
return;
|
|
249
|
+
}
|
|
116
250
|
const url = new URL(req.url ?? '/', 'http://localhost');
|
|
117
251
|
const method = req.method ?? '';
|
|
118
252
|
if (url.pathname !== mcpPath || !['GET', 'POST', 'DELETE'].includes(method)) {
|
|
119
253
|
res.writeHead(404).end();
|
|
120
254
|
return;
|
|
121
255
|
}
|
|
256
|
+
if (method === 'POST') {
|
|
257
|
+
applyBodySizeLimit(req, res, httpOptions.maxBodyBytes ?? 4 * 1024 * 1024);
|
|
258
|
+
}
|
|
122
259
|
const sessionId = req.headers['mcp-session-id'];
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
260
|
+
const headers = normalizeHeaders(req.headers);
|
|
261
|
+
const requestContext = {
|
|
262
|
+
transport: 'http',
|
|
263
|
+
...(typeof sessionId === 'string' ? { sessionId } : {}),
|
|
264
|
+
...(headers === undefined ? {} : { headers }),
|
|
265
|
+
};
|
|
266
|
+
await httpProxyContext.run(requestContext, async () => {
|
|
267
|
+
if (typeof sessionId === 'string') {
|
|
268
|
+
// Route to existing session
|
|
269
|
+
const session = sessions.get(sessionId);
|
|
270
|
+
if (!session) {
|
|
271
|
+
res.writeHead(404).end();
|
|
272
|
+
return;
|
|
273
|
+
}
|
|
274
|
+
await session.transport.handleRequest(req, res);
|
|
129
275
|
}
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
276
|
+
else {
|
|
277
|
+
// New session (initialize request)
|
|
278
|
+
if (httpOptions.maxSessions !== undefined && sessions.size >= httpOptions.maxSessions) {
|
|
279
|
+
res.writeHead(503).end();
|
|
280
|
+
return;
|
|
281
|
+
}
|
|
282
|
+
const proxyServer = createProxyServer(backend, options);
|
|
283
|
+
const transport = new StreamableHTTPServerTransport({
|
|
284
|
+
sessionIdGenerator: randomUUID,
|
|
285
|
+
onsessioninitialized: (id) => {
|
|
286
|
+
sessions.set(id, { transport, proxyServer });
|
|
287
|
+
if (httpOptions.sessionTtlMs !== undefined) {
|
|
288
|
+
const timer = setTimeout(() => {
|
|
289
|
+
const session = sessions.get(id);
|
|
290
|
+
if (session) {
|
|
291
|
+
sessions.delete(id);
|
|
292
|
+
void session.proxyServer.close();
|
|
293
|
+
}
|
|
294
|
+
}, httpOptions.sessionTtlMs);
|
|
295
|
+
timer.unref();
|
|
296
|
+
}
|
|
297
|
+
},
|
|
298
|
+
onsessionclosed: (id) => { sessions.delete(id); },
|
|
299
|
+
});
|
|
300
|
+
await proxyServer.connect(transport);
|
|
301
|
+
await transport.handleRequest(req, res);
|
|
302
|
+
}
|
|
303
|
+
});
|
|
143
304
|
};
|
|
144
305
|
handle().catch((err) => {
|
|
145
306
|
if (!res.headersSent)
|
|
146
307
|
res.writeHead(500).end();
|
|
147
|
-
|
|
308
|
+
(httpOptions.onError ?? console.error)(err);
|
|
309
|
+
});
|
|
310
|
+
});
|
|
311
|
+
const rawClose = server.close.bind(server);
|
|
312
|
+
let shuttingDown = false;
|
|
313
|
+
server.close = ((callback) => {
|
|
314
|
+
if (shuttingDown)
|
|
315
|
+
return rawClose(callback);
|
|
316
|
+
shuttingDown = true;
|
|
317
|
+
const activeSessions = [...sessions.values()];
|
|
318
|
+
sessions.clear();
|
|
319
|
+
void Promise.allSettled(activeSessions.map(({ proxyServer }) => proxyServer.close())).finally(() => {
|
|
320
|
+
rawClose(callback);
|
|
148
321
|
});
|
|
322
|
+
return server;
|
|
149
323
|
});
|
|
150
324
|
return new Promise((resolve, reject) => {
|
|
151
325
|
server.once('error', reject);
|
package/dist/core.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"core.js","sourceRoot":"","sources":["../src/core.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"core.js","sourceRoot":"","sources":["../src/core.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -2,6 +2,8 @@ export type { Middleware } from './middleware.js';
|
|
|
2
2
|
export { compose } from './middleware.js';
|
|
3
3
|
export type { BackendConfig, BackendClient } from './backendClient.js';
|
|
4
4
|
export { createBackendClient } from './backendClient.js';
|
|
5
|
-
export type {
|
|
5
|
+
export type { ProxyContext } from './proxyContext.js';
|
|
6
|
+
export { createProxyContext } from './proxyContext.js';
|
|
7
|
+
export type { ProxyOptions, HttpProxyOptions, ToolMiddleware, ResourceMiddleware, ListToolsMiddleware, } from './core.js';
|
|
6
8
|
export { hasToolContent, createProxyServer, startProxy, startHttpProxy } from './core.js';
|
|
7
9
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAClD,OAAO,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAE1C,YAAY,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACvE,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAEzD,YAAY,EACV,YAAY,EACZ,gBAAgB,EAChB,cAAc,EACd,kBAAkB,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAClD,OAAO,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAE1C,YAAY,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACvE,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAEzD,YAAY,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACtD,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAEvD,YAAY,EACV,YAAY,EACZ,gBAAgB,EAChB,cAAc,EACd,kBAAkB,EAClB,mBAAmB,GACpB,MAAM,WAAW,CAAC;AACnB,OAAO,EAAE,cAAc,EAAE,iBAAiB,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export { compose } from './middleware.js';
|
|
2
2
|
export { createBackendClient } from './backendClient.js';
|
|
3
|
+
export { createProxyContext } from './proxyContext.js';
|
|
3
4
|
export { hasToolContent, createProxyServer, startProxy, startHttpProxy } from './core.js';
|
|
4
5
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAG1C,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAG1C,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAGzD,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AASvD,OAAO,EAAE,cAAc,EAAE,iBAAiB,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC"}
|
package/dist/middleware.d.ts
CHANGED
|
@@ -11,8 +11,13 @@
|
|
|
11
11
|
* 4. piiMW exit → redact PII
|
|
12
12
|
* 5. auditMW exit → log clean result
|
|
13
13
|
*/
|
|
14
|
+
import { type ProxyContext } from './proxyContext.js';
|
|
14
15
|
/** Single middleware unit. May transform req before `next` or res after. */
|
|
15
|
-
export type Middleware<Req, Res> = (req: Req, next: (req: Req) => Promise<Res
|
|
16
|
+
export type Middleware<Req, Res> = (req: Req, next: (req: Req) => Promise<Res>, context: ProxyContext) => Promise<Res>;
|
|
17
|
+
type MiddlewarePipeline<Req, Res> = {
|
|
18
|
+
(req: Req, next: (req: Req) => Promise<Res>): Promise<Res>;
|
|
19
|
+
(req: Req, next: (req: Req) => Promise<Res>, context: ProxyContext): Promise<Res>;
|
|
20
|
+
};
|
|
16
21
|
/**
|
|
17
22
|
* Composes middlewares into one, outermost-first (Koa-style).
|
|
18
23
|
*
|
|
@@ -20,11 +25,12 @@ export type Middleware<Req, Res> = (req: Req, next: (req: Req) => Promise<Res>)
|
|
|
20
25
|
* const pipeline = compose([auditMW, piiMW]);
|
|
21
26
|
* const result = await pipeline(req, (r) => upstream.callTool(r.params));
|
|
22
27
|
*/
|
|
23
|
-
export declare function compose<Req, Res>(middlewares: ReadonlyArray<Middleware<Req, Res>>):
|
|
28
|
+
export declare function compose<Req, Res>(middlewares: ReadonlyArray<Middleware<Req, Res>>): MiddlewarePipeline<Req, Res>;
|
|
24
29
|
/**
|
|
25
30
|
* Like `compose` but in response-processing order (first = innermost).
|
|
26
31
|
* `pipe([piiMW, auditMW])` ≡ `compose([auditMW, piiMW])`.
|
|
27
32
|
* Used internally by mcpose core — consumers pass arrays to `ProxyOptions`.
|
|
28
33
|
*/
|
|
29
|
-
export declare function pipe<Req, Res>(middlewares: ReadonlyArray<Middleware<Req, Res>>):
|
|
34
|
+
export declare function pipe<Req, Res>(middlewares: ReadonlyArray<Middleware<Req, Res>>): MiddlewarePipeline<Req, Res>;
|
|
35
|
+
export {};
|
|
30
36
|
//# sourceMappingURL=middleware.d.ts.map
|
package/dist/middleware.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"middleware.d.ts","sourceRoot":"","sources":["../src/middleware.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;
|
|
1
|
+
{"version":3,"file":"middleware.d.ts","sourceRoot":"","sources":["../src/middleware.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AACH,OAAO,EAAsB,KAAK,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAE1E,4EAA4E;AAC5E,MAAM,MAAM,UAAU,CAAC,GAAG,EAAE,GAAG,IAAI,CACjC,GAAG,EAAE,GAAG,EACR,IAAI,EAAE,CAAC,GAAG,EAAE,GAAG,KAAK,OAAO,CAAC,GAAG,CAAC,EAChC,OAAO,EAAE,YAAY,KAClB,OAAO,CAAC,GAAG,CAAC,CAAC;AAElB,KAAK,kBAAkB,CAAC,GAAG,EAAE,GAAG,IAAI;IAClC,CAAC,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC,GAAG,EAAE,GAAG,KAAK,OAAO,CAAC,GAAG,CAAC,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC;IAC3D,CACE,GAAG,EAAE,GAAG,EACR,IAAI,EAAE,CAAC,GAAG,EAAE,GAAG,KAAK,OAAO,CAAC,GAAG,CAAC,EAChC,OAAO,EAAE,YAAY,GACpB,OAAO,CAAC,GAAG,CAAC,CAAC;CACjB,CAAC;AAEF;;;;;;GAMG;AACH,wBAAgB,OAAO,CAAC,GAAG,EAAE,GAAG,EAC9B,WAAW,EAAE,aAAa,CAAC,UAAU,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,GAC/C,kBAAkB,CAAC,GAAG,EAAE,GAAG,CAAC,CAkB9B;AAED;;;;GAIG;AACH,wBAAgB,IAAI,CAAC,GAAG,EAAE,GAAG,EAC3B,WAAW,EAAE,aAAa,CAAC,UAAU,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,GAC/C,kBAAkB,CAAC,GAAG,EAAE,GAAG,CAAC,CAE9B"}
|
package/dist/middleware.js
CHANGED
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
* 4. piiMW exit → redact PII
|
|
12
12
|
* 5. auditMW exit → log clean result
|
|
13
13
|
*/
|
|
14
|
+
import { createProxyContext } from './proxyContext.js';
|
|
14
15
|
/**
|
|
15
16
|
* Composes middlewares into one, outermost-first (Koa-style).
|
|
16
17
|
*
|
|
@@ -19,7 +20,7 @@
|
|
|
19
20
|
* const result = await pipeline(req, (r) => upstream.callTool(r.params));
|
|
20
21
|
*/
|
|
21
22
|
export function compose(middlewares) {
|
|
22
|
-
return (req, next) => {
|
|
23
|
+
return ((req, next, context = createProxyContext()) => {
|
|
23
24
|
let index = -1;
|
|
24
25
|
const dispatch = (i, currentReq) => {
|
|
25
26
|
if (i <= index) {
|
|
@@ -27,10 +28,10 @@ export function compose(middlewares) {
|
|
|
27
28
|
}
|
|
28
29
|
index = i;
|
|
29
30
|
const fn = i < middlewares.length ? middlewares[i] : (_r, n) => next(_r);
|
|
30
|
-
return Promise.resolve(fn(currentReq, (r) => dispatch(i + 1, r)));
|
|
31
|
+
return Promise.resolve(fn(currentReq, (r) => dispatch(i + 1, r), context));
|
|
31
32
|
};
|
|
32
33
|
return dispatch(0, req);
|
|
33
|
-
};
|
|
34
|
+
});
|
|
34
35
|
}
|
|
35
36
|
/**
|
|
36
37
|
* Like `compose` but in response-processing order (first = innermost).
|
package/dist/middleware.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"middleware.js","sourceRoot":"","sources":["../src/middleware.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;
|
|
1
|
+
{"version":3,"file":"middleware.js","sourceRoot":"","sources":["../src/middleware.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AACH,OAAO,EAAE,kBAAkB,EAAqB,MAAM,mBAAmB,CAAC;AAkB1E;;;;;;GAMG;AACH,MAAM,UAAU,OAAO,CACrB,WAAgD;IAEhD,OAAO,CAAC,CAAC,GAAG,EAAE,IAAI,EAAE,UAAwB,kBAAkB,EAAE,EAAE,EAAE;QAClE,IAAI,KAAK,GAAG,CAAC,CAAC,CAAC;QAEf,MAAM,QAAQ,GAAG,CAAC,CAAS,EAAE,UAAe,EAAgB,EAAE;YAC5D,IAAI,CAAC,IAAI,KAAK,EAAE,CAAC;gBACf,OAAO,OAAO,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,8BAA8B,CAAC,CAAC,CAAC;YACnE,CAAC;YACD,KAAK,GAAG,CAAC,CAAC;YAEV,MAAM,EAAE,GACN,CAAC,GAAG,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAE,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YAEjE,OAAO,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,UAAU,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,QAAQ,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC;QAC7E,CAAC,CAAC;QAEF,OAAO,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;IAC1B,CAAC,CAAiC,CAAC;AACrC,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,IAAI,CAClB,WAAgD;IAEhD,OAAO,OAAO,CAAC,CAAC,GAAG,WAAW,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC;AAC7C,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/** Normalized request metadata that mcpose passes through middleware layers. */
|
|
2
|
+
export interface ProxyContext {
|
|
3
|
+
requestId: string;
|
|
4
|
+
transport: 'stdio' | 'http';
|
|
5
|
+
sessionId?: string;
|
|
6
|
+
headers?: Readonly<Record<string, string>>;
|
|
7
|
+
signal?: AbortSignal;
|
|
8
|
+
}
|
|
9
|
+
/** Creates a middleware context with a fresh request ID. */
|
|
10
|
+
export declare function createProxyContext(overrides?: Partial<ProxyContext>): ProxyContext;
|
|
11
|
+
//# sourceMappingURL=proxyContext.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"proxyContext.d.ts","sourceRoot":"","sources":["../src/proxyContext.ts"],"names":[],"mappings":"AAEA,gFAAgF;AAChF,MAAM,WAAW,YAAY;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,OAAO,GAAG,MAAM,CAAC;IAC5B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IAC3C,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB;AAED,4DAA4D;AAC5D,wBAAgB,kBAAkB,CAChC,SAAS,GAAE,OAAO,CAAC,YAAY,CAAM,GACpC,YAAY,CAUd"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { randomUUID } from 'node:crypto';
|
|
2
|
+
/** Creates a middleware context with a fresh request ID. */
|
|
3
|
+
export function createProxyContext(overrides = {}) {
|
|
4
|
+
return {
|
|
5
|
+
requestId: overrides.requestId ?? randomUUID(),
|
|
6
|
+
transport: overrides.transport ?? 'stdio',
|
|
7
|
+
...(overrides.sessionId === undefined
|
|
8
|
+
? {}
|
|
9
|
+
: { sessionId: overrides.sessionId }),
|
|
10
|
+
...(overrides.headers === undefined ? {} : { headers: overrides.headers }),
|
|
11
|
+
...(overrides.signal === undefined ? {} : { signal: overrides.signal }),
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
//# sourceMappingURL=proxyContext.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"proxyContext.js","sourceRoot":"","sources":["../src/proxyContext.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAWzC,4DAA4D;AAC5D,MAAM,UAAU,kBAAkB,CAChC,YAAmC,EAAE;IAErC,OAAO;QACL,SAAS,EAAE,SAAS,CAAC,SAAS,IAAI,UAAU,EAAE;QAC9C,SAAS,EAAE,SAAS,CAAC,SAAS,IAAI,OAAO;QACzC,GAAG,CAAC,SAAS,CAAC,SAAS,KAAK,SAAS;YACnC,CAAC,CAAC,EAAE;YACJ,CAAC,CAAC,EAAE,SAAS,EAAE,SAAS,CAAC,SAAS,EAAE,CAAC;QACvC,GAAG,CAAC,SAAS,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,SAAS,CAAC,OAAO,EAAE,CAAC;QAC1E,GAAG,CAAC,SAAS,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,SAAS,CAAC,MAAM,EAAE,CAAC;KACxE,CAAC;AACJ,CAAC"}
|
package/dist/testing.d.ts
CHANGED
|
@@ -2,9 +2,10 @@
|
|
|
2
2
|
* Test helpers for mcpose middleware. No test framework imports — works in any env.
|
|
3
3
|
* @module mcpose/testing
|
|
4
4
|
*/
|
|
5
|
-
import type { CallToolRequest, CallToolResult, ReadResourceResult, Tool, Resource, Prompt, CallToolRequestParams, GetPromptResult } from '@modelcontextprotocol/sdk/types.js';
|
|
5
|
+
import type { CallToolRequest, CallToolResult, ReadResourceResult, Tool, Resource, Prompt, CallToolRequestParams, GetPromptResult, ServerCapabilities } from '@modelcontextprotocol/sdk/types.js';
|
|
6
6
|
import type { ToolMiddleware } from './core.js';
|
|
7
7
|
import type { BackendClient } from './backendClient.js';
|
|
8
|
+
import { type ProxyContext } from './proxyContext.js';
|
|
8
9
|
/**
|
|
9
10
|
* Runs a `ToolMiddleware` and narrows result to `CallToolResult`.
|
|
10
11
|
* Throws if upstream returns legacy `{ toolResult }` shape.
|
|
@@ -13,9 +14,11 @@ import type { BackendClient } from './backendClient.js';
|
|
|
13
14
|
* const result = await runToolMiddleware(mw, req, async () => mockResult);
|
|
14
15
|
* expect(result.content[0]).toMatchObject({ type: 'text' });
|
|
15
16
|
*/
|
|
16
|
-
export declare function runToolMiddleware(mw: ToolMiddleware, req: CallToolRequest, next: (req: CallToolRequest) => Promise<CallToolResult
|
|
17
|
+
export declare function runToolMiddleware(mw: ToolMiddleware, req: CallToolRequest, next: (req: CallToolRequest) => Promise<CallToolResult>, context?: ProxyContext): Promise<CallToolResult>;
|
|
17
18
|
/** Config for mock backend client. */
|
|
18
19
|
export interface MockBackendClientOptions {
|
|
20
|
+
/** Default: tools/resources/prompts enabled */
|
|
21
|
+
capabilities?: ServerCapabilities;
|
|
19
22
|
/** Default: `[]` */
|
|
20
23
|
tools?: Tool[];
|
|
21
24
|
/**
|
package/dist/testing.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"testing.d.ts","sourceRoot":"","sources":["../src/testing.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,KAAK,EACV,eAAe,EACf,cAAc,EAId,kBAAkB,EAClB,IAAI,EACJ,QAAQ,EACR,MAAM,EACN,qBAAqB,EAGrB,eAAe,
|
|
1
|
+
{"version":3,"file":"testing.d.ts","sourceRoot":"","sources":["../src/testing.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,KAAK,EACV,eAAe,EACf,cAAc,EAId,kBAAkB,EAClB,IAAI,EACJ,QAAQ,EACR,MAAM,EACN,qBAAqB,EAGrB,eAAe,EACf,kBAAkB,EACnB,MAAM,oCAAoC,CAAC;AAE5C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAChD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACxD,OAAO,EAAsB,KAAK,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAE1E;;;;;;;GAOG;AACH,wBAAsB,iBAAiB,CACrC,EAAE,EAAE,cAAc,EAClB,GAAG,EAAE,eAAe,EACpB,IAAI,EAAE,CAAC,GAAG,EAAE,eAAe,KAAK,OAAO,CAAC,cAAc,CAAC,EACvD,OAAO,GAAE,YAAmC,GAC3C,OAAO,CAAC,cAAc,CAAC,CAQzB;AAED,sCAAsC;AACtC,MAAM,WAAW,wBAAwB;IACvC,+CAA+C;IAC/C,YAAY,CAAC,EAAE,kBAAkB,CAAC;IAClC,oBAAoB;IACpB,KAAK,CAAC,EAAE,IAAI,EAAE,CAAC;IACf;;;OAGG;IACH,gBAAgB,CAAC,EACb,cAAc,GACd,CAAC,CAAC,MAAM,EAAE,qBAAqB,KAAK,cAAc,CAAC,CAAC;IACxD,oBAAoB;IACpB,SAAS,CAAC,EAAE,QAAQ,EAAE,CAAC;IACvB,oEAAoE;IACpE,oBAAoB,CAAC,EAAE,kBAAkB,CAAC;IAC1C,oBAAoB;IACpB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,kCAAkC;IAClC,iBAAiB,CAAC,EAAE,eAAe,CAAC;CACrC;AAED;;;;;;;;;GASG;AACH,wBAAgB,uBAAuB,CACrC,OAAO,GAAE,wBAA6B,GACrC,aAAa,CA8Cf"}
|
package/dist/testing.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { hasToolContent } from './core.js';
|
|
2
|
+
import { createProxyContext } from './proxyContext.js';
|
|
2
3
|
/**
|
|
3
4
|
* Runs a `ToolMiddleware` and narrows result to `CallToolResult`.
|
|
4
5
|
* Throws if upstream returns legacy `{ toolResult }` shape.
|
|
@@ -7,8 +8,8 @@ import { hasToolContent } from './core.js';
|
|
|
7
8
|
* const result = await runToolMiddleware(mw, req, async () => mockResult);
|
|
8
9
|
* expect(result.content[0]).toMatchObject({ type: 'text' });
|
|
9
10
|
*/
|
|
10
|
-
export async function runToolMiddleware(mw, req, next) {
|
|
11
|
-
const result = await mw(req, next);
|
|
11
|
+
export async function runToolMiddleware(mw, req, next, context = createProxyContext()) {
|
|
12
|
+
const result = await mw(req, next, context);
|
|
12
13
|
if (!hasToolContent(result)) {
|
|
13
14
|
throw new Error('runToolMiddleware: middleware returned legacy toolResult shape — expected { content: [...] }');
|
|
14
15
|
}
|
|
@@ -25,7 +26,13 @@ export async function runToolMiddleware(mw, req, next) {
|
|
|
25
26
|
* const result = await pipeline(req, (r) => backend.callTool(r.params, undefined));
|
|
26
27
|
*/
|
|
27
28
|
export function createMockBackendClient(options = {}) {
|
|
29
|
+
const capabilities = options.capabilities ?? {
|
|
30
|
+
tools: {},
|
|
31
|
+
resources: {},
|
|
32
|
+
prompts: {},
|
|
33
|
+
};
|
|
28
34
|
return {
|
|
35
|
+
getServerCapabilities: () => capabilities,
|
|
29
36
|
listTools: async () => ({
|
|
30
37
|
tools: options.tools ?? [],
|
|
31
38
|
}),
|
|
@@ -45,6 +52,9 @@ export function createMockBackendClient(options = {}) {
|
|
|
45
52
|
prompts: options.prompts ?? [],
|
|
46
53
|
}),
|
|
47
54
|
getPrompt: async (_params) => options.getPromptResponse ?? { messages: [] },
|
|
55
|
+
setNotificationHandler: () => undefined,
|
|
56
|
+
removeNotificationHandler: () => undefined,
|
|
57
|
+
close: async () => undefined,
|
|
48
58
|
};
|
|
49
59
|
}
|
|
50
60
|
//# sourceMappingURL=testing.js.map
|
package/dist/testing.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"testing.js","sourceRoot":"","sources":["../src/testing.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"testing.js","sourceRoot":"","sources":["../src/testing.ts"],"names":[],"mappings":"AAoBA,OAAO,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAG3C,OAAO,EAAE,kBAAkB,EAAqB,MAAM,mBAAmB,CAAC;AAE1E;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,iBAAiB,CACrC,EAAkB,EAClB,GAAoB,EACpB,IAAuD,EACvD,UAAwB,kBAAkB,EAAE;IAE5C,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC,GAAG,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC;IAC5C,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC,EAAE,CAAC;QAC5B,MAAM,IAAI,KAAK,CACb,8FAA8F,CAC/F,CAAC;IACJ,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAyBD;;;;;;;;;GASG;AACH,MAAM,UAAU,uBAAuB,CACrC,UAAoC,EAAE;IAEtC,MAAM,YAAY,GAAG,OAAO,CAAC,YAAY,IAAI;QAC3C,KAAK,EAAE,EAAE;QACT,SAAS,EAAE,EAAE;QACb,OAAO,EAAE,EAAE;KACZ,CAAC;IAEF,OAAO;QACL,qBAAqB,EAAE,GAAuB,EAAE,CAAC,YAAY;QAE7D,SAAS,EAAE,KAAK,IAA8B,EAAE,CAAC,CAAC;YAChD,KAAK,EAAE,OAAO,CAAC,KAAK,IAAI,EAAE;SAC3B,CAAC;QAEF,QAAQ,EAAE,KAAK,EACb,MAA6B,EACJ,EAAE;YAC3B,MAAM,IAAI,GAAG,OAAO,CAAC,gBAAgB,CAAC;YACtC,IAAI,OAAO,IAAI,KAAK,UAAU;gBAAE,OAAO,IAAI,CAAC,MAAM,CAAC,CAAC;YACpD,OAAO,IAAI,IAAI,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,eAAe,EAAE,CAAC,EAAE,CAAC;QACxE,CAAC;QAED,aAAa,EAAE,KAAK,IAAkC,EAAE,CAAC,CAAC;YACxD,SAAS,EAAE,OAAO,CAAC,SAAS,IAAI,EAAE;SACnC,CAAC;QAEF,YAAY,EAAE,KAAK,EACjB,OAAkC,EACL,EAAE,CAC/B,OAAO,CAAC,oBAAoB,IAAI;YAC9B,QAAQ,EAAE,CAAC,EAAE,GAAG,EAAE,EAAE,EAAE,IAAI,EAAE,eAAe,EAAE,CAAC;SAC/C;QAEH,WAAW,EAAE,KAAK,IAAgC,EAAE,CAAC,CAAC;YACpD,OAAO,EAAE,OAAO,CAAC,OAAO,IAAI,EAAE;SAC/B,CAAC;QAEF,SAAS,EAAE,KAAK,EACd,OAA+B,EACL,EAAE,CAC5B,OAAO,CAAC,iBAAiB,IAAI,EAAE,QAAQ,EAAE,EAAE,EAAE;QAE/C,sBAAsB,EAAE,GAAG,EAAE,CAAC,SAAS;QACvC,yBAAyB,EAAE,GAAG,EAAE,CAAC,SAAS;QAC1C,KAAK,EAAE,KAAK,IAAI,EAAE,CAAC,SAAS;KACD,CAAC;AAChC,CAAC"}
|