@oharness/engine 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/agent/agent.d.ts +196 -0
- package/dist/agent/agent.js +758 -0
- package/dist/agent/agent.js.map +1 -0
- package/dist/agent/compaction.d.ts +68 -0
- package/dist/agent/compaction.js +179 -0
- package/dist/agent/compaction.js.map +1 -0
- package/dist/agent/hooks.d.ts +77 -0
- package/dist/agent/hooks.js +152 -0
- package/dist/agent/hooks.js.map +1 -0
- package/dist/agent/memory.d.ts +45 -0
- package/dist/agent/memory.js +147 -0
- package/dist/agent/memory.js.map +1 -0
- package/dist/agent/overflow.d.ts +35 -0
- package/dist/agent/overflow.js +69 -0
- package/dist/agent/overflow.js.map +1 -0
- package/dist/agent/permissions.d.ts +181 -0
- package/dist/agent/permissions.js +289 -0
- package/dist/agent/permissions.js.map +1 -0
- package/dist/agent/prompt.d.ts +25 -0
- package/dist/agent/prompt.js +63 -0
- package/dist/agent/prompt.js.map +1 -0
- package/dist/agent/session.d.ts +108 -0
- package/dist/agent/session.js +231 -0
- package/dist/agent/session.js.map +1 -0
- package/dist/agent/settings.d.ts +37 -0
- package/dist/agent/settings.js +113 -0
- package/dist/agent/settings.js.map +1 -0
- package/dist/agent/skills.d.ts +58 -0
- package/dist/agent/skills.js +225 -0
- package/dist/agent/skills.js.map +1 -0
- package/dist/agent/store.d.ts +308 -0
- package/dist/agent/store.js +596 -0
- package/dist/agent/store.js.map +1 -0
- package/dist/agent/subagent.d.ts +44 -0
- package/dist/agent/subagent.js +138 -0
- package/dist/agent/subagent.js.map +1 -0
- package/dist/agent/titles.d.ts +8 -0
- package/dist/agent/titles.js +23 -0
- package/dist/agent/titles.js.map +1 -0
- package/dist/agent/workspace.d.ts +60 -0
- package/dist/agent/workspace.js +156 -0
- package/dist/agent/workspace.js.map +1 -0
- package/dist/artifacts/publish.d.ts +94 -0
- package/dist/artifacts/publish.js +104 -0
- package/dist/artifacts/publish.js.map +1 -0
- package/dist/artifacts/store.d.ts +324 -0
- package/dist/artifacts/store.js +500 -0
- package/dist/artifacts/store.js.map +1 -0
- package/dist/auth/index.d.ts +13 -0
- package/dist/auth/index.js +10 -0
- package/dist/auth/index.js.map +1 -0
- package/dist/auth/manager.d.ts +83 -0
- package/dist/auth/manager.js +266 -0
- package/dist/auth/manager.js.map +1 -0
- package/dist/auth/oauth.d.ts +83 -0
- package/dist/auth/oauth.js +327 -0
- package/dist/auth/oauth.js.map +1 -0
- package/dist/auth/providers/account.d.ts +59 -0
- package/dist/auth/providers/account.js +282 -0
- package/dist/auth/providers/account.js.map +1 -0
- package/dist/auth/providers/anthropic.d.ts +24 -0
- package/dist/auth/providers/anthropic.js +209 -0
- package/dist/auth/providers/anthropic.js.map +1 -0
- package/dist/auth/providers/generic.d.ts +57 -0
- package/dist/auth/providers/generic.js +155 -0
- package/dist/auth/providers/generic.js.map +1 -0
- package/dist/auth/providers/official.d.ts +3 -0
- package/dist/auth/providers/official.js +90 -0
- package/dist/auth/providers/official.js.map +1 -0
- package/dist/auth/providers/ottoport.d.ts +3 -0
- package/dist/auth/providers/ottoport.js +60 -0
- package/dist/auth/providers/ottoport.js.map +1 -0
- package/dist/auth/store.d.ts +22 -0
- package/dist/auth/store.js +138 -0
- package/dist/auth/store.js.map +1 -0
- package/dist/auth/types.d.ts +167 -0
- package/dist/auth/types.js +16 -0
- package/dist/auth/types.js.map +1 -0
- package/dist/config.d.ts +197 -0
- package/dist/config.js +195 -0
- package/dist/config.js.map +1 -0
- package/dist/core/errors.d.ts +46 -0
- package/dist/core/errors.js +83 -0
- package/dist/core/errors.js.map +1 -0
- package/dist/core/tokens.d.ts +12 -0
- package/dist/core/tokens.js +56 -0
- package/dist/core/tokens.js.map +1 -0
- package/dist/core/types.d.ts +91 -0
- package/dist/core/types.js +49 -0
- package/dist/core/types.js.map +1 -0
- package/dist/harness.d.ts +302 -0
- package/dist/harness.js +695 -0
- package/dist/harness.js.map +1 -0
- package/dist/index.d.ts +32 -0
- package/dist/index.js +21 -0
- package/dist/index.js.map +1 -0
- package/dist/mcp/client.d.ts +55 -0
- package/dist/mcp/client.js +199 -0
- package/dist/mcp/client.js.map +1 -0
- package/dist/mcp/index.d.ts +13 -0
- package/dist/mcp/index.js +8 -0
- package/dist/mcp/index.js.map +1 -0
- package/dist/mcp/manager.d.ts +77 -0
- package/dist/mcp/manager.js +325 -0
- package/dist/mcp/manager.js.map +1 -0
- package/dist/mcp/oauth.d.ts +63 -0
- package/dist/mcp/oauth.js +302 -0
- package/dist/mcp/oauth.js.map +1 -0
- package/dist/mcp/protocol.d.ts +130 -0
- package/dist/mcp/protocol.js +14 -0
- package/dist/mcp/protocol.js.map +1 -0
- package/dist/mcp/registry.d.ts +52 -0
- package/dist/mcp/registry.js +100 -0
- package/dist/mcp/registry.js.map +1 -0
- package/dist/mcp/registry.json +293 -0
- package/dist/mcp/secrets.d.ts +20 -0
- package/dist/mcp/secrets.js +75 -0
- package/dist/mcp/secrets.js.map +1 -0
- package/dist/mcp/transport.d.ts +51 -0
- package/dist/mcp/transport.js +158 -0
- package/dist/mcp/transport.js.map +1 -0
- package/dist/paths.d.ts +37 -0
- package/dist/paths.js +63 -0
- package/dist/paths.js.map +1 -0
- package/dist/plugins.d.ts +55 -0
- package/dist/plugins.js +201 -0
- package/dist/plugins.js.map +1 -0
- package/dist/providers/builtin.d.ts +23 -0
- package/dist/providers/builtin.js +141 -0
- package/dist/providers/builtin.js.map +1 -0
- package/dist/providers/catalog.d.ts +129 -0
- package/dist/providers/catalog.js +254 -0
- package/dist/providers/catalog.js.map +1 -0
- package/dist/providers/catalog.json +472 -0
- package/dist/providers/discovery.d.ts +16 -0
- package/dist/providers/discovery.js +161 -0
- package/dist/providers/discovery.js.map +1 -0
- package/dist/providers/http.d.ts +24 -0
- package/dist/providers/http.js +139 -0
- package/dist/providers/http.js.map +1 -0
- package/dist/providers/index.d.ts +10 -0
- package/dist/providers/index.js +8 -0
- package/dist/providers/index.js.map +1 -0
- package/dist/providers/piai.d.ts +124 -0
- package/dist/providers/piai.js +551 -0
- package/dist/providers/piai.js.map +1 -0
- package/dist/providers/registry.d.ts +65 -0
- package/dist/providers/registry.js +195 -0
- package/dist/providers/registry.js.map +1 -0
- package/dist/providers/resilient.d.ts +46 -0
- package/dist/providers/resilient.js +117 -0
- package/dist/providers/resilient.js.map +1 -0
- package/dist/providers/types.d.ts +182 -0
- package/dist/providers/types.js +50 -0
- package/dist/providers/types.js.map +1 -0
- package/dist/schedule/cron.d.ts +35 -0
- package/dist/schedule/cron.js +125 -0
- package/dist/schedule/cron.js.map +1 -0
- package/dist/schedule/scheduler.d.ts +87 -0
- package/dist/schedule/scheduler.js +237 -0
- package/dist/schedule/scheduler.js.map +1 -0
- package/dist/storage/kv.d.ts +56 -0
- package/dist/storage/kv.js +173 -0
- package/dist/storage/kv.js.map +1 -0
- package/dist/storage/migrate.d.ts +11 -0
- package/dist/storage/migrate.js +93 -0
- package/dist/storage/migrate.js.map +1 -0
- package/dist/storage/project.d.ts +9 -0
- package/dist/storage/project.js +57 -0
- package/dist/storage/project.js.map +1 -0
- package/dist/storage/records.d.ts +32 -0
- package/dist/storage/records.js +48 -0
- package/dist/storage/records.js.map +1 -0
- package/dist/sync/client.d.ts +79 -0
- package/dist/sync/client.js +118 -0
- package/dist/sync/client.js.map +1 -0
- package/dist/sync/mirror.d.ts +85 -0
- package/dist/sync/mirror.js +389 -0
- package/dist/sync/mirror.js.map +1 -0
- package/dist/sync/protocol.d.ts +67 -0
- package/dist/sync/protocol.js +16 -0
- package/dist/sync/protocol.js.map +1 -0
- package/dist/sync/settings.d.ts +56 -0
- package/dist/sync/settings.js +60 -0
- package/dist/sync/settings.js.map +1 -0
- package/dist/tools/builtin/artifact.d.ts +16 -0
- package/dist/tools/builtin/artifact.js +134 -0
- package/dist/tools/builtin/artifact.js.map +1 -0
- package/dist/tools/builtin/bash.d.ts +3 -0
- package/dist/tools/builtin/bash.js +142 -0
- package/dist/tools/builtin/bash.js.map +1 -0
- package/dist/tools/builtin/fs.d.ts +19 -0
- package/dist/tools/builtin/fs.js +280 -0
- package/dist/tools/builtin/fs.js.map +1 -0
- package/dist/tools/builtin/index.d.ts +22 -0
- package/dist/tools/builtin/index.js +42 -0
- package/dist/tools/builtin/index.js.map +1 -0
- package/dist/tools/builtin/mcp-resource.d.ts +3 -0
- package/dist/tools/builtin/mcp-resource.js +220 -0
- package/dist/tools/builtin/mcp-resource.js.map +1 -0
- package/dist/tools/builtin/memory.d.ts +10 -0
- package/dist/tools/builtin/memory.js +76 -0
- package/dist/tools/builtin/memory.js.map +1 -0
- package/dist/tools/builtin/recall.d.ts +13 -0
- package/dist/tools/builtin/recall.js +163 -0
- package/dist/tools/builtin/recall.js.map +1 -0
- package/dist/tools/builtin/search.d.ts +3 -0
- package/dist/tools/builtin/search.js +240 -0
- package/dist/tools/builtin/search.js.map +1 -0
- package/dist/tools/builtin/skill.d.ts +10 -0
- package/dist/tools/builtin/skill.js +46 -0
- package/dist/tools/builtin/skill.js.map +1 -0
- package/dist/tools/builtin/task.d.ts +9 -0
- package/dist/tools/builtin/task.js +68 -0
- package/dist/tools/builtin/task.js.map +1 -0
- package/dist/tools/builtin/todo.d.ts +20 -0
- package/dist/tools/builtin/todo.js +63 -0
- package/dist/tools/builtin/todo.js.map +1 -0
- package/dist/tools/define.d.ts +19 -0
- package/dist/tools/define.js +39 -0
- package/dist/tools/define.js.map +1 -0
- package/dist/tools/index.d.ts +7 -0
- package/dist/tools/index.js +5 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/tools/registry.d.ts +39 -0
- package/dist/tools/registry.js +101 -0
- package/dist/tools/registry.js.map +1 -0
- package/dist/tools/types.d.ts +112 -0
- package/dist/tools/types.js +22 -0
- package/dist/tools/types.js.map +1 -0
- package/dist/util/id.d.ts +9 -0
- package/dist/util/id.js +19 -0
- package/dist/util/id.js.map +1 -0
- package/dist/util/json.d.ts +25 -0
- package/dist/util/json.js +100 -0
- package/dist/util/json.js.map +1 -0
- package/dist/util/jwt.d.ts +74 -0
- package/dist/util/jwt.js +177 -0
- package/dist/util/jwt.js.map +1 -0
- package/dist/util/logger.d.ts +13 -0
- package/dist/util/logger.js +59 -0
- package/dist/util/logger.js.map +1 -0
- package/dist/util/queue.d.ts +26 -0
- package/dist/util/queue.js +106 -0
- package/dist/util/queue.js.map +1 -0
- package/dist/util/schema.d.ts +17 -0
- package/dist/util/schema.js +98 -0
- package/dist/util/schema.js.map +1 -0
- package/dist/util/shell.d.ts +20 -0
- package/dist/util/shell.js +24 -0
- package/dist/util/shell.js.map +1 -0
- package/official.json +4 -0
- package/package.json +38 -0
- package/skills/artifact-authoring/SKILL.md +81 -0
- package/skills/canvas/SKILL.md +85 -0
- package/skills/skill-authoring/SKILL.md +85 -0
|
@@ -0,0 +1,325 @@
|
|
|
1
|
+
import { McpAuthRequiredError, errorMessage } from "../core/errors.js";
|
|
2
|
+
import { normalizeObjectSchema } from "../util/schema.js";
|
|
3
|
+
import { matchPattern } from "../tools/registry.js";
|
|
4
|
+
import { createLogger } from "../util/logger.js";
|
|
5
|
+
import { McpClient } from "./client.js";
|
|
6
|
+
import { mcpAuthHeaders } from "./oauth.js";
|
|
7
|
+
import { expandSecrets } from "./secrets.js";
|
|
8
|
+
/**
|
|
9
|
+
* Owns every MCP connection and turns their tools into harness tools.
|
|
10
|
+
*
|
|
11
|
+
* Names are namespaced `mcp__<server>__<tool>` so two servers can expose a
|
|
12
|
+
* `search` tool without colliding, and so permission rules can target a whole
|
|
13
|
+
* server with one pattern.
|
|
14
|
+
*/
|
|
15
|
+
/** Minimum gap between reconnect attempts for one server. */
|
|
16
|
+
const RECONNECT_COOLDOWN_MS = 5_000;
|
|
17
|
+
export class McpManager {
|
|
18
|
+
clients = new Map();
|
|
19
|
+
errors = new Map();
|
|
20
|
+
toolsByServer = new Map();
|
|
21
|
+
configs = new Map();
|
|
22
|
+
/** In-flight reconnects, so concurrent tool calls share one attempt. */
|
|
23
|
+
reconnecting = new Map();
|
|
24
|
+
/** When a reconnect last *failed*, for backing off a dead server. */
|
|
25
|
+
lastFailure = new Map();
|
|
26
|
+
/** Servers that answered 401, and what they said about where to log in. */
|
|
27
|
+
challenges = new Map();
|
|
28
|
+
logger;
|
|
29
|
+
authStore;
|
|
30
|
+
constructor(logger, authStore) {
|
|
31
|
+
this.logger = (logger ?? createLogger("mcp")).child("manager");
|
|
32
|
+
if (authStore)
|
|
33
|
+
this.authStore = authStore;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Connect every configured server. A server that fails to start is recorded
|
|
37
|
+
* and skipped — one broken MCP config should not take the agent down.
|
|
38
|
+
*/
|
|
39
|
+
async connectAll(configs) {
|
|
40
|
+
await Promise.all(Object.entries(configs).map(([name, config]) => this.connect(name, config)));
|
|
41
|
+
return this.status();
|
|
42
|
+
}
|
|
43
|
+
async connect(name, config) {
|
|
44
|
+
await this.disconnect(name);
|
|
45
|
+
// Kept so a server that dies mid-session can be brought back without the
|
|
46
|
+
// caller having to hold onto its configuration.
|
|
47
|
+
this.configs.set(name, config);
|
|
48
|
+
const client = new McpClient(name, config, this.logger, this.authFor(config));
|
|
49
|
+
try {
|
|
50
|
+
await client.connect();
|
|
51
|
+
this.challenges.delete(name);
|
|
52
|
+
const definitions = await client.listTools();
|
|
53
|
+
const allowed = config.allowedTools;
|
|
54
|
+
const tools = definitions
|
|
55
|
+
.filter((def) => !allowed?.length || allowed.some((p) => matchPattern(def.name, p)))
|
|
56
|
+
.map((def) => this.adaptTool(name, client, def));
|
|
57
|
+
this.clients.set(name, client);
|
|
58
|
+
this.toolsByServer.set(name, tools);
|
|
59
|
+
this.errors.delete(name);
|
|
60
|
+
this.logger.info("registered tools", { server: name, count: tools.length });
|
|
61
|
+
return tools;
|
|
62
|
+
}
|
|
63
|
+
catch (err) {
|
|
64
|
+
if (err instanceof McpAuthRequiredError) {
|
|
65
|
+
this.challenges.set(name, {
|
|
66
|
+
url: err.url,
|
|
67
|
+
...(err.challenge ? { challenge: err.challenge } : {}),
|
|
68
|
+
});
|
|
69
|
+
this.errors.set(name, "not authorized yet");
|
|
70
|
+
this.logger.info("authorization required", { server: name });
|
|
71
|
+
}
|
|
72
|
+
else {
|
|
73
|
+
const message = errorMessage(err);
|
|
74
|
+
this.errors.set(name, message);
|
|
75
|
+
this.logger.warn("connection failed", { server: name, error: message });
|
|
76
|
+
}
|
|
77
|
+
await client.close().catch(() => { });
|
|
78
|
+
return [];
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
/** Permanently remove a server: closes it and forgets how to restart it. */
|
|
82
|
+
async remove(name) {
|
|
83
|
+
await this.disconnect(name);
|
|
84
|
+
this.configs.delete(name);
|
|
85
|
+
this.errors.delete(name);
|
|
86
|
+
this.challenges.delete(name);
|
|
87
|
+
}
|
|
88
|
+
/** What a server asked for when it refused, if it refused. */
|
|
89
|
+
authChallenge(name) {
|
|
90
|
+
return this.challenges.get(name);
|
|
91
|
+
}
|
|
92
|
+
/** The configuration a server was connected with, for a caller that needs it. */
|
|
93
|
+
configFor(name) {
|
|
94
|
+
return this.configs.get(name);
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* The per-request header resolver for one server.
|
|
98
|
+
*
|
|
99
|
+
* Only HTTP servers have anywhere to put a bearer token, and only a manager
|
|
100
|
+
* that was given a store has anywhere to keep one.
|
|
101
|
+
*/
|
|
102
|
+
authFor(config) {
|
|
103
|
+
const store = this.authStore;
|
|
104
|
+
if (!store || config.type !== "http")
|
|
105
|
+
return undefined;
|
|
106
|
+
const resolved = expandSecrets(config);
|
|
107
|
+
const url = resolved.type === "http" ? resolved.url : config.url;
|
|
108
|
+
return () => mcpAuthHeaders(url, store);
|
|
109
|
+
}
|
|
110
|
+
async disconnect(name) {
|
|
111
|
+
const client = this.clients.get(name);
|
|
112
|
+
if (!client)
|
|
113
|
+
return;
|
|
114
|
+
this.clients.delete(name);
|
|
115
|
+
this.toolsByServer.delete(name);
|
|
116
|
+
await client.close().catch(() => { });
|
|
117
|
+
}
|
|
118
|
+
async closeAll() {
|
|
119
|
+
await Promise.all([...this.clients.keys()].map((name) => this.disconnect(name)));
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Bring a dropped server back.
|
|
123
|
+
*
|
|
124
|
+
* A stdio server that crashes or an HTTP transport that drops used to take
|
|
125
|
+
* its tools out of commission for the rest of the session, which is a poor
|
|
126
|
+
* outcome for something as ordinary as a subprocess exiting. Attempts are
|
|
127
|
+
* deduplicated and rate-limited: several parallel tool calls hitting a dead
|
|
128
|
+
* server should produce one reconnect, not one each.
|
|
129
|
+
*/
|
|
130
|
+
async reconnect(name) {
|
|
131
|
+
const existing = this.reconnecting.get(name);
|
|
132
|
+
if (existing)
|
|
133
|
+
return existing;
|
|
134
|
+
const config = this.configs.get(name);
|
|
135
|
+
if (!config)
|
|
136
|
+
return false;
|
|
137
|
+
// Back off only after a *failed* attempt. Rate-limiting every attempt
|
|
138
|
+
// meant the first legitimate reconnect after a crash was refused, because
|
|
139
|
+
// the failing call that detected the crash had already spent the window.
|
|
140
|
+
const sinceFailure = Date.now() - (this.lastFailure.get(name) ?? 0);
|
|
141
|
+
if (this.lastFailure.has(name) && sinceFailure < RECONNECT_COOLDOWN_MS)
|
|
142
|
+
return false;
|
|
143
|
+
const attempt = (async () => {
|
|
144
|
+
this.logger.info("reconnecting", { server: name });
|
|
145
|
+
try {
|
|
146
|
+
await this.connect(name, config);
|
|
147
|
+
const revived = this.clients.get(name)?.isConnected === true;
|
|
148
|
+
if (revived)
|
|
149
|
+
this.lastFailure.delete(name);
|
|
150
|
+
else
|
|
151
|
+
this.lastFailure.set(name, Date.now());
|
|
152
|
+
return revived;
|
|
153
|
+
}
|
|
154
|
+
catch {
|
|
155
|
+
this.lastFailure.set(name, Date.now());
|
|
156
|
+
return false;
|
|
157
|
+
}
|
|
158
|
+
finally {
|
|
159
|
+
this.reconnecting.delete(name);
|
|
160
|
+
}
|
|
161
|
+
})();
|
|
162
|
+
this.reconnecting.set(name, attempt);
|
|
163
|
+
return attempt;
|
|
164
|
+
}
|
|
165
|
+
tools() {
|
|
166
|
+
return [...this.toolsByServer.values()].flat();
|
|
167
|
+
}
|
|
168
|
+
client(name) {
|
|
169
|
+
return this.clients.get(name);
|
|
170
|
+
}
|
|
171
|
+
status() {
|
|
172
|
+
const names = new Set([
|
|
173
|
+
...this.clients.keys(),
|
|
174
|
+
...this.errors.keys(),
|
|
175
|
+
...this.challenges.keys(),
|
|
176
|
+
]);
|
|
177
|
+
return [...names].map((name) => {
|
|
178
|
+
const client = this.clients.get(name);
|
|
179
|
+
return {
|
|
180
|
+
name,
|
|
181
|
+
connected: client?.isConnected ?? false,
|
|
182
|
+
// The config, not the client: a server that failed to connect has no
|
|
183
|
+
// client to ask, and reporting every failure as stdio was a lie the
|
|
184
|
+
// authorization path made visible.
|
|
185
|
+
transport: (client?.config.type ?? this.configs.get(name)?.type ?? "stdio"),
|
|
186
|
+
toolCount: this.toolsByServer.get(name)?.length ?? 0,
|
|
187
|
+
serverVersion: client?.serverInfo?.serverInfo?.version,
|
|
188
|
+
error: this.errors.get(name),
|
|
189
|
+
...(this.challenges.has(name) ? { needsAuth: true } : {}),
|
|
190
|
+
};
|
|
191
|
+
});
|
|
192
|
+
}
|
|
193
|
+
/** Aggregated `instructions` from servers that supplied them. */
|
|
194
|
+
serverInstructions() {
|
|
195
|
+
const out = [];
|
|
196
|
+
for (const [name, client] of this.clients) {
|
|
197
|
+
const instructions = client.serverInfo?.instructions?.trim();
|
|
198
|
+
if (instructions)
|
|
199
|
+
out.push(`## MCP server: ${name}\n${instructions}`);
|
|
200
|
+
}
|
|
201
|
+
return out;
|
|
202
|
+
}
|
|
203
|
+
// -------------------------------------------------------------------------
|
|
204
|
+
adaptTool(server, client, def) {
|
|
205
|
+
const name = mcpToolName(server, def.name);
|
|
206
|
+
const readOnly = def.annotations?.readOnlyHint === true;
|
|
207
|
+
return {
|
|
208
|
+
name,
|
|
209
|
+
description: def.description ?? def.title ?? `${def.name} (from MCP server ${server})`,
|
|
210
|
+
inputSchema: normalizeObjectSchema(def.inputSchema ?? {}),
|
|
211
|
+
// The server validates its own inputs, and re-deriving a validator from
|
|
212
|
+
// its JSON Schema would only add a second, less accurate opinion.
|
|
213
|
+
readOnly,
|
|
214
|
+
concurrencySafe: readOnly,
|
|
215
|
+
source: "mcp",
|
|
216
|
+
server,
|
|
217
|
+
renderTitle: (input) => `${server}:${def.name}(${previewArgs(input)})`,
|
|
218
|
+
execute: async (input, ctx) => {
|
|
219
|
+
const call = async () => {
|
|
220
|
+
// Always resolve the current client: a reconnect replaces it, and
|
|
221
|
+
// the one captured at registration time is the dead one.
|
|
222
|
+
const live = this.clients.get(server) ?? client;
|
|
223
|
+
const result = await live.callTool(def.name, input, ctx.signal);
|
|
224
|
+
return convertResult(result, server);
|
|
225
|
+
};
|
|
226
|
+
try {
|
|
227
|
+
if (this.clients.get(server)?.isConnected)
|
|
228
|
+
return await call();
|
|
229
|
+
}
|
|
230
|
+
catch (err) {
|
|
231
|
+
// Fall through to a reconnect: a transport error here usually means
|
|
232
|
+
// the server went away mid-call.
|
|
233
|
+
this.logger.debug("tool call failed; will try reconnecting", {
|
|
234
|
+
server,
|
|
235
|
+
error: errorMessage(err),
|
|
236
|
+
});
|
|
237
|
+
}
|
|
238
|
+
if (ctx.signal.aborted) {
|
|
239
|
+
return { content: [{ type: "text", text: "aborted" }], isError: true };
|
|
240
|
+
}
|
|
241
|
+
const revived = await this.reconnect(server);
|
|
242
|
+
if (!revived) {
|
|
243
|
+
return {
|
|
244
|
+
content: [
|
|
245
|
+
{
|
|
246
|
+
type: "text",
|
|
247
|
+
text: `MCP server "${server}" is not connected and could not be restarted.`,
|
|
248
|
+
},
|
|
249
|
+
],
|
|
250
|
+
isError: true,
|
|
251
|
+
};
|
|
252
|
+
}
|
|
253
|
+
try {
|
|
254
|
+
return await call();
|
|
255
|
+
}
|
|
256
|
+
catch (err) {
|
|
257
|
+
return {
|
|
258
|
+
content: [
|
|
259
|
+
{ type: "text", text: `MCP tool ${name} failed: ${errorMessage(err)}` },
|
|
260
|
+
],
|
|
261
|
+
isError: true,
|
|
262
|
+
};
|
|
263
|
+
}
|
|
264
|
+
},
|
|
265
|
+
};
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
export function mcpToolName(server, tool) {
|
|
269
|
+
return `mcp__${sanitize(server)}__${sanitize(tool)}`;
|
|
270
|
+
}
|
|
271
|
+
/** Tool names must satisfy the strictest provider: `[a-zA-Z0-9_-]`. */
|
|
272
|
+
function sanitize(value) {
|
|
273
|
+
return value.replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
274
|
+
}
|
|
275
|
+
function convertResult(result, server) {
|
|
276
|
+
const content = [];
|
|
277
|
+
for (const block of result.content ?? []) {
|
|
278
|
+
const converted = convertContent(block, server);
|
|
279
|
+
if (converted)
|
|
280
|
+
content.push(converted);
|
|
281
|
+
}
|
|
282
|
+
if (content.length === 0 && result.structuredContent !== undefined) {
|
|
283
|
+
content.push({ type: "text", text: JSON.stringify(result.structuredContent, null, 2) });
|
|
284
|
+
}
|
|
285
|
+
if (content.length === 0) {
|
|
286
|
+
content.push({ type: "text", text: "(the tool returned no content)" });
|
|
287
|
+
}
|
|
288
|
+
return { content, isError: result.isError };
|
|
289
|
+
}
|
|
290
|
+
function convertContent(block, server) {
|
|
291
|
+
switch (block.type) {
|
|
292
|
+
case "text":
|
|
293
|
+
return { type: "text", text: block.text };
|
|
294
|
+
case "image":
|
|
295
|
+
return { type: "image", mimeType: block.mimeType, data: block.data };
|
|
296
|
+
case "audio":
|
|
297
|
+
// No provider takes inline audio through this path; describe it instead.
|
|
298
|
+
return { type: "text", text: `[audio ${block.mimeType} from ${server}, omitted]` };
|
|
299
|
+
case "resource": {
|
|
300
|
+
const { uri, text, mimeType } = block.resource;
|
|
301
|
+
if (text !== undefined)
|
|
302
|
+
return { type: "text", text: `<resource uri="${uri}">\n${text}\n</resource>` };
|
|
303
|
+
return { type: "text", text: `[binary resource ${uri} (${mimeType ?? "unknown"}), omitted]` };
|
|
304
|
+
}
|
|
305
|
+
case "resource_link":
|
|
306
|
+
return {
|
|
307
|
+
type: "text",
|
|
308
|
+
text: `[resource link ${block.uri}${block.name ? ` — ${block.name}` : ""}]`,
|
|
309
|
+
};
|
|
310
|
+
default:
|
|
311
|
+
return undefined;
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
function previewArgs(input) {
|
|
315
|
+
if (input === null || typeof input !== "object")
|
|
316
|
+
return "";
|
|
317
|
+
const entries = Object.entries(input);
|
|
318
|
+
if (entries.length === 0)
|
|
319
|
+
return "";
|
|
320
|
+
const first = entries[0];
|
|
321
|
+
const value = typeof first[1] === "string" ? first[1] : JSON.stringify(first[1]);
|
|
322
|
+
const shown = (value ?? "").slice(0, 40);
|
|
323
|
+
return entries.length === 1 ? shown : `${shown}, …`;
|
|
324
|
+
}
|
|
325
|
+
//# sourceMappingURL=manager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"manager.js","sourceRoot":"","sources":["../../src/mcp/manager.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import type { AuthStore } from "../auth/store.ts";
|
|
2
|
+
import type { AuthorizeResult } from "../auth/types.ts";
|
|
3
|
+
/** Where a server's credential lives in the shared store. */
|
|
4
|
+
export declare function mcpAuthKey(serverUrl: string): string;
|
|
5
|
+
export interface McpAuthServer {
|
|
6
|
+
authorizeUrl: string;
|
|
7
|
+
tokenUrl: string;
|
|
8
|
+
/** Absent when the server does not offer dynamic registration. */
|
|
9
|
+
registrationUrl?: string;
|
|
10
|
+
/** The audience the token is bound to (RFC 8707). */
|
|
11
|
+
resource: string;
|
|
12
|
+
scope?: string;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Everything needed to start a login, worked out from the server's URL and
|
|
16
|
+
* whatever it said in its 401.
|
|
17
|
+
*/
|
|
18
|
+
export declare function discoverMcpAuth(serverUrl: string, challenge?: string): Promise<McpAuthServer>;
|
|
19
|
+
/**
|
|
20
|
+
* The `resource_metadata` URL a 401 pointed at, if it pointed at one.
|
|
21
|
+
*
|
|
22
|
+
* Exported because it is the one piece of the challenge worth reading, and a
|
|
23
|
+
* caller that has the header should not have to re-derive the parse.
|
|
24
|
+
*/
|
|
25
|
+
export declare function resourceMetadataUrl(challenge: string | undefined): string | undefined;
|
|
26
|
+
/**
|
|
27
|
+
* The resource identifier for a server URL.
|
|
28
|
+
*
|
|
29
|
+
* Query and fragment come off and the trailing slash goes, because this value
|
|
30
|
+
* has to match what the authorization server computes for the same server, and
|
|
31
|
+
* a token bound to a nearly-right audience is rejected in a way that is very
|
|
32
|
+
* hard to read.
|
|
33
|
+
*/
|
|
34
|
+
export declare function canonicalResource(serverUrl: string): string;
|
|
35
|
+
export interface RegisteredClient {
|
|
36
|
+
clientId: string;
|
|
37
|
+
clientSecret?: string;
|
|
38
|
+
}
|
|
39
|
+
export declare function registerMcpClient(registrationUrl: string, redirectUri: string, scope?: string): Promise<RegisteredClient>;
|
|
40
|
+
export interface McpLoginOptions {
|
|
41
|
+
serverUrl: string;
|
|
42
|
+
store: AuthStore;
|
|
43
|
+
/** The `WWW-Authenticate` header from the 401 that prompted this. */
|
|
44
|
+
challenge?: string;
|
|
45
|
+
/** A client id issued out of band, for servers that do not register. */
|
|
46
|
+
clientId?: string;
|
|
47
|
+
clientSecret?: string;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Begin a login. The returned `callback()` resolves when the browser comes
|
|
51
|
+
* back, and the credential is stored before it does.
|
|
52
|
+
*/
|
|
53
|
+
export declare function beginMcpLogin(opts: McpLoginOptions): Promise<AuthorizeResult>;
|
|
54
|
+
/** Forget a server's credential; the next connection will ask again. */
|
|
55
|
+
export declare function forgetMcpAuth(serverUrl: string, store: AuthStore): Promise<boolean>;
|
|
56
|
+
/**
|
|
57
|
+
* The Authorization header for a server, or nothing if it has no credential.
|
|
58
|
+
*
|
|
59
|
+
* Resolved per request rather than snapshotted at connect: an access token
|
|
60
|
+
* outlives a long session by about an hour, and a header captured when the
|
|
61
|
+
* transport was built is a session that dies quietly in the middle.
|
|
62
|
+
*/
|
|
63
|
+
export declare function mcpAuthHeaders(serverUrl: string, store: AuthStore): Promise<Record<string, string>>;
|