@x-code-cli/core 0.2.10 → 0.3.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/compression.d.ts +12 -2
- package/dist/agent/compression.d.ts.map +1 -1
- package/dist/agent/compression.js +51 -2
- package/dist/agent/compression.js.map +1 -1
- package/dist/agent/file-ingest.js +2 -2
- package/dist/agent/file-ingest.js.map +1 -1
- package/dist/agent/loop-state.d.ts +3 -2
- package/dist/agent/loop-state.d.ts.map +1 -1
- package/dist/agent/loop-state.js.map +1 -1
- package/dist/agent/loop.d.ts.map +1 -1
- package/dist/agent/loop.js +134 -5
- package/dist/agent/loop.js.map +1 -1
- package/dist/agent/memory-extractor.js +5 -5
- package/dist/agent/memory-extractor.js.map +1 -1
- package/dist/agent/plan-storage.js +1 -1
- package/dist/agent/plan-storage.js.map +1 -1
- package/dist/agent/sub-agents/index.d.ts +2 -1
- package/dist/agent/sub-agents/index.d.ts.map +1 -1
- package/dist/agent/sub-agents/index.js +1 -1
- package/dist/agent/sub-agents/index.js.map +1 -1
- package/dist/agent/sub-agents/loader.d.ts +13 -3
- package/dist/agent/sub-agents/loader.d.ts.map +1 -1
- package/dist/agent/sub-agents/loader.js +36 -9
- package/dist/agent/sub-agents/loader.js.map +1 -1
- package/dist/agent/sub-agents/registry.d.ts +18 -1
- package/dist/agent/sub-agents/registry.d.ts.map +1 -1
- package/dist/agent/sub-agents/registry.js +38 -5
- package/dist/agent/sub-agents/registry.js.map +1 -1
- package/dist/agent/sub-agents/runner.d.ts.map +1 -1
- package/dist/agent/sub-agents/runner.js +45 -1
- package/dist/agent/sub-agents/runner.js.map +1 -1
- package/dist/agent/sub-agents/types.d.ts +4 -1
- package/dist/agent/sub-agents/types.d.ts.map +1 -1
- package/dist/agent/system-prompt.d.ts +21 -0
- package/dist/agent/system-prompt.d.ts.map +1 -1
- package/dist/agent/system-prompt.js +68 -2
- package/dist/agent/system-prompt.js.map +1 -1
- package/dist/agent/tool-execution.d.ts.map +1 -1
- package/dist/agent/tool-execution.js +220 -1
- package/dist/agent/tool-execution.js.map +1 -1
- package/dist/commands/index.d.ts +6 -0
- package/dist/commands/index.d.ts.map +1 -0
- package/dist/commands/index.js +3 -0
- package/dist/commands/index.js.map +1 -0
- package/dist/commands/loader.d.ts +13 -0
- package/dist/commands/loader.d.ts.map +1 -0
- package/dist/commands/loader.js +93 -0
- package/dist/commands/loader.js.map +1 -0
- package/dist/commands/registry.d.ts +44 -0
- package/dist/commands/registry.d.ts.map +1 -0
- package/dist/commands/registry.js +102 -0
- package/dist/commands/registry.js.map +1 -0
- package/dist/commands/types.d.ts +23 -0
- package/dist/commands/types.d.ts.map +1 -0
- package/dist/commands/types.js +26 -0
- package/dist/commands/types.js.map +1 -0
- package/dist/config/index.d.ts +9 -0
- package/dist/config/index.d.ts.map +1 -1
- package/dist/config/index.js +12 -10
- package/dist/config/index.js.map +1 -1
- package/dist/hooks/bus.d.ts +54 -0
- package/dist/hooks/bus.d.ts.map +1 -0
- package/dist/hooks/bus.js +165 -0
- package/dist/hooks/bus.js.map +1 -0
- package/dist/hooks/config-schema.d.ts +854 -0
- package/dist/hooks/config-schema.d.ts.map +1 -0
- package/dist/hooks/config-schema.js +79 -0
- package/dist/hooks/config-schema.js.map +1 -0
- package/dist/hooks/executor.d.ts +16 -0
- package/dist/hooks/executor.d.ts.map +1 -0
- package/dist/hooks/executor.js +183 -0
- package/dist/hooks/executor.js.map +1 -0
- package/dist/hooks/index.d.ts +10 -0
- package/dist/hooks/index.d.ts.map +1 -0
- package/dist/hooks/index.js +6 -0
- package/dist/hooks/index.js.map +1 -0
- package/dist/hooks/registry.d.ts +23 -0
- package/dist/hooks/registry.d.ts.map +1 -0
- package/dist/hooks/registry.js +49 -0
- package/dist/hooks/registry.js.map +1 -0
- package/dist/hooks/types.d.ts +165 -0
- package/dist/hooks/types.d.ts.map +1 -0
- package/dist/hooks/types.js +25 -0
- package/dist/hooks/types.js.map +1 -0
- package/dist/hooks/variables.d.ts +22 -0
- package/dist/hooks/variables.d.ts.map +1 -0
- package/dist/hooks/variables.js +80 -0
- package/dist/hooks/variables.js.map +1 -0
- package/dist/index.d.ts +56 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +37 -1
- package/dist/index.js.map +1 -1
- package/dist/knowledge/auto-memory.d.ts +1 -1
- package/dist/knowledge/auto-memory.d.ts.map +1 -1
- package/dist/knowledge/auto-memory.js +10 -10
- package/dist/knowledge/auto-memory.js.map +1 -1
- package/dist/knowledge/loader.js +12 -12
- package/dist/knowledge/loader.js.map +1 -1
- package/dist/mcp/arg-parser.d.ts +49 -0
- package/dist/mcp/arg-parser.d.ts.map +1 -0
- package/dist/mcp/arg-parser.js +357 -0
- package/dist/mcp/arg-parser.js.map +1 -0
- package/dist/mcp/client.d.ts +73 -0
- package/dist/mcp/client.d.ts.map +1 -0
- package/dist/mcp/client.js +376 -0
- package/dist/mcp/client.js.map +1 -0
- package/dist/mcp/config-schema.d.ts +64 -0
- package/dist/mcp/config-schema.d.ts.map +1 -0
- package/dist/mcp/config-schema.js +86 -0
- package/dist/mcp/config-schema.js.map +1 -0
- package/dist/mcp/config-writer.d.ts +41 -0
- package/dist/mcp/config-writer.d.ts.map +1 -0
- package/dist/mcp/config-writer.js +138 -0
- package/dist/mcp/config-writer.js.map +1 -0
- package/dist/mcp/env-safety.d.ts +12 -0
- package/dist/mcp/env-safety.d.ts.map +1 -0
- package/dist/mcp/env-safety.js +80 -0
- package/dist/mcp/env-safety.js.map +1 -0
- package/dist/mcp/expand-env.d.ts +14 -0
- package/dist/mcp/expand-env.d.ts.map +1 -0
- package/dist/mcp/expand-env.js +52 -0
- package/dist/mcp/expand-env.js.map +1 -0
- package/dist/mcp/loader.d.ts +81 -0
- package/dist/mcp/loader.d.ts.map +1 -0
- package/dist/mcp/loader.js +223 -0
- package/dist/mcp/loader.js.map +1 -0
- package/dist/mcp/name-mangling.d.ts +11 -0
- package/dist/mcp/name-mangling.d.ts.map +1 -0
- package/dist/mcp/name-mangling.js +82 -0
- package/dist/mcp/name-mangling.js.map +1 -0
- package/dist/mcp/oauth/callback-server.d.ts +25 -0
- package/dist/mcp/oauth/callback-server.d.ts.map +1 -0
- package/dist/mcp/oauth/callback-server.js +118 -0
- package/dist/mcp/oauth/callback-server.js.map +1 -0
- package/dist/mcp/oauth/provider.d.ts +80 -0
- package/dist/mcp/oauth/provider.d.ts.map +1 -0
- package/dist/mcp/oauth/provider.js +292 -0
- package/dist/mcp/oauth/provider.js.map +1 -0
- package/dist/mcp/oauth/token-storage.d.ts +42 -0
- package/dist/mcp/oauth/token-storage.d.ts.map +1 -0
- package/dist/mcp/oauth/token-storage.js +121 -0
- package/dist/mcp/oauth/token-storage.js.map +1 -0
- package/dist/mcp/permissions.d.ts +28 -0
- package/dist/mcp/permissions.d.ts.map +1 -0
- package/dist/mcp/permissions.js +105 -0
- package/dist/mcp/permissions.js.map +1 -0
- package/dist/mcp/registry.d.ts +150 -0
- package/dist/mcp/registry.d.ts.map +1 -0
- package/dist/mcp/registry.js +334 -0
- package/dist/mcp/registry.js.map +1 -0
- package/dist/mcp/resources.d.ts +7 -0
- package/dist/mcp/resources.d.ts.map +1 -0
- package/dist/mcp/resources.js +40 -0
- package/dist/mcp/resources.js.map +1 -0
- package/dist/mcp/tool-bridge.d.ts +16 -0
- package/dist/mcp/tool-bridge.d.ts.map +1 -0
- package/dist/mcp/tool-bridge.js +56 -0
- package/dist/mcp/tool-bridge.js.map +1 -0
- package/dist/mcp/trust.d.ts +31 -0
- package/dist/mcp/trust.d.ts.map +1 -0
- package/dist/mcp/trust.js +103 -0
- package/dist/mcp/trust.js.map +1 -0
- package/dist/mcp/types.d.ts +73 -0
- package/dist/mcp/types.d.ts.map +1 -0
- package/dist/mcp/types.js +13 -0
- package/dist/mcp/types.js.map +1 -0
- package/dist/permissions/session-store.d.ts +4 -1
- package/dist/permissions/session-store.d.ts.map +1 -1
- package/dist/permissions/session-store.js +6 -1
- package/dist/permissions/session-store.js.map +1 -1
- package/dist/plugins/consent.d.ts +87 -0
- package/dist/plugins/consent.d.ts.map +1 -0
- package/dist/plugins/consent.js +181 -0
- package/dist/plugins/consent.js.map +1 -0
- package/dist/plugins/enable-state.d.ts +34 -0
- package/dist/plugins/enable-state.d.ts.map +1 -0
- package/dist/plugins/enable-state.js +159 -0
- package/dist/plugins/enable-state.js.map +1 -0
- package/dist/plugins/installer.d.ts +64 -0
- package/dist/plugins/installer.d.ts.map +1 -0
- package/dist/plugins/installer.js +416 -0
- package/dist/plugins/installer.js.map +1 -0
- package/dist/plugins/integration.d.ts +91 -0
- package/dist/plugins/integration.d.ts.map +1 -0
- package/dist/plugins/integration.js +233 -0
- package/dist/plugins/integration.js.map +1 -0
- package/dist/plugins/loader.d.ts +69 -0
- package/dist/plugins/loader.d.ts.map +1 -0
- package/dist/plugins/loader.js +243 -0
- package/dist/plugins/loader.js.map +1 -0
- package/dist/plugins/manifest.d.ts +23 -0
- package/dist/plugins/manifest.d.ts.map +1 -0
- package/dist/plugins/manifest.js +143 -0
- package/dist/plugins/manifest.js.map +1 -0
- package/dist/plugins/marketplace.d.ts +100 -0
- package/dist/plugins/marketplace.d.ts.map +1 -0
- package/dist/plugins/marketplace.js +529 -0
- package/dist/plugins/marketplace.js.map +1 -0
- package/dist/plugins/paths.d.ts +44 -0
- package/dist/plugins/paths.d.ts.map +1 -0
- package/dist/plugins/paths.js +89 -0
- package/dist/plugins/paths.js.map +1 -0
- package/dist/plugins/refresh.d.ts +61 -0
- package/dist/plugins/refresh.d.ts.map +1 -0
- package/dist/plugins/refresh.js +98 -0
- package/dist/plugins/refresh.js.map +1 -0
- package/dist/plugins/registry.d.ts +40 -0
- package/dist/plugins/registry.d.ts.map +1 -0
- package/dist/plugins/registry.js +80 -0
- package/dist/plugins/registry.js.map +1 -0
- package/dist/plugins/types.d.ts +225 -0
- package/dist/plugins/types.d.ts.map +1 -0
- package/dist/plugins/types.js +16 -0
- package/dist/plugins/types.js.map +1 -0
- package/dist/plugins/user-config.d.ts +22 -0
- package/dist/plugins/user-config.d.ts.map +1 -0
- package/dist/plugins/user-config.js +96 -0
- package/dist/plugins/user-config.js.map +1 -0
- package/dist/skills/loader.d.ts +19 -0
- package/dist/skills/loader.d.ts.map +1 -0
- package/dist/skills/loader.js +197 -0
- package/dist/skills/loader.js.map +1 -0
- package/dist/skills/registry.d.ts +74 -0
- package/dist/skills/registry.d.ts.map +1 -0
- package/dist/skills/registry.js +136 -0
- package/dist/skills/registry.js.map +1 -0
- package/dist/skills/settings.d.ts +13 -0
- package/dist/skills/settings.d.ts.map +1 -0
- package/dist/skills/settings.js +100 -0
- package/dist/skills/settings.js.map +1 -0
- package/dist/tools/activate-skill.d.ts +5 -0
- package/dist/tools/activate-skill.d.ts.map +1 -0
- package/dist/tools/activate-skill.js +33 -0
- package/dist/tools/activate-skill.js.map +1 -0
- package/dist/tools/index.d.ts +1 -1
- package/dist/tools/todo-write.d.ts +1 -1
- package/dist/tools/web-fetch.d.ts.map +1 -1
- package/dist/tools/web-fetch.js +2 -1
- package/dist/tools/web-fetch.js.map +1 -1
- package/dist/types/index.d.ts +46 -1
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/index.js.map +1 -1
- package/dist/utils.d.ts +23 -2
- package/dist/utils.d.ts.map +1 -1
- package/dist/utils.js +76 -20
- package/dist/utils.js.map +1 -1
- package/dist/version.d.ts +2 -0
- package/dist/version.d.ts.map +1 -0
- package/dist/version.js +47 -0
- package/dist/version.js.map +1 -0
- package/package.json +2 -1
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
import type { OAuthClientProvider } from '@modelcontextprotocol/sdk/client/auth.js';
|
|
2
|
+
import { McpClient } from './client.js';
|
|
3
|
+
import { type McpCallResult, type McpResourceEntry, type McpServerConfig, type McpServerStatus, type McpToolEntry } from './types.js';
|
|
4
|
+
/** Build an OAuth provider for one HTTP server. Stdio servers get
|
|
5
|
+
* `undefined`. Returns `undefined` for HTTP servers too when OAuth is
|
|
6
|
+
* not wired up at the CLI level (no token storage configured). */
|
|
7
|
+
export type OAuthProviderFactory = (serverName: string, serverUrl: string) => OAuthClientProvider | undefined;
|
|
8
|
+
export interface RegisteredServer {
|
|
9
|
+
name: string;
|
|
10
|
+
client: McpClient;
|
|
11
|
+
status: McpServerStatus;
|
|
12
|
+
/** When status is `failed`, the most recent stderr tail (stdio only).
|
|
13
|
+
* Used by /mcp list to show why a server failed. */
|
|
14
|
+
stderrTail?: string;
|
|
15
|
+
}
|
|
16
|
+
/** Hooks the /mcp auth handler hands in so the registry can surface
|
|
17
|
+
* human-visible progress without depending on the CLI layer. */
|
|
18
|
+
export interface AuthHooks {
|
|
19
|
+
/** Called once just before the browser is opened. Receives the
|
|
20
|
+
* authorization URL the SDK is about to redirect to. */
|
|
21
|
+
onBrowserOpen?: (url: string) => void;
|
|
22
|
+
}
|
|
23
|
+
/** Summary of what `restartAll` actually changed, for the /mcp refresh
|
|
24
|
+
* output line. */
|
|
25
|
+
export interface RestartSummary {
|
|
26
|
+
/** Server names present after restart that weren't present before. */
|
|
27
|
+
added: string[];
|
|
28
|
+
/** Server names removed (present before, not in new config). */
|
|
29
|
+
removed: string[];
|
|
30
|
+
/** Server names present in both but whose config differs. */
|
|
31
|
+
changed: string[];
|
|
32
|
+
/** Server names that survived restart unchanged. */
|
|
33
|
+
unchanged: string[];
|
|
34
|
+
}
|
|
35
|
+
export declare class McpRegistry {
|
|
36
|
+
/** callableName → entry. callableName is the model-facing
|
|
37
|
+
* `<server>__<tool>` form; collisions resolved at insert time. */
|
|
38
|
+
private readonly entries;
|
|
39
|
+
/** uri → entry. URIs are unique per spec; if two servers genuinely
|
|
40
|
+
* expose the same URI we keep the first and warn (handled by loader). */
|
|
41
|
+
private readonly resources;
|
|
42
|
+
private readonly servers;
|
|
43
|
+
/** Most-recently-loaded config per server. The source of truth for
|
|
44
|
+
* `restartServer` (which reconnects with the same config) and for
|
|
45
|
+
* diff'ing in `restartAll` when fresh configs are handed in. */
|
|
46
|
+
private readonly configs;
|
|
47
|
+
/** Factory for per-server OAuth providers. Optional — undefined means
|
|
48
|
+
* HTTP servers requiring auth will surface as `needs_auth` and the
|
|
49
|
+
* /mcp auth handler can't drive them. */
|
|
50
|
+
private oauthFactory;
|
|
51
|
+
constructor(input: {
|
|
52
|
+
servers: RegisteredServer[];
|
|
53
|
+
tools: McpToolEntry[];
|
|
54
|
+
resources: McpResourceEntry[];
|
|
55
|
+
/** Per-server config used at boot. Required for `restartServer` /
|
|
56
|
+
* `authenticateServer` to know what to rebuild. */
|
|
57
|
+
configs?: Map<string, McpServerConfig>;
|
|
58
|
+
/** OAuth provider factory threaded through from the CLI. */
|
|
59
|
+
oauthFactory?: OAuthProviderFactory;
|
|
60
|
+
});
|
|
61
|
+
/** Snapshot of every model-facing tool name; stable iteration order.
|
|
62
|
+
* Consumed by `buildTools` (agent loop) and `buildSystemPrompt`. */
|
|
63
|
+
list(): McpToolEntry[];
|
|
64
|
+
get(callableName: string): McpToolEntry | undefined;
|
|
65
|
+
listResources(): McpResourceEntry[];
|
|
66
|
+
/** Find the server that owns a given URI so the resource tool can
|
|
67
|
+
* dispatch the read. Returns undefined for unknown URIs. */
|
|
68
|
+
resourceServer(uri: string): McpClient | undefined;
|
|
69
|
+
serverStatus(): Array<{
|
|
70
|
+
name: string;
|
|
71
|
+
status: McpServerStatus;
|
|
72
|
+
stderrTail?: string;
|
|
73
|
+
}>;
|
|
74
|
+
getServer(serverName: string): RegisteredServer | undefined;
|
|
75
|
+
getConfig(serverName: string): McpServerConfig | undefined;
|
|
76
|
+
/** Call an MCP tool by its model-facing callable name. Looks up the
|
|
77
|
+
* entry, finds its owning server, and forwards to the SDK client. */
|
|
78
|
+
callTool(callableName: string, args: unknown, signal?: AbortSignal): Promise<McpCallResult>;
|
|
79
|
+
/** Disconnect every server cleanly. Best-effort: one bad shutdown
|
|
80
|
+
* doesn't prevent others from running. Called from the CLI exit hook
|
|
81
|
+
* and (internally) by `restartAll` before rebuilding. */
|
|
82
|
+
shutdown(): Promise<void>;
|
|
83
|
+
/** Reconnect one server in-place using its current config. Used by
|
|
84
|
+
* `authenticateServer` (after fresh tokens are saved) and exposed for
|
|
85
|
+
* callers that want a per-server reload without a full refresh.
|
|
86
|
+
*
|
|
87
|
+
* Tool / resource entries from the old connection are dropped and
|
|
88
|
+
* replaced with whatever the new connection enumerates — tool names
|
|
89
|
+
* may change if the server's `tools/list` output changes between
|
|
90
|
+
* reconnects. Callers must invalidate the agent's systemPromptCache
|
|
91
|
+
* after this returns. */
|
|
92
|
+
restartServer(name: string, opts?: {
|
|
93
|
+
driveOAuth?: AuthHooks;
|
|
94
|
+
}): Promise<RegisteredServer>;
|
|
95
|
+
/** Disconnect everything and rebuild against `newConfigs` (or the
|
|
96
|
+
* existing configs if omitted). Returns a diff summary so the UI
|
|
97
|
+
* can tell the user what actually changed.
|
|
98
|
+
*
|
|
99
|
+
* Used by `/mcp refresh`: re-read the user + project config files,
|
|
100
|
+
* hand the merged map in here, and we'll add / remove / restart the
|
|
101
|
+
* appropriate set. Servers whose config bytes didn't change are
|
|
102
|
+
* still reconnected — fresher to the user, simpler than diffing
|
|
103
|
+
* every nested field. */
|
|
104
|
+
restartAll(newConfigs?: Map<string, McpServerConfig>): Promise<RestartSummary>;
|
|
105
|
+
/** Drive a fresh OAuth round-trip for one HTTP server, then reconnect
|
|
106
|
+
* it. Used by `/mcp auth <name>`.
|
|
107
|
+
*
|
|
108
|
+
* Pre-condition: the caller should have just cleared any stale
|
|
109
|
+
* tokens for this server via the token storage's `clear()` —
|
|
110
|
+
* otherwise an existing-but-expired token could short-circuit the
|
|
111
|
+
* re-auth path and reuse the bad state.
|
|
112
|
+
*
|
|
113
|
+
* Returns the post-auth server state. Throws if the server is stdio
|
|
114
|
+
* (no OAuth needed), if no OAuth factory is wired up, or if the
|
|
115
|
+
* user closes the browser tab / the callback times out. */
|
|
116
|
+
authenticateServer(name: string, hooks?: AuthHooks): Promise<RegisteredServer>;
|
|
117
|
+
/** Replace the OAuth factory wholesale. Used by the CLI when the
|
|
118
|
+
* token storage / onBrowserOpen wiring is built lazily after the
|
|
119
|
+
* registry has been constructed (rare, but the test harness needs
|
|
120
|
+
* to swap it). */
|
|
121
|
+
setOAuthFactory(factory: OAuthProviderFactory | undefined): void;
|
|
122
|
+
/** Drop every tool + resource owned by this server. Idempotent. */
|
|
123
|
+
private removeServerEntries;
|
|
124
|
+
/** Install a fresh ConnectResult into the maps. Caller is responsible
|
|
125
|
+
* for having removed any previous entries for the same server first. */
|
|
126
|
+
private installServer;
|
|
127
|
+
}
|
|
128
|
+
/** Empty registry — used when MCP is disabled entirely (no mcpServers
|
|
129
|
+
* in config, or trust dialog rejected). Cheaper than null-checking the
|
|
130
|
+
* registry everywhere downstream. */
|
|
131
|
+
export declare function emptyRegistry(): McpRegistry;
|
|
132
|
+
/** One server's worth of "connect + enumerate" output. Shared between
|
|
133
|
+
* initial boot (`loadMcpServers`) and the registry's restart paths so
|
|
134
|
+
* the connect-shape stays consistent. */
|
|
135
|
+
export interface ConnectResult {
|
|
136
|
+
server: RegisteredServer;
|
|
137
|
+
tools: ReadonlyArray<{
|
|
138
|
+
name: string;
|
|
139
|
+
description?: string;
|
|
140
|
+
inputSchema: Record<string, unknown>;
|
|
141
|
+
}>;
|
|
142
|
+
resources: ReadonlyArray<McpResourceEntry>;
|
|
143
|
+
}
|
|
144
|
+
/** Build a client for one server, run the connect handshake, and report
|
|
145
|
+
* the enumerated capabilities. `driveOAuth` (when set) opts into the
|
|
146
|
+
* full browser-based OAuth flow on UnauthorizedError; without it,
|
|
147
|
+
* UnauthorizedError surfaces as `status: needs_auth` and the user is
|
|
148
|
+
* expected to invoke /mcp auth explicitly. */
|
|
149
|
+
export declare function connectOneServer(name: string, rawConfig: McpServerConfig, oauthFactory: OAuthProviderFactory | undefined, driveOAuth?: AuthHooks): Promise<ConnectResult>;
|
|
150
|
+
//# sourceMappingURL=registry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/mcp/registry.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,334 @@
|
|
|
1
|
+
import { debugLog } from '../utils.js';
|
|
2
|
+
import { McpClient } from './client.js';
|
|
3
|
+
import { UnsafeEnvError, assertSafeEnv } from './env-safety.js';
|
|
4
|
+
import { EnvExpansionError, expandEnvDeep } from './expand-env.js';
|
|
5
|
+
import { buildCallableName } from './name-mangling.js';
|
|
6
|
+
import { isHttpConfig, isStdioConfig, } from './types.js';
|
|
7
|
+
export class McpRegistry {
|
|
8
|
+
/** callableName → entry. callableName is the model-facing
|
|
9
|
+
* `<server>__<tool>` form; collisions resolved at insert time. */
|
|
10
|
+
entries = new Map();
|
|
11
|
+
/** uri → entry. URIs are unique per spec; if two servers genuinely
|
|
12
|
+
* expose the same URI we keep the first and warn (handled by loader). */
|
|
13
|
+
resources = new Map();
|
|
14
|
+
servers = new Map();
|
|
15
|
+
/** Most-recently-loaded config per server. The source of truth for
|
|
16
|
+
* `restartServer` (which reconnects with the same config) and for
|
|
17
|
+
* diff'ing in `restartAll` when fresh configs are handed in. */
|
|
18
|
+
configs = new Map();
|
|
19
|
+
/** Factory for per-server OAuth providers. Optional — undefined means
|
|
20
|
+
* HTTP servers requiring auth will surface as `needs_auth` and the
|
|
21
|
+
* /mcp auth handler can't drive them. */
|
|
22
|
+
oauthFactory;
|
|
23
|
+
constructor(input) {
|
|
24
|
+
for (const s of input.servers)
|
|
25
|
+
this.servers.set(s.name, s);
|
|
26
|
+
for (const t of input.tools)
|
|
27
|
+
this.entries.set(t.callableName, t);
|
|
28
|
+
for (const r of input.resources)
|
|
29
|
+
this.resources.set(r.uri, r);
|
|
30
|
+
if (input.configs)
|
|
31
|
+
for (const [k, v] of input.configs)
|
|
32
|
+
this.configs.set(k, v);
|
|
33
|
+
this.oauthFactory = input.oauthFactory;
|
|
34
|
+
}
|
|
35
|
+
// ── Tool surface ───────────────────────────────────────────────────────
|
|
36
|
+
/** Snapshot of every model-facing tool name; stable iteration order.
|
|
37
|
+
* Consumed by `buildTools` (agent loop) and `buildSystemPrompt`. */
|
|
38
|
+
list() {
|
|
39
|
+
return [...this.entries.values()];
|
|
40
|
+
}
|
|
41
|
+
get(callableName) {
|
|
42
|
+
return this.entries.get(callableName);
|
|
43
|
+
}
|
|
44
|
+
// ── Resource surface ───────────────────────────────────────────────────
|
|
45
|
+
listResources() {
|
|
46
|
+
return [...this.resources.values()];
|
|
47
|
+
}
|
|
48
|
+
/** Find the server that owns a given URI so the resource tool can
|
|
49
|
+
* dispatch the read. Returns undefined for unknown URIs. */
|
|
50
|
+
resourceServer(uri) {
|
|
51
|
+
const r = this.resources.get(uri);
|
|
52
|
+
if (!r)
|
|
53
|
+
return undefined;
|
|
54
|
+
return this.servers.get(r.serverName)?.client;
|
|
55
|
+
}
|
|
56
|
+
// ── Server surface (for /mcp list / status) ───────────────────────────
|
|
57
|
+
serverStatus() {
|
|
58
|
+
return [...this.servers.values()].map((s) => ({
|
|
59
|
+
name: s.name,
|
|
60
|
+
status: s.status,
|
|
61
|
+
stderrTail: s.stderrTail,
|
|
62
|
+
}));
|
|
63
|
+
}
|
|
64
|
+
getServer(serverName) {
|
|
65
|
+
return this.servers.get(serverName);
|
|
66
|
+
}
|
|
67
|
+
getConfig(serverName) {
|
|
68
|
+
return this.configs.get(serverName);
|
|
69
|
+
}
|
|
70
|
+
// ── Dispatch ───────────────────────────────────────────────────────────
|
|
71
|
+
/** Call an MCP tool by its model-facing callable name. Looks up the
|
|
72
|
+
* entry, finds its owning server, and forwards to the SDK client. */
|
|
73
|
+
async callTool(callableName, args, signal) {
|
|
74
|
+
const entry = this.entries.get(callableName);
|
|
75
|
+
if (!entry)
|
|
76
|
+
throw new Error(`MCP tool not found: ${callableName}`);
|
|
77
|
+
const server = this.servers.get(entry.serverName);
|
|
78
|
+
if (!server)
|
|
79
|
+
throw new Error(`MCP server gone: ${entry.serverName}`);
|
|
80
|
+
return server.client.callTool(entry.rawName, args, signal);
|
|
81
|
+
}
|
|
82
|
+
// ── Lifecycle ──────────────────────────────────────────────────────────
|
|
83
|
+
/** Disconnect every server cleanly. Best-effort: one bad shutdown
|
|
84
|
+
* doesn't prevent others from running. Called from the CLI exit hook
|
|
85
|
+
* and (internally) by `restartAll` before rebuilding. */
|
|
86
|
+
async shutdown() {
|
|
87
|
+
const tasks = [];
|
|
88
|
+
for (const s of this.servers.values()) {
|
|
89
|
+
tasks.push(s.client.close().catch(() => {
|
|
90
|
+
// already logged in client.safeClose; nothing useful to do here
|
|
91
|
+
}));
|
|
92
|
+
}
|
|
93
|
+
await Promise.allSettled(tasks);
|
|
94
|
+
}
|
|
95
|
+
// ── Restart / refresh ──────────────────────────────────────────────────
|
|
96
|
+
/** Reconnect one server in-place using its current config. Used by
|
|
97
|
+
* `authenticateServer` (after fresh tokens are saved) and exposed for
|
|
98
|
+
* callers that want a per-server reload without a full refresh.
|
|
99
|
+
*
|
|
100
|
+
* Tool / resource entries from the old connection are dropped and
|
|
101
|
+
* replaced with whatever the new connection enumerates — tool names
|
|
102
|
+
* may change if the server's `tools/list` output changes between
|
|
103
|
+
* reconnects. Callers must invalidate the agent's systemPromptCache
|
|
104
|
+
* after this returns. */
|
|
105
|
+
async restartServer(name, opts = {}) {
|
|
106
|
+
const config = this.configs.get(name);
|
|
107
|
+
if (!config) {
|
|
108
|
+
throw new Error(`No MCP server registered as "${name}"`);
|
|
109
|
+
}
|
|
110
|
+
// Close the existing client (if any) before spawning a replacement —
|
|
111
|
+
// for stdio servers this kills the previous child process so we
|
|
112
|
+
// don't leave a zombie behind. Errors are non-fatal: a broken
|
|
113
|
+
// connection that can't be closed cleanly should still be replaced.
|
|
114
|
+
const existing = this.servers.get(name);
|
|
115
|
+
if (existing) {
|
|
116
|
+
try {
|
|
117
|
+
await existing.client.close();
|
|
118
|
+
}
|
|
119
|
+
catch (err) {
|
|
120
|
+
debugLog('mcp.restart-close-failed', `${name}: ${String(err)}`);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
// Strip old tools / resources owned by this server. Done *before*
|
|
124
|
+
// the new connect so a partial failure mid-reconnect leaves us in a
|
|
125
|
+
// consistent "nothing from this server" state rather than a mix of
|
|
126
|
+
// old + nothing.
|
|
127
|
+
this.removeServerEntries(name);
|
|
128
|
+
const result = await connectOneServer(name, config, this.oauthFactory, opts.driveOAuth);
|
|
129
|
+
this.installServer(result);
|
|
130
|
+
return result.server;
|
|
131
|
+
}
|
|
132
|
+
/** Disconnect everything and rebuild against `newConfigs` (or the
|
|
133
|
+
* existing configs if omitted). Returns a diff summary so the UI
|
|
134
|
+
* can tell the user what actually changed.
|
|
135
|
+
*
|
|
136
|
+
* Used by `/mcp refresh`: re-read the user + project config files,
|
|
137
|
+
* hand the merged map in here, and we'll add / remove / restart the
|
|
138
|
+
* appropriate set. Servers whose config bytes didn't change are
|
|
139
|
+
* still reconnected — fresher to the user, simpler than diffing
|
|
140
|
+
* every nested field. */
|
|
141
|
+
async restartAll(newConfigs) {
|
|
142
|
+
const oldNames = new Set(this.configs.keys());
|
|
143
|
+
const newNames = new Set((newConfigs ?? this.configs).keys());
|
|
144
|
+
const summary = {
|
|
145
|
+
added: [...newNames].filter((n) => !oldNames.has(n)),
|
|
146
|
+
removed: [...oldNames].filter((n) => !newNames.has(n)),
|
|
147
|
+
changed: [],
|
|
148
|
+
unchanged: [],
|
|
149
|
+
};
|
|
150
|
+
if (newConfigs) {
|
|
151
|
+
for (const name of newNames) {
|
|
152
|
+
if (!oldNames.has(name))
|
|
153
|
+
continue;
|
|
154
|
+
const before = JSON.stringify(this.configs.get(name));
|
|
155
|
+
const after = JSON.stringify(newConfigs.get(name));
|
|
156
|
+
if (before !== after)
|
|
157
|
+
summary.changed.push(name);
|
|
158
|
+
else
|
|
159
|
+
summary.unchanged.push(name);
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
else {
|
|
163
|
+
summary.unchanged = [...newNames];
|
|
164
|
+
}
|
|
165
|
+
// Tear down everything first. Doing close-all then connect-all
|
|
166
|
+
// (rather than per-server close+connect) is more predictable: we
|
|
167
|
+
// never have two clients for the same server alive at once, and
|
|
168
|
+
// stdio child processes definitely exit before their replacements
|
|
169
|
+
// spawn.
|
|
170
|
+
await this.shutdown();
|
|
171
|
+
// Reset internal state. We keep the OAuth factory because that
|
|
172
|
+
// came from the CLI process and isn't tied to any one config.
|
|
173
|
+
this.servers.clear();
|
|
174
|
+
this.entries.clear();
|
|
175
|
+
this.resources.clear();
|
|
176
|
+
this.configs.clear();
|
|
177
|
+
const effective = newConfigs ?? new Map();
|
|
178
|
+
for (const [k, v] of effective)
|
|
179
|
+
this.configs.set(k, v);
|
|
180
|
+
// Reconnect in parallel — same approach as initial boot. Each
|
|
181
|
+
// failure is recorded as `status: failed` rather than aborting the
|
|
182
|
+
// restart.
|
|
183
|
+
const tasks = [...effective.entries()].map(async ([name, config]) => {
|
|
184
|
+
try {
|
|
185
|
+
return await connectOneServer(name, config, this.oauthFactory);
|
|
186
|
+
}
|
|
187
|
+
catch (err) {
|
|
188
|
+
debugLog('mcp.restartAll-connect-failed', `${name}: ${String(err)}`);
|
|
189
|
+
return null;
|
|
190
|
+
}
|
|
191
|
+
});
|
|
192
|
+
const results = await Promise.all(tasks);
|
|
193
|
+
// Sort by name so tool insertion order is stable (matches initial-
|
|
194
|
+
// boot behaviour in loader.ts).
|
|
195
|
+
const installable = results
|
|
196
|
+
.filter((r) => r !== null)
|
|
197
|
+
.sort((a, b) => a.server.name.localeCompare(b.server.name));
|
|
198
|
+
for (const r of installable)
|
|
199
|
+
this.installServer(r);
|
|
200
|
+
return summary;
|
|
201
|
+
}
|
|
202
|
+
/** Drive a fresh OAuth round-trip for one HTTP server, then reconnect
|
|
203
|
+
* it. Used by `/mcp auth <name>`.
|
|
204
|
+
*
|
|
205
|
+
* Pre-condition: the caller should have just cleared any stale
|
|
206
|
+
* tokens for this server via the token storage's `clear()` —
|
|
207
|
+
* otherwise an existing-but-expired token could short-circuit the
|
|
208
|
+
* re-auth path and reuse the bad state.
|
|
209
|
+
*
|
|
210
|
+
* Returns the post-auth server state. Throws if the server is stdio
|
|
211
|
+
* (no OAuth needed), if no OAuth factory is wired up, or if the
|
|
212
|
+
* user closes the browser tab / the callback times out. */
|
|
213
|
+
async authenticateServer(name, hooks = {}) {
|
|
214
|
+
const config = this.configs.get(name);
|
|
215
|
+
if (!config)
|
|
216
|
+
throw new Error(`No MCP server registered as "${name}"`);
|
|
217
|
+
if (!isHttpConfig(config)) {
|
|
218
|
+
throw new Error(`MCP server "${name}" is stdio — OAuth applies to HTTP servers only`);
|
|
219
|
+
}
|
|
220
|
+
if (!this.oauthFactory) {
|
|
221
|
+
throw new Error(`OAuth not configured — set a token storage in the loader to use /mcp auth`);
|
|
222
|
+
}
|
|
223
|
+
return this.restartServer(name, { driveOAuth: hooks });
|
|
224
|
+
}
|
|
225
|
+
/** Replace the OAuth factory wholesale. Used by the CLI when the
|
|
226
|
+
* token storage / onBrowserOpen wiring is built lazily after the
|
|
227
|
+
* registry has been constructed (rare, but the test harness needs
|
|
228
|
+
* to swap it). */
|
|
229
|
+
setOAuthFactory(factory) {
|
|
230
|
+
this.oauthFactory = factory;
|
|
231
|
+
}
|
|
232
|
+
// ── internals ──────────────────────────────────────────────────────────
|
|
233
|
+
/** Drop every tool + resource owned by this server. Idempotent. */
|
|
234
|
+
removeServerEntries(name) {
|
|
235
|
+
for (const [key, entry] of this.entries) {
|
|
236
|
+
if (entry.serverName === name)
|
|
237
|
+
this.entries.delete(key);
|
|
238
|
+
}
|
|
239
|
+
for (const [key, res] of this.resources) {
|
|
240
|
+
if (res.serverName === name)
|
|
241
|
+
this.resources.delete(key);
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
/** Install a fresh ConnectResult into the maps. Caller is responsible
|
|
245
|
+
* for having removed any previous entries for the same server first. */
|
|
246
|
+
installServer(r) {
|
|
247
|
+
this.servers.set(r.server.name, r.server);
|
|
248
|
+
const taken = new Set(this.entries.keys());
|
|
249
|
+
for (const t of r.tools) {
|
|
250
|
+
const callable = buildCallableName(r.server.name, t.name, taken);
|
|
251
|
+
taken.add(callable);
|
|
252
|
+
this.entries.set(callable, {
|
|
253
|
+
callableName: callable,
|
|
254
|
+
rawName: t.name,
|
|
255
|
+
serverName: r.server.name,
|
|
256
|
+
description: t.description ?? '',
|
|
257
|
+
inputSchema: t.inputSchema,
|
|
258
|
+
});
|
|
259
|
+
}
|
|
260
|
+
for (const res of r.resources)
|
|
261
|
+
this.resources.set(res.uri, res);
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
/** Empty registry — used when MCP is disabled entirely (no mcpServers
|
|
265
|
+
* in config, or trust dialog rejected). Cheaper than null-checking the
|
|
266
|
+
* registry everywhere downstream. */
|
|
267
|
+
export function emptyRegistry() {
|
|
268
|
+
return new McpRegistry({ servers: [], tools: [], resources: [] });
|
|
269
|
+
}
|
|
270
|
+
/** Build a client for one server, run the connect handshake, and report
|
|
271
|
+
* the enumerated capabilities. `driveOAuth` (when set) opts into the
|
|
272
|
+
* full browser-based OAuth flow on UnauthorizedError; without it,
|
|
273
|
+
* UnauthorizedError surfaces as `status: needs_auth` and the user is
|
|
274
|
+
* expected to invoke /mcp auth explicitly. */
|
|
275
|
+
export async function connectOneServer(name, rawConfig, oauthFactory, driveOAuth) {
|
|
276
|
+
// Honour `enabled: false` — register but skip the connection.
|
|
277
|
+
if (rawConfig.enabled === false) {
|
|
278
|
+
const client = new McpClient(name, rawConfig);
|
|
279
|
+
return {
|
|
280
|
+
server: { name, client, status: { kind: 'disabled' } },
|
|
281
|
+
tools: [],
|
|
282
|
+
resources: [],
|
|
283
|
+
};
|
|
284
|
+
}
|
|
285
|
+
// Expand ${VAR} references before constructing the client. Then enforce
|
|
286
|
+
// the env safety check on stdio configs — this is the single chokepoint
|
|
287
|
+
// every env source (CLI flag, mcp.json, plugin manifest) flows through,
|
|
288
|
+
// so rejecting a bad key here covers them all. See env-safety.ts for the
|
|
289
|
+
// threat model.
|
|
290
|
+
let expanded;
|
|
291
|
+
try {
|
|
292
|
+
expanded = expandEnvDeep(rawConfig);
|
|
293
|
+
if (isStdioConfig(expanded))
|
|
294
|
+
assertSafeEnv(expanded.env);
|
|
295
|
+
}
|
|
296
|
+
catch (err) {
|
|
297
|
+
const msg = err instanceof EnvExpansionError || err instanceof UnsafeEnvError
|
|
298
|
+
? err.message
|
|
299
|
+
: err instanceof Error
|
|
300
|
+
? err.message
|
|
301
|
+
: String(err);
|
|
302
|
+
const client = new McpClient(name, rawConfig);
|
|
303
|
+
return {
|
|
304
|
+
server: { name, client, status: { kind: 'failed', error: msg } },
|
|
305
|
+
tools: [],
|
|
306
|
+
resources: [],
|
|
307
|
+
};
|
|
308
|
+
}
|
|
309
|
+
const authProvider = oauthFactory && isHttpConfig(expanded) ? oauthFactory(name, expanded.url) : undefined;
|
|
310
|
+
const client = new McpClient(name, expanded, authProvider);
|
|
311
|
+
try {
|
|
312
|
+
const info = driveOAuth ? await client.connectWithOAuth(driveOAuth) : await client.connect();
|
|
313
|
+
return {
|
|
314
|
+
server: {
|
|
315
|
+
name,
|
|
316
|
+
client,
|
|
317
|
+
status: { kind: 'connected', toolCount: info.toolCount, resourceCount: info.resourceCount },
|
|
318
|
+
},
|
|
319
|
+
tools: client.tools(),
|
|
320
|
+
resources: client.resources(),
|
|
321
|
+
};
|
|
322
|
+
}
|
|
323
|
+
catch (err) {
|
|
324
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
325
|
+
const needsAuth = /unauth|401|UnauthorizedError/i.test(msg) && isHttpConfig(expanded);
|
|
326
|
+
const status = needsAuth ? { kind: 'needs_auth' } : { kind: 'failed', error: msg };
|
|
327
|
+
return {
|
|
328
|
+
server: { name, client, status, stderrTail: client.stderr() || undefined },
|
|
329
|
+
tools: [],
|
|
330
|
+
resources: [],
|
|
331
|
+
};
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
//# sourceMappingURL=registry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registry.js","sourceRoot":"","sources":["../../src/mcp/registry.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resources.d.ts","sourceRoot":"","sources":["../../src/mcp/resources.ts"],"names":[],"mappings":"AAmBA,eAAO,MAAM,gBAAgB;;SAa3B,CAAA;AAEF,eAAO,MAAM,eAAe;;SAO1B,CAAA"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
// @x-code-cli/core — MCP Resources surfaced as two built-in tools
|
|
2
|
+
//
|
|
3
|
+
// MCP "resources" are server-exposed data the model may want to pull
|
|
4
|
+
// (e.g. files exposed by filesystem-server, log entries, DB row dumps).
|
|
5
|
+
// Rather than auto-injecting every resource into the conversation
|
|
6
|
+
// (token-expensive, often irrelevant), we expose two tools:
|
|
7
|
+
//
|
|
8
|
+
// - listMcpResources({ server? }) — enumerate URIs the model can fetch
|
|
9
|
+
// - readMcpResource({ uri }) — fetch one by URI
|
|
10
|
+
//
|
|
11
|
+
// Both tools are defined without an `execute` function so the agent
|
|
12
|
+
// loop's processToolCalls dispatcher handles them — see
|
|
13
|
+
// BYPASS_LOOP_GUARD_HANDLERS in tool-execution.ts. They surface in the
|
|
14
|
+
// system prompt only when an MCP registry is configured (buildTools
|
|
15
|
+
// gates the inclusion).
|
|
16
|
+
import { tool } from 'ai';
|
|
17
|
+
import { z } from 'zod';
|
|
18
|
+
export const listMcpResources = tool({
|
|
19
|
+
description: `List resources exposed by connected MCP servers.
|
|
20
|
+
|
|
21
|
+
Output one resource per line: "<uri>\t[<server>] <name> (<mimeType>)" with a description on the next indented line when present.
|
|
22
|
+
|
|
23
|
+
Use this BEFORE readMcpResource so you have a URI to read. If the model already knows the URI (e.g. from a previous list call), readMcpResource directly is fine.`,
|
|
24
|
+
inputSchema: z.object({
|
|
25
|
+
server: z
|
|
26
|
+
.string()
|
|
27
|
+
.optional()
|
|
28
|
+
.describe('Optional server name to filter by. Omit to list resources from all servers.'),
|
|
29
|
+
}),
|
|
30
|
+
// No execute — handled in tool-execution.ts via BYPASS_LOOP_GUARD_HANDLERS.
|
|
31
|
+
});
|
|
32
|
+
export const readMcpResource = tool({
|
|
33
|
+
description: `Read the contents of an MCP resource by its URI.
|
|
34
|
+
|
|
35
|
+
URIs come from listMcpResources. Text resources return their text directly; binary resources surface a one-line marker noting the omitted content.`,
|
|
36
|
+
inputSchema: z.object({
|
|
37
|
+
uri: z.string().describe('The resource URI to read, as returned by listMcpResources.'),
|
|
38
|
+
}),
|
|
39
|
+
});
|
|
40
|
+
//# sourceMappingURL=resources.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resources.js","sourceRoot":"","sources":["../../src/mcp/resources.ts"],"names":[],"mappings":"AAAA,kEAAkE;AAClE,EAAE;AACF,qEAAqE;AACrE,wEAAwE;AACxE,kEAAkE;AAClE,4DAA4D;AAC5D,EAAE;AACF,0EAA0E;AAC1E,wDAAwD;AACxD,EAAE;AACF,oEAAoE;AACpE,wDAAwD;AACxD,uEAAuE;AACvE,oEAAoE;AACpE,wBAAwB;AACxB,OAAO,EAAE,IAAI,EAAE,MAAM,IAAI,CAAA;AAEzB,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAEvB,MAAM,CAAC,MAAM,gBAAgB,GAAG,IAAI,CAAC;IACnC,WAAW,EAAE;;;;kKAImJ;IAChK,WAAW,EAAE,CAAC,CAAC,MAAM,CAAC;QACpB,MAAM,EAAE,CAAC;aACN,MAAM,EAAE;aACR,QAAQ,EAAE;aACV,QAAQ,CAAC,6EAA6E,CAAC;KAC3F,CAAC;IACF,4EAA4E;CAC7E,CAAC,CAAA;AAEF,MAAM,CAAC,MAAM,eAAe,GAAG,IAAI,CAAC;IAClC,WAAW,EAAE;;mJAEoI;IACjJ,WAAW,EAAE,CAAC,CAAC,MAAM,CAAC;QACpB,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,4DAA4D,CAAC;KACvF,CAAC;CACH,CAAC,CAAA"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { McpToolEntry } from './types.js';
|
|
2
|
+
export declare function truncateDescription(input: string): string;
|
|
3
|
+
/** Adapt one MCP tool into an AI SDK Tool. No execute — we hand-dispatch
|
|
4
|
+
* in tool-execution. The schema is passed through as raw JSON Schema
|
|
5
|
+
* (the SDK has first-class support via `jsonSchema(...)` so we don't
|
|
6
|
+
* need a zod conversion step). */
|
|
7
|
+
export declare function bridgeMcpTool(entry: McpToolEntry): import("ai").Tool<unknown, never>;
|
|
8
|
+
/** Build the system-prompt-friendly view of every MCP tool — short
|
|
9
|
+
* description + the model-facing name. Used by `system-prompt.ts` to
|
|
10
|
+
* render the `## MCP Tools` section. */
|
|
11
|
+
export declare function toSystemPromptEntries(entries: readonly McpToolEntry[]): {
|
|
12
|
+
callableName: string;
|
|
13
|
+
serverName: string;
|
|
14
|
+
description: string;
|
|
15
|
+
}[];
|
|
16
|
+
//# sourceMappingURL=tool-bridge.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tool-bridge.d.ts","sourceRoot":"","sources":["../../src/mcp/tool-bridge.ts"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAA;AAY9C,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAIzD;AAED;;;mCAGmC;AACnC,wBAAgB,aAAa,CAAC,KAAK,EAAE,YAAY,qCAWhD;AAED;;yCAEyC;AACzC,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,SAAS,YAAY,EAAE;;;;IAMrE"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
// @x-code-cli/core — MCP tool ↔ AI SDK adapter
|
|
2
|
+
//
|
|
3
|
+
// Two responsibilities:
|
|
4
|
+
// 1. Convert each McpToolEntry into an AI-SDK `tool({...})` definition
|
|
5
|
+
// so streamText() advertises it to the model alongside built-ins.
|
|
6
|
+
// 2. Trim overlong server-supplied descriptions so they don't bloat
|
|
7
|
+
// the system prompt / tool list.
|
|
8
|
+
//
|
|
9
|
+
// The tools are deliberately defined WITHOUT an `execute` function. The
|
|
10
|
+
// AI SDK then routes the model's tool_call into `result.toolCalls` and
|
|
11
|
+
// our `processToolCalls` dispatcher handles it manually — same path as
|
|
12
|
+
// shell / writeFile / edit. This is what lets us gate every MCP call
|
|
13
|
+
// through the permission + loop-guard machinery.
|
|
14
|
+
import { jsonSchema, tool } from 'ai';
|
|
15
|
+
/** Hard cap on the model-facing description length per tool.
|
|
16
|
+
* - 200 chars is plenty for "what does this tool do?" guidance.
|
|
17
|
+
* - Some MCP servers in the wild paste multi-paragraph docs into the
|
|
18
|
+
* description field; left unbounded these blow up the system prompt
|
|
19
|
+
* and chew through the prompt cache window.
|
|
20
|
+
* - Truncation is character-based, with an ellipsis marker so the model
|
|
21
|
+
* knows the string was clipped (the marker also doubles as a hint
|
|
22
|
+
* to server authors when they see their own description in /mcp tools). */
|
|
23
|
+
const DESCRIPTION_MAX_CHARS = 200;
|
|
24
|
+
export function truncateDescription(input) {
|
|
25
|
+
if (input.length <= DESCRIPTION_MAX_CHARS)
|
|
26
|
+
return input;
|
|
27
|
+
// Keep room for the ellipsis marker so the result is still <= cap.
|
|
28
|
+
return input.slice(0, DESCRIPTION_MAX_CHARS - 1) + '…';
|
|
29
|
+
}
|
|
30
|
+
/** Adapt one MCP tool into an AI SDK Tool. No execute — we hand-dispatch
|
|
31
|
+
* in tool-execution. The schema is passed through as raw JSON Schema
|
|
32
|
+
* (the SDK has first-class support via `jsonSchema(...)` so we don't
|
|
33
|
+
* need a zod conversion step). */
|
|
34
|
+
export function bridgeMcpTool(entry) {
|
|
35
|
+
return tool({
|
|
36
|
+
description: truncateDescription(entry.description || `MCP tool from ${entry.serverName}`),
|
|
37
|
+
// The SDK's jsonSchema() helper takes a JSON Schema object and
|
|
38
|
+
// produces a Schema instance compatible with `tool()`. MCP servers
|
|
39
|
+
// hand us back well-formed JSON Schema by spec, so no preprocessing.
|
|
40
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
41
|
+
inputSchema: jsonSchema(entry.inputSchema),
|
|
42
|
+
// No execute — manual dispatch in tool-execution.ts gates the call
|
|
43
|
+
// through permissions + loop-guard.
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
/** Build the system-prompt-friendly view of every MCP tool — short
|
|
47
|
+
* description + the model-facing name. Used by `system-prompt.ts` to
|
|
48
|
+
* render the `## MCP Tools` section. */
|
|
49
|
+
export function toSystemPromptEntries(entries) {
|
|
50
|
+
return entries.map((e) => ({
|
|
51
|
+
callableName: e.callableName,
|
|
52
|
+
serverName: e.serverName,
|
|
53
|
+
description: truncateDescription(e.description),
|
|
54
|
+
}));
|
|
55
|
+
}
|
|
56
|
+
//# sourceMappingURL=tool-bridge.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tool-bridge.js","sourceRoot":"","sources":["../../src/mcp/tool-bridge.ts"],"names":[],"mappings":"AAAA,+CAA+C;AAC/C,EAAE;AACF,wBAAwB;AACxB,yEAAyE;AACzE,uEAAuE;AACvE,sEAAsE;AACtE,sCAAsC;AACtC,EAAE;AACF,wEAAwE;AACxE,uEAAuE;AACvE,uEAAuE;AACvE,qEAAqE;AACrE,iDAAiD;AACjD,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,IAAI,CAAA;AAIrC;;;;;;;8EAO8E;AAC9E,MAAM,qBAAqB,GAAG,GAAG,CAAA;AAEjC,MAAM,UAAU,mBAAmB,CAAC,KAAa;IAC/C,IAAI,KAAK,CAAC,MAAM,IAAI,qBAAqB;QAAE,OAAO,KAAK,CAAA;IACvD,mEAAmE;IACnE,OAAO,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,qBAAqB,GAAG,CAAC,CAAC,GAAG,GAAG,CAAA;AACxD,CAAC;AAED;;;mCAGmC;AACnC,MAAM,UAAU,aAAa,CAAC,KAAmB;IAC/C,OAAO,IAAI,CAAC;QACV,WAAW,EAAE,mBAAmB,CAAC,KAAK,CAAC,WAAW,IAAI,iBAAiB,KAAK,CAAC,UAAU,EAAE,CAAC;QAC1F,+DAA+D;QAC/D,mEAAmE;QACnE,qEAAqE;QACrE,8DAA8D;QAC9D,WAAW,EAAE,UAAU,CAAC,KAAK,CAAC,WAAkB,CAAC;QACjD,mEAAmE;QACnE,oCAAoC;KACrC,CAAC,CAAA;AACJ,CAAC;AAED;;yCAEyC;AACzC,MAAM,UAAU,qBAAqB,CAAC,OAAgC;IACpE,OAAO,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QACzB,YAAY,EAAE,CAAC,CAAC,YAAY;QAC5B,UAAU,EAAE,CAAC,CAAC,UAAU;QACxB,WAAW,EAAE,mBAAmB,CAAC,CAAC,CAAC,WAAW,CAAC;KAChD,CAAC,CAAC,CAAA;AACL,CAAC"}
|