@parlor/agent-host 0.4.5 → 0.4.7
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/mcp-proxy.d.ts.map +1 -1
- package/dist/mcp-proxy.js +27 -11
- package/dist/mcp-proxy.js.map +1 -1
- package/package.json +9 -9
package/dist/mcp-proxy.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mcp-proxy.d.ts","sourceRoot":"","sources":["../src/mcp-proxy.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAEjD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAI/C;;;;;GAKG;AACH,MAAM,WAAW,QAAQ;IACvB,MAAM,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1C,IAAI,CAAC,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,YAAY,CAAC;IACzD,6FAA6F;IAC7F,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC;IAC3C;;;OAGG;IACH,YAAY,CAAC,OAAO,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,UAAU,GAAG,SAAS,GAAG,IAAI,CAAC;IAC3E,aAAa,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAC/B,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACxB;AAED,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,mCAAmC;IACnC,QAAQ,CAAC,MAAM,EAAE,cAAc,CAAC;IAChC,+FAA+F;IAC/F,KAAK,CAAC,KAAK,EAAE,UAAU,GAAG,IAAI,CAAC;IAC/B,KAAK,CAAC,KAAK,EAAE,UAAU,GAAG,IAAI,CAAC;IAC/B,GAAG,IAAI,IAAI,CAAC;IACZ,OAAO,IAAI,IAAI,CAAC;CACjB;AAED,0EAA0E;AAC1E,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,kEAAkE;IAClE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,+DAA+D;IAC/D,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,4DAA4D;IAC5D,KAAK,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IACtC,2EAA2E;IAC3E,OAAO,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;CAC7C;AAED,eAAO,MAAM,eAAe,+FACkE,CAAC;AAE/F,eAAO,MAAM,oBAAoB,yFACuD,CAAC;
|
|
1
|
+
{"version":3,"file":"mcp-proxy.d.ts","sourceRoot":"","sources":["../src/mcp-proxy.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAEjD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAI/C;;;;;GAKG;AACH,MAAM,WAAW,QAAQ;IACvB,MAAM,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1C,IAAI,CAAC,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,YAAY,CAAC;IACzD,6FAA6F;IAC7F,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC;IAC3C;;;OAGG;IACH,YAAY,CAAC,OAAO,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,UAAU,GAAG,SAAS,GAAG,IAAI,CAAC;IAC3E,aAAa,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAC/B,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACxB;AAED,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,mCAAmC;IACnC,QAAQ,CAAC,MAAM,EAAE,cAAc,CAAC;IAChC,+FAA+F;IAC/F,KAAK,CAAC,KAAK,EAAE,UAAU,GAAG,IAAI,CAAC;IAC/B,KAAK,CAAC,KAAK,EAAE,UAAU,GAAG,IAAI,CAAC;IAC/B,GAAG,IAAI,IAAI,CAAC;IACZ,OAAO,IAAI,IAAI,CAAC;CACjB;AAED,0EAA0E;AAC1E,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,kEAAkE;IAClE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,+DAA+D;IAC/D,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,4DAA4D;IAC5D,KAAK,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IACtC,2EAA2E;IAC3E,OAAO,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;CAC7C;AAED,eAAO,MAAM,eAAe,+FACkE,CAAC;AAE/F,eAAO,MAAM,oBAAoB,yFACuD,CAAC;AAodzF,uFAAuF;AACvF,qBAAa,eAAgB,SAAQ,KAAK;IACxC,SAAkB,IAAI,qBAAqB;CAC5C;AAsCD,MAAM,WAAW,eAAe;IAC9B,oGAAoG;IACpG,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAC3C;AAED,wBAAgB,cAAc,CAC5B,UAAU,EAAE,MAAM,EAClB,OAAO,GAAE,eAAoB,GAC5B,QAAQ,CA2IV;AAUD;;;;;GAKG;AACH,wBAAsB,kBAAkB,CACtC,GAAG,EAAE,MAAM,CAAC,UAAU,EACtB,OAAO,CAAC,EAAE;IAAE,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;CAAE,GACpE,OAAO,CAAC,IAAI,CAAC,CAmDf"}
|
package/dist/mcp-proxy.js
CHANGED
|
@@ -79,12 +79,28 @@ function learn(live, method, answer) {
|
|
|
79
79
|
}
|
|
80
80
|
/** One line per message on the agent's stdio: only a body with a raw newline is compacted. */
|
|
81
81
|
const asLine = (text) => text.includes("\n") ? JSON.stringify(JSON.parse(text)) : text;
|
|
82
|
-
|
|
82
|
+
/**
|
|
83
|
+
* What the app last said to this handshake request, or to the same method asked otherwise:
|
|
84
|
+
* an agent's later sessions ask `initialize` with other parameters than its first did.
|
|
85
|
+
*/
|
|
86
|
+
function answerBeforeTurn(live, message) {
|
|
87
|
+
const key = handshakeKey(message);
|
|
88
|
+
if (key === undefined || !live.known)
|
|
89
|
+
return undefined;
|
|
90
|
+
const exact = live.known.get(key);
|
|
91
|
+
if (exact)
|
|
92
|
+
return exact;
|
|
93
|
+
const method = `${message.method} `;
|
|
94
|
+
let latest;
|
|
95
|
+
for (const [known, answer] of live.known)
|
|
96
|
+
if (known.startsWith(method))
|
|
97
|
+
latest = answer;
|
|
98
|
+
return latest;
|
|
99
|
+
}
|
|
100
|
+
function betweenTurns(live, message, known) {
|
|
83
101
|
if (message.id === undefined || typeof message.method !== "string")
|
|
84
102
|
return undefined;
|
|
85
103
|
const { id } = message;
|
|
86
|
-
const key = handshakeKey(message);
|
|
87
|
-
const known = key === undefined ? undefined : live.known?.get(key);
|
|
88
104
|
if (known) {
|
|
89
105
|
learn(live, message.method, known);
|
|
90
106
|
return JSON.stringify({ jsonrpc: "2.0", id, ...known });
|
|
@@ -240,12 +256,13 @@ function handle(live, line, reply) {
|
|
|
240
256
|
return;
|
|
241
257
|
const token = live.token;
|
|
242
258
|
if (token === undefined) {
|
|
243
|
-
const
|
|
259
|
+
const known = message.id === undefined ? undefined : answerBeforeTurn(live, message);
|
|
260
|
+
const answer = betweenTurns(live, message, known);
|
|
244
261
|
if (answer)
|
|
245
262
|
reply(answer);
|
|
246
|
-
const key =
|
|
247
|
-
if (key !== undefined
|
|
248
|
-
live.unconfirmed.set(key, line);
|
|
263
|
+
const key = handshakeKey(message);
|
|
264
|
+
if (known && key !== undefined)
|
|
265
|
+
live.unconfirmed.set(key, { line, answer: known });
|
|
249
266
|
return;
|
|
250
267
|
}
|
|
251
268
|
const key = message.id === undefined ? undefined : handshakeKey(message);
|
|
@@ -504,11 +521,10 @@ export function createMcpProxy(hostBinary, options = {}) {
|
|
|
504
521
|
},
|
|
505
522
|
begin: (token) => {
|
|
506
523
|
live.token = token.token;
|
|
507
|
-
for (const [key, line] of live.unconfirmed) {
|
|
524
|
+
for (const [key, { line, answer }] of live.unconfirmed) {
|
|
508
525
|
const message = parse(line);
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
confirm(live, token.token, line, message, key, answered);
|
|
526
|
+
if (message)
|
|
527
|
+
confirm(live, token.token, line, message, key, answer);
|
|
512
528
|
}
|
|
513
529
|
live.unconfirmed.clear();
|
|
514
530
|
},
|
package/dist/mcp-proxy.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mcp-proxy.js","sourceRoot":"","sources":["../src/mcp-proxy.ts"],"names":[],"mappings":"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","sourcesContent":["import { randomBytes } from \"node:crypto\";\nimport { once } from \"node:events\";\nimport { chmod, mkdir, rm } from \"node:fs/promises\";\nimport { connect, createServer, type Server, type Socket } from \"node:net\";\nimport { dirname } from \"node:path\";\n\nimport type { Delegation } from \"@parlor/server\";\n\nimport type { StdioMcpServer } from \"./acp.js\";\nimport { onLines } from \"./lines.js\";\nimport { logEvent } from \"./log.js\";\n\n/**\n * The agent's MCP server for an app is this host: a stdio server (`parlor-host\n * mcp-proxy`) that connects back to the daemon's 0600 socket and names its session by a\n * nonce. The daemon forwards each message to `<app>/_parlor/mcp` with the current turn's\n * token, so no app credential is ever in the agent's config, logs or environment.\n */\nexport interface McpProxy {\n listen(socketPath: string): Promise<void>;\n open(appServer: string, appOrigin: string): ProxySession;\n /** Whether a session opened before its turn can answer the agent's handshake for the app. */\n knowsHandshake(appOrigin: string): boolean;\n /**\n * Serves `parlor-host mcp-proxy --app <origin>`: a coding agent on this computer outside\n * any turn, such as Claude Code in a terminal. `undefined` refuses the app.\n */\n serveOutside(resolve: (appOrigin: string) => OutsideApp | undefined): void;\n stopListening(): Promise<void>;\n close(): Promise<void>;\n}\n\nexport interface ProxySession {\n readonly nonce: string;\n /** The entry for `session/new`. */\n readonly server: StdioMcpServer;\n /** Forward with this token until `end`; a `tools/call` outside a turn gets NO_TURN_MESSAGE. */\n begin(token: Delegation): void;\n renew(token: Delegation): void;\n end(): void;\n dispose(): void;\n}\n\n/** An app a coding agent on this computer may use outside its sidebar. */\nexport interface OutsideApp {\n readonly appOrigin: string;\n readonly appName: string;\n /** The name the user asks the agent with, its MCP server name. */\n readonly name: string;\n /** Whose account the agent acts as: its email, or its name. */\n readonly account: string;\n /** A token for `agent`'s calls, fresh enough to use now. */\n token(agent: string): Promise<string>;\n /** Asks on this computer, for an agent that cannot ask the user itself. */\n askHere(question: string): Promise<boolean>;\n}\n\nexport const NO_TURN_MESSAGE =\n \"No turn is active: the user has not asked anything right now. Wait for their next message.\";\n\nexport const DISCONNECTED_MESSAGE =\n \"This computer no longer serves the app: it was disconnected, or Parlor Host stopped.\";\n\nconst OUTSIDE_PREFIX = \"app \";\nconst AGENT_NAMES: Readonly<Record<string, string>> = {\n \"claude-code\": \"Claude Code\",\n \"codex-mcp-client\": \"Codex\",\n codex: \"Codex\",\n};\n\nconst SOCKET_ENV = \"PARLOR_HOST_PROXY_SOCKET\";\nconst NONCE_ENV = \"PARLOR_HOST_PROXY_NONCE\";\nconst NO_TURN_CODE = -32000;\nconst REFUSED_CODE = -32001;\n/** An agent waits for its MCP servers before its first answer; an app that is down must not hold it. */\nconst OUTSIDE_TOKEN_WAIT_MS = 5_000;\n\ntype JsonRpcId = string | number | null;\n\ninterface Message {\n readonly jsonrpc?: unknown;\n readonly id?: JsonRpcId;\n readonly method?: unknown;\n readonly result?: unknown;\n}\n\n/** An app's answer to one handshake request, without its id. */\ntype KnownAnswer = { readonly result: unknown } | { readonly error: unknown };\n\ninterface Live {\n readonly appOrigin: string;\n /** The app's answers to the handshake every session repeats; undefined outside turns' sessions. */\n readonly known: Map<string, KnownAnswer> | undefined;\n token: string | undefined;\n protocolVersion: string | undefined;\n initialized: unknown;\n tools: unknown;\n readonly inflight: Set<AbortController>;\n readonly sockets: Set<Socket>;\n /** Handshake requests answered from `known` before a turn, asked again once one begins. */\n readonly unconfirmed: Map<string, string>;\n}\n\nfunction parse(text: string): Message | undefined {\n try {\n const value: unknown = JSON.parse(text);\n return typeof value === \"object\" && value !== null && !Array.isArray(value)\n ? (value as Message)\n : undefined;\n } catch {\n return undefined;\n }\n}\n\nconst result = (id: JsonRpcId, value: unknown) =>\n JSON.stringify({ jsonrpc: \"2.0\", id, result: value });\n\nconst failure = (id: JsonRpcId, code: number, message: string) =>\n JSON.stringify({ jsonrpc: \"2.0\", id, error: { code, message } });\n\n/**\n * What a new session asks before its first prompt, answered by the app the same way each\n * time for the same parameters. A session gets the last answer at once while the app is\n * asked again behind it; a list that changed is announced to the agent.\n */\nconst HANDSHAKE: ReadonlySet<string> = new Set([\n \"server/discover\",\n \"initialize\",\n \"tools/list\",\n \"resources/list\",\n \"resources/templates/list\",\n \"prompts/list\",\n]);\nconst LIST_CHANGED: Readonly<Record<string, string>> = {\n \"tools/list\": \"notifications/tools/list_changed\",\n \"resources/list\": \"notifications/resources/list_changed\",\n \"prompts/list\": \"notifications/prompts/list_changed\",\n};\n/** Statuses the same request gets again: never a credential, rate or server failure. */\nconst STABLE_REFUSALS: ReadonlySet<number> = new Set([400, 404, 405]);\n\nconst handshakeKey = (message: Message) =>\n typeof message.method === \"string\" && HANDSHAKE.has(message.method)\n ? `${message.method} ${JSON.stringify((message as { readonly params?: unknown }).params ?? null)}`\n : undefined;\n\nfunction knownAnswer(answer: Message | undefined): KnownAnswer | undefined {\n if (answer === undefined) return undefined;\n if (answer.result !== undefined) return { result: answer.result };\n const { error } = answer as { readonly error?: unknown };\n return error === undefined ? undefined : { error };\n}\n\n/** What the session learns from an `initialize` or `tools/list` answer, wherever it came from. */\nfunction learn(live: Live, method: string, answer: KnownAnswer): void {\n if (!(\"result\" in answer)) return;\n if (method === \"initialize\") {\n live.initialized = answer.result;\n const version = (answer.result as { readonly protocolVersion?: unknown } | undefined)\n ?.protocolVersion;\n if (typeof version === \"string\") live.protocolVersion = version;\n }\n if (method === \"tools/list\") live.tools = answer.result;\n}\n\n/** One line per message on the agent's stdio: only a body with a raw newline is compacted. */\nconst asLine = (text: string) =>\n text.includes(\"\\n\") ? JSON.stringify(JSON.parse(text)) : text;\n\nfunction betweenTurns(live: Live, message: Message): string | undefined {\n if (message.id === undefined || typeof message.method !== \"string\") return undefined;\n const { id } = message;\n const key = handshakeKey(message);\n const known = key === undefined ? undefined : live.known?.get(key);\n if (known) {\n learn(live, message.method, known);\n return JSON.stringify({ jsonrpc: \"2.0\", id, ...known });\n }\n switch (message.method) {\n case \"ping\":\n return result(id, {});\n case \"initialize\":\n return live.initialized === undefined\n ? failure(id, NO_TURN_CODE, NO_TURN_MESSAGE)\n : result(id, live.initialized);\n case \"tools/list\":\n return live.tools === undefined\n ? failure(id, NO_TURN_CODE, NO_TURN_MESSAGE)\n : result(id, live.tools);\n case \"tools/call\":\n return result(id, {\n content: [{ type: \"text\", text: NO_TURN_MESSAGE }],\n isError: true,\n });\n default:\n return failure(id, NO_TURN_CODE, NO_TURN_MESSAGE);\n }\n}\n\nasync function* serverSentData(body: ReadableStream<Uint8Array>): AsyncGenerator<string> {\n const decoder = new TextDecoder();\n let buffer = \"\";\n let data: string[] = [];\n for await (const chunk of body) {\n buffer += decoder.decode(chunk, { stream: true });\n let end = buffer.indexOf(\"\\n\");\n while (end !== -1) {\n const line = buffer.slice(0, end).replace(/\\r$/, \"\");\n buffer = buffer.slice(end + 1);\n if (line === \"\") {\n if (data.length > 0) yield data.join(\"\\n\");\n data = [];\n } else if (line.startsWith(\"data:\")) {\n data.push(line.slice(line.startsWith(\"data: \") ? 6 : 5));\n }\n end = buffer.indexOf(\"\\n\");\n }\n }\n if (data.length > 0) yield data.join(\"\\n\");\n}\n\nfunction refusal(status: number): string {\n return status === 401\n ? \"This computer can no longer act for the app: the turn ended or the computer was disconnected.\"\n : `The app answered HTTP ${status}.`;\n}\n\n/** Sends one message to the app; resolves with its status and what the request was answered. */\nasync function forward(\n live: Live,\n token: string,\n line: string,\n message: Message,\n reply: (line: string) => void,\n): Promise<{ readonly status: number; readonly answer: Message | undefined }> {\n const method = typeof message.method === \"string\" ? message.method : \"response\";\n const controller = new AbortController();\n live.inflight.add(controller);\n let status = 0;\n let given: Message | undefined;\n try {\n const response = await fetch(`${live.appOrigin}/_parlor/mcp`, {\n method: \"POST\",\n headers: {\n authorization: `Bearer ${token}`,\n accept: \"application/json, text/event-stream\",\n \"content-type\": \"application/json\",\n ...(live.protocolVersion ? { \"mcp-protocol-version\": live.protocolVersion } : {}),\n },\n body: line,\n signal: controller.signal,\n });\n status = response.status;\n const bodies: string[] = [];\n if ((response.headers.get(\"content-type\") ?? \"\").includes(\"text/event-stream\")) {\n if (response.body)\n for await (const data of serverSentData(response.body)) bodies.push(data);\n } else {\n const text = await response.text();\n if (text.trim() !== \"\") bodies.push(text);\n }\n let answered = false;\n for (const text of bodies) {\n const answer = parse(text);\n if (answer?.jsonrpc !== \"2.0\") continue;\n if (answer.id === message.id) {\n answered = true;\n given = answer;\n const known = knownAnswer(answer);\n if (known) learn(live, method, known);\n }\n reply(asLine(text));\n }\n if (message.id !== undefined && !answered) {\n const refused = failure(message.id, REFUSED_CODE, refusal(status));\n given = parse(refused);\n reply(refused);\n }\n } catch (error) {\n status = 0;\n if (message.id !== undefined) {\n reply(\n controller.signal.aborted\n ? failure(message.id, NO_TURN_CODE, NO_TURN_MESSAGE)\n : failure(\n message.id,\n REFUSED_CODE,\n `The app could not be reached: ${String(error)}`,\n ),\n );\n }\n } finally {\n live.inflight.delete(controller);\n logEvent(\"proxy_forward\", { appOrigin: live.appOrigin, rpcMethod: method, status });\n }\n return { status, answer: given };\n}\n\n/** Keeps the app's answer to a handshake request when the same request gets it again. */\nfunction remember(\n live: Live,\n key: string,\n outcome: { readonly status: number; readonly answer: Message | undefined },\n): KnownAnswer | undefined {\n const { status } = outcome;\n const stable = (status >= 200 && status < 300) || STABLE_REFUSALS.has(status);\n const known = stable ? knownAnswer(outcome.answer) : undefined;\n // A refused initialize would leave every later session without the app's tools.\n if (!known || (key.startsWith(\"initialize \") && !(\"result\" in known))) return undefined;\n live.known?.set(key, known);\n return known;\n}\n\n/** Answers a handshake request from what the app said last, then asks the app again. */\nfunction replay(\n live: Live,\n token: string,\n line: string,\n message: Message,\n key: string,\n known: KnownAnswer,\n reply: (line: string) => void,\n): void {\n learn(live, message.method as string, known);\n reply(JSON.stringify({ jsonrpc: \"2.0\", id: message.id, ...known }));\n confirm(live, token, line, message, key, known);\n}\n\n/** Asks the app what a known answer said, and tells the agent when a list changed since. */\nfunction confirm(\n live: Live,\n token: string,\n line: string,\n message: Message,\n key: string,\n known: KnownAnswer,\n): void {\n const method = message.method as string;\n void forward(live, token, line, message, () => undefined).then((outcome) => {\n const fresh = remember(live, key, outcome);\n const changed = LIST_CHANGED[method];\n if (!changed || !fresh || JSON.stringify(fresh) === JSON.stringify(known)) return;\n const notice = JSON.stringify({ jsonrpc: \"2.0\", method: changed });\n for (const socket of live.sockets) if (!socket.destroyed) socket.write(`${notice}\\n`);\n });\n}\n\nfunction handle(live: Live, line: string, reply: (line: string) => void): void {\n const message = parse(line);\n if (!message) return;\n const token = live.token;\n if (token === undefined) {\n const answer = betweenTurns(live, message);\n if (answer) reply(answer);\n const key = message.id === undefined ? undefined : handshakeKey(message);\n if (key !== undefined && live.known?.has(key)) live.unconfirmed.set(key, line);\n return;\n }\n const key = message.id === undefined ? undefined : handshakeKey(message);\n if (key === undefined) {\n void forward(live, token, line, message, reply);\n return;\n }\n const known = live.known?.get(key);\n if (known) {\n replay(live, token, line, message, key, known, reply);\n return;\n }\n void forward(live, token, line, message, reply).then((outcome) =>\n remember(live, key, outcome),\n );\n}\n\n/**\n * One agent outside a turn, on one socket. Reads run as asked; the first change in the\n * conversation waits for the user, through the agent's own elicitation where it has it.\n */\nfunction outsideSession(\n app: OutsideApp,\n socket: Socket,\n reply: (line: string) => void,\n tokenWaitMs: number,\n): (line: string) => void {\n const live: Live = {\n appOrigin: app.appOrigin.replace(/\\/+$/, \"\"),\n known: undefined,\n token: undefined,\n protocolVersion: undefined,\n initialized: undefined,\n tools: undefined,\n inflight: new Set(),\n sockets: new Set([socket]),\n unconfirmed: new Map(),\n };\n let agent = \"A coding agent\";\n let elicits = false;\n let changesAllowed: Promise<boolean> | undefined;\n let asked = 0;\n const answers = new Map<string, (allowed: boolean) => void>();\n\n const send = async (line: string, message: Message, onReply = reply) => {\n let token: string;\n try {\n token = await answeredWithin(app.token(agent), tokenWaitMs);\n } catch (error) {\n if (message.id !== undefined) {\n onReply(\n failure(\n message.id,\n REFUSED_CODE,\n error instanceof AppNotAnswering\n ? notAnsweringMessage(app)\n : `${app.appName} refused: ${String(error)}`,\n ),\n );\n }\n return;\n }\n await forward(live, token, line, message, onReply);\n };\n\n const readOnly = async (tool: string): Promise<boolean> => {\n if (live.tools === undefined) {\n const id = `parlor-tools-${++asked}`;\n const list = { jsonrpc: \"2.0\", id, method: \"tools/list\", params: {} };\n await send(JSON.stringify(list), list, () => undefined);\n }\n const tools = (live.tools as { readonly tools?: readonly ToolEntry[] } | undefined)\n ?.tools;\n return (\n tools?.find((entry) => entry.name === tool)?.annotations?.readOnlyHint === true\n );\n };\n\n const askToChange = (): Promise<boolean> => {\n const question = `${agent} wants to change ${app.appName} (${app.appOrigin}) as ${app.account}. Allow changes from this conversation?`;\n if (!elicits) return app.askHere(question);\n const id = `parlor-allow-${++asked}`;\n const answered = new Promise<boolean>((resolve) => answers.set(id, resolve));\n reply(\n JSON.stringify({\n jsonrpc: \"2.0\",\n id,\n method: \"elicitation/create\",\n params: {\n message: question,\n requestedSchema: { type: \"object\", properties: {} },\n },\n }),\n );\n return answered;\n };\n\n return (line) => {\n const message = parse(line);\n if (!message) return;\n if (message.method === undefined && typeof message.id === \"string\") {\n const answer = answers.get(message.id);\n if (answer) {\n answers.delete(message.id);\n const action = (message.result as { readonly action?: unknown } | undefined)\n ?.action;\n answer(action === \"accept\");\n return;\n }\n }\n if (message.method === \"initialize\") {\n const params = (message as { readonly params?: InitializeParams }).params;\n const client = params?.clientInfo?.name;\n if (typeof client === \"string\" && client !== \"\")\n agent = AGENT_NAMES[client] ?? client;\n elicits = params?.capabilities?.elicitation !== undefined;\n logEvent(\"outside_agent\", { appOrigin: app.appOrigin, agent, elicits });\n void send(line, message, (answer) => reply(withGuidance(answer, app, agent)));\n return;\n }\n if (message.method === \"tools/call\" && message.id !== undefined) {\n const tool = (message as { readonly params?: { readonly name?: unknown } }).params\n ?.name;\n void (async () => {\n if (typeof tool === \"string\" && !(await readOnly(tool))) {\n changesAllowed ??= askToChange().then((allowed) => {\n if (!allowed) changesAllowed = undefined;\n return allowed;\n });\n if (!(await changesAllowed)) {\n reply(\n result(message.id!, {\n content: [\n {\n type: \"text\",\n text: `Nothing was changed: the user did not allow changes to ${app.appName} from this conversation, or could not be asked here. Tell them so. If they ask for the change again, they are asked again first; nothing in ${app.appName} itself turns this on.`,\n },\n ],\n isError: true,\n }),\n );\n return;\n }\n }\n await send(line, message);\n })();\n return;\n }\n void send(line, message);\n };\n}\n\n/** `OutsideApp.token` throws it while the app does not answer this computer at all. */\nexport class AppNotAnswering extends Error {\n override readonly name = \"AppNotAnswering\";\n}\n\nfunction answeredWithin<T>(pending: Promise<T>, ms: number): Promise<T> {\n let timer: ReturnType<typeof setTimeout> | undefined;\n const late = new Promise<never>((_, reject) => {\n timer = setTimeout(() => reject(new AppNotAnswering()), ms);\n timer.unref?.();\n });\n return Promise.race([pending, late]).finally(() => clearTimeout(timer));\n}\n\nconst notAnsweringMessage = (app: OutsideApp) =>\n `${app.appName} (${app.appOrigin}) is not answering, so its tools are unavailable in this conversation. Start it, or stop its tools with \\`parlor-host tools --off ${app.appOrigin}\\`.`;\n\ninterface ToolEntry {\n readonly name?: string;\n readonly annotations?: { readonly readOnlyHint?: boolean };\n}\n\ninterface InitializeParams {\n readonly clientInfo?: { readonly name?: unknown };\n readonly capabilities?: { readonly elicitation?: unknown };\n}\n\n/** The app's own instructions, led by when to use it at all: only when the user names it. */\nfunction withGuidance(line: string, app: OutsideApp, agent: string): string {\n const answer = parse(line);\n const initialized = answer?.result as { readonly instructions?: unknown } | undefined;\n if (!initialized || typeof initialized !== \"object\") return line;\n const guidance = `Use these tools only when the user names ${app.appName} or \"${app.name}\" in their request: they act on the live app at ${app.appOrigin} as ${app.account}, and ${agent} runs outside the app here. When the user does, use them rather than opening ${app.appName} in a browser: they read and change the same data directly. If your tools load on demand, search them for \"${app.name}\" first. Reading is free; before the first change in this conversation the user is asked to allow changes.`;\n const own =\n typeof initialized.instructions === \"string\" ? initialized.instructions : \"\";\n return JSON.stringify({\n ...answer,\n result: { ...initialized, instructions: own ? `${guidance}\\n\\n${own}` : guidance },\n });\n}\n\nexport interface McpProxyOptions {\n /** How long an agent outside a turn waits for its app's token before it is told the app is down. */\n readonly tokenWaitMs?: number | undefined;\n}\n\nexport function createMcpProxy(\n hostBinary: string,\n options: McpProxyOptions = {},\n): McpProxy {\n const tokenWaitMs = options.tokenWaitMs ?? OUTSIDE_TOKEN_WAIT_MS;\n const sessions = new Map<string, Live>();\n const handshakes = new Map<string, Map<string, KnownAnswer>>();\n let server: Server | undefined;\n let socketPath: string | undefined;\n let outside: (appOrigin: string) => OutsideApp | undefined = () => undefined;\n\n const accept = (socket: Socket) => {\n let live: Live | undefined;\n let outsideLine: ((line: string) => void) | undefined;\n const reply = (line: string) => {\n if (!socket.destroyed) socket.write(`${line}\\n`);\n };\n onLines(socket, (line) => {\n if (outsideLine !== undefined) {\n outsideLine(line);\n return;\n }\n if (live !== undefined) {\n handle(live, line, reply);\n return;\n }\n const first = line.trim();\n if (first.startsWith(OUTSIDE_PREFIX)) {\n const appOrigin = first.slice(OUTSIDE_PREFIX.length);\n const app = outside(appOrigin);\n if (!app) {\n reply(JSON.stringify({ refused: notServedMessage(appOrigin) }));\n socket.end();\n return;\n }\n outsideLine = outsideSession(app, socket, reply, tokenWaitMs);\n return;\n }\n live = sessions.get(first);\n if (live) live.sockets.add(socket);\n else socket.destroy();\n });\n socket.on(\"close\", () => live?.sockets.delete(socket));\n socket.on(\"error\", () => socket.destroy());\n };\n\n return {\n async listen(path) {\n await mkdir(dirname(path), { recursive: true, mode: 0o700 });\n await rm(path, { force: true });\n const listening = createServer(accept);\n await new Promise<void>((resolve, reject) => {\n listening.once(\"error\", reject);\n listening.listen(path, () => resolve());\n });\n await chmod(path, 0o600);\n server = listening;\n socketPath = path;\n },\n serveOutside(resolve) {\n outside = resolve;\n },\n knowsHandshake(appOrigin) {\n const keys = [...(handshakes.get(appOrigin.replace(/\\/+$/, \"\"))?.keys() ?? [])];\n return [\"initialize \", \"tools/list \"].every((method) =>\n keys.some((key) => key.startsWith(method)),\n );\n },\n open(appServer, appOrigin) {\n if (socketPath === undefined)\n throw new Error(\"The MCP proxy is not listening yet.\");\n const nonce = randomBytes(24).toString(\"base64url\");\n const origin = appOrigin.replace(/\\/+$/, \"\");\n let known = handshakes.get(origin);\n if (!known) {\n known = new Map();\n handshakes.set(origin, known);\n }\n const live: Live = {\n appOrigin: origin,\n known,\n token: undefined,\n protocolVersion: undefined,\n initialized: undefined,\n tools: undefined,\n inflight: new Set(),\n sockets: new Set(),\n unconfirmed: new Map(),\n };\n sessions.set(nonce, live);\n const end = () => {\n live.token = undefined;\n for (const controller of live.inflight) controller.abort();\n };\n return {\n nonce,\n server: {\n name: appServer,\n command: hostBinary,\n args: [\"mcp-proxy\"],\n env: { [SOCKET_ENV]: socketPath, [NONCE_ENV]: nonce },\n },\n begin: (token) => {\n live.token = token.token;\n for (const [key, line] of live.unconfirmed) {\n const message = parse(line);\n const answered = live.known?.get(key);\n if (message && answered)\n confirm(live, token.token, line, message, key, answered);\n }\n live.unconfirmed.clear();\n },\n renew: (token) => {\n if (live.token !== undefined) live.token = token.token;\n },\n end,\n dispose: () => {\n end();\n sessions.delete(nonce);\n for (const socket of live.sockets) socket.destroy();\n },\n };\n },\n async stopListening() {\n const closing = server;\n server = undefined;\n if (!closing) return;\n closing.close();\n if (socketPath) await rm(socketPath, { force: true });\n },\n async close() {\n for (const live of sessions.values()) {\n for (const controller of live.inflight) controller.abort();\n for (const socket of live.sockets) socket.destroy();\n }\n sessions.clear();\n const closing = server;\n server = undefined;\n if (closing) {\n await new Promise<void>((resolve) => closing.close(() => resolve()));\n if (socketPath) await rm(socketPath, { force: true });\n }\n },\n };\n}\n\n/** Why an agent outside a turn cannot use `appOrigin` here. */\nfunction notServedMessage(appOrigin: string): string {\n return `This computer does not let coding agents use ${appOrigin}: it is not connected, or that was turned off. Connect it again with \\`npx @parlor/agent-host connect ${appOrigin}\\`.`;\n}\n\nconst notRunningMessage = (appOrigin: string) =>\n `Parlor Host is not running on this computer, so ${appOrigin} cannot be reached. Open the app's agent sidebar, or run \\`npx @parlor/agent-host connect ${appOrigin}\\`.`;\n\n/**\n * `parlor-host mcp-proxy`: stdio to the daemon socket and back. Inside a turn the\n * environment names the session; `--app` serves an agent outside any turn. Once the daemon\n * hangs up, every request still unanswered, and every later one, is answered with an error\n * here.\n */\nexport async function runMcpProxyProcess(\n env: NodeJS.ProcessEnv,\n outside?: { readonly appOrigin: string; readonly socketPath: string },\n): Promise<void> {\n const path = outside?.socketPath ?? env[SOCKET_ENV];\n const nonce = env[NONCE_ENV];\n if (!path || (!outside && !nonce)) {\n throw new Error(`${SOCKET_ENV} and ${NONCE_ENV} must be set, or --app.`);\n }\n let why = outside ? notRunningMessage(outside.appOrigin) : DISCONNECTED_MESSAGE;\n const unanswered = new Set<JsonRpcId>();\n const toAgent = (line: string) => void process.stdout.write(`${line}\\n`);\n const refuse = (id: JsonRpcId) => toAgent(failure(id, REFUSED_CODE, why));\n process.stdout.on(\"error\", () => undefined);\n\n const daemon = connect(path);\n daemon.on(\"error\", () => daemon.destroy());\n daemon.once(\"connect\", () => {\n if (outside) why = DISCONNECTED_MESSAGE;\n });\n const hungUp = new Promise<void>((resolve) =>\n daemon.once(\"close\", () => {\n for (const id of unanswered) refuse(id);\n unanswered.clear();\n resolve();\n }),\n );\n daemon.write(outside ? `${OUTSIDE_PREFIX}${outside.appOrigin}\\n` : `${nonce}\\n`);\n onLines(daemon, (line) => {\n const refused = (parse(line) as { readonly refused?: unknown } | undefined)?.refused;\n if (typeof refused === \"string\") {\n why = refused;\n return;\n }\n const message = parse(line);\n if (message?.id !== undefined && message.method === undefined) {\n unanswered.delete(message.id);\n }\n toAgent(line);\n });\n\n const agent = onLines(process.stdin, (line) => {\n const message = parse(line);\n const id = typeof message?.method === \"string\" ? message.id : undefined;\n if (!daemon.destroyed) {\n if (id !== undefined) unanswered.add(id);\n daemon.write(`${line}\\n`);\n } else if (id !== undefined) {\n refuse(id);\n }\n });\n await once(agent, \"close\");\n daemon.end();\n await hungUp;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"mcp-proxy.js","sourceRoot":"","sources":["../src/mcp-proxy.ts"],"names":[],"mappings":"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","sourcesContent":["import { randomBytes } from \"node:crypto\";\nimport { once } from \"node:events\";\nimport { chmod, mkdir, rm } from \"node:fs/promises\";\nimport { connect, createServer, type Server, type Socket } from \"node:net\";\nimport { dirname } from \"node:path\";\n\nimport type { Delegation } from \"@parlor/server\";\n\nimport type { StdioMcpServer } from \"./acp.js\";\nimport { onLines } from \"./lines.js\";\nimport { logEvent } from \"./log.js\";\n\n/**\n * The agent's MCP server for an app is this host: a stdio server (`parlor-host\n * mcp-proxy`) that connects back to the daemon's 0600 socket and names its session by a\n * nonce. The daemon forwards each message to `<app>/_parlor/mcp` with the current turn's\n * token, so no app credential is ever in the agent's config, logs or environment.\n */\nexport interface McpProxy {\n listen(socketPath: string): Promise<void>;\n open(appServer: string, appOrigin: string): ProxySession;\n /** Whether a session opened before its turn can answer the agent's handshake for the app. */\n knowsHandshake(appOrigin: string): boolean;\n /**\n * Serves `parlor-host mcp-proxy --app <origin>`: a coding agent on this computer outside\n * any turn, such as Claude Code in a terminal. `undefined` refuses the app.\n */\n serveOutside(resolve: (appOrigin: string) => OutsideApp | undefined): void;\n stopListening(): Promise<void>;\n close(): Promise<void>;\n}\n\nexport interface ProxySession {\n readonly nonce: string;\n /** The entry for `session/new`. */\n readonly server: StdioMcpServer;\n /** Forward with this token until `end`; a `tools/call` outside a turn gets NO_TURN_MESSAGE. */\n begin(token: Delegation): void;\n renew(token: Delegation): void;\n end(): void;\n dispose(): void;\n}\n\n/** An app a coding agent on this computer may use outside its sidebar. */\nexport interface OutsideApp {\n readonly appOrigin: string;\n readonly appName: string;\n /** The name the user asks the agent with, its MCP server name. */\n readonly name: string;\n /** Whose account the agent acts as: its email, or its name. */\n readonly account: string;\n /** A token for `agent`'s calls, fresh enough to use now. */\n token(agent: string): Promise<string>;\n /** Asks on this computer, for an agent that cannot ask the user itself. */\n askHere(question: string): Promise<boolean>;\n}\n\nexport const NO_TURN_MESSAGE =\n \"No turn is active: the user has not asked anything right now. Wait for their next message.\";\n\nexport const DISCONNECTED_MESSAGE =\n \"This computer no longer serves the app: it was disconnected, or Parlor Host stopped.\";\n\nconst OUTSIDE_PREFIX = \"app \";\nconst AGENT_NAMES: Readonly<Record<string, string>> = {\n \"claude-code\": \"Claude Code\",\n \"codex-mcp-client\": \"Codex\",\n codex: \"Codex\",\n};\n\nconst SOCKET_ENV = \"PARLOR_HOST_PROXY_SOCKET\";\nconst NONCE_ENV = \"PARLOR_HOST_PROXY_NONCE\";\nconst NO_TURN_CODE = -32000;\nconst REFUSED_CODE = -32001;\n/** An agent waits for its MCP servers before its first answer; an app that is down must not hold it. */\nconst OUTSIDE_TOKEN_WAIT_MS = 5_000;\n\ntype JsonRpcId = string | number | null;\n\ninterface Message {\n readonly jsonrpc?: unknown;\n readonly id?: JsonRpcId;\n readonly method?: unknown;\n readonly result?: unknown;\n}\n\n/** An app's answer to one handshake request, without its id. */\ntype KnownAnswer = { readonly result: unknown } | { readonly error: unknown };\n\ninterface Live {\n readonly appOrigin: string;\n /** The app's answers to the handshake every session repeats; undefined outside turns' sessions. */\n readonly known: Map<string, KnownAnswer> | undefined;\n token: string | undefined;\n protocolVersion: string | undefined;\n initialized: unknown;\n tools: unknown;\n readonly inflight: Set<AbortController>;\n readonly sockets: Set<Socket>;\n /** Handshake requests answered from `known` before a turn, asked again once one begins. */\n readonly unconfirmed: Map<\n string,\n { readonly line: string; readonly answer: KnownAnswer }\n >;\n}\n\nfunction parse(text: string): Message | undefined {\n try {\n const value: unknown = JSON.parse(text);\n return typeof value === \"object\" && value !== null && !Array.isArray(value)\n ? (value as Message)\n : undefined;\n } catch {\n return undefined;\n }\n}\n\nconst result = (id: JsonRpcId, value: unknown) =>\n JSON.stringify({ jsonrpc: \"2.0\", id, result: value });\n\nconst failure = (id: JsonRpcId, code: number, message: string) =>\n JSON.stringify({ jsonrpc: \"2.0\", id, error: { code, message } });\n\n/**\n * What a new session asks before its first prompt, answered by the app the same way each\n * time for the same parameters. A session gets the last answer at once while the app is\n * asked again behind it; a list that changed is announced to the agent.\n */\nconst HANDSHAKE: ReadonlySet<string> = new Set([\n \"server/discover\",\n \"initialize\",\n \"tools/list\",\n \"resources/list\",\n \"resources/templates/list\",\n \"prompts/list\",\n]);\nconst LIST_CHANGED: Readonly<Record<string, string>> = {\n \"tools/list\": \"notifications/tools/list_changed\",\n \"resources/list\": \"notifications/resources/list_changed\",\n \"prompts/list\": \"notifications/prompts/list_changed\",\n};\n/** Statuses the same request gets again: never a credential, rate or server failure. */\nconst STABLE_REFUSALS: ReadonlySet<number> = new Set([400, 404, 405]);\n\nconst handshakeKey = (message: Message) =>\n typeof message.method === \"string\" && HANDSHAKE.has(message.method)\n ? `${message.method} ${JSON.stringify((message as { readonly params?: unknown }).params ?? null)}`\n : undefined;\n\nfunction knownAnswer(answer: Message | undefined): KnownAnswer | undefined {\n if (answer === undefined) return undefined;\n if (answer.result !== undefined) return { result: answer.result };\n const { error } = answer as { readonly error?: unknown };\n return error === undefined ? undefined : { error };\n}\n\n/** What the session learns from an `initialize` or `tools/list` answer, wherever it came from. */\nfunction learn(live: Live, method: string, answer: KnownAnswer): void {\n if (!(\"result\" in answer)) return;\n if (method === \"initialize\") {\n live.initialized = answer.result;\n const version = (answer.result as { readonly protocolVersion?: unknown } | undefined)\n ?.protocolVersion;\n if (typeof version === \"string\") live.protocolVersion = version;\n }\n if (method === \"tools/list\") live.tools = answer.result;\n}\n\n/** One line per message on the agent's stdio: only a body with a raw newline is compacted. */\nconst asLine = (text: string) =>\n text.includes(\"\\n\") ? JSON.stringify(JSON.parse(text)) : text;\n\n/**\n * What the app last said to this handshake request, or to the same method asked otherwise:\n * an agent's later sessions ask `initialize` with other parameters than its first did.\n */\nfunction answerBeforeTurn(live: Live, message: Message): KnownAnswer | undefined {\n const key = handshakeKey(message);\n if (key === undefined || !live.known) return undefined;\n const exact = live.known.get(key);\n if (exact) return exact;\n const method = `${message.method as string} `;\n let latest: KnownAnswer | undefined;\n for (const [known, answer] of live.known) if (known.startsWith(method)) latest = answer;\n return latest;\n}\n\nfunction betweenTurns(\n live: Live,\n message: Message,\n known: KnownAnswer | undefined,\n): string | undefined {\n if (message.id === undefined || typeof message.method !== \"string\") return undefined;\n const { id } = message;\n if (known) {\n learn(live, message.method, known);\n return JSON.stringify({ jsonrpc: \"2.0\", id, ...known });\n }\n switch (message.method) {\n case \"ping\":\n return result(id, {});\n case \"initialize\":\n return live.initialized === undefined\n ? failure(id, NO_TURN_CODE, NO_TURN_MESSAGE)\n : result(id, live.initialized);\n case \"tools/list\":\n return live.tools === undefined\n ? failure(id, NO_TURN_CODE, NO_TURN_MESSAGE)\n : result(id, live.tools);\n case \"tools/call\":\n return result(id, {\n content: [{ type: \"text\", text: NO_TURN_MESSAGE }],\n isError: true,\n });\n default:\n return failure(id, NO_TURN_CODE, NO_TURN_MESSAGE);\n }\n}\n\nasync function* serverSentData(body: ReadableStream<Uint8Array>): AsyncGenerator<string> {\n const decoder = new TextDecoder();\n let buffer = \"\";\n let data: string[] = [];\n for await (const chunk of body) {\n buffer += decoder.decode(chunk, { stream: true });\n let end = buffer.indexOf(\"\\n\");\n while (end !== -1) {\n const line = buffer.slice(0, end).replace(/\\r$/, \"\");\n buffer = buffer.slice(end + 1);\n if (line === \"\") {\n if (data.length > 0) yield data.join(\"\\n\");\n data = [];\n } else if (line.startsWith(\"data:\")) {\n data.push(line.slice(line.startsWith(\"data: \") ? 6 : 5));\n }\n end = buffer.indexOf(\"\\n\");\n }\n }\n if (data.length > 0) yield data.join(\"\\n\");\n}\n\nfunction refusal(status: number): string {\n return status === 401\n ? \"This computer can no longer act for the app: the turn ended or the computer was disconnected.\"\n : `The app answered HTTP ${status}.`;\n}\n\n/** Sends one message to the app; resolves with its status and what the request was answered. */\nasync function forward(\n live: Live,\n token: string,\n line: string,\n message: Message,\n reply: (line: string) => void,\n): Promise<{ readonly status: number; readonly answer: Message | undefined }> {\n const method = typeof message.method === \"string\" ? message.method : \"response\";\n const controller = new AbortController();\n live.inflight.add(controller);\n let status = 0;\n let given: Message | undefined;\n try {\n const response = await fetch(`${live.appOrigin}/_parlor/mcp`, {\n method: \"POST\",\n headers: {\n authorization: `Bearer ${token}`,\n accept: \"application/json, text/event-stream\",\n \"content-type\": \"application/json\",\n ...(live.protocolVersion ? { \"mcp-protocol-version\": live.protocolVersion } : {}),\n },\n body: line,\n signal: controller.signal,\n });\n status = response.status;\n const bodies: string[] = [];\n if ((response.headers.get(\"content-type\") ?? \"\").includes(\"text/event-stream\")) {\n if (response.body)\n for await (const data of serverSentData(response.body)) bodies.push(data);\n } else {\n const text = await response.text();\n if (text.trim() !== \"\") bodies.push(text);\n }\n let answered = false;\n for (const text of bodies) {\n const answer = parse(text);\n if (answer?.jsonrpc !== \"2.0\") continue;\n if (answer.id === message.id) {\n answered = true;\n given = answer;\n const known = knownAnswer(answer);\n if (known) learn(live, method, known);\n }\n reply(asLine(text));\n }\n if (message.id !== undefined && !answered) {\n const refused = failure(message.id, REFUSED_CODE, refusal(status));\n given = parse(refused);\n reply(refused);\n }\n } catch (error) {\n status = 0;\n if (message.id !== undefined) {\n reply(\n controller.signal.aborted\n ? failure(message.id, NO_TURN_CODE, NO_TURN_MESSAGE)\n : failure(\n message.id,\n REFUSED_CODE,\n `The app could not be reached: ${String(error)}`,\n ),\n );\n }\n } finally {\n live.inflight.delete(controller);\n logEvent(\"proxy_forward\", { appOrigin: live.appOrigin, rpcMethod: method, status });\n }\n return { status, answer: given };\n}\n\n/** Keeps the app's answer to a handshake request when the same request gets it again. */\nfunction remember(\n live: Live,\n key: string,\n outcome: { readonly status: number; readonly answer: Message | undefined },\n): KnownAnswer | undefined {\n const { status } = outcome;\n const stable = (status >= 200 && status < 300) || STABLE_REFUSALS.has(status);\n const known = stable ? knownAnswer(outcome.answer) : undefined;\n // A refused initialize would leave every later session without the app's tools.\n if (!known || (key.startsWith(\"initialize \") && !(\"result\" in known))) return undefined;\n live.known?.set(key, known);\n return known;\n}\n\n/** Answers a handshake request from what the app said last, then asks the app again. */\nfunction replay(\n live: Live,\n token: string,\n line: string,\n message: Message,\n key: string,\n known: KnownAnswer,\n reply: (line: string) => void,\n): void {\n learn(live, message.method as string, known);\n reply(JSON.stringify({ jsonrpc: \"2.0\", id: message.id, ...known }));\n confirm(live, token, line, message, key, known);\n}\n\n/** Asks the app what a known answer said, and tells the agent when a list changed since. */\nfunction confirm(\n live: Live,\n token: string,\n line: string,\n message: Message,\n key: string,\n known: KnownAnswer,\n): void {\n const method = message.method as string;\n void forward(live, token, line, message, () => undefined).then((outcome) => {\n const fresh = remember(live, key, outcome);\n const changed = LIST_CHANGED[method];\n if (!changed || !fresh || JSON.stringify(fresh) === JSON.stringify(known)) return;\n const notice = JSON.stringify({ jsonrpc: \"2.0\", method: changed });\n for (const socket of live.sockets) if (!socket.destroyed) socket.write(`${notice}\\n`);\n });\n}\n\nfunction handle(live: Live, line: string, reply: (line: string) => void): void {\n const message = parse(line);\n if (!message) return;\n const token = live.token;\n if (token === undefined) {\n const known = message.id === undefined ? undefined : answerBeforeTurn(live, message);\n const answer = betweenTurns(live, message, known);\n if (answer) reply(answer);\n const key = handshakeKey(message);\n if (known && key !== undefined) live.unconfirmed.set(key, { line, answer: known });\n return;\n }\n const key = message.id === undefined ? undefined : handshakeKey(message);\n if (key === undefined) {\n void forward(live, token, line, message, reply);\n return;\n }\n const known = live.known?.get(key);\n if (known) {\n replay(live, token, line, message, key, known, reply);\n return;\n }\n void forward(live, token, line, message, reply).then((outcome) =>\n remember(live, key, outcome),\n );\n}\n\n/**\n * One agent outside a turn, on one socket. Reads run as asked; the first change in the\n * conversation waits for the user, through the agent's own elicitation where it has it.\n */\nfunction outsideSession(\n app: OutsideApp,\n socket: Socket,\n reply: (line: string) => void,\n tokenWaitMs: number,\n): (line: string) => void {\n const live: Live = {\n appOrigin: app.appOrigin.replace(/\\/+$/, \"\"),\n known: undefined,\n token: undefined,\n protocolVersion: undefined,\n initialized: undefined,\n tools: undefined,\n inflight: new Set(),\n sockets: new Set([socket]),\n unconfirmed: new Map(),\n };\n let agent = \"A coding agent\";\n let elicits = false;\n let changesAllowed: Promise<boolean> | undefined;\n let asked = 0;\n const answers = new Map<string, (allowed: boolean) => void>();\n\n const send = async (line: string, message: Message, onReply = reply) => {\n let token: string;\n try {\n token = await answeredWithin(app.token(agent), tokenWaitMs);\n } catch (error) {\n if (message.id !== undefined) {\n onReply(\n failure(\n message.id,\n REFUSED_CODE,\n error instanceof AppNotAnswering\n ? notAnsweringMessage(app)\n : `${app.appName} refused: ${String(error)}`,\n ),\n );\n }\n return;\n }\n await forward(live, token, line, message, onReply);\n };\n\n const readOnly = async (tool: string): Promise<boolean> => {\n if (live.tools === undefined) {\n const id = `parlor-tools-${++asked}`;\n const list = { jsonrpc: \"2.0\", id, method: \"tools/list\", params: {} };\n await send(JSON.stringify(list), list, () => undefined);\n }\n const tools = (live.tools as { readonly tools?: readonly ToolEntry[] } | undefined)\n ?.tools;\n return (\n tools?.find((entry) => entry.name === tool)?.annotations?.readOnlyHint === true\n );\n };\n\n const askToChange = (): Promise<boolean> => {\n const question = `${agent} wants to change ${app.appName} (${app.appOrigin}) as ${app.account}. Allow changes from this conversation?`;\n if (!elicits) return app.askHere(question);\n const id = `parlor-allow-${++asked}`;\n const answered = new Promise<boolean>((resolve) => answers.set(id, resolve));\n reply(\n JSON.stringify({\n jsonrpc: \"2.0\",\n id,\n method: \"elicitation/create\",\n params: {\n message: question,\n requestedSchema: { type: \"object\", properties: {} },\n },\n }),\n );\n return answered;\n };\n\n return (line) => {\n const message = parse(line);\n if (!message) return;\n if (message.method === undefined && typeof message.id === \"string\") {\n const answer = answers.get(message.id);\n if (answer) {\n answers.delete(message.id);\n const action = (message.result as { readonly action?: unknown } | undefined)\n ?.action;\n answer(action === \"accept\");\n return;\n }\n }\n if (message.method === \"initialize\") {\n const params = (message as { readonly params?: InitializeParams }).params;\n const client = params?.clientInfo?.name;\n if (typeof client === \"string\" && client !== \"\")\n agent = AGENT_NAMES[client] ?? client;\n elicits = params?.capabilities?.elicitation !== undefined;\n logEvent(\"outside_agent\", { appOrigin: app.appOrigin, agent, elicits });\n void send(line, message, (answer) => reply(withGuidance(answer, app, agent)));\n return;\n }\n if (message.method === \"tools/call\" && message.id !== undefined) {\n const tool = (message as { readonly params?: { readonly name?: unknown } }).params\n ?.name;\n void (async () => {\n if (typeof tool === \"string\" && !(await readOnly(tool))) {\n changesAllowed ??= askToChange().then((allowed) => {\n if (!allowed) changesAllowed = undefined;\n return allowed;\n });\n if (!(await changesAllowed)) {\n reply(\n result(message.id!, {\n content: [\n {\n type: \"text\",\n text: `Nothing was changed: the user did not allow changes to ${app.appName} from this conversation, or could not be asked here. Tell them so. If they ask for the change again, they are asked again first; nothing in ${app.appName} itself turns this on.`,\n },\n ],\n isError: true,\n }),\n );\n return;\n }\n }\n await send(line, message);\n })();\n return;\n }\n void send(line, message);\n };\n}\n\n/** `OutsideApp.token` throws it while the app does not answer this computer at all. */\nexport class AppNotAnswering extends Error {\n override readonly name = \"AppNotAnswering\";\n}\n\nfunction answeredWithin<T>(pending: Promise<T>, ms: number): Promise<T> {\n let timer: ReturnType<typeof setTimeout> | undefined;\n const late = new Promise<never>((_, reject) => {\n timer = setTimeout(() => reject(new AppNotAnswering()), ms);\n timer.unref?.();\n });\n return Promise.race([pending, late]).finally(() => clearTimeout(timer));\n}\n\nconst notAnsweringMessage = (app: OutsideApp) =>\n `${app.appName} (${app.appOrigin}) is not answering, so its tools are unavailable in this conversation. Start it, or stop its tools with \\`parlor-host tools --off ${app.appOrigin}\\`.`;\n\ninterface ToolEntry {\n readonly name?: string;\n readonly annotations?: { readonly readOnlyHint?: boolean };\n}\n\ninterface InitializeParams {\n readonly clientInfo?: { readonly name?: unknown };\n readonly capabilities?: { readonly elicitation?: unknown };\n}\n\n/** The app's own instructions, led by when to use it at all: only when the user names it. */\nfunction withGuidance(line: string, app: OutsideApp, agent: string): string {\n const answer = parse(line);\n const initialized = answer?.result as { readonly instructions?: unknown } | undefined;\n if (!initialized || typeof initialized !== \"object\") return line;\n const guidance = `Use these tools only when the user names ${app.appName} or \"${app.name}\" in their request: they act on the live app at ${app.appOrigin} as ${app.account}, and ${agent} runs outside the app here. When the user does, use them rather than opening ${app.appName} in a browser: they read and change the same data directly. If your tools load on demand, search them for \"${app.name}\" first. Reading is free; before the first change in this conversation the user is asked to allow changes.`;\n const own =\n typeof initialized.instructions === \"string\" ? initialized.instructions : \"\";\n return JSON.stringify({\n ...answer,\n result: { ...initialized, instructions: own ? `${guidance}\\n\\n${own}` : guidance },\n });\n}\n\nexport interface McpProxyOptions {\n /** How long an agent outside a turn waits for its app's token before it is told the app is down. */\n readonly tokenWaitMs?: number | undefined;\n}\n\nexport function createMcpProxy(\n hostBinary: string,\n options: McpProxyOptions = {},\n): McpProxy {\n const tokenWaitMs = options.tokenWaitMs ?? OUTSIDE_TOKEN_WAIT_MS;\n const sessions = new Map<string, Live>();\n const handshakes = new Map<string, Map<string, KnownAnswer>>();\n let server: Server | undefined;\n let socketPath: string | undefined;\n let outside: (appOrigin: string) => OutsideApp | undefined = () => undefined;\n\n const accept = (socket: Socket) => {\n let live: Live | undefined;\n let outsideLine: ((line: string) => void) | undefined;\n const reply = (line: string) => {\n if (!socket.destroyed) socket.write(`${line}\\n`);\n };\n onLines(socket, (line) => {\n if (outsideLine !== undefined) {\n outsideLine(line);\n return;\n }\n if (live !== undefined) {\n handle(live, line, reply);\n return;\n }\n const first = line.trim();\n if (first.startsWith(OUTSIDE_PREFIX)) {\n const appOrigin = first.slice(OUTSIDE_PREFIX.length);\n const app = outside(appOrigin);\n if (!app) {\n reply(JSON.stringify({ refused: notServedMessage(appOrigin) }));\n socket.end();\n return;\n }\n outsideLine = outsideSession(app, socket, reply, tokenWaitMs);\n return;\n }\n live = sessions.get(first);\n if (live) live.sockets.add(socket);\n else socket.destroy();\n });\n socket.on(\"close\", () => live?.sockets.delete(socket));\n socket.on(\"error\", () => socket.destroy());\n };\n\n return {\n async listen(path) {\n await mkdir(dirname(path), { recursive: true, mode: 0o700 });\n await rm(path, { force: true });\n const listening = createServer(accept);\n await new Promise<void>((resolve, reject) => {\n listening.once(\"error\", reject);\n listening.listen(path, () => resolve());\n });\n await chmod(path, 0o600);\n server = listening;\n socketPath = path;\n },\n serveOutside(resolve) {\n outside = resolve;\n },\n knowsHandshake(appOrigin) {\n const keys = [...(handshakes.get(appOrigin.replace(/\\/+$/, \"\"))?.keys() ?? [])];\n return [\"initialize \", \"tools/list \"].every((method) =>\n keys.some((key) => key.startsWith(method)),\n );\n },\n open(appServer, appOrigin) {\n if (socketPath === undefined)\n throw new Error(\"The MCP proxy is not listening yet.\");\n const nonce = randomBytes(24).toString(\"base64url\");\n const origin = appOrigin.replace(/\\/+$/, \"\");\n let known = handshakes.get(origin);\n if (!known) {\n known = new Map();\n handshakes.set(origin, known);\n }\n const live: Live = {\n appOrigin: origin,\n known,\n token: undefined,\n protocolVersion: undefined,\n initialized: undefined,\n tools: undefined,\n inflight: new Set(),\n sockets: new Set(),\n unconfirmed: new Map(),\n };\n sessions.set(nonce, live);\n const end = () => {\n live.token = undefined;\n for (const controller of live.inflight) controller.abort();\n };\n return {\n nonce,\n server: {\n name: appServer,\n command: hostBinary,\n args: [\"mcp-proxy\"],\n env: { [SOCKET_ENV]: socketPath, [NONCE_ENV]: nonce },\n },\n begin: (token) => {\n live.token = token.token;\n for (const [key, { line, answer }] of live.unconfirmed) {\n const message = parse(line);\n if (message) confirm(live, token.token, line, message, key, answer);\n }\n live.unconfirmed.clear();\n },\n renew: (token) => {\n if (live.token !== undefined) live.token = token.token;\n },\n end,\n dispose: () => {\n end();\n sessions.delete(nonce);\n for (const socket of live.sockets) socket.destroy();\n },\n };\n },\n async stopListening() {\n const closing = server;\n server = undefined;\n if (!closing) return;\n closing.close();\n if (socketPath) await rm(socketPath, { force: true });\n },\n async close() {\n for (const live of sessions.values()) {\n for (const controller of live.inflight) controller.abort();\n for (const socket of live.sockets) socket.destroy();\n }\n sessions.clear();\n const closing = server;\n server = undefined;\n if (closing) {\n await new Promise<void>((resolve) => closing.close(() => resolve()));\n if (socketPath) await rm(socketPath, { force: true });\n }\n },\n };\n}\n\n/** Why an agent outside a turn cannot use `appOrigin` here. */\nfunction notServedMessage(appOrigin: string): string {\n return `This computer does not let coding agents use ${appOrigin}: it is not connected, or that was turned off. Connect it again with \\`npx @parlor/agent-host connect ${appOrigin}\\`.`;\n}\n\nconst notRunningMessage = (appOrigin: string) =>\n `Parlor Host is not running on this computer, so ${appOrigin} cannot be reached. Open the app's agent sidebar, or run \\`npx @parlor/agent-host connect ${appOrigin}\\`.`;\n\n/**\n * `parlor-host mcp-proxy`: stdio to the daemon socket and back. Inside a turn the\n * environment names the session; `--app` serves an agent outside any turn. Once the daemon\n * hangs up, every request still unanswered, and every later one, is answered with an error\n * here.\n */\nexport async function runMcpProxyProcess(\n env: NodeJS.ProcessEnv,\n outside?: { readonly appOrigin: string; readonly socketPath: string },\n): Promise<void> {\n const path = outside?.socketPath ?? env[SOCKET_ENV];\n const nonce = env[NONCE_ENV];\n if (!path || (!outside && !nonce)) {\n throw new Error(`${SOCKET_ENV} and ${NONCE_ENV} must be set, or --app.`);\n }\n let why = outside ? notRunningMessage(outside.appOrigin) : DISCONNECTED_MESSAGE;\n const unanswered = new Set<JsonRpcId>();\n const toAgent = (line: string) => void process.stdout.write(`${line}\\n`);\n const refuse = (id: JsonRpcId) => toAgent(failure(id, REFUSED_CODE, why));\n process.stdout.on(\"error\", () => undefined);\n\n const daemon = connect(path);\n daemon.on(\"error\", () => daemon.destroy());\n daemon.once(\"connect\", () => {\n if (outside) why = DISCONNECTED_MESSAGE;\n });\n const hungUp = new Promise<void>((resolve) =>\n daemon.once(\"close\", () => {\n for (const id of unanswered) refuse(id);\n unanswered.clear();\n resolve();\n }),\n );\n daemon.write(outside ? `${OUTSIDE_PREFIX}${outside.appOrigin}\\n` : `${nonce}\\n`);\n onLines(daemon, (line) => {\n const refused = (parse(line) as { readonly refused?: unknown } | undefined)?.refused;\n if (typeof refused === \"string\") {\n why = refused;\n return;\n }\n const message = parse(line);\n if (message?.id !== undefined && message.method === undefined) {\n unanswered.delete(message.id);\n }\n toAgent(line);\n });\n\n const agent = onLines(process.stdin, (line) => {\n const message = parse(line);\n const id = typeof message?.method === \"string\" ? message.id : undefined;\n if (!daemon.destroyed) {\n if (id !== undefined) unanswered.add(id);\n daemon.write(`${line}\\n`);\n } else if (id !== undefined) {\n refuse(id);\n }\n });\n await once(agent, \"close\");\n daemon.end();\n await hungUp;\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@parlor/agent-host",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.7",
|
|
4
4
|
"homepage": "https://cychien.github.io/parlor",
|
|
5
5
|
"bugs": "https://github.com/cychien/parlor/issues",
|
|
6
6
|
"license": "MIT",
|
|
@@ -31,13 +31,13 @@
|
|
|
31
31
|
"@agentclientprotocol/sdk": "^1.9.0",
|
|
32
32
|
"citty": "^0.2.2",
|
|
33
33
|
"tsx": "^4.23.15",
|
|
34
|
-
"@parlor/
|
|
35
|
-
"@parlor/capabilities": "0.4.
|
|
36
|
-
"@parlor/
|
|
37
|
-
"@parlor/
|
|
38
|
-
"@parlor/core": "0.4.
|
|
39
|
-
"@parlor/server": "0.4.
|
|
40
|
-
"@parlor/sync": "0.4.
|
|
34
|
+
"@parlor/chat": "0.4.7",
|
|
35
|
+
"@parlor/capabilities": "0.4.7",
|
|
36
|
+
"@parlor/auth": "0.4.7",
|
|
37
|
+
"@parlor/client": "0.4.7",
|
|
38
|
+
"@parlor/core": "0.4.7",
|
|
39
|
+
"@parlor/server": "0.4.7",
|
|
40
|
+
"@parlor/sync": "0.4.7"
|
|
41
41
|
},
|
|
42
42
|
"devDependencies": {
|
|
43
43
|
"@agentclientprotocol/claude-agent-acp": "0.93.0",
|
|
@@ -50,7 +50,7 @@
|
|
|
50
50
|
"typescript": "^7.0.2",
|
|
51
51
|
"vitest": "^5.0.3",
|
|
52
52
|
"zod": "^4.6.5",
|
|
53
|
-
"@parlor/data": "0.4.
|
|
53
|
+
"@parlor/data": "0.4.7"
|
|
54
54
|
},
|
|
55
55
|
"scripts": {
|
|
56
56
|
"build": "tsc -p tsconfig.json",
|