@thinkwell/acp 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.
@@ -0,0 +1,71 @@
1
+ import { type ChildProcess } from "node:child_process";
2
+ import { ClientSideConnection, type SessionNotification, type PromptResponse } from "@agentclientprotocol/sdk";
3
+ import { McpOverAcpHandler } from "./mcp-over-acp-handler.js";
4
+ import type { ActiveSession } from "./session.js";
5
+ import type { McpServerConfig } from "./types.js";
6
+ /**
7
+ * Session creation options
8
+ */
9
+ export interface SessionOptions {
10
+ cwd?: string;
11
+ systemPrompt?: string;
12
+ mcpServers?: McpServerConfig[];
13
+ }
14
+ /**
15
+ * Connection to the SACP conductor via the ACP SDK.
16
+ *
17
+ * This class wraps the official @agentclientprotocol/sdk's ClientSideConnection
18
+ * and adds SACP-specific functionality (MCP-over-ACP handling).
19
+ */
20
+ export declare class SacpConnection {
21
+ private readonly _process;
22
+ private readonly _connection;
23
+ private readonly _mcpHandler;
24
+ private readonly _sessionHandlers;
25
+ private _initialized;
26
+ constructor(process: ChildProcess, connection: ClientSideConnection, mcpHandler: McpOverAcpHandler);
27
+ /**
28
+ * Get the MCP handler for registering servers
29
+ */
30
+ get mcpHandler(): McpOverAcpHandler;
31
+ /**
32
+ * Initialize the connection (negotiate protocol version and capabilities)
33
+ */
34
+ initialize(): Promise<void>;
35
+ /**
36
+ * Create a new session
37
+ */
38
+ createSession(options: SessionOptions): Promise<string>;
39
+ /**
40
+ * Send a prompt to an existing session
41
+ */
42
+ sendPrompt(sessionId: string, content: string): Promise<PromptResponse>;
43
+ /**
44
+ * Set the handler for session updates
45
+ */
46
+ setSessionHandler(sessionId: string, handler: ActiveSession): void;
47
+ /**
48
+ * Remove the handler for session updates
49
+ */
50
+ removeSessionHandler(sessionId: string): void;
51
+ /**
52
+ * Handle a session update notification from the agent
53
+ */
54
+ handleSessionUpdate(notification: SessionNotification): void;
55
+ private _convertNotification;
56
+ /**
57
+ * Close the connection
58
+ */
59
+ close(): void;
60
+ }
61
+ /**
62
+ * Connect to a conductor process
63
+ */
64
+ export declare function connect(command: string[]): Promise<SacpConnection>;
65
+ /**
66
+ * Create a session builder for this connection
67
+ */
68
+ export declare function session(connection: SacpConnection): SessionBuilder;
69
+ import { SessionBuilder } from "./session.js";
70
+ export { SessionBuilder };
71
+ //# sourceMappingURL=connection.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"connection.d.ts","sourceRoot":"","sources":["../src/connection.ts"],"names":[],"mappings":"AAAA,OAAO,EAAS,KAAK,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAE9D,OAAO,EACL,oBAAoB,EAIpB,KAAK,mBAAmB,EAKxB,KAAK,cAAc,EAEpB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAC9D,OAAO,KAAK,EAAE,aAAa,EAAiB,MAAM,cAAc,CAAC;AACjE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAElD;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,UAAU,CAAC,EAAE,eAAe,EAAE,CAAC;CAChC;AAED;;;;;GAKG;AACH,qBAAa,cAAc;IACzB,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAe;IACxC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAuB;IACnD,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAoB;IAChD,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAyC;IAC1E,OAAO,CAAC,YAAY,CAAkB;gBAGpC,OAAO,EAAE,YAAY,EACrB,UAAU,EAAE,oBAAoB,EAChC,UAAU,EAAE,iBAAiB;IAO/B;;OAEG;IACH,IAAI,UAAU,IAAI,iBAAiB,CAElC;IAED;;OAEG;IACG,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAWjC;;OAEG;IACG,aAAa,CAAC,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,MAAM,CAAC;IAoB7D;;OAEG;IACG,UAAU,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC;IAS7E;;OAEG;IACH,iBAAiB,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,aAAa,GAAG,IAAI;IAIlE;;OAEG;IACH,oBAAoB,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI;IAI7C;;OAEG;IACH,mBAAmB,CAAC,YAAY,EAAE,mBAAmB,GAAG,IAAI;IAe5D,OAAO,CAAC,oBAAoB;IAmC5B;;OAEG;IACH,KAAK,IAAI,IAAI;CAGd;AA2GD;;GAEG;AACH,wBAAsB,OAAO,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,cAAc,CAAC,CA+CxE;AAED;;GAEG;AACH,wBAAgB,OAAO,CAAC,UAAU,EAAE,cAAc,GAAG,cAAc,CAElE;AAGD,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,EAAE,cAAc,EAAE,CAAC"}
@@ -0,0 +1,263 @@
1
+ import { spawn } from "node:child_process";
2
+ import { ClientSideConnection, ndJsonStream, } from "@agentclientprotocol/sdk";
3
+ import { McpOverAcpHandler } from "./mcp-over-acp-handler.js";
4
+ /**
5
+ * Connection to the SACP conductor via the ACP SDK.
6
+ *
7
+ * This class wraps the official @agentclientprotocol/sdk's ClientSideConnection
8
+ * and adds SACP-specific functionality (MCP-over-ACP handling).
9
+ */
10
+ export class SacpConnection {
11
+ _process;
12
+ _connection;
13
+ _mcpHandler;
14
+ _sessionHandlers = new Map();
15
+ _initialized = false;
16
+ constructor(process, connection, mcpHandler) {
17
+ this._process = process;
18
+ this._connection = connection;
19
+ this._mcpHandler = mcpHandler;
20
+ }
21
+ /**
22
+ * Get the MCP handler for registering servers
23
+ */
24
+ get mcpHandler() {
25
+ return this._mcpHandler;
26
+ }
27
+ /**
28
+ * Initialize the connection (negotiate protocol version and capabilities)
29
+ */
30
+ async initialize() {
31
+ if (this._initialized)
32
+ return;
33
+ await this._connection.initialize({
34
+ protocolVersion: 1,
35
+ clientCapabilities: {},
36
+ });
37
+ this._initialized = true;
38
+ }
39
+ /**
40
+ * Create a new session
41
+ */
42
+ async createSession(options) {
43
+ await this.initialize();
44
+ // Convert our McpServerConfig to the SDK's McpServer type
45
+ const mcpServers = (options.mcpServers ?? []).map((s) => ({
46
+ type: "http",
47
+ name: s.name,
48
+ url: s.url,
49
+ headers: [],
50
+ }));
51
+ const request = {
52
+ cwd: options.cwd ?? process.cwd(),
53
+ mcpServers,
54
+ };
55
+ const response = await this._connection.newSession(request);
56
+ return response.sessionId;
57
+ }
58
+ /**
59
+ * Send a prompt to an existing session
60
+ */
61
+ async sendPrompt(sessionId, content) {
62
+ const request = {
63
+ sessionId,
64
+ prompt: [{ type: "text", text: content }],
65
+ };
66
+ return this._connection.prompt(request);
67
+ }
68
+ /**
69
+ * Set the handler for session updates
70
+ */
71
+ setSessionHandler(sessionId, handler) {
72
+ this._sessionHandlers.set(sessionId, handler);
73
+ }
74
+ /**
75
+ * Remove the handler for session updates
76
+ */
77
+ removeSessionHandler(sessionId) {
78
+ this._sessionHandlers.delete(sessionId);
79
+ }
80
+ /**
81
+ * Handle a session update notification from the agent
82
+ */
83
+ handleSessionUpdate(notification) {
84
+ const { sessionId } = notification;
85
+ const handler = this._sessionHandlers.get(sessionId);
86
+ if (!handler) {
87
+ console.error(`No handler for session: ${sessionId}`);
88
+ return;
89
+ }
90
+ // Convert ACP notification to our SessionUpdate type
91
+ const update = this._convertNotification(notification);
92
+ if (update) {
93
+ handler.pushUpdate(update);
94
+ }
95
+ }
96
+ _convertNotification(notification) {
97
+ const { update } = notification;
98
+ // Use the sessionUpdate discriminator to determine type
99
+ switch (update.sessionUpdate) {
100
+ case "agent_message_chunk":
101
+ case "user_message_chunk":
102
+ case "agent_thought_chunk": {
103
+ const content = update.content;
104
+ if (content.type === "text") {
105
+ return { type: "text", content: content.text };
106
+ }
107
+ break;
108
+ }
109
+ case "tool_call": {
110
+ return {
111
+ type: "tool_use",
112
+ id: update.toolCallId,
113
+ name: update.title,
114
+ input: update.rawInput ?? {},
115
+ };
116
+ }
117
+ case "plan":
118
+ case "tool_call_update":
119
+ case "available_commands_update":
120
+ case "current_mode_update":
121
+ // These are informational updates we don't need to handle
122
+ break;
123
+ }
124
+ return null;
125
+ }
126
+ /**
127
+ * Close the connection
128
+ */
129
+ close() {
130
+ this._process.kill();
131
+ }
132
+ }
133
+ /**
134
+ * Create a Client implementation that handles incoming agent requests
135
+ */
136
+ function createClient(connectionHolder, mcpHandler) {
137
+ return {
138
+ // Required: Handle session updates from the agent
139
+ sessionUpdate(notification) {
140
+ if (!connectionHolder.connection) {
141
+ console.error("Connection not yet initialized, dropping session update");
142
+ return Promise.resolve();
143
+ }
144
+ connectionHolder.connection.handleSessionUpdate(notification);
145
+ return Promise.resolve();
146
+ },
147
+ // Required: Handle permission requests
148
+ requestPermission(request) {
149
+ // For now, auto-approve by selecting the first option
150
+ // In a real client, this would prompt the user
151
+ const firstOption = request.options[0];
152
+ return Promise.resolve({
153
+ outcome: {
154
+ outcome: "selected",
155
+ optionId: firstOption?.optionId ?? "approve",
156
+ },
157
+ });
158
+ },
159
+ // Extension method handler for _mcp/* requests
160
+ async extMethod(method, params) {
161
+ if (mcpHandler.isMcpRequest(method)) {
162
+ const result = await mcpHandler.routeRequest(method, params);
163
+ return result ?? {};
164
+ }
165
+ throw new Error(`Unknown extension method: ${method}`);
166
+ },
167
+ // Extension notification handler
168
+ async extNotification(method, params) {
169
+ if (mcpHandler.isMcpRequest(method)) {
170
+ await mcpHandler.routeRequest(method, params);
171
+ }
172
+ },
173
+ };
174
+ }
175
+ /**
176
+ * Convert Node.js streams to Web Streams for the ACP SDK
177
+ */
178
+ function nodeToWebStreams(stdout, stdin) {
179
+ // Convert Node readable to Web ReadableStream
180
+ const readable = new ReadableStream({
181
+ start(controller) {
182
+ stdout.on("data", (chunk) => {
183
+ controller.enqueue(new Uint8Array(chunk));
184
+ });
185
+ stdout.on("end", () => {
186
+ controller.close();
187
+ });
188
+ stdout.on("error", (err) => {
189
+ controller.error(err);
190
+ });
191
+ },
192
+ cancel() {
193
+ stdout.destroy();
194
+ },
195
+ });
196
+ // Convert Node writable to Web WritableStream
197
+ const writable = new WritableStream({
198
+ write(chunk) {
199
+ return new Promise((resolve, reject) => {
200
+ stdin.write(Buffer.from(chunk), (err) => {
201
+ if (err)
202
+ reject(err);
203
+ else
204
+ resolve();
205
+ });
206
+ });
207
+ },
208
+ close() {
209
+ return new Promise((resolve) => {
210
+ stdin.end(() => resolve());
211
+ });
212
+ },
213
+ abort(reason) {
214
+ stdin.destroy(reason instanceof Error ? reason : new Error(String(reason)));
215
+ },
216
+ });
217
+ return { readable, writable };
218
+ }
219
+ /**
220
+ * Connect to a conductor process
221
+ */
222
+ export async function connect(command) {
223
+ if (command.length === 0) {
224
+ throw new Error("Conductor command cannot be empty");
225
+ }
226
+ const [cmd, ...args] = command;
227
+ const childProcess = spawn(cmd, args, {
228
+ stdio: ["pipe", "pipe", "pipe"],
229
+ });
230
+ if (!childProcess.stdout || !childProcess.stdin) {
231
+ throw new Error("Conductor process must have stdio");
232
+ }
233
+ // Log stderr for debugging
234
+ childProcess.stderr?.on("data", (data) => {
235
+ console.error("[conductor stderr]", data.toString());
236
+ });
237
+ // Convert Node streams to Web streams for the SDK
238
+ const { readable, writable } = nodeToWebStreams(childProcess.stdout, childProcess.stdin);
239
+ // Create the ndjson stream
240
+ const stream = ndJsonStream(writable, readable);
241
+ // Create the MCP handler
242
+ const mcpHandler = new McpOverAcpHandler();
243
+ // Use a holder object to break the circular reference.
244
+ // The client factory is called lazily by ClientSideConnection,
245
+ // so we need the holder to be populated before any messages arrive.
246
+ const connectionHolder = { connection: null };
247
+ // Create the ACP client connection
248
+ const clientConnection = new ClientSideConnection((_agent) => createClient(connectionHolder, mcpHandler), stream);
249
+ // Create our wrapper connection and store it in the holder
250
+ const sacpConnection = new SacpConnection(childProcess, clientConnection, mcpHandler);
251
+ connectionHolder.connection = sacpConnection;
252
+ return sacpConnection;
253
+ }
254
+ /**
255
+ * Create a session builder for this connection
256
+ */
257
+ export function session(connection) {
258
+ return new SessionBuilder(connection, connection.mcpHandler);
259
+ }
260
+ // Re-export for convenience
261
+ import { SessionBuilder } from "./session.js";
262
+ export { SessionBuilder };
263
+ //# sourceMappingURL=connection.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"connection.js","sourceRoot":"","sources":["../src/connection.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ export type { JsonSchema, SchemaProvider, McpContext, McpServerConfig, McpConnectRequest, McpConnectResponse, McpMessageRequest, McpMessageResponse, McpContent, McpError, McpDisconnectNotification, McpToolsListResult, McpToolDefinition, McpToolsCallParams, McpToolsCallResult, SessionMessage, StopReason, ToolHandler, RegisteredTool, } from "./types.js";
2
+ export type { JsonValue, JsonObject } from "./json.js";
3
+ export { McpServer, McpServerBuilder, mcpServer } from "./mcp-server.js";
4
+ export { McpOverAcpHandler } from "./mcp-over-acp-handler.js";
5
+ export { ActiveSession, SessionBuilder } from "./session.js";
6
+ export type { SessionUpdate, PromptMessage, McpReadyOptions } from "./session.js";
7
+ export { SacpConnection, connect } from "./connection.js";
8
+ export type { SessionOptions } from "./connection.js";
9
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,YAAY,EACV,UAAU,EACV,cAAc,EACd,UAAU,EACV,eAAe,EACf,iBAAiB,EACjB,kBAAkB,EAClB,iBAAiB,EACjB,kBAAkB,EAClB,UAAU,EACV,QAAQ,EACR,yBAAyB,EACzB,kBAAkB,EAClB,iBAAiB,EACjB,kBAAkB,EAClB,kBAAkB,EAClB,cAAc,EACd,UAAU,EACV,WAAW,EACX,cAAc,GACf,MAAM,YAAY,CAAC;AAEpB,YAAY,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAGvD,OAAO,EAAE,SAAS,EAAE,gBAAgB,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAGzE,OAAO,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAG9D,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAC7D,YAAY,EAAE,aAAa,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAGlF,OAAO,EAAE,cAAc,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAC1D,YAAY,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,9 @@
1
+ // MCP Server
2
+ export { McpServer, McpServerBuilder, mcpServer } from "./mcp-server.js";
3
+ // MCP-over-ACP Handler
4
+ export { McpOverAcpHandler } from "./mcp-over-acp-handler.js";
5
+ // Session
6
+ export { ActiveSession, SessionBuilder } from "./session.js";
7
+ // Connection
8
+ export { SacpConnection, connect } from "./connection.js";
9
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAyBA,aAAa;AACb,OAAO,EAAE,SAAS,EAAE,gBAAgB,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAEzE,uBAAuB;AACvB,OAAO,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAE9D,UAAU;AACV,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAG7D,aAAa;AACb,OAAO,EAAE,cAAc,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC"}
package/dist/json.d.ts ADDED
@@ -0,0 +1,13 @@
1
+ /**
2
+ * JSON value types
3
+ */
4
+ export type JsonValue = string | number | boolean | null | JsonValue[] | {
5
+ [key: string]: JsonValue;
6
+ };
7
+ /**
8
+ * JSON object type
9
+ */
10
+ export type JsonObject = {
11
+ [key: string]: JsonValue;
12
+ };
13
+ //# sourceMappingURL=json.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"json.d.ts","sourceRoot":"","sources":["../src/json.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,MAAM,SAAS,GACjB,MAAM,GACN,MAAM,GACN,OAAO,GACP,IAAI,GACJ,SAAS,EAAE,GACX;IAAE,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,CAAA;CAAE,CAAC;AAEjC;;GAEG;AACH,MAAM,MAAM,UAAU,GAAG;IAAE,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,CAAA;CAAE,CAAC"}
package/dist/json.js ADDED
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=json.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"json.js","sourceRoot":"","sources":["../src/json.ts"],"names":[],"mappings":""}
@@ -0,0 +1,77 @@
1
+ import type { McpServer } from "./mcp-server.js";
2
+ import type { McpConnectResponse } from "./types.js";
3
+ /**
4
+ * Handler for MCP-over-ACP protocol messages.
5
+ *
6
+ * This class manages the lifecycle of MCP connections tunneled through ACP:
7
+ * - mcp/connect: Establishes a new MCP connection
8
+ * - mcp/message: Routes MCP requests to the appropriate server
9
+ * - mcp/disconnect: Tears down an MCP connection
10
+ *
11
+ * Note: The ACP SDK strips the underscore prefix from extension methods,
12
+ * so we receive "mcp/connect" even though the wire format is "_mcp/connect".
13
+ */
14
+ export declare class McpOverAcpHandler {
15
+ /** Maps acp:uuid URLs to registered MCP servers */
16
+ private readonly _serversByUrl;
17
+ /** Maps connection IDs to active connections */
18
+ private readonly _connections;
19
+ /** Current session ID for context */
20
+ private _sessionId;
21
+ /** Maps session IDs to pending tools discovery promises */
22
+ private readonly _toolsDiscoveryBySession;
23
+ /**
24
+ * Register an MCP server to handle requests for its acp: URL
25
+ */
26
+ register(server: McpServer): void;
27
+ /**
28
+ * Unregister an MCP server
29
+ */
30
+ unregister(server: McpServer): void;
31
+ /**
32
+ * Set the current session ID for context
33
+ */
34
+ setSessionId(sessionId: string): void;
35
+ /**
36
+ * Handle an incoming mcp/connect request
37
+ */
38
+ handleConnect(params: Record<string, unknown>): McpConnectResponse;
39
+ /**
40
+ * Handle an incoming mcp/message request.
41
+ *
42
+ * IMPORTANT: The response to _mcp/message is just the raw MCP result,
43
+ * NOT wrapped in {connectionId, result}. The conductor expects the raw
44
+ * MCP response (e.g., InitializeResult, ToolsListResult) directly.
45
+ */
46
+ handleMessage(params: Record<string, unknown>): Promise<unknown>;
47
+ /**
48
+ * Wait for the agent to discover tools via tools/list.
49
+ *
50
+ * This is used to avoid a race condition where the client sends a prompt
51
+ * before the agent has finished MCP initialization. The promise resolves
52
+ * when tools/list is called or when the timeout expires.
53
+ *
54
+ * @param sessionId - The session to wait for
55
+ * @param timeout - Maximum time to wait in milliseconds (default: 2000ms)
56
+ */
57
+ waitForToolsDiscovery(sessionId: string, timeout?: number): Promise<void>;
58
+ /**
59
+ * Resolve the tools discovery promise for a session
60
+ */
61
+ private _resolveToolsDiscovery;
62
+ /**
63
+ * Handle an incoming mcp/disconnect notification
64
+ */
65
+ handleDisconnect(params: Record<string, unknown>): void;
66
+ /**
67
+ * Check if this is an MCP-over-ACP request.
68
+ * Note: The ACP SDK strips the underscore prefix, so we check for "mcp/".
69
+ */
70
+ isMcpRequest(method: string): boolean;
71
+ /**
72
+ * Route an MCP-over-ACP request to the appropriate handler.
73
+ * Note: Methods arrive without the underscore prefix (e.g., "mcp/connect" not "_mcp/connect").
74
+ */
75
+ routeRequest(method: string, params: Record<string, unknown>): Promise<unknown>;
76
+ }
77
+ //# sourceMappingURL=mcp-over-acp-handler.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcp-over-acp-handler.d.ts","sourceRoot":"","sources":["../src/mcp-over-acp-handler.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AACjD,OAAO,KAAK,EAEV,kBAAkB,EAInB,MAAM,YAAY,CAAC;AAmBpB;;;;;;;;;;GAUG;AACH,qBAAa,iBAAiB;IAC5B,mDAAmD;IACnD,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAqC;IACnE,gDAAgD;IAChD,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAyC;IACtE,qCAAqC;IACrC,OAAO,CAAC,UAAU,CAAc;IAChC,2DAA2D;IAC3D,OAAO,CAAC,QAAQ,CAAC,wBAAwB,CAA+C;IAExF;;OAEG;IACH,QAAQ,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI;IAIjC;;OAEG;IACH,UAAU,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI;IAInC;;OAEG;IACH,YAAY,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI;IAIrC;;OAEG;IACH,aAAa,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,kBAAkB;IAuClE;;;;;;OAMG;IACG,aAAa,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC;IAyBtE;;;;;;;;;OASG;IACH,qBAAqB,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,GAAE,MAAa,GAAG,OAAO,CAAC,IAAI,CAAC;IA+B/E;;OAEG;IACH,OAAO,CAAC,sBAAsB;IAO9B;;OAEG;IACH,gBAAgB,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI;IAKvD;;;OAGG;IACH,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO;IAIrC;;;OAGG;IACG,YAAY,CAChB,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC9B,OAAO,CAAC,OAAO,CAAC;CAapB"}
@@ -0,0 +1,183 @@
1
+ /**
2
+ * Handler for MCP-over-ACP protocol messages.
3
+ *
4
+ * This class manages the lifecycle of MCP connections tunneled through ACP:
5
+ * - mcp/connect: Establishes a new MCP connection
6
+ * - mcp/message: Routes MCP requests to the appropriate server
7
+ * - mcp/disconnect: Tears down an MCP connection
8
+ *
9
+ * Note: The ACP SDK strips the underscore prefix from extension methods,
10
+ * so we receive "mcp/connect" even though the wire format is "_mcp/connect".
11
+ */
12
+ export class McpOverAcpHandler {
13
+ /** Maps acp:uuid URLs to registered MCP servers */
14
+ _serversByUrl = new Map();
15
+ /** Maps connection IDs to active connections */
16
+ _connections = new Map();
17
+ /** Current session ID for context */
18
+ _sessionId = "";
19
+ /** Maps session IDs to pending tools discovery promises */
20
+ _toolsDiscoveryBySession = new Map();
21
+ /**
22
+ * Register an MCP server to handle requests for its acp: URL
23
+ */
24
+ register(server) {
25
+ this._serversByUrl.set(server.acpUrl, server);
26
+ }
27
+ /**
28
+ * Unregister an MCP server
29
+ */
30
+ unregister(server) {
31
+ this._serversByUrl.delete(server.acpUrl);
32
+ }
33
+ /**
34
+ * Set the current session ID for context
35
+ */
36
+ setSessionId(sessionId) {
37
+ this._sessionId = sessionId;
38
+ }
39
+ /**
40
+ * Handle an incoming mcp/connect request
41
+ */
42
+ handleConnect(params) {
43
+ // The protocol uses "acp_url" as the parameter name
44
+ // Generate connectionId if not provided by conductor
45
+ const connectionId = params.connectionId ?? `conn-${Date.now()}-${Math.random().toString(36).slice(2)}`;
46
+ const url = (params.acp_url ?? params.url);
47
+ const server = this._serversByUrl.get(url);
48
+ if (!server) {
49
+ throw new Error(`No MCP server registered for URL: ${url}`);
50
+ }
51
+ // Store the connection
52
+ this._connections.set(connectionId, {
53
+ connectionId,
54
+ server,
55
+ sessionId: this._sessionId,
56
+ });
57
+ // Include tool definitions in the connect response
58
+ // The conductor bridge may use this to provide tool info to the agent
59
+ const tools = server.getToolDefinitions();
60
+ // Return response with snake_case field names to match the Rust conductor's expectations
61
+ // Note: The conductor only requires connection_id, but we include extra info for potential use
62
+ return {
63
+ connection_id: connectionId,
64
+ connectionId, // Also include camelCase for backwards compatibility
65
+ serverInfo: {
66
+ name: server.name,
67
+ version: "0.1.0",
68
+ },
69
+ capabilities: {
70
+ tools: {},
71
+ },
72
+ // Include tools directly - the bridge may forward this to the agent
73
+ tools,
74
+ };
75
+ }
76
+ /**
77
+ * Handle an incoming mcp/message request.
78
+ *
79
+ * IMPORTANT: The response to _mcp/message is just the raw MCP result,
80
+ * NOT wrapped in {connectionId, result}. The conductor expects the raw
81
+ * MCP response (e.g., InitializeResult, ToolsListResult) directly.
82
+ */
83
+ async handleMessage(params) {
84
+ const connectionId = params.connectionId;
85
+ const method = params.method;
86
+ const mcpParams = params.params;
87
+ const connection = this._connections.get(connectionId);
88
+ if (!connection) {
89
+ // Return MCP-style error for unknown connection
90
+ throw new Error(`Unknown connection: ${connectionId}`);
91
+ }
92
+ // If this is a tools/list request, resolve any pending tools discovery promise
93
+ if (method === "tools/list") {
94
+ this._resolveToolsDiscovery(connection.sessionId);
95
+ }
96
+ const context = {
97
+ connectionId,
98
+ sessionId: connection.sessionId,
99
+ };
100
+ // Return the raw MCP result - the conductor will wrap it appropriately
101
+ return await connection.server.handleMethod(method, mcpParams, context);
102
+ }
103
+ /**
104
+ * Wait for the agent to discover tools via tools/list.
105
+ *
106
+ * This is used to avoid a race condition where the client sends a prompt
107
+ * before the agent has finished MCP initialization. The promise resolves
108
+ * when tools/list is called or when the timeout expires.
109
+ *
110
+ * @param sessionId - The session to wait for
111
+ * @param timeout - Maximum time to wait in milliseconds (default: 2000ms)
112
+ */
113
+ waitForToolsDiscovery(sessionId, timeout = 2000) {
114
+ // If there's already a pending promise for this session, return it
115
+ const existing = this._toolsDiscoveryBySession.get(sessionId);
116
+ if (existing) {
117
+ return new Promise((resolve) => {
118
+ const originalResolve = existing.resolve;
119
+ existing.resolve = () => {
120
+ originalResolve();
121
+ resolve();
122
+ };
123
+ });
124
+ }
125
+ return new Promise((resolve) => {
126
+ const state = {
127
+ resolve: () => {
128
+ if (state.timeoutId) {
129
+ clearTimeout(state.timeoutId);
130
+ }
131
+ this._toolsDiscoveryBySession.delete(sessionId);
132
+ resolve();
133
+ },
134
+ timeoutId: setTimeout(() => {
135
+ state.timeoutId = null;
136
+ state.resolve();
137
+ }, timeout),
138
+ };
139
+ this._toolsDiscoveryBySession.set(sessionId, state);
140
+ });
141
+ }
142
+ /**
143
+ * Resolve the tools discovery promise for a session
144
+ */
145
+ _resolveToolsDiscovery(sessionId) {
146
+ const state = this._toolsDiscoveryBySession.get(sessionId);
147
+ if (state) {
148
+ state.resolve();
149
+ }
150
+ }
151
+ /**
152
+ * Handle an incoming mcp/disconnect notification
153
+ */
154
+ handleDisconnect(params) {
155
+ const connectionId = params.connectionId;
156
+ this._connections.delete(connectionId);
157
+ }
158
+ /**
159
+ * Check if this is an MCP-over-ACP request.
160
+ * Note: The ACP SDK strips the underscore prefix, so we check for "mcp/".
161
+ */
162
+ isMcpRequest(method) {
163
+ return method.startsWith("mcp/");
164
+ }
165
+ /**
166
+ * Route an MCP-over-ACP request to the appropriate handler.
167
+ * Note: Methods arrive without the underscore prefix (e.g., "mcp/connect" not "_mcp/connect").
168
+ */
169
+ async routeRequest(method, params) {
170
+ switch (method) {
171
+ case "mcp/connect":
172
+ return this.handleConnect(params);
173
+ case "mcp/message":
174
+ return this.handleMessage(params);
175
+ case "mcp/disconnect":
176
+ this.handleDisconnect(params);
177
+ return undefined;
178
+ default:
179
+ throw new Error(`Unknown MCP-over-ACP method: ${method}`);
180
+ }
181
+ }
182
+ }
183
+ //# sourceMappingURL=mcp-over-acp-handler.js.map