@thinkwell/conductor 0.2.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.
Files changed (54) hide show
  1. package/README.md +140 -0
  2. package/dist/conductor.d.ts +219 -0
  3. package/dist/conductor.d.ts.map +1 -0
  4. package/dist/conductor.js +960 -0
  5. package/dist/conductor.js.map +1 -0
  6. package/dist/connectors/channel.d.ts +60 -0
  7. package/dist/connectors/channel.d.ts.map +1 -0
  8. package/dist/connectors/channel.js +155 -0
  9. package/dist/connectors/channel.js.map +1 -0
  10. package/dist/connectors/index.d.ts +6 -0
  11. package/dist/connectors/index.d.ts.map +1 -0
  12. package/dist/connectors/index.js +6 -0
  13. package/dist/connectors/index.js.map +1 -0
  14. package/dist/connectors/stdio.d.ts +36 -0
  15. package/dist/connectors/stdio.d.ts.map +1 -0
  16. package/dist/connectors/stdio.js +198 -0
  17. package/dist/connectors/stdio.js.map +1 -0
  18. package/dist/index.d.ts +72 -0
  19. package/dist/index.d.ts.map +1 -0
  20. package/dist/index.js +76 -0
  21. package/dist/index.js.map +1 -0
  22. package/dist/instantiators.d.ts +129 -0
  23. package/dist/instantiators.d.ts.map +1 -0
  24. package/dist/instantiators.js +183 -0
  25. package/dist/instantiators.js.map +1 -0
  26. package/dist/logger.d.ts +121 -0
  27. package/dist/logger.d.ts.map +1 -0
  28. package/dist/logger.js +162 -0
  29. package/dist/logger.js.map +1 -0
  30. package/dist/mcp-bridge/http-listener.d.ts +35 -0
  31. package/dist/mcp-bridge/http-listener.d.ts.map +1 -0
  32. package/dist/mcp-bridge/http-listener.js +204 -0
  33. package/dist/mcp-bridge/http-listener.js.map +1 -0
  34. package/dist/mcp-bridge/index.d.ts +9 -0
  35. package/dist/mcp-bridge/index.d.ts.map +1 -0
  36. package/dist/mcp-bridge/index.js +8 -0
  37. package/dist/mcp-bridge/index.js.map +1 -0
  38. package/dist/mcp-bridge/mcp-bridge.d.ts +80 -0
  39. package/dist/mcp-bridge/mcp-bridge.d.ts.map +1 -0
  40. package/dist/mcp-bridge/mcp-bridge.js +170 -0
  41. package/dist/mcp-bridge/mcp-bridge.js.map +1 -0
  42. package/dist/mcp-bridge/types.d.ts +69 -0
  43. package/dist/mcp-bridge/types.d.ts.map +1 -0
  44. package/dist/mcp-bridge/types.js +8 -0
  45. package/dist/mcp-bridge/types.js.map +1 -0
  46. package/dist/message-queue.d.ts +46 -0
  47. package/dist/message-queue.d.ts.map +1 -0
  48. package/dist/message-queue.js +90 -0
  49. package/dist/message-queue.js.map +1 -0
  50. package/dist/types.d.ts +129 -0
  51. package/dist/types.d.ts.map +1 -0
  52. package/dist/types.js +13 -0
  53. package/dist/types.js.map +1 -0
  54. package/package.json +40 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.js","sourceRoot":"","sources":["../src/logger.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,35 @@
1
+ /**
2
+ * HTTP Listener for MCP Bridge
3
+ *
4
+ * Listens on an ephemeral HTTP port for MCP connections from agents
5
+ * and bridges them to ACP `_mcp/*` messages.
6
+ *
7
+ * The listener handles the Streamable HTTP transport for MCP:
8
+ * - POST requests for JSON-RPC messages
9
+ * - SSE responses for streaming
10
+ */
11
+ import type { McpBridgeMessage } from "./types.js";
12
+ /**
13
+ * Options for creating an HTTP listener
14
+ */
15
+ export interface HttpListenerOptions {
16
+ acpUrl: string;
17
+ onMessage: (message: McpBridgeMessage) => void;
18
+ }
19
+ /**
20
+ * An active HTTP listener for a specific `acp:` URL
21
+ */
22
+ export interface HttpListener {
23
+ readonly acpUrl: string;
24
+ readonly port: number;
25
+ setSessionId(sessionId: string): void;
26
+ close(): Promise<void>;
27
+ }
28
+ /**
29
+ * Create an HTTP listener for MCP connections
30
+ *
31
+ * The listener waits for the session ID before accepting connections,
32
+ * ensuring we can always correlate connections with sessions.
33
+ */
34
+ export declare function createHttpListener(options: HttpListenerOptions): Promise<HttpListener>;
35
+ //# sourceMappingURL=http-listener.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"http-listener.d.ts","sourceRoot":"","sources":["../../src/mcp-bridge/http-listener.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAeH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAEnD;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,CAAC,OAAO,EAAE,gBAAgB,KAAK,IAAI,CAAC;CAChD;AAED;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,YAAY,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACtC,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACxB;AAWD;;;;;GAKG;AACH,wBAAsB,kBAAkB,CAAC,OAAO,EAAE,mBAAmB,GAAG,OAAO,CAAC,YAAY,CAAC,CAyH5F"}
@@ -0,0 +1,204 @@
1
+ /**
2
+ * HTTP Listener for MCP Bridge
3
+ *
4
+ * Listens on an ephemeral HTTP port for MCP connections from agents
5
+ * and bridges them to ACP `_mcp/*` messages.
6
+ *
7
+ * The listener handles the Streamable HTTP transport for MCP:
8
+ * - POST requests for JSON-RPC messages
9
+ * - SSE responses for streaming
10
+ */
11
+ import { createServer } from "node:http";
12
+ import { randomUUID } from "node:crypto";
13
+ import { isJsonRpcRequest, isJsonRpcNotification, createResponder, } from "@thinkwell/protocol";
14
+ /**
15
+ * Create an HTTP listener for MCP connections
16
+ *
17
+ * The listener waits for the session ID before accepting connections,
18
+ * ensuring we can always correlate connections with sessions.
19
+ */
20
+ export async function createHttpListener(options) {
21
+ const { acpUrl, onMessage } = options;
22
+ let sessionId = null;
23
+ const connections = new Map();
24
+ let server = null;
25
+ // Create HTTP server
26
+ server = createServer(async (req, res) => {
27
+ // CORS headers for local development
28
+ res.setHeader("Access-Control-Allow-Origin", "*");
29
+ res.setHeader("Access-Control-Allow-Methods", "POST, OPTIONS, GET");
30
+ res.setHeader("Access-Control-Allow-Headers", "Content-Type, Mcp-Session-Id");
31
+ if (req.method === "OPTIONS") {
32
+ res.writeHead(204);
33
+ res.end();
34
+ return;
35
+ }
36
+ if (req.method === "GET") {
37
+ // GET request is for SSE stream - return 204 to acknowledge
38
+ res.writeHead(204);
39
+ res.end();
40
+ return;
41
+ }
42
+ if (req.method !== "POST") {
43
+ res.writeHead(405, { "Content-Type": "application/json" });
44
+ res.end(JSON.stringify({ error: "Method not allowed" }));
45
+ return;
46
+ }
47
+ try {
48
+ // Parse the request body first - don't wait for session ID
49
+ const body = await readBody(req);
50
+ const message = JSON.parse(body);
51
+ // Get or create connection for this request
52
+ // For simplicity, we use a single connection per listener
53
+ // (in practice, MCP typically uses one connection per session)
54
+ let connection = connections.get("default");
55
+ if (!connection) {
56
+ const connectionId = randomUUID();
57
+ // Use a placeholder session ID - it will be set later
58
+ // The session ID is not needed for MCP protocol messages
59
+ connection = {
60
+ connectionId,
61
+ sessionId: sessionId ?? "pending",
62
+ pendingResponses: new Map(),
63
+ };
64
+ connections.set("default", connection);
65
+ // Notify conductor of new connection
66
+ onMessage({
67
+ type: "connection-received",
68
+ acpUrl,
69
+ sessionId: connection.sessionId,
70
+ connectionId,
71
+ send: (responseData) => {
72
+ // This is called when conductor sends a response back
73
+ // We need to route it to the right pending response
74
+ },
75
+ close: () => {
76
+ connections.delete("default");
77
+ },
78
+ });
79
+ }
80
+ // Handle the message
81
+ await handleMessage(connection, message, res, onMessage);
82
+ }
83
+ catch (error) {
84
+ console.error("MCP bridge HTTP error:", error);
85
+ res.writeHead(500, { "Content-Type": "application/json" });
86
+ res.end(JSON.stringify({ error: "Internal server error" }));
87
+ }
88
+ });
89
+ // Listen on an ephemeral port
90
+ await new Promise((resolve, reject) => {
91
+ server.listen(0, "127.0.0.1", () => resolve());
92
+ server.on("error", reject);
93
+ });
94
+ const address = server.address();
95
+ if (!address || typeof address === "string") {
96
+ throw new Error("Failed to get server address");
97
+ }
98
+ const port = address.port;
99
+ return {
100
+ acpUrl,
101
+ port,
102
+ setSessionId(id) {
103
+ sessionId = id;
104
+ // Update any existing connections with the real session ID
105
+ for (const conn of connections.values()) {
106
+ conn.sessionId = id;
107
+ }
108
+ },
109
+ async close() {
110
+ // Close all connections
111
+ for (const [key, conn] of connections) {
112
+ onMessage({
113
+ type: "connection-closed",
114
+ connectionId: conn.connectionId,
115
+ });
116
+ connections.delete(key);
117
+ }
118
+ // Close the server
119
+ if (server) {
120
+ await new Promise((resolve) => {
121
+ server.close(() => resolve());
122
+ });
123
+ }
124
+ },
125
+ };
126
+ }
127
+ /**
128
+ * Handle an incoming MCP message
129
+ */
130
+ async function handleMessage(connection, message, res, onMessage) {
131
+ if (isJsonRpcRequest(message)) {
132
+ // Use string key for the pending responses map
133
+ const idKey = String(message.id);
134
+ // Create a promise to wait for the response
135
+ const responsePromise = new Promise((resolve) => {
136
+ connection.pendingResponses.set(idKey, resolve);
137
+ });
138
+ // Create a dispatch with a responder that sends the response to HTTP
139
+ const dispatch = {
140
+ type: "request",
141
+ id: message.id,
142
+ method: message.method,
143
+ params: message.params,
144
+ responder: createResponder((result) => {
145
+ const resolver = connection.pendingResponses.get(idKey);
146
+ connection.pendingResponses.delete(idKey);
147
+ resolver?.({ jsonrpc: "2.0", id: message.id, result });
148
+ }, (error) => {
149
+ const resolver = connection.pendingResponses.get(idKey);
150
+ connection.pendingResponses.delete(idKey);
151
+ resolver?.({ jsonrpc: "2.0", id: message.id, error });
152
+ }),
153
+ };
154
+ // Notify conductor of the request
155
+ onMessage({
156
+ type: "client-message",
157
+ connectionId: connection.connectionId,
158
+ dispatch,
159
+ });
160
+ // Wait for the response
161
+ const response = await responsePromise;
162
+ // Return JSON-RPC response directly
163
+ // Include Mcp-Session-Id header per MCP Streamable HTTP spec
164
+ res.writeHead(200, {
165
+ "Content-Type": "application/json",
166
+ "Mcp-Session-Id": connection.connectionId,
167
+ });
168
+ res.end(JSON.stringify(response));
169
+ }
170
+ else if (isJsonRpcNotification(message)) {
171
+ // Create a notification dispatch
172
+ const dispatch = {
173
+ type: "notification",
174
+ method: message.method,
175
+ params: message.params,
176
+ };
177
+ // Notify conductor
178
+ onMessage({
179
+ type: "client-message",
180
+ connectionId: connection.connectionId,
181
+ dispatch,
182
+ });
183
+ // Notifications don't have responses
184
+ res.writeHead(202);
185
+ res.end();
186
+ }
187
+ else {
188
+ // Unknown message type
189
+ res.writeHead(400, { "Content-Type": "application/json" });
190
+ res.end(JSON.stringify({ error: "Invalid message type" }));
191
+ }
192
+ }
193
+ /**
194
+ * Read the request body as a string
195
+ */
196
+ function readBody(req) {
197
+ return new Promise((resolve, reject) => {
198
+ const chunks = [];
199
+ req.on("data", (chunk) => chunks.push(chunk));
200
+ req.on("end", () => resolve(Buffer.concat(chunks).toString("utf-8")));
201
+ req.on("error", reject);
202
+ });
203
+ }
204
+ //# sourceMappingURL=http-listener.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"http-listener.js","sourceRoot":"","sources":["../../src/mcp-bridge/http-listener.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * MCP Bridge module
3
+ *
4
+ * Provides bridging between MCP-over-ACP and traditional HTTP-based MCP.
5
+ */
6
+ export { McpBridge, type McpBridgeOptions } from "./mcp-bridge.js";
7
+ export { createHttpListener, type HttpListener, type HttpListenerOptions } from "./http-listener.js";
8
+ export type { McpServerSpec, TransformedMcpServer, PendingSession, McpBridgeListener, McpBridgeConnection, McpBridgeMessage, } from "./types.js";
9
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/mcp-bridge/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,SAAS,EAAE,KAAK,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACnE,OAAO,EAAE,kBAAkB,EAAE,KAAK,YAAY,EAAE,KAAK,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AACrG,YAAY,EACV,aAAa,EACb,oBAAoB,EACpB,cAAc,EACd,iBAAiB,EACjB,mBAAmB,EACnB,gBAAgB,GACjB,MAAM,YAAY,CAAC"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * MCP Bridge module
3
+ *
4
+ * Provides bridging between MCP-over-ACP and traditional HTTP-based MCP.
5
+ */
6
+ export { McpBridge } from "./mcp-bridge.js";
7
+ export { createHttpListener } from "./http-listener.js";
8
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/mcp-bridge/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,SAAS,EAAyB,MAAM,iBAAiB,CAAC;AACnE,OAAO,EAAE,kBAAkB,EAA+C,MAAM,oBAAoB,CAAC"}
@@ -0,0 +1,80 @@
1
+ /**
2
+ * MCP Bridge
3
+ *
4
+ * The MCP bridge manages HTTP listeners for `acp:` URLs and coordinates
5
+ * the transformation of MCP server configurations during session creation.
6
+ *
7
+ * Key responsibilities:
8
+ * 1. Transform `acp:$UUID` URLs to `http://localhost:$PORT` during session/new
9
+ * 2. Spawn HTTP listeners for each `acp:` URL
10
+ * 3. Route MCP messages between agents and proxies via `_mcp/*` messages
11
+ * 4. Manage connection lifecycle
12
+ */
13
+ import type { Responder } from "@thinkwell/protocol";
14
+ import type { McpServerSpec } from "./types.js";
15
+ import type { MessageQueue } from "../message-queue.js";
16
+ /**
17
+ * Options for creating an MCP bridge
18
+ */
19
+ export interface McpBridgeOptions {
20
+ messageQueue: MessageQueue;
21
+ }
22
+ /**
23
+ * Active connection through the MCP bridge
24
+ */
25
+ interface ActiveMcpConnection {
26
+ connectionId: string;
27
+ acpUrl: string;
28
+ sessionId: string;
29
+ responder: Responder | null;
30
+ }
31
+ /**
32
+ * MCP Bridge manager
33
+ *
34
+ * Manages HTTP listeners and connection lifecycle for MCP-over-ACP bridging.
35
+ */
36
+ export declare class McpBridge {
37
+ private readonly messageQueue;
38
+ private listeners;
39
+ private connections;
40
+ private pendingSessions;
41
+ constructor(options: McpBridgeOptions);
42
+ /**
43
+ * Transform MCP servers in a session/new request
44
+ *
45
+ * For each `acp:` URL:
46
+ * 1. Spawn an HTTP listener on an ephemeral port
47
+ * 2. Replace the URL with `http://localhost:$PORT`
48
+ *
49
+ * Returns the transformed server list and a session key for later correlation.
50
+ */
51
+ transformMcpServers(servers: McpServerSpec[] | undefined, sessionKey: string): Promise<{
52
+ transformedServers: McpServerSpec[] | undefined;
53
+ hasAcpServers: boolean;
54
+ }>;
55
+ /**
56
+ * Complete session creation after receiving the session ID from the agent
57
+ *
58
+ * This delivers the session ID to all pending listeners so they can
59
+ * correlate connections with the session.
60
+ */
61
+ completeSession(sessionKey: string, sessionId: string): void;
62
+ /**
63
+ * Cancel a pending session (e.g., on error)
64
+ */
65
+ cancelSession(sessionKey: string): Promise<void>;
66
+ /**
67
+ * Handle a message from an HTTP listener
68
+ */
69
+ private handleBridgeMessage;
70
+ /**
71
+ * Get connection info by connection ID
72
+ */
73
+ getConnection(connectionId: string): ActiveMcpConnection | undefined;
74
+ /**
75
+ * Close all listeners and connections
76
+ */
77
+ close(): Promise<void>;
78
+ }
79
+ export {};
80
+ //# sourceMappingURL=mcp-bridge.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcp-bridge.d.ts","sourceRoot":"","sources":["../../src/mcp-bridge/mcp-bridge.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAGH,OAAO,KAAK,EAAY,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAG/D,OAAO,KAAK,EAAE,aAAa,EAA0C,MAAM,YAAY,CAAC;AACxF,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAExD;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,YAAY,EAAE,YAAY,CAAC;CAC5B;AAUD;;GAEG;AACH,UAAU,mBAAmB;IAC3B,YAAY,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,SAAS,GAAG,IAAI,CAAC;CAC7B;AAED;;;;GAIG;AACH,qBAAa,SAAS;IACpB,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAe;IAG5C,OAAO,CAAC,SAAS,CAAmC;IAGpD,OAAO,CAAC,WAAW,CAA0C;IAG7D,OAAO,CAAC,eAAe,CAAyC;gBAEpD,OAAO,EAAE,gBAAgB;IAIrC;;;;;;;;OAQG;IACG,mBAAmB,CACvB,OAAO,EAAE,aAAa,EAAE,GAAG,SAAS,EACpC,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC;QACT,kBAAkB,EAAE,aAAa,EAAE,GAAG,SAAS,CAAC;QAChD,aAAa,EAAE,OAAO,CAAC;KACxB,CAAC;IA8CF;;;;;OAKG;IACH,eAAe,CAAC,UAAU,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,IAAI;IAW5D;;OAEG;IACG,aAAa,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAYtD;;OAEG;IACH,OAAO,CAAC,mBAAmB;IA4C3B;;OAEG;IACH,aAAa,CAAC,YAAY,EAAE,MAAM,GAAG,mBAAmB,GAAG,SAAS;IAIpE;;OAEG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;CAe7B"}
@@ -0,0 +1,170 @@
1
+ /**
2
+ * MCP Bridge
3
+ *
4
+ * The MCP bridge manages HTTP listeners for `acp:` URLs and coordinates
5
+ * the transformation of MCP server configurations during session creation.
6
+ *
7
+ * Key responsibilities:
8
+ * 1. Transform `acp:$UUID` URLs to `http://localhost:$PORT` during session/new
9
+ * 2. Spawn HTTP listeners for each `acp:` URL
10
+ * 3. Route MCP messages between agents and proxies via `_mcp/*` messages
11
+ * 4. Manage connection lifecycle
12
+ */
13
+ import { createHttpListener } from "./http-listener.js";
14
+ /**
15
+ * MCP Bridge manager
16
+ *
17
+ * Manages HTTP listeners and connection lifecycle for MCP-over-ACP bridging.
18
+ */
19
+ export class McpBridge {
20
+ messageQueue;
21
+ // Maps acp:uuid → HttpListener
22
+ listeners = new Map();
23
+ // Maps connectionId → ActiveMcpConnection
24
+ connections = new Map();
25
+ // Pending sessions waiting for session ID
26
+ pendingSessions = new Map();
27
+ constructor(options) {
28
+ this.messageQueue = options.messageQueue;
29
+ }
30
+ /**
31
+ * Transform MCP servers in a session/new request
32
+ *
33
+ * For each `acp:` URL:
34
+ * 1. Spawn an HTTP listener on an ephemeral port
35
+ * 2. Replace the URL with `http://localhost:$PORT`
36
+ *
37
+ * Returns the transformed server list and a session key for later correlation.
38
+ */
39
+ async transformMcpServers(servers, sessionKey) {
40
+ if (!servers || servers.length === 0) {
41
+ return { transformedServers: servers, hasAcpServers: false };
42
+ }
43
+ const pendingSession = {
44
+ listeners: [],
45
+ urlMap: new Map(),
46
+ };
47
+ const transformedServers = [];
48
+ let hasAcpServers = false;
49
+ for (const server of servers) {
50
+ if (server.url.startsWith("acp:")) {
51
+ hasAcpServers = true;
52
+ // Spawn HTTP listener for this acp: URL
53
+ const listener = await createHttpListener({
54
+ acpUrl: server.url,
55
+ onMessage: (msg) => this.handleBridgeMessage(msg),
56
+ });
57
+ this.listeners.set(server.url, listener);
58
+ pendingSession.listeners.push(listener);
59
+ pendingSession.urlMap.set(server.url, `http://127.0.0.1:${listener.port}`);
60
+ // Transform to HTTP URL
61
+ transformedServers.push({
62
+ ...server,
63
+ url: `http://127.0.0.1:${listener.port}`,
64
+ type: "http",
65
+ });
66
+ }
67
+ else {
68
+ // Pass through non-acp servers unchanged
69
+ transformedServers.push(server);
70
+ }
71
+ }
72
+ if (hasAcpServers) {
73
+ this.pendingSessions.set(sessionKey, pendingSession);
74
+ }
75
+ return { transformedServers, hasAcpServers };
76
+ }
77
+ /**
78
+ * Complete session creation after receiving the session ID from the agent
79
+ *
80
+ * This delivers the session ID to all pending listeners so they can
81
+ * correlate connections with the session.
82
+ */
83
+ completeSession(sessionKey, sessionId) {
84
+ const pending = this.pendingSessions.get(sessionKey);
85
+ if (!pending)
86
+ return;
87
+ for (const listener of pending.listeners) {
88
+ listener.setSessionId(sessionId);
89
+ }
90
+ this.pendingSessions.delete(sessionKey);
91
+ }
92
+ /**
93
+ * Cancel a pending session (e.g., on error)
94
+ */
95
+ async cancelSession(sessionKey) {
96
+ const pending = this.pendingSessions.get(sessionKey);
97
+ if (!pending)
98
+ return;
99
+ for (const listener of pending.listeners) {
100
+ await listener.close();
101
+ this.listeners.delete(listener.acpUrl);
102
+ }
103
+ this.pendingSessions.delete(sessionKey);
104
+ }
105
+ /**
106
+ * Handle a message from an HTTP listener
107
+ */
108
+ handleBridgeMessage(msg) {
109
+ switch (msg.type) {
110
+ case "connection-received": {
111
+ // Track the new connection
112
+ this.connections.set(msg.connectionId, {
113
+ connectionId: msg.connectionId,
114
+ acpUrl: msg.acpUrl,
115
+ sessionId: msg.sessionId,
116
+ responder: null,
117
+ });
118
+ // Queue the connection notification for the conductor
119
+ this.messageQueue.push({
120
+ type: "mcp-connection-received",
121
+ acpUrl: msg.acpUrl,
122
+ connectionId: msg.connectionId,
123
+ });
124
+ break;
125
+ }
126
+ case "client-message": {
127
+ // Route MCP message to conductor
128
+ this.messageQueue.push({
129
+ type: "mcp-client-to-server",
130
+ connectionId: msg.connectionId,
131
+ dispatch: msg.dispatch,
132
+ });
133
+ break;
134
+ }
135
+ case "connection-closed": {
136
+ // Clean up connection
137
+ this.connections.delete(msg.connectionId);
138
+ // Queue disconnect notification
139
+ this.messageQueue.push({
140
+ type: "mcp-connection-disconnected",
141
+ connectionId: msg.connectionId,
142
+ });
143
+ break;
144
+ }
145
+ }
146
+ }
147
+ /**
148
+ * Get connection info by connection ID
149
+ */
150
+ getConnection(connectionId) {
151
+ return this.connections.get(connectionId);
152
+ }
153
+ /**
154
+ * Close all listeners and connections
155
+ */
156
+ async close() {
157
+ // Close all connections
158
+ this.connections.clear();
159
+ // Close all listeners
160
+ for (const listener of this.listeners.values()) {
161
+ await listener.close();
162
+ }
163
+ this.listeners.clear();
164
+ // Cancel pending sessions
165
+ for (const key of this.pendingSessions.keys()) {
166
+ await this.cancelSession(key);
167
+ }
168
+ }
169
+ }
170
+ //# sourceMappingURL=mcp-bridge.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcp-bridge.js","sourceRoot":"","sources":["../../src/mcp-bridge/mcp-bridge.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,69 @@
1
+ /**
2
+ * Types for the MCP Bridge
3
+ *
4
+ * The MCP bridge enables agents without native MCP-over-ACP support
5
+ * to work with proxy components that provide MCP servers using ACP transport.
6
+ */
7
+ import type { Dispatch } from "@thinkwell/protocol";
8
+ /**
9
+ * MCP server configuration that may use ACP transport
10
+ */
11
+ export interface McpServerSpec {
12
+ name: string;
13
+ url: string;
14
+ type?: string;
15
+ }
16
+ /**
17
+ * Transformed MCP server configuration with stdio transport
18
+ */
19
+ export interface TransformedMcpServer {
20
+ name: string;
21
+ command: string;
22
+ args: string[];
23
+ }
24
+ /**
25
+ * Pending session that's waiting for the session ID from the agent's response
26
+ */
27
+ export interface PendingSession {
28
+ acpUrl: string;
29
+ sessionIdResolver: (sessionId: string) => void;
30
+ sessionIdRejector: (error: Error) => void;
31
+ }
32
+ /**
33
+ * Active MCP bridge listener
34
+ */
35
+ export interface McpBridgeListener {
36
+ acpUrl: string;
37
+ port: number;
38
+ sessionId: string | null;
39
+ close(): Promise<void>;
40
+ }
41
+ /**
42
+ * Active MCP connection through the bridge
43
+ */
44
+ export interface McpBridgeConnection {
45
+ connectionId: string;
46
+ acpUrl: string;
47
+ sessionId: string;
48
+ send(message: unknown): void;
49
+ close(): void;
50
+ }
51
+ /**
52
+ * Messages from the MCP bridge to the conductor
53
+ */
54
+ export type McpBridgeMessage = {
55
+ type: "connection-received";
56
+ acpUrl: string;
57
+ sessionId: string;
58
+ connectionId: string;
59
+ send: (message: unknown) => void;
60
+ close: () => void;
61
+ } | {
62
+ type: "client-message";
63
+ connectionId: string;
64
+ dispatch: Dispatch;
65
+ } | {
66
+ type: "connection-closed";
67
+ connectionId: string;
68
+ };
69
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/mcp-bridge/types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAEpD;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,EAAE,CAAC;CAChB;AAED;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,MAAM,CAAC;IACf,iBAAiB,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;IAC/C,iBAAiB,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;CAC3C;AAED;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACxB;AAED;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,YAAY,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAAC;IAC7B,KAAK,IAAI,IAAI,CAAC;CACf;AAED;;GAEG;AACH,MAAM,MAAM,gBAAgB,GACxB;IACE,IAAI,EAAE,qBAAqB,CAAC;IAC5B,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;IACrB,IAAI,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC;IACjC,KAAK,EAAE,MAAM,IAAI,CAAC;CACnB,GACD;IACE,IAAI,EAAE,gBAAgB,CAAC;IACvB,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,QAAQ,CAAC;CACpB,GACD;IACE,IAAI,EAAE,mBAAmB,CAAC;IAC1B,YAAY,EAAE,MAAM,CAAC;CACtB,CAAC"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Types for the MCP Bridge
3
+ *
4
+ * The MCP bridge enables agents without native MCP-over-ACP support
5
+ * to work with proxy components that provide MCP servers using ACP transport.
6
+ */
7
+ export {};
8
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/mcp-bridge/types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG"}