@kya-os/mcp 1.18.0 → 1.20.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/CHANGELOG.md +336 -0
- package/CONFORMANCE.md +10 -4
- package/README.md +57 -0
- package/SPEC.md +37 -3
- package/dist/card/cimd.js +6 -2
- package/dist/card/cimd.js.map +1 -1
- package/dist/card/index.d.ts +1 -0
- package/dist/card/index.js +1 -0
- package/dist/card/index.js.map +1 -1
- package/dist/card/revocation.d.ts +15 -4
- package/dist/card/revocation.js +9 -4
- package/dist/card/revocation.js.map +1 -1
- package/dist/card/status-list-proof.d.ts +32 -0
- package/dist/card/status-list-proof.js +102 -0
- package/dist/card/status-list-proof.js.map +1 -0
- package/dist/delegation/verification-method-key.d.ts +4 -1
- package/dist/delegation/verification-method-key.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/middleware/index.d.ts +3 -1
- package/dist/middleware/index.js +2 -0
- package/dist/middleware/index.js.map +1 -1
- package/dist/middleware/kya-os-transport.d.ts +43 -12
- package/dist/middleware/kya-os-transport.js +151 -28
- package/dist/middleware/kya-os-transport.js.map +1 -1
- package/dist/middleware/mcp-tool-callback.d.ts +48 -0
- package/dist/middleware/mcp-tool-callback.js +38 -0
- package/dist/middleware/mcp-tool-callback.js.map +1 -0
- package/dist/middleware/serve-in-process.d.ts +41 -0
- package/dist/middleware/serve-in-process.js +86 -0
- package/dist/middleware/serve-in-process.js.map +1 -0
- package/dist/middleware/with-kya-os-server.d.ts +14 -3
- package/dist/middleware/with-kya-os-server.js +4 -1
- package/dist/middleware/with-kya-os-server.js.map +1 -1
- package/dist/middleware/with-kya-os.config-types.d.ts +24 -0
- package/dist/middleware/with-kya-os.d.ts +4 -0
- package/dist/middleware/with-kya-os.delegation-gate.d.ts +2 -1
- package/dist/middleware/with-kya-os.delegation-gate.js +12 -18
- package/dist/middleware/with-kya-os.delegation-gate.js.map +1 -1
- package/dist/middleware/with-kya-os.delegation-verify.d.ts +7 -12
- package/dist/middleware/with-kya-os.delegation-verify.js +37 -9
- package/dist/middleware/with-kya-os.delegation-verify.js.map +1 -1
- package/dist/middleware/with-kya-os.deps.d.ts +15 -4
- package/dist/middleware/with-kya-os.helpers.d.ts +5 -0
- package/dist/middleware/with-kya-os.helpers.js +13 -0
- package/dist/middleware/with-kya-os.helpers.js.map +1 -1
- package/dist/middleware/with-kya-os.js +23 -0
- package/dist/middleware/with-kya-os.js.map +1 -1
- package/dist/middleware/with-kya-os.outcome.d.ts +18 -0
- package/dist/middleware/with-kya-os.outcome.js +36 -0
- package/dist/middleware/with-kya-os.outcome.js.map +1 -0
- package/dist/middleware/with-kya-os.policy-gate.d.ts +2 -1
- package/dist/middleware/with-kya-os.policy-gate.js +2 -1
- package/dist/middleware/with-kya-os.policy-gate.js.map +1 -1
- package/dist/middleware/with-kya-os.session.d.ts +76 -10
- package/dist/middleware/with-kya-os.session.js +739 -164
- package/dist/middleware/with-kya-os.session.js.map +1 -1
- package/dist/middleware/with-kya-os.types.d.ts +102 -8
- package/dist/proof/generator.d.ts +13 -0
- package/dist/proof/generator.js +15 -0
- package/dist/proof/generator.js.map +1 -1
- package/dist/proof/verifier.js +14 -9
- package/dist/proof/verifier.js.map +1 -1
- package/package.json +3 -1
|
@@ -13,33 +13,72 @@
|
|
|
13
13
|
* 1. Incoming `tools/call` requests are captured (by id) to record tool
|
|
14
14
|
* name and arguments for proof generation.
|
|
15
15
|
* 2. Outgoing responses for those ids get a proof injected into `_meta`,
|
|
16
|
-
* unless the middleware's own wrappers
|
|
17
|
-
*
|
|
18
|
-
* 3.
|
|
19
|
-
*
|
|
16
|
+
* unless the middleware's own wrappers produced the result, which they
|
|
17
|
+
* mark with a private per-middleware stamp.
|
|
18
|
+
* 3. The wrappers leave their proofs here, and every proof is made in
|
|
19
|
+
* `send()`, over the result as the MCP SDK finished it: the SDK changes
|
|
20
|
+
* a result after the handler returns (`resultType` on the 2026-07-28
|
|
21
|
+
* revision, a filled-in or appended `content`), and the proof covers
|
|
22
|
+
* what it covers of the result the client receives.
|
|
23
|
+
* 4. All other message types pass through unmodified, except that the
|
|
24
|
+
* middleware's private members are removed from every result before it
|
|
25
|
+
* is sent.
|
|
20
26
|
*
|
|
21
27
|
* @module kya-os-transport
|
|
22
28
|
*/
|
|
23
|
-
import { attachOuterProofLayer,
|
|
29
|
+
import { attachOuterProofLayer, withoutOutcomeMeta, withoutPrivateMeta, withoutPrivateMembers, } from "./with-kya-os.session.js";
|
|
24
30
|
import { logger } from "../logging/index.js";
|
|
25
31
|
/**
|
|
26
32
|
* Creates a transport wrapper that injects KYA-OS proofs into `tools/call`
|
|
27
|
-
* responses
|
|
33
|
+
* responses, and makes the proofs the middleware's wrappers and
|
|
34
|
+
* `proveOutcome` leave to it, over each result as it is sent. A server on the
|
|
35
|
+
* low-level `Server` API connects through it:
|
|
36
|
+
* `server.connect(createKyaOsTransport(transport, kyaos))`.
|
|
37
|
+
*
|
|
38
|
+
* It proves and audits the result of every tool it is not told to exclude,
|
|
39
|
+
* including tools registered without a wrapper, as `withKyaOs` does. A
|
|
40
|
+
* low-level server that used only the wrappers on an unwrapped transport,
|
|
41
|
+
* which 1.19.0 allowed, sent its unwrapped tools' results unproven; through
|
|
42
|
+
* this transport they carry a proof too.
|
|
28
43
|
*
|
|
29
44
|
* @param inner - The real transport (Stdio, HTTP, etc.)
|
|
30
45
|
* @param kyaos - Configured KyaOsMiddleware instance
|
|
31
|
-
* @param exclude -
|
|
46
|
+
* @param exclude - More tool names whose results are not proved by the
|
|
47
|
+
* transport itself, in addition to the protocol tools `_kyaos` and
|
|
48
|
+
* `_kyaos_handshake`, which are always excluded (as `excludeTools` adds
|
|
49
|
+
* to them in `withKyaOs`). A wrapper's own proof is made whatever this
|
|
50
|
+
* says.
|
|
32
51
|
*/
|
|
33
|
-
export function createKyaOsTransport(inner, kyaos, exclude = [
|
|
52
|
+
export function createKyaOsTransport(inner, kyaos, exclude = []) {
|
|
34
53
|
// Request id → { toolName, args } for pending tool calls
|
|
35
54
|
const pending = new Map();
|
|
36
|
-
|
|
37
|
-
//
|
|
38
|
-
//
|
|
39
|
-
|
|
55
|
+
const excluded = new Set(["_kyaos", "_kyaos_handshake", ...exclude]);
|
|
56
|
+
// From here on the middleware's wrappers stamp what they return, and the
|
|
57
|
+
// layer tells a stamped result from one that only looks proven, and makes
|
|
58
|
+
// the proofs they leave to it. Undefined for a custom middleware, whose
|
|
59
|
+
// results are all proved here.
|
|
60
|
+
const layer = attachOuterProofLayer(kyaos.wrapWithProof);
|
|
61
|
+
// While started and not closed, this transport counts as open for the
|
|
62
|
+
// middleware; its wrappers run only then.
|
|
63
|
+
let release;
|
|
64
|
+
const releaseOpen = () => {
|
|
65
|
+
release?.();
|
|
66
|
+
release = undefined;
|
|
67
|
+
};
|
|
68
|
+
// The close handler the server installed through the wrapper. It runs the
|
|
69
|
+
// handler the caller set on the inner transport before connecting, which
|
|
70
|
+
// the server read through the getter below and chained.
|
|
71
|
+
let closeHandler;
|
|
72
|
+
const closed = () => {
|
|
73
|
+
releaseOpen();
|
|
74
|
+
closeHandler?.();
|
|
75
|
+
};
|
|
40
76
|
const wrapper = {
|
|
41
77
|
start: () => inner.start(),
|
|
42
|
-
close: () =>
|
|
78
|
+
close: async () => {
|
|
79
|
+
releaseOpen();
|
|
80
|
+
await inner.close();
|
|
81
|
+
},
|
|
43
82
|
// McpServer writes into wrapper.onmessage — forward to inner so the
|
|
44
83
|
// real transport can drive it.
|
|
45
84
|
set onmessage(handler) {
|
|
@@ -48,11 +87,17 @@ export function createKyaOsTransport(inner, kyaos, exclude = ["_kyaos", "_kyaos_
|
|
|
48
87
|
get onmessage() {
|
|
49
88
|
return inner.onmessage;
|
|
50
89
|
},
|
|
90
|
+
// The inner transport may close on its own (the client went away), so
|
|
91
|
+
// its close also ends this transport's count. Before a handler is set
|
|
92
|
+
// here, the getter reports the inner transport's own: the SDK reads it
|
|
93
|
+
// when it connects and chains it (a session map's cleanup, say), so it
|
|
94
|
+
// keeps running.
|
|
51
95
|
set onclose(handler) {
|
|
52
|
-
|
|
96
|
+
closeHandler = handler;
|
|
97
|
+
inner.onclose = closed;
|
|
53
98
|
},
|
|
54
99
|
get onclose() {
|
|
55
|
-
return inner.onclose;
|
|
100
|
+
return closeHandler ?? (inner.onclose === closed ? undefined : inner.onclose);
|
|
56
101
|
},
|
|
57
102
|
set onerror(handler) {
|
|
58
103
|
inner.onerror = handler;
|
|
@@ -60,9 +105,43 @@ export function createKyaOsTransport(inner, kyaos, exclude = ["_kyaos", "_kyaos_
|
|
|
60
105
|
get onerror() {
|
|
61
106
|
return inner.onerror;
|
|
62
107
|
},
|
|
108
|
+
// What the SDK reads off, or hands to, the transport it connects passes
|
|
109
|
+
// through to the inner transport: its session id (which the SDK puts on
|
|
110
|
+
// each request's context), the negotiated protocol versions, the scope
|
|
111
|
+
// challenge resolver, and whether it streams per request. These are every
|
|
112
|
+
// transport member SDK 1 and SDK 2 servers read or feature-detect.
|
|
113
|
+
get sessionId() {
|
|
114
|
+
return inner.sessionId;
|
|
115
|
+
},
|
|
116
|
+
set sessionId(sessionId) {
|
|
117
|
+
inner.sessionId = sessionId;
|
|
118
|
+
},
|
|
119
|
+
get setProtocolVersion() {
|
|
120
|
+
return inner.setProtocolVersion === undefined
|
|
121
|
+
? undefined
|
|
122
|
+
: (version) => inner.setProtocolVersion(version);
|
|
123
|
+
},
|
|
124
|
+
get setSupportedProtocolVersions() {
|
|
125
|
+
return inner.setSupportedProtocolVersions === undefined
|
|
126
|
+
? undefined
|
|
127
|
+
: (versions) => inner.setSupportedProtocolVersions(versions);
|
|
128
|
+
},
|
|
129
|
+
// SDK 2's McpServer installs per-tool OAuth scope enforcement only when
|
|
130
|
+
// the transport has this member (an `in` check), so a wrapper without it
|
|
131
|
+
// silently switched the enforcement off.
|
|
132
|
+
get setScopeChallengeResolver() {
|
|
133
|
+
return inner.setScopeChallengeResolver === undefined
|
|
134
|
+
? undefined
|
|
135
|
+
: (resolver) => inner.setScopeChallengeResolver(resolver);
|
|
136
|
+
},
|
|
137
|
+
get hasPerRequestStream() {
|
|
138
|
+
return inner.hasPerRequestStream;
|
|
139
|
+
},
|
|
63
140
|
// McpServer calls send() for every outgoing message.
|
|
64
141
|
// Intercept tools/call responses here to inject proofs.
|
|
65
|
-
|
|
142
|
+
// The SDK's send options (relatedRequestId, resumption tokens) are
|
|
143
|
+
// passed through unchanged.
|
|
144
|
+
async send(message, options) {
|
|
66
145
|
// Only a response (result or error, no method) can answer a pending call:
|
|
67
146
|
// a server-initiated request such as elicitation/create numbers its ids
|
|
68
147
|
// in the server's own space, so its id can equal a pending client id.
|
|
@@ -74,11 +153,12 @@ export function createKyaOsTransport(inner, kyaos, exclude = ["_kyaos", "_kyaos_
|
|
|
74
153
|
const rawResult = message.result;
|
|
75
154
|
// A result the middleware's wrappers already proved or audited (a
|
|
76
155
|
// delegated call's scope-bearing proof, a signed needs_authorization
|
|
77
|
-
// outcome, an
|
|
78
|
-
//
|
|
79
|
-
//
|
|
80
|
-
//
|
|
81
|
-
|
|
156
|
+
// outcome, an outcome application code proved with proveOutcome, an
|
|
157
|
+
// audited error) passes through: proving it again would replace its
|
|
158
|
+
// proof and record its lifecycle twice. Only the stamp shows that;
|
|
159
|
+
// proof, proofError and audit members can come from any handler,
|
|
160
|
+
// including one relaying an upstream server's result.
|
|
161
|
+
if (rawResult && layer?.owns(rawResult) !== true) {
|
|
82
162
|
// Those members are untrusted here, so they are removed and the
|
|
83
163
|
// result is proved and audited as any other. Other members stay.
|
|
84
164
|
const received = withoutOutcomeMeta(rawResult);
|
|
@@ -116,13 +196,33 @@ export function createKyaOsTransport(inner, kyaos, exclude = ["_kyaos", "_kyaos_
|
|
|
116
196
|
}
|
|
117
197
|
}
|
|
118
198
|
}
|
|
119
|
-
//
|
|
199
|
+
// Whichever path the message took: a proof a wrapper left for the wire
|
|
200
|
+
// is made now, over the result as it is sent, and only by a proof left
|
|
201
|
+
// for the tool this answers. The private members never leave the
|
|
202
|
+
// process, from a result or from any other part of a message: a
|
|
203
|
+
// notification or request's params (a tool logging a wrapped result,
|
|
204
|
+
// say) or an error's data.
|
|
120
205
|
if (typeof message.result === "object" && message.result !== null) {
|
|
121
|
-
const
|
|
206
|
+
const result = message.result;
|
|
207
|
+
const sent = layer
|
|
208
|
+
? await layer.send(result, call === undefined ? undefined : { toolName: call.toolName })
|
|
209
|
+
: withoutPrivateMeta(result);
|
|
122
210
|
if (sent !== message.result)
|
|
123
211
|
message = { ...message, result: sent };
|
|
124
212
|
}
|
|
125
|
-
|
|
213
|
+
const scrub = (value) => (layer ? layer.scrub(value) : withoutPrivateMembers(value));
|
|
214
|
+
if (message.params !== undefined) {
|
|
215
|
+
const params = scrub(message.params);
|
|
216
|
+
if (params !== message.params)
|
|
217
|
+
message = { ...message, params };
|
|
218
|
+
}
|
|
219
|
+
const error = message.error;
|
|
220
|
+
if (error !== null && typeof error === "object" && error.data !== undefined) {
|
|
221
|
+
const data = scrub(error.data);
|
|
222
|
+
if (data !== error.data)
|
|
223
|
+
message = { ...message, error: { ...error, data } };
|
|
224
|
+
}
|
|
225
|
+
return options === undefined ? inner.send(message) : inner.send(message, options);
|
|
126
226
|
},
|
|
127
227
|
};
|
|
128
228
|
// Intercept incoming messages from the real transport to capture
|
|
@@ -131,18 +231,35 @@ export function createKyaOsTransport(inner, kyaos, exclude = ["_kyaos", "_kyaos_
|
|
|
131
231
|
// via server.connect() — so we proxy through the getter/setter above and
|
|
132
232
|
// add our interception in a one-time initializer on start().
|
|
133
233
|
const originalStart = inner.start.bind(inner);
|
|
234
|
+
let interceptor;
|
|
134
235
|
wrapper.start = async () => {
|
|
135
236
|
await originalStart();
|
|
237
|
+
// Counted once however often start() is called, until the transport closes.
|
|
238
|
+
release ??= layer?.open();
|
|
239
|
+
// A close handler set on the inner transport and never read through the
|
|
240
|
+
// wrapper is adopted, so it still runs, after the one installed here.
|
|
241
|
+
const foreign = inner.onclose;
|
|
242
|
+
if (foreign !== undefined && foreign !== closed) {
|
|
243
|
+
const installed = closeHandler;
|
|
244
|
+
closeHandler = installed === undefined ? foreign : () => {
|
|
245
|
+
foreign();
|
|
246
|
+
installed();
|
|
247
|
+
};
|
|
248
|
+
}
|
|
249
|
+
inner.onclose = closed;
|
|
136
250
|
// At this point McpServer has called server.connect(wrapper) which set
|
|
137
251
|
// wrapper.onmessage = <McpServer handler>. That assignment forwarded to
|
|
138
|
-
// inner.onmessage via the setter above. Now we inject our interceptor
|
|
252
|
+
// inner.onmessage via the setter above. Now we inject our interceptor,
|
|
253
|
+
// once.
|
|
254
|
+
if (interceptor !== undefined && inner.onmessage === interceptor)
|
|
255
|
+
return;
|
|
139
256
|
const downstream = inner.onmessage;
|
|
140
|
-
|
|
257
|
+
interceptor = (message, extra) => {
|
|
141
258
|
if (message.method === "tools/call" &&
|
|
142
259
|
message.id !== undefined) {
|
|
143
260
|
const params = message.params;
|
|
144
261
|
const toolName = params?.name;
|
|
145
|
-
if (toolName && !
|
|
262
|
+
if (toolName && !excluded.has(toolName)) {
|
|
146
263
|
pending.set(message.id, {
|
|
147
264
|
toolName,
|
|
148
265
|
args: params?.arguments ?? {},
|
|
@@ -155,8 +272,14 @@ export function createKyaOsTransport(inner, kyaos, exclude = ["_kyaos", "_kyaos_
|
|
|
155
272
|
const params = message.params;
|
|
156
273
|
pending.delete(params?.requestId);
|
|
157
274
|
}
|
|
158
|
-
|
|
275
|
+
// The SDK's message context (session id, authInfo, requestInfo) rides
|
|
276
|
+
// through unchanged.
|
|
277
|
+
if (extra === undefined)
|
|
278
|
+
downstream?.(message);
|
|
279
|
+
else
|
|
280
|
+
downstream?.(message, extra);
|
|
159
281
|
};
|
|
282
|
+
inner.onmessage = interceptor;
|
|
160
283
|
};
|
|
161
284
|
return wrapper;
|
|
162
285
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"kya-os-transport.js","sourceRoot":"","sources":["../../src/middleware/kya-os-transport.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"kya-os-transport.js","sourceRoot":"","sources":["../../src/middleware/kya-os-transport.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Register a middleware-wrapped handler with the MCP SDK's `registerTool`.
|
|
3
|
+
*
|
|
4
|
+
* A {@link KyaOsToolHandler} takes `(args, sessionId?, context?)`; the SDK
|
|
5
|
+
* calls a tool callback with `(args, extra)`, where `extra` is its own request
|
|
6
|
+
* context. Passed straight in, the handler needs a cast, and the SDK's context
|
|
7
|
+
* then arrives as the KYA-OS session id: no session matches it, and the
|
|
8
|
+
* result goes out unproven. The adapter passes the arguments alone, so the
|
|
9
|
+
* handler resolves its session as any unthreaded call does. The SDK's
|
|
10
|
+
* transport session id is a different thing from a KYA-OS session id, so
|
|
11
|
+
* nothing from `extra` is forwarded.
|
|
12
|
+
*
|
|
13
|
+
* Typed structurally, so this package keeps no type dependency on the SDK.
|
|
14
|
+
*/
|
|
15
|
+
import type { KyaOsToolHandler } from "./with-kya-os.types.js";
|
|
16
|
+
/** A tool result in the shape the MCP SDK's `registerTool` callback returns. */
|
|
17
|
+
export interface McpToolCallbackResult {
|
|
18
|
+
content: Array<{
|
|
19
|
+
type: "text";
|
|
20
|
+
text: string;
|
|
21
|
+
[key: string]: unknown;
|
|
22
|
+
}>;
|
|
23
|
+
structuredContent?: Record<string, unknown>;
|
|
24
|
+
isError?: boolean;
|
|
25
|
+
_meta?: Record<string, unknown>;
|
|
26
|
+
[key: string]: unknown;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* A callback for a tool registered with an `inputSchema` (an empty one for a
|
|
30
|
+
* tool without arguments): the SDK calls it with the parsed arguments and its
|
|
31
|
+
* request context.
|
|
32
|
+
*/
|
|
33
|
+
export type McpToolCallback<T extends Record<string, unknown> = Record<string, unknown>> = (args: T, extra: unknown) => Promise<McpToolCallbackResult>;
|
|
34
|
+
/**
|
|
35
|
+
* Adapt a handler (one from `wrapWithProof`, `wrapWithDelegation`,
|
|
36
|
+
* `withPolicyGate`, or one returning `proveOutcome`'s result) to the MCP
|
|
37
|
+
* SDK's `registerTool`, with no cast:
|
|
38
|
+
*
|
|
39
|
+
* ```ts
|
|
40
|
+
* server.registerTool('checkout', { inputSchema }, toMcpToolCallback(gated));
|
|
41
|
+
* ```
|
|
42
|
+
*
|
|
43
|
+
* The handler's result is returned as it is; the SDK validates it. Called
|
|
44
|
+
* with one argument, which is how the SDK calls a tool registered without an
|
|
45
|
+
* `inputSchema`, the handler gets empty arguments instead of the SDK's
|
|
46
|
+
* request context.
|
|
47
|
+
*/
|
|
48
|
+
export declare function toMcpToolCallback<T extends Record<string, unknown> = Record<string, unknown>>(handler: KyaOsToolHandler<T>): McpToolCallback<T>;
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Register a middleware-wrapped handler with the MCP SDK's `registerTool`.
|
|
3
|
+
*
|
|
4
|
+
* A {@link KyaOsToolHandler} takes `(args, sessionId?, context?)`; the SDK
|
|
5
|
+
* calls a tool callback with `(args, extra)`, where `extra` is its own request
|
|
6
|
+
* context. Passed straight in, the handler needs a cast, and the SDK's context
|
|
7
|
+
* then arrives as the KYA-OS session id: no session matches it, and the
|
|
8
|
+
* result goes out unproven. The adapter passes the arguments alone, so the
|
|
9
|
+
* handler resolves its session as any unthreaded call does. The SDK's
|
|
10
|
+
* transport session id is a different thing from a KYA-OS session id, so
|
|
11
|
+
* nothing from `extra` is forwarded.
|
|
12
|
+
*
|
|
13
|
+
* Typed structurally, so this package keeps no type dependency on the SDK.
|
|
14
|
+
*/
|
|
15
|
+
/**
|
|
16
|
+
* Adapt a handler (one from `wrapWithProof`, `wrapWithDelegation`,
|
|
17
|
+
* `withPolicyGate`, or one returning `proveOutcome`'s result) to the MCP
|
|
18
|
+
* SDK's `registerTool`, with no cast:
|
|
19
|
+
*
|
|
20
|
+
* ```ts
|
|
21
|
+
* server.registerTool('checkout', { inputSchema }, toMcpToolCallback(gated));
|
|
22
|
+
* ```
|
|
23
|
+
*
|
|
24
|
+
* The handler's result is returned as it is; the SDK validates it. Called
|
|
25
|
+
* with one argument, which is how the SDK calls a tool registered without an
|
|
26
|
+
* `inputSchema`, the handler gets empty arguments instead of the SDK's
|
|
27
|
+
* request context.
|
|
28
|
+
*/
|
|
29
|
+
export function toMcpToolCallback(handler) {
|
|
30
|
+
return async (...params) => {
|
|
31
|
+
const args = params.length > 1 ? params[0] : {};
|
|
32
|
+
// KyaOsToolHandler types content items' `type` as string; the SDK checks
|
|
33
|
+
// the result it receives, so the narrower declared type is not a claim
|
|
34
|
+
// this adapter has to prove.
|
|
35
|
+
return (await handler(args));
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
//# sourceMappingURL=mcp-tool-callback.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mcp-tool-callback.js","sourceRoot":"","sources":["../../src/middleware/mcp-tool-callback.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAuBH;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,iBAAiB,CAC/B,OAA4B;IAE5B,OAAO,KAAK,EAAE,GAAG,MAAqB,EAAE,EAAE;QACxC,MAAM,IAAI,GAAG,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAE,EAAQ,CAAC;QACvD,yEAAyE;QACzE,uEAAuE;QACvE,6BAA6B;QAC7B,OAAO,CAAC,MAAM,OAAO,CAAC,IAAI,CAAC,CAA0B,CAAC;IACxD,CAAC,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Call KYA-OS-wrapped tool handlers in process, outside an MCP server, and
|
|
3
|
+
* get the results a client would receive.
|
|
4
|
+
*
|
|
5
|
+
* The middleware makes its response proofs where the KYA-OS transport sends a
|
|
6
|
+
* result, because the MCP SDK changes a result after the handler returns it.
|
|
7
|
+
* A script, a walkthrough or a test that calls a wrapped handler directly
|
|
8
|
+
* therefore needs a KYA-OS transport to send what the handler returns, as a
|
|
9
|
+
* server connected through `withKyaOs()` or `createKyaOsTransport()` has. This
|
|
10
|
+
* module is that transport, with nothing on the far end but the caller.
|
|
11
|
+
*
|
|
12
|
+
* ```ts
|
|
13
|
+
* const local = serveInProcess(kyaos);
|
|
14
|
+
* const checkout = local.tool('checkout', kyaos.wrapWithDelegation('checkout', consent, handler));
|
|
15
|
+
* const result = await checkout({ item: 'laptop' }); // proved, as a client receives it
|
|
16
|
+
* await local.close();
|
|
17
|
+
* ```
|
|
18
|
+
*
|
|
19
|
+
* @module serve-in-process
|
|
20
|
+
*/
|
|
21
|
+
import type { KyaOsMiddleware, KyaOsToolHandler, KyaOsToolResult } from "./with-kya-os.types.js";
|
|
22
|
+
/** A KYA-OS transport for in-process calls, open until {@link InProcessServer.close}. */
|
|
23
|
+
export interface InProcessServer {
|
|
24
|
+
/**
|
|
25
|
+
* `handler`, answering as an MCP server would: its result goes through the
|
|
26
|
+
* KYA-OS transport, and the caller gets what a client receives, proof
|
|
27
|
+
* included. `toolName` names the call, as a client's `tools/call` would.
|
|
28
|
+
*/
|
|
29
|
+
tool<R = KyaOsToolResult>(toolName: string, handler: KyaOsToolHandler): (args: Record<string, unknown>, sessionId?: string) => Promise<R>;
|
|
30
|
+
/**
|
|
31
|
+
* Close the transport. It no longer counts as open for the middleware, and
|
|
32
|
+
* its tools refuse further calls.
|
|
33
|
+
*/
|
|
34
|
+
close(): Promise<void>;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Open a KYA-OS transport for `kyaos` whose far end is the caller. While it
|
|
38
|
+
* is open it counts as an open KYA-OS transport for the middleware, so close
|
|
39
|
+
* it when done.
|
|
40
|
+
*/
|
|
41
|
+
export declare function serveInProcess(kyaos: KyaOsMiddleware): InProcessServer;
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Call KYA-OS-wrapped tool handlers in process, outside an MCP server, and
|
|
3
|
+
* get the results a client would receive.
|
|
4
|
+
*
|
|
5
|
+
* The middleware makes its response proofs where the KYA-OS transport sends a
|
|
6
|
+
* result, because the MCP SDK changes a result after the handler returns it.
|
|
7
|
+
* A script, a walkthrough or a test that calls a wrapped handler directly
|
|
8
|
+
* therefore needs a KYA-OS transport to send what the handler returns, as a
|
|
9
|
+
* server connected through `withKyaOs()` or `createKyaOsTransport()` has. This
|
|
10
|
+
* module is that transport, with nothing on the far end but the caller.
|
|
11
|
+
*
|
|
12
|
+
* ```ts
|
|
13
|
+
* const local = serveInProcess(kyaos);
|
|
14
|
+
* const checkout = local.tool('checkout', kyaos.wrapWithDelegation('checkout', consent, handler));
|
|
15
|
+
* const result = await checkout({ item: 'laptop' }); // proved, as a client receives it
|
|
16
|
+
* await local.close();
|
|
17
|
+
* ```
|
|
18
|
+
*
|
|
19
|
+
* @module serve-in-process
|
|
20
|
+
*/
|
|
21
|
+
import { createKyaOsTransport } from "./kya-os-transport.js";
|
|
22
|
+
/**
|
|
23
|
+
* Open a KYA-OS transport for `kyaos` whose far end is the caller. While it
|
|
24
|
+
* is open it counts as an open KYA-OS transport for the middleware, so close
|
|
25
|
+
* it when done.
|
|
26
|
+
*/
|
|
27
|
+
export function serveInProcess(kyaos) {
|
|
28
|
+
// Each call's answer, by its request id, as it crossed the wire.
|
|
29
|
+
const answers = new Map();
|
|
30
|
+
let closed = false;
|
|
31
|
+
const inner = {
|
|
32
|
+
start: async () => { },
|
|
33
|
+
close: async () => { },
|
|
34
|
+
send: async (message) => {
|
|
35
|
+
// What crosses the wire is JSON.
|
|
36
|
+
if (typeof message.id === "number")
|
|
37
|
+
answers.set(message.id, JSON.parse(JSON.stringify(message)));
|
|
38
|
+
},
|
|
39
|
+
};
|
|
40
|
+
const transport = createKyaOsTransport(inner, kyaos);
|
|
41
|
+
const ready = transport.start();
|
|
42
|
+
let nextId = 0;
|
|
43
|
+
return {
|
|
44
|
+
tool(toolName, handler) {
|
|
45
|
+
return async (args, sessionId) => {
|
|
46
|
+
if (closed)
|
|
47
|
+
throw new Error("[kya-os] serveInProcess: the transport is closed");
|
|
48
|
+
await ready;
|
|
49
|
+
const id = ++nextId;
|
|
50
|
+
inner.onmessage?.({
|
|
51
|
+
jsonrpc: "2.0",
|
|
52
|
+
id,
|
|
53
|
+
method: "tools/call",
|
|
54
|
+
params: { name: toolName, arguments: args },
|
|
55
|
+
});
|
|
56
|
+
let result;
|
|
57
|
+
try {
|
|
58
|
+
result = await handler(args, sessionId);
|
|
59
|
+
}
|
|
60
|
+
catch (error) {
|
|
61
|
+
// Answered as a server answers a failed request, so the transport
|
|
62
|
+
// forgets the call; then the caller gets the handler's error.
|
|
63
|
+
await transport.send({
|
|
64
|
+
jsonrpc: "2.0",
|
|
65
|
+
id,
|
|
66
|
+
error: { code: -32603, message: error instanceof Error ? error.message : String(error) },
|
|
67
|
+
});
|
|
68
|
+
answers.delete(id);
|
|
69
|
+
throw error;
|
|
70
|
+
}
|
|
71
|
+
await transport.send({ jsonrpc: "2.0", id, result });
|
|
72
|
+
const answer = answers.get(id);
|
|
73
|
+
answers.delete(id);
|
|
74
|
+
return answer.result;
|
|
75
|
+
};
|
|
76
|
+
},
|
|
77
|
+
async close() {
|
|
78
|
+
if (closed)
|
|
79
|
+
return;
|
|
80
|
+
closed = true;
|
|
81
|
+
await ready;
|
|
82
|
+
await transport.close();
|
|
83
|
+
},
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
//# sourceMappingURL=serve-in-process.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"serve-in-process.js","sourceRoot":"","sources":["../../src/middleware/serve-in-process.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,EAAE,oBAAoB,EAAuB,MAAM,uBAAuB,CAAC;AAqBlF;;;;GAIG;AACH,MAAM,UAAU,cAAc,CAAC,KAAsB;IACnD,iEAAiE;IACjE,MAAM,OAAO,GAAG,IAAI,GAAG,EAA0B,CAAC;IAClD,IAAI,MAAM,GAAG,KAAK,CAAC;IACnB,MAAM,KAAK,GAMP;QACF,KAAK,EAAE,KAAK,IAAI,EAAE,GAAE,CAAC;QACrB,KAAK,EAAE,KAAK,IAAI,EAAE,GAAE,CAAC;QACrB,IAAI,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE;YACtB,iCAAiC;YACjC,IAAI,OAAO,OAAO,CAAC,EAAE,KAAK,QAAQ;gBAAE,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAmB,CAAC,CAAC;QACrH,CAAC;KACF,CAAC;IACF,MAAM,SAAS,GAAG,oBAAoB,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;IACrD,MAAM,KAAK,GAAG,SAAS,CAAC,KAAK,EAAE,CAAC;IAChC,IAAI,MAAM,GAAG,CAAC,CAAC;IAEf,OAAO;QACL,IAAI,CAAsB,QAAgB,EAAE,OAAyB;YACnE,OAAO,KAAK,EAAE,IAA6B,EAAE,SAAkB,EAAc,EAAE;gBAC7E,IAAI,MAAM;oBAAE,MAAM,IAAI,KAAK,CAAC,kDAAkD,CAAC,CAAC;gBAChF,MAAM,KAAK,CAAC;gBACZ,MAAM,EAAE,GAAG,EAAE,MAAM,CAAC;gBACpB,KAAK,CAAC,SAAS,EAAE,CAAC;oBAChB,OAAO,EAAE,KAAK;oBACd,EAAE;oBACF,MAAM,EAAE,YAAY;oBACpB,MAAM,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,SAAS,EAAE,IAAI,EAAE;iBAC5C,CAAC,CAAC;gBACH,IAAI,MAAuB,CAAC;gBAC5B,IAAI,CAAC;oBACH,MAAM,GAAG,MAAM,OAAO,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;gBAC1C,CAAC;gBAAC,OAAO,KAAK,EAAE,CAAC;oBACf,kEAAkE;oBAClE,8DAA8D;oBAC9D,MAAM,SAAS,CAAC,IAAI,CAAC;wBACnB,OAAO,EAAE,KAAK;wBACd,EAAE;wBACF,KAAK,EAAE,EAAE,IAAI,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE;qBACzF,CAAC,CAAC;oBACH,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;oBACnB,MAAM,KAAK,CAAC;gBACd,CAAC;gBACD,MAAM,SAAS,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC;gBACrD,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,EAAE,CAAkB,CAAC;gBAChD,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;gBACnB,OAAO,MAAM,CAAC,MAAM,CAAC;YACvB,CAAC,CAAC;QACJ,CAAC;QACD,KAAK,CAAC,KAAK;YACT,IAAI,MAAM;gBAAE,OAAO;YACnB,MAAM,GAAG,IAAI,CAAC;YACd,MAAM,KAAK,CAAC;YACZ,MAAM,SAAS,CAAC,KAAK,EAAE,CAAC;QAC1B,CAAC;KACF,CAAC;AACJ,CAAC"}
|
|
@@ -42,16 +42,27 @@ export interface WithKyaOsOptions {
|
|
|
42
42
|
* once. Passed through to the middleware (see `KyaOsConfig.requireAtomicNonce`).
|
|
43
43
|
*/
|
|
44
44
|
requireAtomicNonce?: boolean;
|
|
45
|
+
/**
|
|
46
|
+
* How long a wrapper's result may wait to be sent before its proof is
|
|
47
|
+
* given up (default five minutes, at most 2147483647). Passed through to
|
|
48
|
+
* the middleware (see `KyaOsConfig.pendingProofTtlMs`).
|
|
49
|
+
*/
|
|
50
|
+
pendingProofTtlMs?: number;
|
|
45
51
|
/**
|
|
46
52
|
* Response-proof profile for every proof this server mints (SPEC §7.3).
|
|
47
53
|
* Defaults to the body profile; the envelope profile also binds
|
|
48
|
-
* `structuredContent` and `
|
|
49
|
-
*
|
|
54
|
+
* `structuredContent`, `isError` and `resultType`. Under either profile the
|
|
55
|
+
* proofs are made by the transport this function wraps. Passed through to
|
|
56
|
+
* the middleware (see `KyaOsConfig.responseProofProfile`).
|
|
50
57
|
*/
|
|
51
58
|
responseProofProfile?: ResponseProofProfile;
|
|
52
59
|
/** Auto-create sessions for non-KYA-OS clients (default: true) */
|
|
53
60
|
autoSession?: boolean;
|
|
54
|
-
/**
|
|
61
|
+
/**
|
|
62
|
+
* Attach proofs to all tool responses (default: true). With `false` no
|
|
63
|
+
* transport is wrapped, so nothing is proven, and the wrappers refuse to
|
|
64
|
+
* run; leave a tool unproven with `excludeTools` instead.
|
|
65
|
+
*/
|
|
55
66
|
proofAllTools?: boolean;
|
|
56
67
|
/**
|
|
57
68
|
* Also emit the proof under the legacy bare `_meta.proof` key (default: true),
|
|
@@ -80,6 +80,9 @@ export async function withKyaOs(server, options) {
|
|
|
80
80
|
...(options.requireAtomicNonce !== undefined
|
|
81
81
|
? { requireAtomicNonce: options.requireAtomicNonce }
|
|
82
82
|
: {}),
|
|
83
|
+
...(options.pendingProofTtlMs !== undefined
|
|
84
|
+
? { pendingProofTtlMs: options.pendingProofTtlMs }
|
|
85
|
+
: {}),
|
|
83
86
|
...(options.responseProofProfile !== undefined
|
|
84
87
|
? { responseProofProfile: options.responseProofProfile }
|
|
85
88
|
: {}),
|
|
@@ -125,7 +128,7 @@ export async function withKyaOs(server, options) {
|
|
|
125
128
|
// Tool registration order does not matter — proofs are injected at the
|
|
126
129
|
// transport boundary, after McpServer has already dispatched the call.
|
|
127
130
|
if (options.proofAllTools !== false) {
|
|
128
|
-
const exclude =
|
|
131
|
+
const exclude = options.excludeTools ?? [];
|
|
129
132
|
const originalConnect = server.connect.bind(server);
|
|
130
133
|
server.connect = (transport) => originalConnect(createKyaOsTransport(transport, kyaos, exclude));
|
|
131
134
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"with-kya-os-server.js","sourceRoot":"","sources":["../../src/middleware/with-kya-os-server.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAQH,OAAO,EAAE,wBAAwB,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AACnF,OAAO,EACL,cAAc,EACd,qBAAqB,GAItB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,oBAAoB,EAAkB,MAAM,uBAAuB,CAAC;AAC7E,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAC7C,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;
|
|
1
|
+
{"version":3,"file":"with-kya-os-server.js","sourceRoot":"","sources":["../../src/middleware/with-kya-os-server.ts"],"names":[],"mappings":"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"}
|
|
@@ -147,6 +147,20 @@ export interface KyaOsConfig {
|
|
|
147
147
|
* holder binding. Default false, with a startup warning for such a cache.
|
|
148
148
|
*/
|
|
149
149
|
requireAtomicNonce?: boolean;
|
|
150
|
+
/**
|
|
151
|
+
* How long, in milliseconds, a wrapper's result may wait to be sent before
|
|
152
|
+
* its proof is given up (default 300000, five minutes). Proofs are made
|
|
153
|
+
* where the KYA-OS transport sends a result, once: a result delivered later
|
|
154
|
+
* than this, or a second time (an MCP task result fetched again), goes out
|
|
155
|
+
* without a proof and with `proofError`, and the audit trail records
|
|
156
|
+
* `PROOF_EXPIRED`. A result never sent is closed with `PROOF_NOT_SENT` when
|
|
157
|
+
* the window ends. Raise it for task results fetched later; memory stays
|
|
158
|
+
* bounded by the count and size caps on waiting proofs. At most
|
|
159
|
+
* 2147483647 (2^31 - 1, about 24.8 days), the longest timer a JavaScript
|
|
160
|
+
* runtime keeps; a larger value, zero, or a value that is not a finite
|
|
161
|
+
* number is refused.
|
|
162
|
+
*/
|
|
163
|
+
pendingProofTtlMs?: number;
|
|
150
164
|
/**
|
|
151
165
|
* Durable store for approved authorization grants, enabling the no-paste
|
|
152
166
|
* retry: an agent that already obtained a grant can call again — even on a
|
|
@@ -198,6 +212,16 @@ export interface KyaOsConfig {
|
|
|
198
212
|
* outright rather than mis-verifying them. The default stays body-only so
|
|
199
213
|
* existing verifiers keep working; opt in once your client population
|
|
200
214
|
* verifies the envelope profile.
|
|
215
|
+
*
|
|
216
|
+
* Proofs under either profile are made by the KYA-OS transport when it
|
|
217
|
+
* sends a result, after the MCP SDK has finished it: the SDK changes a
|
|
218
|
+
* result after the handler returns (`resultType` on the 2026-07-28
|
|
219
|
+
* revision, a filled-in or appended `content`), and the proof covers what
|
|
220
|
+
* the client receives. `withKyaOs` wraps the transport it is connected
|
|
221
|
+
* through; wrap one yourself with `createKyaOsTransport`. Once a KYA-OS
|
|
222
|
+
* transport has been created for the middleware, every wrapper result must
|
|
223
|
+
* go out through one: while none is open, every wrapper and `proveOutcome`
|
|
224
|
+
* throws on entry.
|
|
201
225
|
*/
|
|
202
226
|
responseProofProfile?: ResponseProofProfile;
|
|
203
227
|
/** Delegation verification overrides */
|
|
@@ -29,6 +29,10 @@ export * from "./with-kya-os.types.js";
|
|
|
29
29
|
* - You need custom request handler patterns
|
|
30
30
|
* - You want per-tool control over proof/delegation wrapping
|
|
31
31
|
*
|
|
32
|
+
* Connect such a server through `createKyaOsTransport`: proofs are made where
|
|
33
|
+
* that transport sends a result, and the wrappers refuse to run while no
|
|
34
|
+
* KYA-OS transport is open.
|
|
35
|
+
*
|
|
32
36
|
* @param config - Agent identity and session configuration
|
|
33
37
|
* @param cryptoProvider - Platform-specific crypto implementation
|
|
34
38
|
* @returns Middleware components for session management and proof generation
|