@adonis-agora/agent 0.31.0 → 0.33.1
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 +795 -0
- package/dist/assets/spa/assets/index-DjIMQOxi.js +9 -0
- package/dist/assets/spa/index.html +1 -1
- package/dist/providers/agent_provider.d.ts.map +1 -1
- package/dist/providers/agent_provider.js +140 -2
- package/dist/providers/agent_provider.js.map +1 -1
- package/dist/src/agent-deps-factory.d.ts +16 -2
- package/dist/src/agent-deps-factory.d.ts.map +1 -1
- package/dist/src/agent-deps-factory.js +8 -0
- package/dist/src/agent-deps-factory.js.map +1 -1
- package/dist/src/agent-deps.d.ts +21 -1
- package/dist/src/agent-deps.d.ts.map +1 -1
- package/dist/src/agent-deps.js.map +1 -1
- package/dist/src/agent-loop.d.ts +228 -9
- package/dist/src/agent-loop.d.ts.map +1 -1
- package/dist/src/agent-loop.js +1360 -209
- package/dist/src/agent-loop.js.map +1 -1
- package/dist/src/agent-service.d.ts +27 -0
- package/dist/src/agent-service.d.ts.map +1 -1
- package/dist/src/agent-service.js +29 -0
- package/dist/src/agent-service.js.map +1 -1
- package/dist/src/ai-sdk/ai-sdk-model.d.ts.map +1 -1
- package/dist/src/ai-sdk/ai-sdk-model.js +21 -1
- package/dist/src/ai-sdk/ai-sdk-model.js.map +1 -1
- package/dist/src/client/sse.d.ts +32 -2
- package/dist/src/client/sse.d.ts.map +1 -1
- package/dist/src/client/sse.js +45 -2
- package/dist/src/client/sse.js.map +1 -1
- package/dist/src/define_config.d.ts +41 -7
- package/dist/src/define_config.d.ts.map +1 -1
- package/dist/src/define_config.js.map +1 -1
- package/dist/src/durable/agent-run-workflow.d.ts +10 -11
- package/dist/src/durable/agent-run-workflow.d.ts.map +1 -1
- package/dist/src/durable/agent-run-workflow.js +49 -21
- package/dist/src/durable/agent-run-workflow.js.map +1 -1
- package/dist/src/durable/durable-agent-runner.d.ts +3 -2
- package/dist/src/durable/durable-agent-runner.d.ts.map +1 -1
- package/dist/src/durable/durable-agent-runner.js +2 -2
- package/dist/src/durable/durable-agent-runner.js.map +1 -1
- package/dist/src/elicitation.d.ts +207 -0
- package/dist/src/elicitation.d.ts.map +1 -0
- package/dist/src/elicitation.js +315 -0
- package/dist/src/elicitation.js.map +1 -0
- package/dist/src/evals/approval-prior.d.ts +58 -0
- package/dist/src/evals/approval-prior.d.ts.map +1 -0
- package/dist/src/evals/approval-prior.js +82 -0
- package/dist/src/evals/approval-prior.js.map +1 -0
- package/dist/src/evals/evaluate.d.ts +51 -0
- package/dist/src/evals/evaluate.d.ts.map +1 -0
- package/dist/src/evals/evaluate.js +76 -0
- package/dist/src/evals/evaluate.js.map +1 -0
- package/dist/src/evals/governance-sample-source.d.ts +23 -0
- package/dist/src/evals/governance-sample-source.d.ts.map +1 -0
- package/dist/src/evals/governance-sample-source.js +93 -0
- package/dist/src/evals/governance-sample-source.js.map +1 -0
- package/dist/src/evals/in-memory-score-store.d.ts +16 -0
- package/dist/src/evals/in-memory-score-store.d.ts.map +1 -0
- package/dist/src/evals/in-memory-score-store.js +57 -0
- package/dist/src/evals/in-memory-score-store.js.map +1 -0
- package/dist/src/evals/index.d.ts +15 -0
- package/dist/src/evals/index.d.ts.map +1 -0
- package/dist/src/evals/index.js +14 -0
- package/dist/src/evals/index.js.map +1 -0
- package/dist/src/evals/judge.d.ts +30 -0
- package/dist/src/evals/judge.d.ts.map +1 -0
- package/dist/src/evals/judge.js +53 -0
- package/dist/src/evals/judge.js.map +1 -0
- package/dist/src/evals/live-scoring.d.ts +42 -0
- package/dist/src/evals/live-scoring.d.ts.map +1 -0
- package/dist/src/evals/live-scoring.js +103 -0
- package/dist/src/evals/live-scoring.js.map +1 -0
- package/dist/src/evals/sample-source.d.ts +40 -0
- package/dist/src/evals/sample-source.d.ts.map +1 -0
- package/dist/src/evals/sample-source.js +33 -0
- package/dist/src/evals/sample-source.js.map +1 -0
- package/dist/src/evals/score-store.d.ts +54 -0
- package/dist/src/evals/score-store.d.ts.map +1 -0
- package/dist/src/evals/score-store.js +2 -0
- package/dist/src/evals/score-store.js.map +1 -0
- package/dist/src/evals/scorers/answer-relevancy.scorer.d.ts +28 -0
- package/dist/src/evals/scorers/answer-relevancy.scorer.d.ts.map +1 -0
- package/dist/src/evals/scorers/answer-relevancy.scorer.js +42 -0
- package/dist/src/evals/scorers/answer-relevancy.scorer.js.map +1 -0
- package/dist/src/evals/scorers/approval-outcome.scorer.d.ts +22 -0
- package/dist/src/evals/scorers/approval-outcome.scorer.d.ts.map +1 -0
- package/dist/src/evals/scorers/approval-outcome.scorer.js +60 -0
- package/dist/src/evals/scorers/approval-outcome.scorer.js.map +1 -0
- package/dist/src/evals/scorers/approval-risk.scorer.d.ts +28 -0
- package/dist/src/evals/scorers/approval-risk.scorer.d.ts.map +1 -0
- package/dist/src/evals/scorers/approval-risk.scorer.js +54 -0
- package/dist/src/evals/scorers/approval-risk.scorer.js.map +1 -0
- package/dist/src/evals/scorers/run-completion.scorer.d.ts +18 -0
- package/dist/src/evals/scorers/run-completion.scorer.d.ts.map +1 -0
- package/dist/src/evals/scorers/run-completion.scorer.js +55 -0
- package/dist/src/evals/scorers/run-completion.scorer.js.map +1 -0
- package/dist/src/evals/summarize.d.ts +44 -0
- package/dist/src/evals/summarize.d.ts.map +1 -0
- package/dist/src/evals/summarize.js +87 -0
- package/dist/src/evals/summarize.js.map +1 -0
- package/dist/src/evals/types.d.ts +81 -0
- package/dist/src/evals/types.d.ts.map +1 -0
- package/dist/src/evals/types.js +15 -0
- package/dist/src/evals/types.js.map +1 -0
- package/dist/src/history-window.d.ts +50 -11
- package/dist/src/history-window.d.ts.map +1 -1
- package/dist/src/history-window.js +84 -12
- package/dist/src/history-window.js.map +1 -1
- package/dist/src/index.d.ts +9 -2
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +9 -2
- package/dist/src/index.js.map +1 -1
- package/dist/src/mcp/server.d.ts +8 -0
- package/dist/src/mcp/server.d.ts.map +1 -1
- package/dist/src/mcp/server.js +27 -1
- package/dist/src/mcp/server.js.map +1 -1
- package/dist/src/mcp-client/importer.d.ts +75 -0
- package/dist/src/mcp-client/importer.d.ts.map +1 -0
- package/dist/src/mcp-client/importer.js +161 -0
- package/dist/src/mcp-client/importer.js.map +1 -0
- package/dist/src/mcp-client/index.d.ts +9 -0
- package/dist/src/mcp-client/index.d.ts.map +1 -0
- package/dist/src/mcp-client/index.js +8 -0
- package/dist/src/mcp-client/index.js.map +1 -0
- package/dist/src/mcp-client/options.d.ts +99 -0
- package/dist/src/mcp-client/options.d.ts.map +1 -0
- package/dist/src/mcp-client/options.js +2 -0
- package/dist/src/mcp-client/options.js.map +1 -0
- package/dist/src/mcp-client/tool-input.d.ts +39 -0
- package/dist/src/mcp-client/tool-input.d.ts.map +1 -0
- package/dist/src/mcp-client/tool-input.js +61 -0
- package/dist/src/mcp-client/tool-input.js.map +1 -0
- package/dist/src/mcp-client/tool-kind.d.ts +37 -0
- package/dist/src/mcp-client/tool-kind.d.ts.map +1 -0
- package/dist/src/mcp-client/tool-kind.js +20 -0
- package/dist/src/mcp-client/tool-kind.js.map +1 -0
- package/dist/src/mcp-client/tool-name.d.ts +22 -0
- package/dist/src/mcp-client/tool-name.d.ts.map +1 -0
- package/dist/src/mcp-client/tool-name.js +35 -0
- package/dist/src/mcp-client/tool-name.js.map +1 -0
- package/dist/src/mcp-client/tool-source.d.ts +75 -0
- package/dist/src/mcp-client/tool-source.d.ts.map +1 -0
- package/dist/src/mcp-client/tool-source.js +244 -0
- package/dist/src/mcp-client/tool-source.js.map +1 -0
- package/dist/src/mcp-client/transient.d.ts +28 -0
- package/dist/src/mcp-client/transient.d.ts.map +1 -0
- package/dist/src/mcp-client/transient.js +126 -0
- package/dist/src/mcp-client/transient.js.map +1 -0
- package/dist/src/mcp-client/unsafe-regex.d.ts +23 -0
- package/dist/src/mcp-client/unsafe-regex.d.ts.map +1 -0
- package/dist/src/mcp-client/unsafe-regex.js +194 -0
- package/dist/src/mcp-client/unsafe-regex.js.map +1 -0
- package/dist/src/memory.d.ts +448 -0
- package/dist/src/memory.d.ts.map +1 -0
- package/dist/src/memory.js +338 -0
- package/dist/src/memory.js.map +1 -0
- package/dist/src/processors.d.ts +134 -0
- package/dist/src/processors.d.ts.map +1 -0
- package/dist/src/processors.js +215 -0
- package/dist/src/processors.js.map +1 -0
- package/dist/src/rag/index.d.ts +1 -1
- package/dist/src/rag/index.d.ts.map +1 -1
- package/dist/src/rag/index.js +1 -1
- package/dist/src/rag/index.js.map +1 -1
- package/dist/src/rag/pg-vector-store.d.ts +41 -0
- package/dist/src/rag/pg-vector-store.d.ts.map +1 -1
- package/dist/src/rag/pg-vector-store.js +93 -15
- package/dist/src/rag/pg-vector-store.js.map +1 -1
- package/dist/src/replay-integrity.d.ts +17 -0
- package/dist/src/replay-integrity.d.ts.map +1 -0
- package/dist/src/replay-integrity.js +19 -0
- package/dist/src/replay-integrity.js.map +1 -0
- package/dist/src/runners/inline-agent-runner.d.ts +33 -7
- package/dist/src/runners/inline-agent-runner.d.ts.map +1 -1
- package/dist/src/runners/inline-agent-runner.js +113 -27
- package/dist/src/runners/inline-agent-runner.js.map +1 -1
- package/dist/src/skills.d.ts +291 -0
- package/dist/src/skills.d.ts.map +1 -0
- package/dist/src/skills.js +0 -0
- package/dist/src/skills.js.map +1 -0
- package/dist/src/spi/agent-runner.d.ts +20 -6
- package/dist/src/spi/agent-runner.d.ts.map +1 -1
- package/dist/src/spi/agent-store.d.ts +53 -0
- package/dist/src/spi/agent-store.d.ts.map +1 -1
- package/dist/src/spi/governance-queries.d.ts +5 -0
- package/dist/src/spi/governance-queries.d.ts.map +1 -1
- package/dist/src/spi/history-window.d.ts +64 -10
- package/dist/src/spi/history-window.d.ts.map +1 -1
- package/dist/src/spi/model-provider.d.ts +18 -0
- package/dist/src/spi/model-provider.d.ts.map +1 -1
- package/dist/src/spi/processors.d.ts +161 -0
- package/dist/src/spi/processors.d.ts.map +1 -0
- package/dist/src/spi/processors.js +57 -0
- package/dist/src/spi/processors.js.map +1 -0
- package/dist/src/spi/token-stream-sink.d.ts +43 -0
- package/dist/src/spi/token-stream-sink.d.ts.map +1 -1
- package/dist/src/spi/token-stream-sink.js +17 -1
- package/dist/src/spi/token-stream-sink.js.map +1 -1
- package/dist/src/sse.d.ts +5 -2
- package/dist/src/sse.d.ts.map +1 -1
- package/dist/src/sse.js +11 -2
- package/dist/src/sse.js.map +1 -1
- package/dist/src/stores/lucid-governance-queries.d.ts.map +1 -1
- package/dist/src/stores/lucid-governance-queries.js +3 -0
- package/dist/src/stores/lucid-governance-queries.js.map +1 -1
- package/dist/src/stores/lucid-schema.d.ts.map +1 -1
- package/dist/src/stores/lucid-schema.js +15 -0
- package/dist/src/stores/lucid-schema.js.map +1 -1
- package/dist/src/stores/lucid.d.ts +11 -3
- package/dist/src/stores/lucid.d.ts.map +1 -1
- package/dist/src/stores/lucid.js +65 -0
- package/dist/src/stores/lucid.js.map +1 -1
- package/dist/src/structured-output.d.ts +57 -0
- package/dist/src/structured-output.d.ts.map +1 -0
- package/dist/src/structured-output.js +80 -0
- package/dist/src/structured-output.js.map +1 -0
- package/dist/src/testing/fake-model-provider.d.ts +8 -4
- package/dist/src/testing/fake-model-provider.d.ts.map +1 -1
- package/dist/src/testing/fake-model-provider.js +6 -9
- package/dist/src/testing/fake-model-provider.js.map +1 -1
- package/dist/src/testing/in-memory-governance-queries.d.ts.map +1 -1
- package/dist/src/testing/in-memory-governance-queries.js +1 -0
- package/dist/src/testing/in-memory-governance-queries.js.map +1 -1
- package/dist/src/testing/in-memory-store.d.ts +4 -3
- package/dist/src/testing/in-memory-store.d.ts.map +1 -1
- package/dist/src/testing/in-memory-store.js +13 -7
- package/dist/src/testing/in-memory-store.js.map +1 -1
- package/dist/src/testing/index.d.ts +1 -1
- package/dist/src/testing/index.d.ts.map +1 -1
- package/dist/src/testing/index.js.map +1 -1
- package/dist/src/tool-registry.d.ts +9 -0
- package/dist/src/tool-registry.d.ts.map +1 -1
- package/dist/src/tool-registry.js +11 -0
- package/dist/src/tool-registry.js.map +1 -1
- package/dist/src/types.d.ts +70 -2
- package/dist/src/types.d.ts.map +1 -1
- package/package.json +38 -24
- package/skills/agent-personas-agents/SKILL.md +16 -12
- package/dist/assets/spa/assets/index-3Q2m5_Ax.js +0 -9
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
import { McpToolSource } from './tool-source.js';
|
|
2
|
+
/**
|
|
3
|
+
* Connects to each configured MCP server and registers what it exports into the shared
|
|
4
|
+
* {@link ToolRegistry} — the same registry `@aiTool` discovery writes to, so an imported tool goes
|
|
5
|
+
* through every gate a hand-written one does.
|
|
6
|
+
*
|
|
7
|
+
* The provider calls {@link start} inside `app.booted()`, AFTER tool discovery has registered the
|
|
8
|
+
* app's own tools, which is what lets the name-collision check below see them.
|
|
9
|
+
*
|
|
10
|
+
* The registry is keyed by name and nothing else, so a name is OWNED by whoever registered it
|
|
11
|
+
* first: the application, or one named server. A second claimant is refused rather than allowed to
|
|
12
|
+
* replace a live handler, because the substitution is invisible from everywhere else — the model
|
|
13
|
+
* goes on calling `deploy`, and `deploy` now reaches somebody else's server.
|
|
14
|
+
*/
|
|
15
|
+
export class McpToolImporter {
|
|
16
|
+
servers;
|
|
17
|
+
registry;
|
|
18
|
+
logger;
|
|
19
|
+
sources = new Map();
|
|
20
|
+
/** Local tool name → what is registered under it, so ownership survives a {@link refresh}. */
|
|
21
|
+
owners = new Map();
|
|
22
|
+
constructor(servers, registry, logger) {
|
|
23
|
+
this.servers = servers;
|
|
24
|
+
this.registry = registry;
|
|
25
|
+
this.logger = logger;
|
|
26
|
+
// A name identifies a server in the logs, in `refresh(name)`, in the ownership map and in the
|
|
27
|
+
// default tool prefix. Two servers sharing one leaves every one of those pointing at a single
|
|
28
|
+
// arbitrary member of the pair — a collision that IS statically detectable, so it is refused
|
|
29
|
+
// here rather than surfacing as one server's tools mysteriously missing.
|
|
30
|
+
const names = servers.map((config) => config.name);
|
|
31
|
+
const duplicate = names.find((name, index) => names.indexOf(name) !== index);
|
|
32
|
+
if (duplicate !== undefined) {
|
|
33
|
+
throw new Error(`Two MCP servers are configured as "${duplicate}". Give each server a distinct name.`);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
/** Open each configured server and import from all of them. */
|
|
37
|
+
async start() {
|
|
38
|
+
for (const config of this.servers) {
|
|
39
|
+
this.sources.set(config.name, new McpToolSource(config, this.logger));
|
|
40
|
+
}
|
|
41
|
+
return this.refresh();
|
|
42
|
+
}
|
|
43
|
+
async close() {
|
|
44
|
+
await Promise.all([...this.sources.values()].map((source) => source.close()));
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Re-import from one server, or from all of them — the way back for a server that was down at
|
|
48
|
+
* boot, or whose exports have changed since.
|
|
49
|
+
*
|
|
50
|
+
* A re-import is the server's CURRENT answer to `tools/list`, so it removes as well as adds: a
|
|
51
|
+
* tool the server has dropped or renamed is unregistered, because going on offering the model a
|
|
52
|
+
* tool whose next call fails remotely is worse than not offering it at all. Only names this
|
|
53
|
+
* importer registered for THAT server are eligible — never the application's own, never another
|
|
54
|
+
* server's.
|
|
55
|
+
*
|
|
56
|
+
* A server that could not be reached prunes nothing. Its tools are unknown, not gone, and a
|
|
57
|
+
* network blip is not a reason to withdraw a working tool from the model.
|
|
58
|
+
*
|
|
59
|
+
* Returns how many tools the servers it re-imported from just claimed, which is not the
|
|
60
|
+
* registry's total: a name skipped for a collision is not counted, and a scoped refresh says
|
|
61
|
+
* nothing about what the other servers hold.
|
|
62
|
+
*/
|
|
63
|
+
async refresh(serverName) {
|
|
64
|
+
const configs = this.servers.filter((config) => this.sources.has(config.name) && (serverName === undefined || config.name === serverName));
|
|
65
|
+
if (serverName !== undefined && configs.length === 0) {
|
|
66
|
+
// A scoped refresh that matched nothing re-imported nothing, and `0` reads identically to a
|
|
67
|
+
// server that answered with no tools — so the name is reported rather than left to look like
|
|
68
|
+
// an answer.
|
|
69
|
+
const open = [...this.sources.keys()];
|
|
70
|
+
this.logger?.warn(`MCP refresh("${serverName}") matched no open MCP server — nothing was re-imported. Open servers: ${open.length > 0 ? open.join(', ') : '(none)'}.`);
|
|
71
|
+
return 0;
|
|
72
|
+
}
|
|
73
|
+
// Connecting and listing is the slow part and the servers are independent, so it runs in
|
|
74
|
+
// parallel — but registration below replays in CONFIGURATION order, because which server owns a
|
|
75
|
+
// name two of them both export has to be the same answer on every boot.
|
|
76
|
+
const listed = await Promise.all(configs.map(async (config) => ({ config, tools: await this.importFrom(config) })));
|
|
77
|
+
// Pruning runs BEFORE any registration, so a name one server has just dropped is free for the
|
|
78
|
+
// next server in configuration order to claim within this same refresh.
|
|
79
|
+
for (const { config, tools } of listed) {
|
|
80
|
+
if (tools !== undefined) {
|
|
81
|
+
this.prune(config.name, new Set(tools.map((tool) => tool.spec.name)));
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
let total = 0;
|
|
85
|
+
for (const { config, tools } of listed) {
|
|
86
|
+
if (tools !== undefined) {
|
|
87
|
+
total += this.register(config, tools);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
return total;
|
|
91
|
+
}
|
|
92
|
+
/** Every tool currently imported, and where each came from — what the servers export NOW. */
|
|
93
|
+
importedTools() {
|
|
94
|
+
return [...this.owners.values()];
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* A server that is unreachable costs its own tools and nothing else: the model is simply never
|
|
98
|
+
* offered them. Booting the whole application on the availability of a third-party process is the
|
|
99
|
+
* wrong trade — until a server declares `required: true`, which says the app is not useful
|
|
100
|
+
* without it and should fail loudly instead.
|
|
101
|
+
*
|
|
102
|
+
* `undefined` is a server that could not be reached, as distinct from one that exports no tools:
|
|
103
|
+
* the first has already been reported here, the second is worth reporting on registration.
|
|
104
|
+
*/
|
|
105
|
+
async importFrom(config) {
|
|
106
|
+
const source = this.sources.get(config.name);
|
|
107
|
+
if (source === undefined) {
|
|
108
|
+
return undefined;
|
|
109
|
+
}
|
|
110
|
+
try {
|
|
111
|
+
return await source.import();
|
|
112
|
+
}
|
|
113
|
+
catch (error) {
|
|
114
|
+
const message = `MCP server "${config.name}" could not be imported: ${error instanceof Error ? error.message : String(error)}`;
|
|
115
|
+
if (config.required === true) {
|
|
116
|
+
throw new Error(message, { cause: error });
|
|
117
|
+
}
|
|
118
|
+
this.logger?.warn(`${message} — its tools are unavailable in this process.`);
|
|
119
|
+
return undefined;
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Drop what `serverName` used to export and no longer does. Keyed on ownership rather than on the
|
|
124
|
+
* name's prefix: `namespace: false` imports under bare names, where a prefix says nothing about
|
|
125
|
+
* who registered one.
|
|
126
|
+
*/
|
|
127
|
+
prune(serverName, exported) {
|
|
128
|
+
for (const [name, owner] of [...this.owners]) {
|
|
129
|
+
if (owner.serverName !== serverName || exported.has(name)) {
|
|
130
|
+
continue;
|
|
131
|
+
}
|
|
132
|
+
this.owners.delete(name);
|
|
133
|
+
this.registry.unregister(name);
|
|
134
|
+
this.logger?.warn(`MCP server "${serverName}": tool "${name}" is no longer exported — unregistered.`);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
register(config, tools) {
|
|
138
|
+
let count = 0;
|
|
139
|
+
for (const tool of tools) {
|
|
140
|
+
const owner = this.owners.get(tool.spec.name);
|
|
141
|
+
if (owner === undefined && this.registry.has(tool.spec.name)) {
|
|
142
|
+
this.logger?.warn(`MCP server "${config.name}": tool "${tool.spec.name}" is already registered by this application — skipped. Namespace the server's tools to import it alongside.`);
|
|
143
|
+
continue;
|
|
144
|
+
}
|
|
145
|
+
if (owner !== undefined && owner.serverName !== config.name) {
|
|
146
|
+
this.logger?.warn(`MCP server "${config.name}": tool "${tool.spec.name}" is already imported from MCP server "${owner.serverName}" — skipped. Namespace one of the two servers to import both.`);
|
|
147
|
+
continue;
|
|
148
|
+
}
|
|
149
|
+
this.registry.register(tool.spec, tool.handler);
|
|
150
|
+
this.owners.set(tool.spec.name, {
|
|
151
|
+
name: tool.spec.name,
|
|
152
|
+
serverName: config.name,
|
|
153
|
+
remoteName: tool.remoteName,
|
|
154
|
+
description: tool.spec.description,
|
|
155
|
+
});
|
|
156
|
+
count += 1;
|
|
157
|
+
}
|
|
158
|
+
return count;
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
//# sourceMappingURL=importer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"importer.js","sourceRoot":"","sources":["../../../src/mcp-client/importer.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export { type McpRegisteredTool, McpToolImporter } from './importer.js';
|
|
2
|
+
export type { McpCustomTransportConfig, McpHttpTransportConfig, McpLogger, McpServerConfig, McpStdioTransportConfig, McpTransportConfig, } from './options.js';
|
|
3
|
+
export { type McpInputSchemaOptions, mcpInputSchema } from './tool-input.js';
|
|
4
|
+
export { type McpToolAnnotations, type McpToolInfo, type McpToolKindPolicy, resolveMcpToolKind, } from './tool-kind.js';
|
|
5
|
+
export { localToolName, MAX_TOOL_NAME_LENGTH } from './tool-name.js';
|
|
6
|
+
export { type McpImportedTool, McpToolCallError, McpToolSource } from './tool-source.js';
|
|
7
|
+
export { isPreExecutionMcpError, isTransientMcpError } from './transient.js';
|
|
8
|
+
export { findUnsafePattern, isUnsafeRegex } from './unsafe-regex.js';
|
|
9
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/mcp-client/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,iBAAiB,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AACxE,YAAY,EACV,wBAAwB,EACxB,sBAAsB,EACtB,SAAS,EACT,eAAe,EACf,uBAAuB,EACvB,kBAAkB,GACnB,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,KAAK,qBAAqB,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAC7E,OAAO,EACL,KAAK,kBAAkB,EACvB,KAAK,WAAW,EAChB,KAAK,iBAAiB,EACtB,kBAAkB,GACnB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,aAAa,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAC;AACrE,OAAO,EAAE,KAAK,eAAe,EAAE,gBAAgB,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACzF,OAAO,EAAE,sBAAsB,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AAC7E,OAAO,EAAE,iBAAiB,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export { McpToolImporter } from './importer.js';
|
|
2
|
+
export { mcpInputSchema } from './tool-input.js';
|
|
3
|
+
export { resolveMcpToolKind, } from './tool-kind.js';
|
|
4
|
+
export { localToolName, MAX_TOOL_NAME_LENGTH } from './tool-name.js';
|
|
5
|
+
export { McpToolCallError, McpToolSource } from './tool-source.js';
|
|
6
|
+
export { isPreExecutionMcpError, isTransientMcpError } from './transient.js';
|
|
7
|
+
export { findUnsafePattern, isUnsafeRegex } from './unsafe-regex.js';
|
|
8
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/mcp-client/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAA0B,eAAe,EAAE,MAAM,eAAe,CAAC;AASxE,OAAO,EAA8B,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAC7E,OAAO,EAIL,kBAAkB,GACnB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,aAAa,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAC;AACrE,OAAO,EAAwB,gBAAgB,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACzF,OAAO,EAAE,sBAAsB,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AAC7E,OAAO,EAAE,iBAAiB,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC"}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import type { Transport } from '@modelcontextprotocol/sdk/shared/transport.js';
|
|
2
|
+
import type { jsonSchemaValidator } from '@modelcontextprotocol/sdk/validation';
|
|
3
|
+
import type { ToolTransientRetrySetting } from '../tool-retry.js';
|
|
4
|
+
import type { McpToolKindPolicy } from './tool-kind.js';
|
|
5
|
+
/** A server this process starts and talks to over its stdin/stdout. */
|
|
6
|
+
export interface McpStdioTransportConfig {
|
|
7
|
+
type: 'stdio';
|
|
8
|
+
command: string;
|
|
9
|
+
args?: string[];
|
|
10
|
+
/** Replaces the inherited environment entirely (the SDK's own semantics), rather than adding to it. */
|
|
11
|
+
env?: Record<string, string>;
|
|
12
|
+
cwd?: string;
|
|
13
|
+
}
|
|
14
|
+
/** A server reachable over MCP's streamable-HTTP transport. */
|
|
15
|
+
export interface McpHttpTransportConfig {
|
|
16
|
+
type: 'http';
|
|
17
|
+
url: string;
|
|
18
|
+
/** Sent on every request — the usual place for a static bearer token or an API key. */
|
|
19
|
+
headers?: Record<string, string>;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Anything else: an OAuth-carrying HTTP transport, the legacy SSE transport, or an in-process
|
|
23
|
+
* linked pair in a test. Called again for each reconnect, so it must return a FRESH transport —
|
|
24
|
+
* a `Transport` that has been closed cannot be restarted.
|
|
25
|
+
*/
|
|
26
|
+
export interface McpCustomTransportConfig {
|
|
27
|
+
type: 'custom';
|
|
28
|
+
create: () => Transport | Promise<Transport>;
|
|
29
|
+
}
|
|
30
|
+
export type McpTransportConfig = McpStdioTransportConfig | McpHttpTransportConfig | McpCustomTransportConfig;
|
|
31
|
+
/** Somewhere to report a server that misbehaved. Structurally satisfied by AdonisJS's `Logger`. */
|
|
32
|
+
export interface McpLogger {
|
|
33
|
+
warn(message: string): void;
|
|
34
|
+
}
|
|
35
|
+
/** One MCP server to import tools from, and the policy every tool it exports is imported under. */
|
|
36
|
+
export interface McpServerConfig {
|
|
37
|
+
/** Identifies the server in logs, and prefixes its tool names by default. */
|
|
38
|
+
name: string;
|
|
39
|
+
transport: McpTransportConfig;
|
|
40
|
+
/**
|
|
41
|
+
* How an imported tool gets its `kind`. Defaults to `'action'` — every remote tool waits for a
|
|
42
|
+
* human. See {@link McpToolKindPolicy} for what widening it means.
|
|
43
|
+
*/
|
|
44
|
+
kind?: McpToolKindPolicy;
|
|
45
|
+
/** Import only these remote tool names. Omit to import everything the server lists. */
|
|
46
|
+
include?: string[];
|
|
47
|
+
/** Import everything except these remote tool names. Applied after {@link include}. */
|
|
48
|
+
exclude?: string[];
|
|
49
|
+
/** Prefix for imported tool names: the server name (default), a string, or `false` for none. */
|
|
50
|
+
namespace?: boolean | string;
|
|
51
|
+
/** Roles allowed to invoke every tool from this server. Omit → the module's `defaultRoles`. */
|
|
52
|
+
roles?: string[];
|
|
53
|
+
/** Ability every tool from this server is checked against by an ability-aware `RolesPolicy`. */
|
|
54
|
+
ability?: string;
|
|
55
|
+
/** Cap on the MCP initialize handshake. Default 10s. */
|
|
56
|
+
connectTimeoutMs?: number;
|
|
57
|
+
/** Cap on `tools/list` and on every tool call. Default 30s. */
|
|
58
|
+
requestTimeoutMs?: number;
|
|
59
|
+
/**
|
|
60
|
+
* Retry policy for a call that failed transiently, applied around the tool's own invocation with
|
|
61
|
+
* `invokeWithTransientRetry` — the same in-place retry the agent loop uses for a rolled-back
|
|
62
|
+
* database step, so a retry never becomes a second durable checkpoint. Defaults to
|
|
63
|
+
* `{ attempts: 2, backoffMs: 150 }`; `false` surfaces the first failure.
|
|
64
|
+
*
|
|
65
|
+
* WHICH FAILURES COUNT DEPENDS ON THE {@link McpServerConfig.kind}. A `read` tool uses
|
|
66
|
+
* {@link import('./transient.js').isTransientMcpError} — dropped connections, request timeouts,
|
|
67
|
+
* retryable HTTP statuses, socket errors. An `action` tool uses the narrower
|
|
68
|
+
* {@link import('./transient.js').isPreExecutionMcpError}, which accepts only failures that PROVE
|
|
69
|
+
* the tool did not run: a timeout or a 503 may equally be a remote effect whose answer was lost,
|
|
70
|
+
* and re-issuing that would spend one human approval on two remote side effects.
|
|
71
|
+
*
|
|
72
|
+
* Supplying `classify` takes that judgement over for every kind, including `action`.
|
|
73
|
+
*
|
|
74
|
+
* Retrying here, rather than by widening the app-wide `toolTransientRetry` classifier, keeps the
|
|
75
|
+
* two from compounding: a host that would rather retry at the loop layer should pass
|
|
76
|
+
* `isTransientMcpError` into that classifier AND set this to `false`.
|
|
77
|
+
*/
|
|
78
|
+
transientRetry?: ToolTransientRetrySetting;
|
|
79
|
+
/** Compiles each tool's JSON Schema. Defaults to the MCP SDK's AJV adapter. */
|
|
80
|
+
validator?: jsonSchemaValidator;
|
|
81
|
+
/**
|
|
82
|
+
* Skip a tool whose input schema carries a `pattern` that can backtrack exponentially — a string
|
|
83
|
+
* this server writes and the model fills in, which together can pin the event loop of whichever
|
|
84
|
+
* process runs the tool. Default `true`. Turn it off only for a `validator` whose regex engine
|
|
85
|
+
* does not backtrack, where the screen costs tools and buys nothing.
|
|
86
|
+
*/
|
|
87
|
+
rejectUnsafePatterns?: boolean;
|
|
88
|
+
/** What this client calls itself in the MCP handshake. Defaults to `adonis-agora-agent-mcp`. */
|
|
89
|
+
clientInfo?: {
|
|
90
|
+
name: string;
|
|
91
|
+
version: string;
|
|
92
|
+
};
|
|
93
|
+
/**
|
|
94
|
+
* Fail application boot when this server cannot be reached. Default `false`: an unreachable
|
|
95
|
+
* server costs its own tools, not the app — see {@link import('./importer.js').McpToolImporter}.
|
|
96
|
+
*/
|
|
97
|
+
required?: boolean;
|
|
98
|
+
}
|
|
99
|
+
//# sourceMappingURL=options.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"options.d.ts","sourceRoot":"","sources":["../../../src/mcp-client/options.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,+CAA+C,CAAC;AAC/E,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,sCAAsC,CAAC;AAChF,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,kBAAkB,CAAC;AAClE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAExD,uEAAuE;AACvE,MAAM,WAAW,uBAAuB;IACtC,IAAI,EAAE,OAAO,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,uGAAuG;IACvG,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC7B,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED,+DAA+D;AAC/D,MAAM,WAAW,sBAAsB;IACrC,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;IACZ,uFAAuF;IACvF,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAClC;AAED;;;;GAIG;AACH,MAAM,WAAW,wBAAwB;IACvC,IAAI,EAAE,QAAQ,CAAC;IACf,MAAM,EAAE,MAAM,SAAS,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC;CAC9C;AAED,MAAM,MAAM,kBAAkB,GAC1B,uBAAuB,GACvB,sBAAsB,GACtB,wBAAwB,CAAC;AAE7B,mGAAmG;AACnG,MAAM,WAAW,SAAS;IACxB,IAAI,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;CAC7B;AAED,mGAAmG;AACnG,MAAM,WAAW,eAAe;IAC9B,6EAA6E;IAC7E,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,kBAAkB,CAAC;IAC9B;;;OAGG;IACH,IAAI,CAAC,EAAE,iBAAiB,CAAC;IACzB,uFAAuF;IACvF,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,uFAAuF;IACvF,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,gGAAgG;IAChG,SAAS,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC;IAC7B,+FAA+F;IAC/F,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IACjB,gGAAgG;IAChG,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,wDAAwD;IACxD,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,+DAA+D;IAC/D,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B;;;;;;;;;;;;;;;;;;OAkBG;IACH,cAAc,CAAC,EAAE,yBAAyB,CAAC;IAC3C,+EAA+E;IAC/E,SAAS,CAAC,EAAE,mBAAmB,CAAC;IAChC;;;;;OAKG;IACH,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B,gGAAgG;IAChG,UAAU,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;IAC/C;;;OAGG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"options.js","sourceRoot":"","sources":["../../../src/mcp-client/options.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import type { jsonSchemaValidator } from '@modelcontextprotocol/sdk/validation';
|
|
2
|
+
import type { StandardJSONSchemaV1, StandardSchemaV1 } from '@standard-schema/spec';
|
|
3
|
+
export interface McpInputSchemaOptions {
|
|
4
|
+
/**
|
|
5
|
+
* Compiles the JSON Schema. Defaults to the SDK's AJV adapter; swap in
|
|
6
|
+
* `CfWorkerJsonSchemaValidator` (or your own) on a runtime where AJV's code generation is not
|
|
7
|
+
* available.
|
|
8
|
+
*/
|
|
9
|
+
validator?: jsonSchemaValidator;
|
|
10
|
+
/**
|
|
11
|
+
* Reject a schema carrying a `pattern` that can backtrack exponentially (see
|
|
12
|
+
* {@link findUnsafePattern}). Default `true`. Turn it off only for a `validator` whose regex
|
|
13
|
+
* engine does not backtrack, where the screen costs tools and buys nothing.
|
|
14
|
+
*/
|
|
15
|
+
rejectUnsafePatterns?: boolean;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Wraps one MCP tool's JSON Schema as the [Standard Schema](https://standardschema.dev) that
|
|
19
|
+
* `ToolSpec.inputSchema` requires, so an imported tool goes through the same `~standard.validate`
|
|
20
|
+
* gate in `ToolRegistry.invoke` as a hand-written `@AiTool`.
|
|
21
|
+
*
|
|
22
|
+
* Both halves are the server's real schema, not an approximation of it:
|
|
23
|
+
* - `validate` compiles the schema and rejects what it rejects. A tool whose schema cannot be
|
|
24
|
+
* compiled THROWS from here — the caller drops that tool, because the alternative (a schema that
|
|
25
|
+
* accepts anything) would let the model send a remote tool arbitrary arguments under the
|
|
26
|
+
* appearance of a validated call. A schema whose `pattern` can backtrack exponentially throws
|
|
27
|
+
* the same way: validating against it is a denial of service on this process, so the tool is
|
|
28
|
+
* worth no more than one whose schema does not compile.
|
|
29
|
+
* - `jsonSchema.input` hands the schema back verbatim, which is what makes the model see the real
|
|
30
|
+
* parameter shapes: `@adonis-agora/agent/ai-sdk` derives tool parameters from Zod or from
|
|
31
|
+
* this Standard JSON Schema extension, and degrades any other Standard Schema to an untyped
|
|
32
|
+
* object.
|
|
33
|
+
*
|
|
34
|
+
* `input` and `output` return the same document because validation here is a pass-through: a valid
|
|
35
|
+
* value is handed on unchanged, so the input and output types are the same type. The requested
|
|
36
|
+
* `target` draft is ignored — the server's schema is a document we relay, not one we can transpile.
|
|
37
|
+
*/
|
|
38
|
+
export declare function mcpInputSchema(jsonSchema: Record<string, unknown>, options?: McpInputSchemaOptions): StandardSchemaV1<unknown, Record<string, unknown>> & StandardJSONSchemaV1;
|
|
39
|
+
//# sourceMappingURL=tool-input.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tool-input.d.ts","sourceRoot":"","sources":["../../../src/mcp-client/tool-input.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAkB,mBAAmB,EAAE,MAAM,sCAAsC,CAAC;AAEhG,OAAO,KAAK,EAAE,oBAAoB,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAepF,MAAM,WAAW,qBAAqB;IACpC;;;;OAIG;IACH,SAAS,CAAC,EAAE,mBAAmB,CAAC;IAChC;;;;OAIG;IACH,oBAAoB,CAAC,EAAE,OAAO,CAAC;CAChC;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,cAAc,CAC5B,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACnC,OAAO,GAAE,qBAA0B,GAClC,gBAAgB,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,GAAG,oBAAoB,CA8B3E"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { AjvJsonSchemaValidator } from '@modelcontextprotocol/sdk/validation/ajv';
|
|
2
|
+
import { findUnsafePattern } from './unsafe-regex.js';
|
|
3
|
+
/**
|
|
4
|
+
* The default validator: the SDK's own AJV adapter, which is already configured for the schemas MCP
|
|
5
|
+
* servers actually emit (non-strict, format-aware, no meta-schema resolution — so a server that
|
|
6
|
+
* declares draft-2020-12 compiles as readily as one that declares draft-07).
|
|
7
|
+
*/
|
|
8
|
+
let defaultValidator;
|
|
9
|
+
function sharedValidator() {
|
|
10
|
+
defaultValidator ??= new AjvJsonSchemaValidator();
|
|
11
|
+
return defaultValidator;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Wraps one MCP tool's JSON Schema as the [Standard Schema](https://standardschema.dev) that
|
|
15
|
+
* `ToolSpec.inputSchema` requires, so an imported tool goes through the same `~standard.validate`
|
|
16
|
+
* gate in `ToolRegistry.invoke` as a hand-written `@AiTool`.
|
|
17
|
+
*
|
|
18
|
+
* Both halves are the server's real schema, not an approximation of it:
|
|
19
|
+
* - `validate` compiles the schema and rejects what it rejects. A tool whose schema cannot be
|
|
20
|
+
* compiled THROWS from here — the caller drops that tool, because the alternative (a schema that
|
|
21
|
+
* accepts anything) would let the model send a remote tool arbitrary arguments under the
|
|
22
|
+
* appearance of a validated call. A schema whose `pattern` can backtrack exponentially throws
|
|
23
|
+
* the same way: validating against it is a denial of service on this process, so the tool is
|
|
24
|
+
* worth no more than one whose schema does not compile.
|
|
25
|
+
* - `jsonSchema.input` hands the schema back verbatim, which is what makes the model see the real
|
|
26
|
+
* parameter shapes: `@adonis-agora/agent/ai-sdk` derives tool parameters from Zod or from
|
|
27
|
+
* this Standard JSON Schema extension, and degrades any other Standard Schema to an untyped
|
|
28
|
+
* object.
|
|
29
|
+
*
|
|
30
|
+
* `input` and `output` return the same document because validation here is a pass-through: a valid
|
|
31
|
+
* value is handed on unchanged, so the input and output types are the same type. The requested
|
|
32
|
+
* `target` draft is ignored — the server's schema is a document we relay, not one we can transpile.
|
|
33
|
+
*/
|
|
34
|
+
export function mcpInputSchema(jsonSchema, options = {}) {
|
|
35
|
+
if (options.rejectUnsafePatterns !== false) {
|
|
36
|
+
const unsafe = findUnsafePattern(jsonSchema);
|
|
37
|
+
if (unsafe !== undefined) {
|
|
38
|
+
throw new Error(`input schema carries a pattern that can backtrack exponentially: /${unsafe}/`);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
// The MCP wire type describes a tool's schema as an open record and the validator SPI describes
|
|
42
|
+
// it as a typed JSON Schema interface — the same document, typed from two directions.
|
|
43
|
+
const validate = (options.validator ?? sharedValidator()).getValidator(jsonSchema);
|
|
44
|
+
return {
|
|
45
|
+
'~standard': {
|
|
46
|
+
version: 1,
|
|
47
|
+
vendor: 'adonis-agora-agent-mcp',
|
|
48
|
+
validate(value) {
|
|
49
|
+
const result = validate(value);
|
|
50
|
+
return result.valid
|
|
51
|
+
? { value: result.data }
|
|
52
|
+
: { issues: [{ message: result.errorMessage }] };
|
|
53
|
+
},
|
|
54
|
+
jsonSchema: {
|
|
55
|
+
input: () => jsonSchema,
|
|
56
|
+
output: () => jsonSchema,
|
|
57
|
+
},
|
|
58
|
+
},
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
//# sourceMappingURL=tool-input.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tool-input.js","sourceRoot":"","sources":["../../../src/mcp-client/tool-input.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,sBAAsB,EAAE,MAAM,0CAA0C,CAAC;AAElF,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAEtD;;;;GAIG;AACH,IAAI,gBAAiD,CAAC;AAEtD,SAAS,eAAe;IACtB,gBAAgB,KAAK,IAAI,sBAAsB,EAAE,CAAC;IAClD,OAAO,gBAAgB,CAAC;AAC1B,CAAC;AAiBD;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,UAAU,cAAc,CAC5B,UAAmC,EACnC,OAAO,GAA0B,EAAE;IAEnC,IAAI,OAAO,CAAC,oBAAoB,KAAK,KAAK,EAAE,CAAC;QAC3C,MAAM,MAAM,GAAG,iBAAiB,CAAC,UAAU,CAAC,CAAC;QAC7C,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;YACzB,MAAM,IAAI,KAAK,CACb,qEAAqE,MAAM,GAAG,CAC/E,CAAC;QACJ,CAAC;IACH,CAAC;IACD,gGAAgG;IAChG,sFAAsF;IACtF,MAAM,QAAQ,GAAG,CAAC,OAAO,CAAC,SAAS,IAAI,eAAe,EAAE,CAAC,CAAC,YAAY,CACpE,UAA4B,CAC7B,CAAC;IACF,OAAO;QACL,WAAW,EAAE;YACX,OAAO,EAAE,CAAC;YACV,MAAM,EAAE,wBAAwB;YAChC,QAAQ,CAAC,KAAc;gBACrB,MAAM,MAAM,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;gBAC/B,OAAO,MAAM,CAAC,KAAK;oBACjB,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,IAAI,EAAE;oBACxB,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,OAAO,EAAE,MAAM,CAAC,YAAY,EAAE,CAAC,EAAE,CAAC;YACrD,CAAC;YACD,UAAU,EAAE;gBACV,KAAK,EAAE,GAAG,EAAE,CAAC,UAAU;gBACvB,MAAM,EAAE,GAAG,EAAE,CAAC,UAAU;aACzB;SACF;KACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import type { ToolKind } from '../types.js';
|
|
2
|
+
/**
|
|
3
|
+
* An MCP server's self-reported behaviour hints for one tool (MCP `ToolAnnotations`). Every field is
|
|
4
|
+
* a claim made by the remote server, so nothing here is a security boundary — see
|
|
5
|
+
* {@link McpToolKindPolicy} for why the default policy ignores them.
|
|
6
|
+
*/
|
|
7
|
+
export interface McpToolAnnotations {
|
|
8
|
+
title?: string | undefined;
|
|
9
|
+
readOnlyHint?: boolean | undefined;
|
|
10
|
+
destructiveHint?: boolean | undefined;
|
|
11
|
+
idempotentHint?: boolean | undefined;
|
|
12
|
+
openWorldHint?: boolean | undefined;
|
|
13
|
+
}
|
|
14
|
+
/** What a {@link McpToolKindPolicy} decides on: one tool as the remote server described it. */
|
|
15
|
+
export interface McpToolInfo {
|
|
16
|
+
name: string;
|
|
17
|
+
description?: string;
|
|
18
|
+
annotations?: McpToolAnnotations;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* How an imported MCP tool gets its {@link ToolKind}.
|
|
22
|
+
*
|
|
23
|
+
* The stakes: the loop auto-executes a `read` tool and pauses the turn for human approval on an
|
|
24
|
+
* `action` one. A tool imported from an MCP server was written by someone outside this codebase and
|
|
25
|
+
* its effects are not visible from here, so the DEFAULT (`'action'`) is the conservative one — a
|
|
26
|
+
* remote tool needs a human before it runs. Widening that is a decision the host makes explicitly:
|
|
27
|
+
*
|
|
28
|
+
* - `'action'` (default) — every imported tool is HITL-gated.
|
|
29
|
+
* - `'read'` — every imported tool auto-executes. Only for a server you own and audit.
|
|
30
|
+
* - `'trust-annotations'` — believe the server's `readOnlyHint`. The hint is asserted by the very
|
|
31
|
+
* party whose effects it describes, so this is a statement of trust in that server, not a check.
|
|
32
|
+
* - a predicate — decide per tool (e.g. read for a known-safe name list, action for the rest).
|
|
33
|
+
*/
|
|
34
|
+
export type McpToolKindPolicy = 'action' | 'read' | 'trust-annotations' | ((tool: McpToolInfo) => 'read' | 'action');
|
|
35
|
+
/** Resolves one imported tool's kind. Anything other than an explicit widening stays `action`. */
|
|
36
|
+
export declare function resolveMcpToolKind(tool: McpToolInfo, policy: McpToolKindPolicy | undefined): ToolKind;
|
|
37
|
+
//# sourceMappingURL=tool-kind.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tool-kind.d.ts","sourceRoot":"","sources":["../../../src/mcp-client/tool-kind.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAE5C;;;;GAIG;AACH,MAAM,WAAW,kBAAkB;IACjC,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC3B,YAAY,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IACnC,eAAe,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IACtC,cAAc,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IACrC,aAAa,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;CACrC;AAED,+FAA+F;AAC/F,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,kBAAkB,CAAC;CAClC;AAED;;;;;;;;;;;;;GAaG;AACH,MAAM,MAAM,iBAAiB,GACzB,QAAQ,GACR,MAAM,GACN,mBAAmB,GACnB,CAAC,CAAC,IAAI,EAAE,WAAW,KAAK,MAAM,GAAG,QAAQ,CAAC,CAAC;AAE/C,kGAAkG;AAClG,wBAAgB,kBAAkB,CAChC,IAAI,EAAE,WAAW,EACjB,MAAM,EAAE,iBAAiB,GAAG,SAAS,GACpC,QAAQ,CAiBV"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/** Resolves one imported tool's kind. Anything other than an explicit widening stays `action`. */
|
|
2
|
+
export function resolveMcpToolKind(tool, policy) {
|
|
3
|
+
if (typeof policy === 'function') {
|
|
4
|
+
return policy(tool);
|
|
5
|
+
}
|
|
6
|
+
if (policy === 'read') {
|
|
7
|
+
return 'read';
|
|
8
|
+
}
|
|
9
|
+
if (policy === 'trust-annotations') {
|
|
10
|
+
// `destructiveHint` is only meaningful when `readOnlyHint` is false, so a tool claiming both is
|
|
11
|
+
// describing itself incoherently — resolved on the gated side rather than guessing which half
|
|
12
|
+
// of the claim to believe.
|
|
13
|
+
const annotations = tool.annotations;
|
|
14
|
+
return annotations?.readOnlyHint === true && annotations.destructiveHint !== true
|
|
15
|
+
? 'read'
|
|
16
|
+
: 'action';
|
|
17
|
+
}
|
|
18
|
+
return 'action';
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=tool-kind.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tool-kind.js","sourceRoot":"","sources":["../../../src/mcp-client/tool-kind.ts"],"names":[],"mappings":"AA0CA,kGAAkG;AAClG,MAAM,UAAU,kBAAkB,CAChC,IAAiB,EACjB,MAAqC;IAErC,IAAI,OAAO,MAAM,KAAK,UAAU,EAAE,CAAC;QACjC,OAAO,MAAM,CAAC,IAAI,CAAC,CAAC;IACtB,CAAC;IACD,IAAI,MAAM,KAAK,MAAM,EAAE,CAAC;QACtB,OAAO,MAAM,CAAC;IAChB,CAAC;IACD,IAAI,MAAM,KAAK,mBAAmB,EAAE,CAAC;QACnC,gGAAgG;QAChG,8FAA8F;QAC9F,2BAA2B;QAC3B,MAAM,WAAW,GAAG,IAAI,CAAC,WAAW,CAAC;QACrC,OAAO,WAAW,EAAE,YAAY,KAAK,IAAI,IAAI,WAAW,CAAC,eAAe,KAAK,IAAI;YAC/E,CAAC,CAAC,MAAM;YACR,CAAC,CAAC,QAAQ,CAAC;IACf,CAAC;IACD,OAAO,QAAQ,CAAC;AAClB,CAAC"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The tightest tool-name rule among the major model providers (`^[a-zA-Z0-9_-]{1,64}$`). An MCP
|
|
3
|
+
* server is under no such constraint — `repo/create.issue` is a legal MCP tool name — so a name is
|
|
4
|
+
* reshaped here rather than being discovered at turn time as a provider-side rejection.
|
|
5
|
+
*/
|
|
6
|
+
export declare const MAX_TOOL_NAME_LENGTH = 64;
|
|
7
|
+
/**
|
|
8
|
+
* The name the model and the {@link import('../tool-registry.js').ToolRegistry} see for one
|
|
9
|
+
* imported tool.
|
|
10
|
+
*
|
|
11
|
+
* Namespaced under the server by default: the registry is keyed by name, so an un-namespaced import
|
|
12
|
+
* would let a remote server's `search` silently replace the app's own `search` — the collision would
|
|
13
|
+
* present itself as the app tool quietly doing something else.
|
|
14
|
+
*
|
|
15
|
+
* `namespace: false` opts out (for a server whose names are already qualified), and a string sets
|
|
16
|
+
* the prefix explicitly.
|
|
17
|
+
*
|
|
18
|
+
* The result is stable across restarts, including when truncated: a stored tool call in a thread
|
|
19
|
+
* refers to a tool by this name, so a name that changed between boots would strand history.
|
|
20
|
+
*/
|
|
21
|
+
export declare function localToolName(serverName: string, remoteName: string, namespace: boolean | string | undefined): string;
|
|
22
|
+
//# sourceMappingURL=tool-name.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tool-name.d.ts","sourceRoot":"","sources":["../../../src/mcp-client/tool-name.ts"],"names":[],"mappings":"AAEA;;;;GAIG;AACH,eAAO,MAAM,oBAAoB,KAAK,CAAC;AAQvC;;;;;;;;;;;;;GAaG;AACH,wBAAgB,aAAa,CAC3B,UAAU,EAAE,MAAM,EAClB,UAAU,EAAE,MAAM,EAClB,SAAS,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,GACtC,MAAM,CAQR"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { createHash } from 'node:crypto';
|
|
2
|
+
/**
|
|
3
|
+
* The tightest tool-name rule among the major model providers (`^[a-zA-Z0-9_-]{1,64}$`). An MCP
|
|
4
|
+
* server is under no such constraint — `repo/create.issue` is a legal MCP tool name — so a name is
|
|
5
|
+
* reshaped here rather than being discovered at turn time as a provider-side rejection.
|
|
6
|
+
*/
|
|
7
|
+
export const MAX_TOOL_NAME_LENGTH = 64;
|
|
8
|
+
const HASH_LENGTH = 6;
|
|
9
|
+
function sanitize(name) {
|
|
10
|
+
return name.replace(/[^a-zA-Z0-9_-]+/g, '_');
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* The name the model and the {@link import('../tool-registry.js').ToolRegistry} see for one
|
|
14
|
+
* imported tool.
|
|
15
|
+
*
|
|
16
|
+
* Namespaced under the server by default: the registry is keyed by name, so an un-namespaced import
|
|
17
|
+
* would let a remote server's `search` silently replace the app's own `search` — the collision would
|
|
18
|
+
* present itself as the app tool quietly doing something else.
|
|
19
|
+
*
|
|
20
|
+
* `namespace: false` opts out (for a server whose names are already qualified), and a string sets
|
|
21
|
+
* the prefix explicitly.
|
|
22
|
+
*
|
|
23
|
+
* The result is stable across restarts, including when truncated: a stored tool call in a thread
|
|
24
|
+
* refers to a tool by this name, so a name that changed between boots would strand history.
|
|
25
|
+
*/
|
|
26
|
+
export function localToolName(serverName, remoteName, namespace) {
|
|
27
|
+
const prefix = namespace === false ? '' : typeof namespace === 'string' ? namespace : serverName;
|
|
28
|
+
const full = sanitize(prefix === '' ? remoteName : `${prefix}_${remoteName}`);
|
|
29
|
+
if (full.length <= MAX_TOOL_NAME_LENGTH) {
|
|
30
|
+
return full;
|
|
31
|
+
}
|
|
32
|
+
const digest = createHash('sha1').update(full).digest('hex').slice(0, HASH_LENGTH);
|
|
33
|
+
return `${full.slice(0, MAX_TOOL_NAME_LENGTH - HASH_LENGTH - 1)}_${digest}`;
|
|
34
|
+
}
|
|
35
|
+
//# sourceMappingURL=tool-name.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tool-name.js","sourceRoot":"","sources":["../../../src/mcp-client/tool-name.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAEzC;;;;GAIG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAG,EAAE,CAAC;AAEvC,MAAM,WAAW,GAAG,CAAC,CAAC;AAEtB,SAAS,QAAQ,CAAC,IAAY;IAC5B,OAAO,IAAI,CAAC,OAAO,CAAC,kBAAkB,EAAE,GAAG,CAAC,CAAC;AAC/C,CAAC;AAED;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,aAAa,CAC3B,UAAkB,EAClB,UAAkB,EAClB,SAAuC;IAEvC,MAAM,MAAM,GAAG,SAAS,KAAK,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,SAAS,KAAK,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,UAAU,CAAC;IACjG,MAAM,IAAI,GAAG,QAAQ,CAAC,MAAM,KAAK,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,GAAG,MAAM,IAAI,UAAU,EAAE,CAAC,CAAC;IAC9E,IAAI,IAAI,CAAC,MAAM,IAAI,oBAAoB,EAAE,CAAC;QACxC,OAAO,IAAI,CAAC;IACd,CAAC;IACD,MAAM,MAAM,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,WAAW,CAAC,CAAC;IACnF,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,oBAAoB,GAAG,WAAW,GAAG,CAAC,CAAC,IAAI,MAAM,EAAE,CAAC;AAC9E,CAAC"}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import type { ToolHandler } from '../spi/tool.js';
|
|
2
|
+
import type { ToolSpec } from '../types.js';
|
|
3
|
+
import type { McpLogger, McpServerConfig } from './options.js';
|
|
4
|
+
/** One remote tool, mapped onto what `ToolRegistry.register` takes, plus where it came from. */
|
|
5
|
+
export interface McpImportedTool {
|
|
6
|
+
spec: ToolSpec;
|
|
7
|
+
handler: ToolHandler;
|
|
8
|
+
/** The name on the server, which namespacing and sanitizing may have changed in `spec.name`. */
|
|
9
|
+
remoteName: string;
|
|
10
|
+
serverName: string;
|
|
11
|
+
}
|
|
12
|
+
/** A remote tool that answered with `isError` — a business failure of the tool, not of the transport. */
|
|
13
|
+
export declare class McpToolCallError extends Error {
|
|
14
|
+
readonly serverName: string;
|
|
15
|
+
readonly toolName: string;
|
|
16
|
+
constructor(serverName: string, toolName: string, message: string);
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* One MCP server, as a source of tools.
|
|
20
|
+
*
|
|
21
|
+
* Holds a single client and reconnects on demand. The connection is deliberately not treated as
|
|
22
|
+
* durable state: a remote server may restart, be redeployed, or drop an idle connection, and the
|
|
23
|
+
* first symptom is a failed tool call. So a call that fails transiently drops the client, and the
|
|
24
|
+
* retry — core's `invokeWithTransientRetry`, the same one the agent loop wraps every tool with —
|
|
25
|
+
* reconnects on its next attempt.
|
|
26
|
+
*
|
|
27
|
+
* Every timeout here is the SDK's own per-request timeout rather than a race of our own, so a
|
|
28
|
+
* timed-out request is also CANCELLED on the wire instead of being abandoned.
|
|
29
|
+
*/
|
|
30
|
+
export declare class McpToolSource {
|
|
31
|
+
private readonly config;
|
|
32
|
+
private readonly logger?;
|
|
33
|
+
private client;
|
|
34
|
+
private connecting;
|
|
35
|
+
constructor(config: McpServerConfig, logger?: McpLogger | undefined);
|
|
36
|
+
get name(): string;
|
|
37
|
+
/** Connect if needed, list the server's tools, and map the selected ones onto specs + handlers. */
|
|
38
|
+
import(): Promise<McpImportedTool[]>;
|
|
39
|
+
close(): Promise<void>;
|
|
40
|
+
private isSelected;
|
|
41
|
+
/**
|
|
42
|
+
* A tool whose schema won't compile — or whose `pattern` can backtrack exponentially — is
|
|
43
|
+
* dropped, not imported with a permissive stand-in: the model would then be free to send that
|
|
44
|
+
* remote tool any arguments at all, and the call would still look validated from this side.
|
|
45
|
+
*/
|
|
46
|
+
private toImportedTool;
|
|
47
|
+
private callTool;
|
|
48
|
+
private callOnce;
|
|
49
|
+
/** The wire call alone, so only a TRANSPORT failure can recycle the client — never a tool's own. */
|
|
50
|
+
private request;
|
|
51
|
+
private errorText;
|
|
52
|
+
private ensureClient;
|
|
53
|
+
private connect;
|
|
54
|
+
private createTransport;
|
|
55
|
+
private dropClient;
|
|
56
|
+
/**
|
|
57
|
+
* The configured policy with a classifier filled in. The library's default classifier recognizes
|
|
58
|
+
* local database lock contention, which is not how a remote server fails — leaving it in place
|
|
59
|
+
* would mean the policy is on and never matches anything.
|
|
60
|
+
*
|
|
61
|
+
* WHICH CLASSIFIER, AND WHY IT DEPENDS ON THE KIND. An `action` is a tool whose effects happen on
|
|
62
|
+
* somebody else's machine and are invisible from here, which is why one waits for a human at all.
|
|
63
|
+
* Most of what {@link isTransientMcpError} accepts cannot tell "the request never arrived" from
|
|
64
|
+
* "it ran and the answer was lost" — a timeout, a reset, a 503 — so retrying on it would spend one
|
|
65
|
+
* approval on two remote effects. An `action` therefore retries only
|
|
66
|
+
* {@link isPreExecutionMcpError}: failures that prove nothing ran. A `read` keeps the broader
|
|
67
|
+
* policy, where a second identical call costs a round trip.
|
|
68
|
+
*
|
|
69
|
+
* A host that supplied its own `classify` has taken that judgement over, and it is honoured for
|
|
70
|
+
* every kind.
|
|
71
|
+
*/
|
|
72
|
+
private retrySetting;
|
|
73
|
+
private requestTimeoutMs;
|
|
74
|
+
}
|
|
75
|
+
//# sourceMappingURL=tool-source.d.ts.map
|