@code-yeongyu/senpi 2026.10.25-4 → 2026.10.26-2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +47 -0
- package/dist/bundle/chunks/{anthropic-messages-WBASBTIW.js → anthropic-messages-ODSFJCXR.js} +3 -3
- package/dist/bundle/chunks/{args-B444OQBK.js → args-SWKJAYQD.js} +1 -1
- package/dist/bundle/chunks/azure-openai-responses-REGXS4XO.js +2 -0
- package/dist/bundle/chunks/bedrock-converse-stream.js +3 -3
- package/dist/bundle/chunks/chunk-2XF6W6F6.js +410 -0
- package/dist/bundle/chunks/{chunk-WDPQ6CZJ.js → chunk-4QVORFQ2.js} +1 -1
- package/dist/bundle/chunks/{chunk-6AOVUTUR.js → chunk-5W3DTM2J.js} +2 -2
- package/dist/bundle/chunks/{chunk-E6WYH3ZL.js → chunk-6GAMRAVM.js} +9 -7
- package/dist/bundle/chunks/{chunk-N7IN46Q5.js → chunk-7IZH2KQX.js} +9 -7
- package/dist/bundle/chunks/{chunk-7GZUFOM3.js → chunk-ARSENVDY.js} +1 -1
- package/dist/bundle/chunks/{chunk-STMXIBXF.js → chunk-CNDPCYNT.js} +1 -1
- package/dist/bundle/chunks/{chunk-XF3LJC3O.js → chunk-CYOHFREV.js} +1 -1
- package/dist/bundle/chunks/{chunk-E6D4RIT7.js → chunk-DNDZPKIQ.js} +2 -2
- package/dist/bundle/chunks/{chunk-E4LBKOZG.js → chunk-EQNUL2WB.js} +4 -4
- package/dist/bundle/chunks/{chunk-2RB5EL4X.js → chunk-ESNSRUW4.js} +1 -1
- package/dist/bundle/chunks/{chunk-4AOMNOGY.js → chunk-FQDARFHT.js} +1 -1
- package/dist/bundle/chunks/{chunk-BWA4FVFW.js → chunk-GPPOPK76.js} +3 -3
- package/dist/bundle/chunks/{chunk-SBGIXMX3.js → chunk-GWGNVYPB.js} +1 -1
- package/dist/bundle/chunks/{chunk-KKD4CYCI.js → chunk-H4WJ4LY3.js} +1 -1
- package/dist/bundle/chunks/{chunk-V2UYXTRR.js → chunk-HWTD4QF3.js} +1 -1
- package/dist/bundle/chunks/chunk-I2WFLKZ2.js +5 -0
- package/dist/bundle/chunks/{chunk-WD6WBYC5.js → chunk-IHKHCWWG.js} +1 -1
- package/dist/bundle/chunks/{chunk-T36LJ6MW.js → chunk-IY4G44MN.js} +1 -1
- package/dist/bundle/chunks/{chunk-BZ7726QO.js → chunk-J2YAYTB2.js} +1 -1
- package/dist/bundle/chunks/{chunk-UFJ2K7Q7.js → chunk-JH7MVRNJ.js} +1 -1
- package/dist/bundle/chunks/chunk-KBSFTXAT.js +2 -0
- package/dist/bundle/chunks/{chunk-OLCDIITS.js → chunk-KRO63T4Q.js} +1 -1
- package/dist/bundle/chunks/{chunk-TTU2RNVX.js → chunk-KTDIIF2F.js} +1 -1
- package/dist/bundle/chunks/{chunk-KNVNKDER.js → chunk-L2O6K3SJ.js} +1 -1
- package/dist/bundle/chunks/{chunk-3BTN337S.js → chunk-NDNIMC5W.js} +1 -1
- package/dist/bundle/chunks/{chunk-ITGYN22E.js → chunk-ODRGPC5S.js} +1 -1
- package/dist/bundle/chunks/{chunk-4MOZXOJX.js → chunk-PDG4XWO2.js} +1 -1
- package/dist/bundle/chunks/{chunk-3QCYBOKN.js → chunk-PPECSSWX.js} +1 -1
- package/dist/bundle/chunks/{chunk-4P7WARQZ.js → chunk-PY4ZQHTN.js} +1 -1
- package/dist/bundle/chunks/{chunk-C2MQ4QXN.js → chunk-RPW3XQW3.js} +48 -42
- package/dist/bundle/chunks/{chunk-JMOUU75H.js → chunk-RQ5JTXUC.js} +1 -1
- package/dist/bundle/chunks/chunk-TQ67PB7U.js +13 -0
- package/dist/bundle/chunks/{chunk-5JJDR6XI.js → chunk-UJPG4ROT.js} +1 -1
- package/dist/bundle/chunks/{chunk-FHXR4ZAC.js → chunk-XM36IFP3.js} +1 -1
- package/dist/bundle/chunks/{chunk-PT6JJUN2.js → chunk-XMNPK472.js} +1 -1
- package/dist/bundle/chunks/{client-WTYEICLH.js → chunk-Y3TMJV3J.js} +3 -3
- package/dist/bundle/chunks/{chunk-GSSD3R5X.js → chunk-Z6BREXV3.js} +1 -1
- package/dist/bundle/chunks/{chunk-KXB5WIS5.js → chunk-Z6SAQ5O3.js} +1 -1
- package/dist/bundle/chunks/{chunk-LOIF6PHI.js → chunk-ZAUVY6ZC.js} +3 -3
- package/dist/bundle/chunks/{chunk-7CNOCJCN.js → chunk-ZP6JJDYV.js} +1 -1
- package/dist/bundle/chunks/cli-main-Q2GA53XM.js +3 -0
- package/dist/bundle/chunks/client-LOS6GSEW.js +2 -0
- package/dist/bundle/chunks/{cloudflare-workers-ai-system-one-K5H6BJP3.js → cloudflare-workers-ai-system-one-WDHT7BBV.js} +1 -1
- package/dist/bundle/chunks/cursor-agent.js +3 -3
- package/dist/bundle/chunks/devin-agent.js +3 -3
- package/dist/bundle/chunks/dispatch-5R3TYAYB.js +9 -0
- package/dist/bundle/chunks/google-generative-ai-FHYFXKLA.js +2 -0
- package/dist/bundle/chunks/google-vertex-5DWE5U5K.js +2 -0
- package/dist/bundle/chunks/{help-fast-path-3Z26DQSV.js → help-fast-path-FETLIF3W.js} +1 -1
- package/dist/bundle/chunks/host-command-XEB7SHT3.js +2 -0
- package/dist/bundle/chunks/{host-lifecycle-3VHHIGDL.js → host-lifecycle-HX3EGRRW.js} +1 -1
- package/dist/bundle/chunks/host-lifecycle.js +2 -2
- package/dist/bundle/chunks/{host-session-command-56XF6ACS.js → host-session-command-FFN52LXJ.js} +1 -1
- package/dist/bundle/chunks/{host-socket-request-QL2WEZTN.js → host-socket-request-K4LCUOUD.js} +1 -1
- package/dist/bundle/chunks/interactive-mode-5DEKY3YW.js +2 -0
- package/dist/bundle/chunks/{mcp-presenter-bootstrap-XUSCQVRC.js → mcp-presenter-bootstrap-FOMKF4TU.js} +1 -1
- package/dist/bundle/chunks/{mistral-conversations-DH44NOYV.js → mistral-conversations-I2PI7DDF.js} +1 -1
- package/dist/bundle/chunks/{multi-session-host-Z2CW4SDM.js → multi-session-host-OPR5VBFO.js} +6 -7
- package/dist/bundle/chunks/{openai-codex-responses-SERAFKAS.js → openai-codex-responses-WSEX6SH7.js} +1 -1
- package/dist/bundle/chunks/{openai-completions-BZB5O45A.js → openai-completions-YCBHTBSS.js} +1 -1
- package/dist/bundle/chunks/openai-responses-GXNSQF4A.js +3 -0
- package/dist/bundle/chunks/{package-manager-cli-N55U6PEO.js → package-manager-cli-W55E3LHP.js} +1 -1
- package/dist/bundle/chunks/{pi-messages-VXATX45B.js → pi-messages-O6GISIRW.js} +2 -2
- package/dist/bundle/chunks/{role-JVSBNKGE.js → role-SHIZQKK4.js} +1 -1
- package/dist/bundle/chunks/{rotation-stream-CBGCBYHV.js → rotation-stream-2PCZWNKF.js} +1 -1
- package/dist/bundle/chunks/rpc-mode-IDUJTSYS.js +2 -0
- package/dist/bundle/chunks/{rpc-monitor-source-AE3C6EQV.js → rpc-monitor-source-DRZXJHTL.js} +1 -1
- package/dist/bundle/chunks/{schedule-command-VS7CZC2J.js → schedule-command-B7RRSANU.js} +1 -1
- package/dist/bundle/chunks/session-control-endpoint-LMZH5JLH.js +3 -0
- package/dist/bundle/chunks/{session-picker-E4KUJDLO.js → session-picker-DTGBOXDR.js} +1 -1
- package/dist/bundle/chunks/session-worker.js +214 -205
- package/dist/bundle/chunks/{typesafe-system-one-P75WJ767.js → typesafe-system-one-XGYJJVSE.js} +1 -1
- package/dist/bundle/cli.js +2 -2
- package/dist/bundle/host-supervisor.js +2 -2
- package/dist/bundle/index.js +1 -1
- package/dist/bundle/rpc-entry.js +1 -1
- package/dist/bundle/runtime-manifest.json +1 -1
- package/dist/cli/host-command-args.d.ts +1 -0
- package/dist/cli/host-command-args.js +5 -0
- package/dist/cli/host-command.js +7 -1
- package/dist/cli.js +21 -3
- package/dist/core/agent-session.d.ts +11 -1
- package/dist/core/agent-session.js +19 -2
- package/dist/core/extensions/builtin/compaction/index.js +7 -1
- package/dist/core/extensions/builtin/herdr/index.js +9 -5
- package/dist/core/extensions/builtin/mcp/auth/oauth-issuer.d.ts +6 -0
- package/dist/core/extensions/builtin/mcp/auth/oauth-issuer.js +25 -0
- package/dist/core/extensions/builtin/mcp/auth/oauth-provider.d.ts +3 -3
- package/dist/core/extensions/builtin/mcp/auth/oauth-provider.js +50 -19
- package/dist/core/extensions/builtin/mcp/auth/oauth-refresh.js +4 -3
- package/dist/core/extensions/builtin/mcp/auth/oauth.js +19 -12
- package/dist/core/extensions/builtin/mcp/catalog-cache.d.ts +2 -1
- package/dist/core/extensions/builtin/mcp/catalog-cache.js +19 -6
- package/dist/core/extensions/builtin/mcp/catalog.d.ts +3 -2
- package/dist/core/extensions/builtin/mcp/catalog.js +20 -3
- package/dist/core/extensions/builtin/mcp/expose/call.d.ts +2 -1
- package/dist/core/extensions/builtin/mcp/expose/call.js +2 -1
- package/dist/core/extensions/builtin/mcp/expose/register.js +1 -1
- package/dist/core/extensions/builtin/mcp/expose/schema-compat.d.ts +2 -2
- package/dist/core/extensions/builtin/mcp/expose/schema-compat.js +11 -1
- package/dist/core/extensions/builtin/mcp/invocation.js +16 -2
- package/dist/core/extensions/builtin/mcp/modern/dispatch.js +1 -0
- package/dist/core/extensions/builtin/mcp/modern/parameter-headers.d.ts +4 -1
- package/dist/core/extensions/builtin/mcp/modern/parameter-headers.js +33 -35
- package/dist/core/extensions/builtin/mcp/modern/request.d.ts +1 -1
- package/dist/core/extensions/builtin/mcp/modern/request.js +4 -1
- package/dist/core/extensions/builtin/mcp/modern/sdk-bridge.js +18 -3
- package/dist/core/extensions/builtin/mcp/modern/stdio-probe.js +23 -0
- package/dist/core/extensions/builtin/mcp/modern/subscriptions.d.ts +14 -0
- package/dist/core/extensions/builtin/mcp/modern/subscriptions.js +226 -0
- package/dist/core/extensions/builtin/mcp/modern/tool-schema.d.ts +13 -0
- package/dist/core/extensions/builtin/mcp/modern/tool-schema.js +75 -0
- package/dist/core/extensions/builtin/mcp/modern/tools.d.ts +107 -0
- package/dist/core/extensions/builtin/mcp/modern/tools.js +53 -0
- package/dist/core/extensions/builtin/mcp/modern/transport.d.ts +2 -0
- package/dist/core/extensions/builtin/mcp/modern/transport.js +4 -2
- package/dist/core/extensions/builtin/mcp/resources.js +4 -0
- package/dist/core/extensions/builtin/mcp/tool-client.d.ts +13 -0
- package/dist/core/extensions/builtin/mcp/tool-client.js +17 -0
- package/dist/core/extensions/builtin/mcp/tool-contracts.d.ts +19 -0
- package/dist/core/extensions/builtin/mcp/tool-contracts.js +2 -0
- package/dist/core/extensions/builtin/mcp/wrap.js +2 -2
- package/dist/core/extensions/builtin/permission-system/bash-command-segments.d.ts +37 -0
- package/dist/core/extensions/builtin/permission-system/bash-command-segments.js +899 -0
- package/dist/core/extensions/builtin/permission-system/parsers.d.ts +2 -0
- package/dist/core/extensions/builtin/permission-system/parsers.js +44 -10
- package/dist/core/extensions/builtin/terminal/extension-state.js +2 -1
- package/dist/core/extensions/builtin/vertex-model-garden/auth.d.ts +9 -0
- package/dist/core/extensions/builtin/vertex-model-garden/auth.js +17 -1
- package/dist/core/extensions/builtin/websearch/websearch/providers/google.d.ts +6 -0
- package/dist/core/extensions/builtin/websearch/websearch/providers/google.js +6 -1
- package/dist/core/extensions/types.d.ts +2 -0
- package/dist/core/lifecycle-children.d.ts +3 -1
- package/dist/core/lifecycle-children.js +79 -15
- package/dist/core/lifecycle-record.js +1 -24
- package/dist/core/lifecycle-session-binding.js +2 -1
- package/dist/core/lifecycle-wait-items.d.ts +17 -0
- package/dist/core/lifecycle-wait-items.js +72 -0
- package/dist/core/model-runtime.js +6 -1
- package/dist/core/provider-api-key-auth.d.ts +6 -1
- package/dist/core/provider-api-key-auth.js +11 -4
- package/dist/core/provider-composer.d.ts +8 -1
- package/dist/core/provider-composer.js +7 -3
- package/dist/core/sdk.js +4 -1
- package/dist/core/session-activity.js +2 -0
- package/dist/core/session-lifecycle-types.d.ts +20 -4
- package/dist/core/session-lifecycle.js +35 -4
- package/dist/core/structured-session-lane.d.ts +33 -0
- package/dist/core/structured-session-lane.js +62 -0
- package/dist/core/work-custody-record.d.ts +2 -1
- package/dist/core/work-custody-record.js +2 -0
- package/dist/core/work-obligations.d.ts +1 -1
- package/dist/core/work-obligations.js +8 -2
- package/dist/modes/interactive/session-control-commands.js +21 -4
- package/dist/modes/interactive/session-control-rpc-commands.d.ts +1 -1
- package/dist/modes/interactive/session-control-rpc-commands.js +19 -0
- package/dist/modes/json-event.d.ts +79 -1
- package/dist/modes/json-event.js +79 -1
- package/dist/modes/rpc/compact-content-index.d.ts +85 -0
- package/dist/modes/rpc/compact-content-index.js +254 -0
- package/dist/modes/rpc/compact-content-store.d.ts +59 -0
- package/dist/modes/rpc/compact-content-store.js +134 -0
- package/dist/modes/rpc/compact-index-pages.d.ts +12 -0
- package/dist/modes/rpc/compact-index-pages.js +31 -0
- package/dist/modes/rpc/compact-session-state.d.ts +83 -0
- package/dist/modes/rpc/compact-session-state.js +197 -0
- package/dist/modes/rpc/compact-spool-dir.d.ts +8 -0
- package/dist/modes/rpc/compact-spool-dir.js +94 -0
- package/dist/modes/rpc/compact-spool-storage.d.ts +53 -0
- package/dist/modes/rpc/compact-spool-storage.js +162 -0
- package/dist/modes/rpc/compact-storage-io.d.ts +28 -0
- package/dist/modes/rpc/compact-storage-io.js +25 -0
- package/dist/modes/rpc/compact-transition.d.ts +41 -0
- package/dist/modes/rpc/compact-transition.js +12 -0
- package/dist/modes/rpc/connection-handler.d.ts +4 -0
- package/dist/modes/rpc/connection-handler.js +51 -13
- package/dist/modes/rpc/connection-question-bridge.d.ts +2 -1
- package/dist/modes/rpc/connection-question-bridge.js +6 -2
- package/dist/modes/rpc/extension-ui-response.d.ts +7 -2
- package/dist/modes/rpc/extension-ui-response.js +27 -7
- package/dist/modes/rpc/get-snapshot.d.ts +18 -0
- package/dist/modes/rpc/get-snapshot.js +43 -0
- package/dist/modes/rpc/host-capabilities.js +3 -0
- package/dist/modes/rpc/host-ensure-start.js +6 -3
- package/dist/modes/rpc/host-ensure-types.d.ts +2 -0
- package/dist/modes/rpc/host-ensure.js +1 -0
- package/dist/modes/rpc/host-handoff.d.ts +2 -0
- package/dist/modes/rpc/host-handover-request.d.ts +1 -1
- package/dist/modes/rpc/host-handover-request.js +4 -3
- package/dist/modes/rpc/host-handover-wire.js +6 -0
- package/dist/modes/rpc/host-idle-handover.d.ts +2 -0
- package/dist/modes/rpc/host-idle-handover.js +3 -1
- package/dist/modes/rpc/host-observe-request.js +1 -0
- package/dist/modes/rpc/host-runner.d.ts +1 -0
- package/dist/modes/rpc/host-runner.js +9 -7
- package/dist/modes/rpc/host-successor.js +4 -0
- package/dist/modes/rpc/json-normal-value.d.ts +6 -0
- package/dist/modes/rpc/json-normal-value.js +100 -0
- package/dist/modes/rpc/mcp-presenter-bootstrap.js +5 -0
- package/dist/modes/rpc/media-placeholders.d.ts +9 -3
- package/dist/modes/rpc/media-placeholders.js +12 -4
- package/dist/modes/rpc/rpc-host-command-types.d.ts +2 -0
- package/dist/modes/rpc/rpc-question-types.d.ts +1 -0
- package/dist/modes/rpc/rpc-read-response-types.d.ts +7 -0
- package/dist/modes/rpc/rpc-session-command-types.d.ts +6 -0
- package/dist/modes/rpc/rpc-session-state-types.d.ts +3 -0
- package/dist/modes/rpc/rpc-session-state.js +2 -0
- package/dist/modes/rpc/rpc-types.d.ts +1 -0
- package/dist/modes/rpc/security-presentations.js +2 -1
- package/dist/modes/rpc/session-attachment-gate.js +1 -0
- package/dist/modes/rpc/session-binding.js +30 -17
- package/dist/modes/rpc/session-command-activity.js +1 -0
- package/dist/modes/rpc/session-event-fanout.d.ts +1 -1
- package/dist/modes/rpc/session-event-fanout.js +17 -9
- package/dist/modes/rpc/session-event-writer.d.ts +2 -0
- package/dist/modes/rpc/session-event-writer.js +24 -5
- package/dist/modes/rpc/session-extension-ui-requests.d.ts +2 -1
- package/dist/modes/rpc/session-extension-ui-requests.js +15 -10
- package/dist/modes/rpc/session-held.js +1 -0
- package/dist/modes/rpc/session-record-stream.d.ts +3 -3
- package/dist/modes/rpc/session-record-stream.js +3 -3
- package/dist/modes/rpc/session-status-stream.d.ts +2 -1
- package/dist/modes/rpc/session-status-stream.js +8 -2
- package/dist/modes/rpc/session-status-subscriptions.d.ts +2 -1
- package/dist/modes/rpc/session-status-subscriptions.js +4 -0
- package/dist/modes/rpc/session-structured-lanes.d.ts +12 -0
- package/dist/modes/rpc/session-structured-lanes.js +24 -0
- package/dist/modes/rpc/session-worker-client.js +6 -5
- package/dist/modes/rpc/session-worker.js +5 -2
- package/dist/modes/rpc/snapshot-types.d.ts +29 -0
- package/dist/modes/rpc/snapshot-types.js +2 -0
- package/dist/modes/rpc/structured-session-records.d.ts +12 -0
- package/dist/modes/rpc/structured-session-records.js +88 -0
- package/dist/modes/rpc/ui-answer-ledger.d.ts +13 -0
- package/dist/modes/rpc/ui-answer-ledger.js +34 -0
- package/dist/senpi +21 -3
- package/docs/extensions.md +7 -1
- package/docs/mcp.md +20 -0
- package/docs/rpc.md +61 -2
- package/package.json +7 -6
- package/dist/bundle/chunks/azure-openai-responses-7I45DI72.js +0 -2
- package/dist/bundle/chunks/chunk-DMI55M2N.js +0 -2
- package/dist/bundle/chunks/chunk-DODH3N6U.js +0 -410
- package/dist/bundle/chunks/chunk-J37GRED2.js +0 -5
- package/dist/bundle/chunks/chunk-TBU6VYHN.js +0 -13
- package/dist/bundle/chunks/cli-main-YYH3IBC6.js +0 -3
- package/dist/bundle/chunks/dispatch-MXG5YWLV.js +0 -9
- package/dist/bundle/chunks/google-generative-ai-UM5Y7T6B.js +0 -2
- package/dist/bundle/chunks/google-vertex-OKU2VQHL.js +0 -2
- package/dist/bundle/chunks/host-command-TDLLHXVI.js +0 -2
- package/dist/bundle/chunks/interactive-mode-OEPULLZK.js +0 -2
- package/dist/bundle/chunks/openai-responses-TNHQ6SJS.js +0 -3
- package/dist/bundle/chunks/rpc-mode-ETXQWEB2.js +0 -2
- package/dist/bundle/chunks/session-control-endpoint-4LEIDIVI.js +0 -3
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { Ajv2020 } from "ajv/dist/2020.js";
|
|
2
|
+
export class McpToolSchemaError extends Error {
|
|
3
|
+
constructor(code, message) {
|
|
4
|
+
super(message);
|
|
5
|
+
this.name = "McpToolSchemaError";
|
|
6
|
+
this.code = code;
|
|
7
|
+
}
|
|
8
|
+
}
|
|
9
|
+
const validators = new WeakMap();
|
|
10
|
+
const dialect = "https://json-schema.org/draft/2020-12/schema";
|
|
11
|
+
/** No coercion/default insertion/removal, no network resolver, no shared $id namespace. */
|
|
12
|
+
export function compileModernSchema(schema) {
|
|
13
|
+
const cached = typeof schema === "boolean" ? undefined : validators.get(schema);
|
|
14
|
+
if (cached !== undefined)
|
|
15
|
+
return cached;
|
|
16
|
+
checkBounds(schema);
|
|
17
|
+
if (typeof schema !== "boolean" &&
|
|
18
|
+
schema.$schema !== undefined &&
|
|
19
|
+
schema.$schema !== dialect &&
|
|
20
|
+
schema.$schema !== `${dialect}#`) {
|
|
21
|
+
throw new McpToolSchemaError("MCP_SCHEMA_UNSUPPORTED_DIALECT", "Modern MCP supports JSON Schema 2020-12.");
|
|
22
|
+
}
|
|
23
|
+
try {
|
|
24
|
+
if (typeof schema !== "boolean" && schema.$async !== undefined)
|
|
25
|
+
throw new McpToolSchemaError("MCP_SCHEMA_INVALID", "Async schemas are unsupported.");
|
|
26
|
+
const ajv = new Ajv2020({
|
|
27
|
+
strict: false,
|
|
28
|
+
validateFormats: false,
|
|
29
|
+
allErrors: false,
|
|
30
|
+
inlineRefs: false,
|
|
31
|
+
addUsedSchema: false,
|
|
32
|
+
});
|
|
33
|
+
const validate = ajv.compile(schema);
|
|
34
|
+
if (typeof schema !== "boolean")
|
|
35
|
+
validators.set(schema, validate);
|
|
36
|
+
return validate;
|
|
37
|
+
}
|
|
38
|
+
catch (error) {
|
|
39
|
+
if (error instanceof McpToolSchemaError)
|
|
40
|
+
throw error;
|
|
41
|
+
throw new McpToolSchemaError("MCP_SCHEMA_INVALID", "Invalid MCP schema or unresolved schema reference.");
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
/** Reject one unusable definition, never its valid siblings; diagnostics contain no schema or arguments. */
|
|
45
|
+
export function hasSupportedModernToolSchemas(tool) {
|
|
46
|
+
try {
|
|
47
|
+
compileModernSchema(tool.inputSchema);
|
|
48
|
+
if (tool.outputSchema !== undefined)
|
|
49
|
+
compileModernSchema(tool.outputSchema);
|
|
50
|
+
return true;
|
|
51
|
+
}
|
|
52
|
+
catch (error) {
|
|
53
|
+
if (!(error instanceof McpToolSchemaError))
|
|
54
|
+
throw error;
|
|
55
|
+
console.warn(`MCP tool ${JSON.stringify(tool.name)} skipped: ${error.code}: ${error.message}`);
|
|
56
|
+
return false;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
function checkBounds(schema) {
|
|
60
|
+
const pending = [{ value: schema, depth: 0 }];
|
|
61
|
+
let nodes = 0;
|
|
62
|
+
while (pending.length > 0) {
|
|
63
|
+
const current = pending.pop();
|
|
64
|
+
if (current === undefined)
|
|
65
|
+
break;
|
|
66
|
+
if (++nodes > 16_384 || current.depth > 64) {
|
|
67
|
+
throw new McpToolSchemaError("MCP_SCHEMA_LIMIT", "MCP schema exceeds the depth or node limit.");
|
|
68
|
+
}
|
|
69
|
+
if (current.value !== null && typeof current.value === "object") {
|
|
70
|
+
for (const value of Object.values(current.value))
|
|
71
|
+
pending.push({ value, depth: current.depth + 1 });
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
//# sourceMappingURL=tool-schema.js.map
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import type { Client } from "@modelcontextprotocol/sdk/client/index.js";
|
|
2
|
+
import type { RequestOptions } from "@modelcontextprotocol/sdk/shared/protocol.js";
|
|
3
|
+
import { z } from "zod";
|
|
4
|
+
import type { McpJsonSchema } from "../tool-contracts.ts";
|
|
5
|
+
export declare function listModernTools(client: Client, params?: Parameters<Client["listTools"]>[0], options?: RequestOptions): Promise<{
|
|
6
|
+
nextCursor?: string | undefined;
|
|
7
|
+
tools: {
|
|
8
|
+
description?: string | undefined;
|
|
9
|
+
annotations?: {
|
|
10
|
+
title?: string | undefined;
|
|
11
|
+
readOnlyHint?: boolean | undefined;
|
|
12
|
+
destructiveHint?: boolean | undefined;
|
|
13
|
+
idempotentHint?: boolean | undefined;
|
|
14
|
+
openWorldHint?: boolean | undefined;
|
|
15
|
+
} | undefined;
|
|
16
|
+
execution?: {
|
|
17
|
+
taskSupport?: "forbidden" | "optional" | "required" | undefined;
|
|
18
|
+
} | undefined;
|
|
19
|
+
_meta?: Record<string, unknown> | undefined;
|
|
20
|
+
icons?: {
|
|
21
|
+
src: string;
|
|
22
|
+
mimeType?: string | undefined;
|
|
23
|
+
sizes?: string[] | undefined;
|
|
24
|
+
theme?: "dark" | "light" | undefined;
|
|
25
|
+
}[] | undefined;
|
|
26
|
+
name: string;
|
|
27
|
+
title?: string | undefined;
|
|
28
|
+
inputSchema: boolean | Record<string, z.JSONType>;
|
|
29
|
+
outputSchema?: boolean | Record<string, z.JSONType> | undefined;
|
|
30
|
+
}[];
|
|
31
|
+
}>;
|
|
32
|
+
export declare function callModernTool(client: Client, params: Parameters<Client["callTool"]>[0], outputSchema: McpJsonSchema | undefined, options?: RequestOptions): Promise<{
|
|
33
|
+
isError?: boolean | undefined;
|
|
34
|
+
structuredContent?: z.JSONType | undefined;
|
|
35
|
+
content?: ({
|
|
36
|
+
type: "text";
|
|
37
|
+
text: string;
|
|
38
|
+
annotations?: {
|
|
39
|
+
audience?: ("assistant" | "user")[] | undefined;
|
|
40
|
+
priority?: number | undefined;
|
|
41
|
+
lastModified?: string | undefined;
|
|
42
|
+
} | undefined;
|
|
43
|
+
_meta?: Record<string, unknown> | undefined;
|
|
44
|
+
} | {
|
|
45
|
+
type: "image";
|
|
46
|
+
data: string;
|
|
47
|
+
mimeType: string;
|
|
48
|
+
annotations?: {
|
|
49
|
+
audience?: ("assistant" | "user")[] | undefined;
|
|
50
|
+
priority?: number | undefined;
|
|
51
|
+
lastModified?: string | undefined;
|
|
52
|
+
} | undefined;
|
|
53
|
+
_meta?: Record<string, unknown> | undefined;
|
|
54
|
+
} | {
|
|
55
|
+
type: "audio";
|
|
56
|
+
data: string;
|
|
57
|
+
mimeType: string;
|
|
58
|
+
annotations?: {
|
|
59
|
+
audience?: ("assistant" | "user")[] | undefined;
|
|
60
|
+
priority?: number | undefined;
|
|
61
|
+
lastModified?: string | undefined;
|
|
62
|
+
} | undefined;
|
|
63
|
+
_meta?: Record<string, unknown> | undefined;
|
|
64
|
+
} | {
|
|
65
|
+
uri: string;
|
|
66
|
+
description?: string | undefined;
|
|
67
|
+
mimeType?: string | undefined;
|
|
68
|
+
size?: number | undefined;
|
|
69
|
+
annotations?: {
|
|
70
|
+
audience?: ("assistant" | "user")[] | undefined;
|
|
71
|
+
priority?: number | undefined;
|
|
72
|
+
lastModified?: string | undefined;
|
|
73
|
+
} | undefined;
|
|
74
|
+
_meta?: {
|
|
75
|
+
[x: string]: unknown;
|
|
76
|
+
} | undefined;
|
|
77
|
+
icons?: {
|
|
78
|
+
src: string;
|
|
79
|
+
mimeType?: string | undefined;
|
|
80
|
+
sizes?: string[] | undefined;
|
|
81
|
+
theme?: "dark" | "light" | undefined;
|
|
82
|
+
}[] | undefined;
|
|
83
|
+
name: string;
|
|
84
|
+
title?: string | undefined;
|
|
85
|
+
type: "resource_link";
|
|
86
|
+
} | {
|
|
87
|
+
type: "resource";
|
|
88
|
+
resource: {
|
|
89
|
+
uri: string;
|
|
90
|
+
mimeType?: string | undefined;
|
|
91
|
+
_meta?: Record<string, unknown> | undefined;
|
|
92
|
+
text: string;
|
|
93
|
+
} | {
|
|
94
|
+
uri: string;
|
|
95
|
+
mimeType?: string | undefined;
|
|
96
|
+
_meta?: Record<string, unknown> | undefined;
|
|
97
|
+
blob: string;
|
|
98
|
+
};
|
|
99
|
+
annotations?: {
|
|
100
|
+
audience?: ("assistant" | "user")[] | undefined;
|
|
101
|
+
priority?: number | undefined;
|
|
102
|
+
lastModified?: string | undefined;
|
|
103
|
+
} | undefined;
|
|
104
|
+
_meta?: Record<string, unknown> | undefined;
|
|
105
|
+
})[] | undefined;
|
|
106
|
+
}>;
|
|
107
|
+
//# sourceMappingURL=tools.d.ts.map
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { loadMcpSdkTypes } from "../sdk.lazy.js";
|
|
3
|
+
import { McpMrtrError } from "./errors.js";
|
|
4
|
+
import { compileModernSchema, hasSupportedModernToolSchemas, McpToolSchemaError } from "./tool-schema.js";
|
|
5
|
+
const jsonSchema = z.union([z.boolean(), z.record(z.string(), z.json())]);
|
|
6
|
+
const modernToolSchema = z.looseObject({
|
|
7
|
+
name: z.string(),
|
|
8
|
+
inputSchema: jsonSchema,
|
|
9
|
+
outputSchema: jsonSchema.optional(),
|
|
10
|
+
});
|
|
11
|
+
const listResult = z.looseObject({
|
|
12
|
+
tools: z.array(modernToolSchema),
|
|
13
|
+
nextCursor: z.string().optional(),
|
|
14
|
+
});
|
|
15
|
+
const callResult = z.looseObject({
|
|
16
|
+
isError: z.boolean().optional(),
|
|
17
|
+
structuredContent: z.json().optional(),
|
|
18
|
+
});
|
|
19
|
+
export async function listModernTools(client, params, options) {
|
|
20
|
+
// Keep the SDK behind its documented startup boundary, and its Zod identity separate.
|
|
21
|
+
const { ResultSchema, ToolSchema } = await loadMcpSdkTypes();
|
|
22
|
+
const toolMetadata = ToolSchema.omit({ inputSchema: true, outputSchema: true });
|
|
23
|
+
const raw = await client.request({ method: "tools/list", params }, ResultSchema, options);
|
|
24
|
+
const parsed = listResult.safeParse(raw);
|
|
25
|
+
if (!parsed.success)
|
|
26
|
+
throw new McpMrtrError("MCP_MRTR_INVALID_RESULT");
|
|
27
|
+
const tools = parsed.data.tools.filter(hasSupportedModernToolSchemas).map((tool) => {
|
|
28
|
+
const metadata = toolMetadata.safeParse(tool);
|
|
29
|
+
if (!metadata.success)
|
|
30
|
+
throw new McpMrtrError("MCP_MRTR_INVALID_RESULT");
|
|
31
|
+
return { ...tool, ...metadata.data };
|
|
32
|
+
});
|
|
33
|
+
return { ...parsed.data, tools };
|
|
34
|
+
}
|
|
35
|
+
export async function callModernTool(client, params, outputSchema, options) {
|
|
36
|
+
const { CallToolResultSchema, ResultSchema } = await loadMcpSdkTypes();
|
|
37
|
+
const validate = outputSchema === undefined ? undefined : compileModernSchema(outputSchema);
|
|
38
|
+
const raw = await client.request({ method: "tools/call", params }, ResultSchema, options);
|
|
39
|
+
const parsed = callResult.safeParse(raw);
|
|
40
|
+
if (!parsed.success)
|
|
41
|
+
throw new McpMrtrError("MCP_MRTR_INVALID_RESULT");
|
|
42
|
+
const content = CallToolResultSchema.shape.content.optional().safeParse(raw.content);
|
|
43
|
+
if (!content.success)
|
|
44
|
+
throw new McpMrtrError("MCP_MRTR_INVALID_RESULT");
|
|
45
|
+
const result = { ...parsed.data, ...(content.data === undefined ? {} : { content: content.data }) };
|
|
46
|
+
if (validate !== undefined && result.isError !== true) {
|
|
47
|
+
if (!Object.hasOwn(result, "structuredContent") || !validate(result.structuredContent)) {
|
|
48
|
+
throw new McpToolSchemaError("MCP_OUTPUT_SCHEMA_MISMATCH", "Tool result does not match outputSchema.");
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
return result;
|
|
52
|
+
}
|
|
53
|
+
//# sourceMappingURL=tools.js.map
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { FetchLike, Transport } from "@modelcontextprotocol/sdk/shared/transport.js";
|
|
2
2
|
import { type JSONRPCMessage } from "@modelcontextprotocol/sdk/types.js";
|
|
3
3
|
import { type ModernClientInfo } from "./wire.ts";
|
|
4
|
+
import type { McpLogger } from "../log.ts";
|
|
4
5
|
export type ModernHttpTransportOptions = {
|
|
5
6
|
readonly url: string | URL;
|
|
6
7
|
readonly fetch: FetchLike;
|
|
@@ -8,6 +9,7 @@ export type ModernHttpTransportOptions = {
|
|
|
8
9
|
readonly clientCapabilities: Readonly<Record<string, unknown>>;
|
|
9
10
|
readonly protocolVersion?: string;
|
|
10
11
|
readonly headers?: RequestInit["headers"];
|
|
12
|
+
readonly logger?: Pick<McpLogger, "warn">;
|
|
11
13
|
};
|
|
12
14
|
export declare class ModernTransportError extends Error {
|
|
13
15
|
constructor(message: string);
|
|
@@ -4,7 +4,7 @@ import { AuthError } from "../errors.js";
|
|
|
4
4
|
import { sanitizeModernMessage } from "./diagnostics.js";
|
|
5
5
|
import { McpMrtrError } from "./errors.js";
|
|
6
6
|
import { getModernDispatchGuard, modernDispatchGuard } from "./request.js";
|
|
7
|
-
import { clearMcpParameterHeaders, ModernParameterHeaders } from "./parameter-headers.js";
|
|
7
|
+
import { clearMcpParameterHeaders, ModernParameterHeaders, ParameterHeaderValidationError, } from "./parameter-headers.js";
|
|
8
8
|
export class ModernTransportError extends Error {
|
|
9
9
|
constructor(message) {
|
|
10
10
|
super(message);
|
|
@@ -119,6 +119,8 @@ export class ModernHttpTransport {
|
|
|
119
119
|
}
|
|
120
120
|
}
|
|
121
121
|
catch (error) {
|
|
122
|
+
if (error instanceof ParameterHeaderValidationError)
|
|
123
|
+
throw error;
|
|
122
124
|
const failure = error instanceof McpMrtrError || error instanceof AuthError
|
|
123
125
|
? error
|
|
124
126
|
: new McpMrtrError("MCP_MRTR_TRANSPORT_FAILED");
|
|
@@ -142,7 +144,7 @@ export class ModernHttpTransport {
|
|
|
142
144
|
...incoming,
|
|
143
145
|
result: {
|
|
144
146
|
...result,
|
|
145
|
-
tools: this.#parameterHeaders.filterTools(result.tools, this.#toolLists.get(incoming.id) === true),
|
|
147
|
+
tools: this.#parameterHeaders.filterTools(result.tools, this.#toolLists.get(incoming.id) === true, (message) => this.#options.logger?.warn(message)),
|
|
146
148
|
},
|
|
147
149
|
};
|
|
148
150
|
}
|
|
@@ -19,6 +19,7 @@ import { ResourceUpdatedNotificationSchema, registerMcpNotificationHandler } fro
|
|
|
19
19
|
import { mcpRequestOptions } from "./request-origin.js";
|
|
20
20
|
import { McpMrtrError } from "./modern/errors.js";
|
|
21
21
|
import { ensureMcpToolCallConnection } from "./health.js";
|
|
22
|
+
import { isModernMcpClient } from "./modern/request.js";
|
|
22
23
|
/** Route resource updated notifications into the shared refresh path. */
|
|
23
24
|
export function subscribeMcpResourceUpdated(client, onChange) {
|
|
24
25
|
registerMcpNotificationHandler(client, ResourceUpdatedNotificationSchema, () => {
|
|
@@ -27,6 +28,9 @@ export function subscribeMcpResourceUpdated(client, onChange) {
|
|
|
27
28
|
}
|
|
28
29
|
/** Best-effort per-resource subscriptions when the server declares support. */
|
|
29
30
|
export async function ensureMcpResourceSubscriptions(client, resources) {
|
|
31
|
+
// Modern streams derive their resource URI filter from resources/list results.
|
|
32
|
+
if (isModernMcpClient(client))
|
|
33
|
+
return;
|
|
30
34
|
if (client.getServerCapabilities()?.resources?.subscribe !== true)
|
|
31
35
|
return;
|
|
32
36
|
await Promise.all(resources.map((resource) => client.subscribeResource({ uri: resource.uri }).catch(() => undefined)));
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { Client } from "@modelcontextprotocol/sdk/client/index.js";
|
|
2
|
+
import type { RequestOptions } from "@modelcontextprotocol/sdk/shared/protocol.js";
|
|
3
|
+
import type { McpJsonSchema, McpListedTool, McpToolResult } from "./tool-contracts.ts";
|
|
4
|
+
/**
|
|
5
|
+
* Tool operations have an era-specific contract. The SDK client remains the
|
|
6
|
+
* lifecycle/request owner, but its legacy tool helpers never parse modern data.
|
|
7
|
+
*/
|
|
8
|
+
export declare function listMcpTools(client: Client, params?: Parameters<Client["listTools"]>[0], options?: RequestOptions): Promise<{
|
|
9
|
+
tools: McpListedTool[];
|
|
10
|
+
nextCursor?: string;
|
|
11
|
+
}>;
|
|
12
|
+
export declare function callMcpToolRequest(client: Client, params: Parameters<Client["callTool"]>[0], outputSchema: McpJsonSchema | undefined, options?: RequestOptions): Promise<McpToolResult>;
|
|
13
|
+
//# sourceMappingURL=tool-client.d.ts.map
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { isModernMcpClient } from "./modern/request.js";
|
|
2
|
+
import { callModernTool, listModernTools } from "./modern/tools.js";
|
|
3
|
+
/**
|
|
4
|
+
* Tool operations have an era-specific contract. The SDK client remains the
|
|
5
|
+
* lifecycle/request owner, but its legacy tool helpers never parse modern data.
|
|
6
|
+
*/
|
|
7
|
+
export async function listMcpTools(client, params, options) {
|
|
8
|
+
if (!isModernMcpClient(client))
|
|
9
|
+
return client.listTools(params, options);
|
|
10
|
+
return listModernTools(client, params, options);
|
|
11
|
+
}
|
|
12
|
+
export async function callMcpToolRequest(client, params, outputSchema, options) {
|
|
13
|
+
if (!isModernMcpClient(client))
|
|
14
|
+
return client.callTool(params, undefined, options);
|
|
15
|
+
return callModernTool(client, params, outputSchema, options);
|
|
16
|
+
}
|
|
17
|
+
//# sourceMappingURL=tool-client.js.map
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { Client } from "@modelcontextprotocol/sdk/client/index.js";
|
|
2
|
+
import type { Tool } from "@modelcontextprotocol/sdk/types.js";
|
|
3
|
+
/** Raw JSON Schema, not the SDK v1 object-root subset. */
|
|
4
|
+
export type McpJsonSchema = boolean | Record<string, unknown>;
|
|
5
|
+
export type McpJsonValue = null | boolean | number | string | McpJsonValue[] | {
|
|
6
|
+
[key: string]: McpJsonValue;
|
|
7
|
+
};
|
|
8
|
+
export type McpListedTool = Omit<Tool, "inputSchema" | "outputSchema"> & {
|
|
9
|
+
readonly inputSchema: McpJsonSchema;
|
|
10
|
+
readonly outputSchema?: McpJsonSchema;
|
|
11
|
+
};
|
|
12
|
+
export interface McpModernToolResult {
|
|
13
|
+
readonly content?: Awaited<ReturnType<Client["callTool"]>>["content"];
|
|
14
|
+
readonly structuredContent?: McpJsonValue;
|
|
15
|
+
readonly isError?: boolean;
|
|
16
|
+
readonly [key: string]: unknown;
|
|
17
|
+
}
|
|
18
|
+
export type McpToolResult = McpModernToolResult | Awaited<ReturnType<Client["callTool"]>>;
|
|
19
|
+
//# sourceMappingURL=tool-contracts.d.ts.map
|
|
@@ -2,8 +2,8 @@ import { redactMcpLogText } from "./log.js";
|
|
|
2
2
|
/** The modern operation uses one injectable monotonic clock and scheduler. */
|
|
3
3
|
export const mcpElapsedClock = {
|
|
4
4
|
now: () => performance.now(),
|
|
5
|
-
schedule: setTimeout,
|
|
6
|
-
cancel: clearTimeout,
|
|
5
|
+
schedule: (callback, ms) => setTimeout(callback, ms),
|
|
6
|
+
cancel: (timer) => clearTimeout(timer),
|
|
7
7
|
};
|
|
8
8
|
export function wrapAsync(scope, fn, sink) {
|
|
9
9
|
return async (...args) => {
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Splits a shell command into the simple commands it would run, so the `bash` permission decision
|
|
3
|
+
* can judge every one of them, not only the first.
|
|
4
|
+
*
|
|
5
|
+
* The lexer follows bash's word and operator rules closely enough to find each simple command:
|
|
6
|
+
* `;`, `&&`, `||`, `|`, `|&`, `&` and line breaks end one; subshells `( … )`, command substitution
|
|
7
|
+
* `$( … )` and backticks, process substitution `<( … )` / `>( … )`, `${ … }` and `$(( … ))` and the
|
|
8
|
+
* bodies of unquoted here-documents are searched for the commands they run; redirections and their
|
|
9
|
+
* targets are dropped. Every command name is then normalized: leading assignments and reserved
|
|
10
|
+
* words are skipped, a path is reduced to its basename, and a wrapper (`env`, `sudo`, `xargs`,
|
|
11
|
+
* `bash -c`, `find -exec`, …) yields both its own name and the command it runs.
|
|
12
|
+
*
|
|
13
|
+
* Anything the lexer does not understand (an unterminated quote, a `case`, a function definition,
|
|
14
|
+
* a command name built by an expansion, an unknown wrapper option) makes the whole command
|
|
15
|
+
* `unparsed`, and the caller must not let any command-specific rule allow it.
|
|
16
|
+
*/
|
|
17
|
+
export type BashCommandAnalysis = {
|
|
18
|
+
readonly kind: "parsed";
|
|
19
|
+
readonly segments: readonly (readonly string[])[];
|
|
20
|
+
} | {
|
|
21
|
+
readonly kind: "unparsed";
|
|
22
|
+
};
|
|
23
|
+
/** Longer commands are not lexed at all: they are `unparsed`, so only a `*` rule can decide them. */
|
|
24
|
+
export declare const MAX_COMMAND_LENGTH: number;
|
|
25
|
+
/**
|
|
26
|
+
* Every simple command `command` would run, each as its normalized words (command name first), in
|
|
27
|
+
* source order; or `unparsed` when any part of the command is outside what this lexer understands.
|
|
28
|
+
*/
|
|
29
|
+
export declare function analyzeBashCommand(command: string): BashCommandAnalysis;
|
|
30
|
+
/** Lexer steps the last `analyzeBashCommand` call used (for scaling tests). */
|
|
31
|
+
export declare function lastAnalysisSteps(): number;
|
|
32
|
+
/**
|
|
33
|
+
* Candidate command names for a command the lexer could not parse, used only so a deny rule still
|
|
34
|
+
* matches: every plain word, at every position, read as the start of a command.
|
|
35
|
+
*/
|
|
36
|
+
export declare function bestEffortCommandLines(command: string): string[][];
|
|
37
|
+
//# sourceMappingURL=bash-command-segments.d.ts.map
|