@zooid/context-mcp 0.13.0 → 0.14.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bin.js +44 -4
- package/dist/bin.js.map +1 -1
- package/dist/{chunk-L5USYHTS.js → chunk-IZ2JCKE4.js} +168 -14
- package/dist/chunk-IZ2JCKE4.js.map +1 -0
- package/dist/index.js +34 -1
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
- package/src/bin.ts +63 -9
- package/src/daemon-socket.test.ts +152 -19
- package/src/daemon-socket.ts +124 -12
- package/src/factory.test.ts +10 -0
- package/src/index.ts +3 -2
- package/src/integration.test.ts +99 -15
- package/src/mcp-server.test.ts +225 -21
- package/src/mcp-server.ts +87 -7
- package/src/socket-paths.test.ts +25 -0
- package/src/socket-paths.ts +29 -0
- package/src/spawn-registry.test.ts +14 -1
- package/src/spawn-registry.ts +29 -1
- package/src/types.ts +2 -0
- package/dist/chunk-L5USYHTS.js.map +0 -1
package/dist/bin.js
CHANGED
|
@@ -3,7 +3,7 @@ import {
|
|
|
3
3
|
JSONRPCMessageSchema,
|
|
4
4
|
buildContextMcpServer,
|
|
5
5
|
callDaemon
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-IZ2JCKE4.js";
|
|
7
7
|
|
|
8
8
|
// ../../node_modules/.pnpm/@modelcontextprotocol+sdk@1.29.0_zod@3.25.76/node_modules/@modelcontextprotocol/sdk/dist/esm/server/stdio.js
|
|
9
9
|
import process2 from "process";
|
|
@@ -125,10 +125,50 @@ var remoteProvider = {
|
|
|
125
125
|
method: "getThreadHistory",
|
|
126
126
|
params: { ...opts ?? {}, threadId }
|
|
127
127
|
}),
|
|
128
|
-
getChannelMembers: () => callDaemon(sockPath, {
|
|
129
|
-
|
|
128
|
+
getChannelMembers: () => callDaemon(sockPath, {
|
|
129
|
+
spawnId,
|
|
130
|
+
method: "getChannelMembers",
|
|
131
|
+
params: {}
|
|
132
|
+
}),
|
|
133
|
+
getRoomInfo: () => callDaemon(sockPath, {
|
|
134
|
+
spawnId,
|
|
135
|
+
method: "getRoomInfo",
|
|
136
|
+
params: {}
|
|
137
|
+
}),
|
|
138
|
+
getRooms: () => callDaemon(sockPath, {
|
|
139
|
+
spawnId,
|
|
140
|
+
method: "getRooms",
|
|
141
|
+
params: {}
|
|
142
|
+
}),
|
|
143
|
+
sendMessage: (input) => callDaemon(sockPath, {
|
|
144
|
+
spawnId,
|
|
145
|
+
method: "sendMessage",
|
|
146
|
+
params: input
|
|
147
|
+
})
|
|
148
|
+
};
|
|
149
|
+
var remoteTasks = {
|
|
150
|
+
startTasks: (_caller, input) => callDaemon(sockPath, {
|
|
151
|
+
spawnId,
|
|
152
|
+
method: "startTasks",
|
|
153
|
+
params: input
|
|
154
|
+
}),
|
|
155
|
+
completeTask: (_caller, input) => callDaemon(sockPath, {
|
|
156
|
+
spawnId,
|
|
157
|
+
method: "completeTask",
|
|
158
|
+
params: input
|
|
159
|
+
}),
|
|
160
|
+
describeRole: () => callDaemon(sockPath, {
|
|
161
|
+
spawnId,
|
|
162
|
+
method: "describeRole",
|
|
163
|
+
params: {}
|
|
164
|
+
})
|
|
130
165
|
};
|
|
131
|
-
var
|
|
166
|
+
var role = await callDaemon(sockPath, { spawnId, method: "describeRole", params: {} }).then((r) => r).catch(() => void 0);
|
|
167
|
+
var server = buildContextMcpServer({
|
|
168
|
+
resolve: async () => remoteProvider,
|
|
169
|
+
resolveTasks: async () => remoteTasks,
|
|
170
|
+
role
|
|
171
|
+
});
|
|
132
172
|
await server.connect(new StdioServerTransport());
|
|
133
173
|
process.stderr.write(`zooid-context-mcp: ready (spawnId=${spawnId})
|
|
134
174
|
`);
|
package/dist/bin.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../node_modules/.pnpm/@modelcontextprotocol+sdk@1.29.0_zod@3.25.76/node_modules/@modelcontextprotocol/sdk/src/server/stdio.ts","../../../node_modules/.pnpm/@modelcontextprotocol+sdk@1.29.0_zod@3.25.76/node_modules/@modelcontextprotocol/sdk/src/shared/stdio.ts","../src/bin.ts"],"sourcesContent":[null,null,"#!/usr/bin/env node\nimport { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'\nimport { buildContextMcpServer } from './mcp-server.js'\nimport { callDaemon } from './daemon-socket.js'\nimport type {
|
|
1
|
+
{"version":3,"sources":["../../../node_modules/.pnpm/@modelcontextprotocol+sdk@1.29.0_zod@3.25.76/node_modules/@modelcontextprotocol/sdk/src/server/stdio.ts","../../../node_modules/.pnpm/@modelcontextprotocol+sdk@1.29.0_zod@3.25.76/node_modules/@modelcontextprotocol/sdk/src/shared/stdio.ts","../src/bin.ts"],"sourcesContent":[null,null,"#!/usr/bin/env node\nimport { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'\nimport { buildContextMcpServer } from './mcp-server.js'\nimport { callDaemon } from './daemon-socket.js'\nimport type {\n StartTasksOutput,\n CompleteTaskOutput,\n TaskActions,\n TaskRole,\n TransportContextProvider,\n} from '@zooid/core'\n\nconst spawnIdIdx = process.argv.indexOf('--spawn-id')\nconst spawnId = spawnIdIdx >= 0 ? process.argv[spawnIdIdx + 1] : undefined\nconst sockPath = process.env.ZOOID_DAEMON_SOCK\nif (!spawnId || !sockPath) {\n process.stderr.write('zooid-context-mcp: --spawn-id and ZOOID_DAEMON_SOCK are required\\n')\n process.exit(2)\n}\nprocess.stderr.write(\n `zooid-context-mcp: starting (pid=${process.pid} spawnId=${spawnId} sock=${sockPath})\\n`,\n)\n\nconst remoteProvider: TransportContextProvider = {\n getRoomHistory: (_channelId, opts) =>\n callDaemon(sockPath, {\n spawnId,\n method: 'getRoomHistory',\n params: (opts ?? {}) as Record<string, unknown>,\n }) as Promise<Awaited<ReturnType<TransportContextProvider['getRoomHistory']>>>,\n getRecentThreads: (_channelId, opts) =>\n callDaemon(sockPath, {\n spawnId,\n method: 'getRecentThreads',\n params: (opts ?? {}) as Record<string, unknown>,\n }) as Promise<Awaited<ReturnType<TransportContextProvider['getRecentThreads']>>>,\n getThreadHistory: (_channelId, threadId, opts) =>\n callDaemon(sockPath, {\n spawnId,\n method: 'getThreadHistory',\n params: { ...(opts ?? {}), threadId } as Record<string, unknown>,\n }) as Promise<Awaited<ReturnType<TransportContextProvider['getThreadHistory']>>>,\n getChannelMembers: () =>\n callDaemon(sockPath, {\n spawnId,\n method: 'getChannelMembers',\n params: {},\n }) as Promise<Awaited<ReturnType<TransportContextProvider['getChannelMembers']>>>,\n getRoomInfo: () =>\n callDaemon(sockPath, {\n spawnId,\n method: 'getRoomInfo',\n params: {},\n }) as Promise<Awaited<ReturnType<TransportContextProvider['getRoomInfo']>>>,\n getRooms: () =>\n callDaemon(sockPath, {\n spawnId,\n method: 'getRooms',\n params: {},\n }) as Promise<Awaited<ReturnType<TransportContextProvider['getRooms']>>>,\n sendMessage: (input) =>\n callDaemon(sockPath, {\n spawnId,\n method: 'sendMessage',\n params: input as unknown as Record<string, unknown>,\n }) as Promise<Awaited<ReturnType<TransportContextProvider['sendMessage']>>>,\n}\n\nconst remoteTasks: TaskActions = {\n startTasks: (_caller, input) =>\n callDaemon(sockPath, {\n spawnId,\n method: 'startTasks',\n params: input as unknown as Record<string, unknown>,\n }) as Promise<StartTasksOutput>,\n completeTask: (_caller, input) =>\n callDaemon(sockPath, {\n spawnId,\n method: 'completeTask',\n params: input as unknown as Record<string, unknown>,\n }) as Promise<CompleteTaskOutput>,\n describeRole: () =>\n callDaemon(sockPath, {\n spawnId,\n method: 'describeRole',\n params: {},\n }) as Promise<TaskRole>,\n}\n\n// A failed role query yields undefined, which registers neither task tool —\n// the safe direction for MCP: the tools are additive, and a spawn that\n// cannot reach the daemon cannot usefully call them anyway ([[ZOD084]]).\nconst role = await callDaemon(sockPath, { spawnId, method: 'describeRole', params: {} })\n .then((r) => r as TaskRole)\n .catch(() => undefined)\n\nconst server = buildContextMcpServer({\n resolve: async () => remoteProvider,\n resolveTasks: async () => remoteTasks,\n role,\n})\nawait server.connect(new StdioServerTransport())\nprocess.stderr.write(`zooid-context-mcp: ready (spawnId=${spawnId})\\n`)\n"],"mappings":";;;;;;;;AAAA,OAAOA,cAAa;;;ACKd,IAAO,aAAP,MAAiB;EAGnB,OAAO,OAAa;AAChB,SAAK,UAAU,KAAK,UAAU,OAAO,OAAO,CAAC,KAAK,SAAS,KAAK,CAAC,IAAI;EACzE;EAEA,cAAW;AACP,QAAI,CAAC,KAAK,SAAS;AACf,aAAO;IACX;AAEA,UAAM,QAAQ,KAAK,QAAQ,QAAQ,IAAI;AACvC,QAAI,UAAU,IAAI;AACd,aAAO;IACX;AAEA,UAAM,OAAO,KAAK,QAAQ,SAAS,QAAQ,GAAG,KAAK,EAAE,QAAQ,OAAO,EAAE;AACtE,SAAK,UAAU,KAAK,QAAQ,SAAS,QAAQ,CAAC;AAC9C,WAAO,mBAAmB,IAAI;EAClC;EAEA,QAAK;AACD,SAAK,UAAU;EACnB;;AAGE,SAAU,mBAAmB,MAAY;AAC3C,SAAO,qBAAqB,MAAM,KAAK,MAAM,IAAI,CAAC;AACtD;AAEM,SAAU,iBAAiB,SAAuB;AACpD,SAAO,KAAK,UAAU,OAAO,IAAI;AACrC;;;AD3BM,IAAO,uBAAP,MAA2B;EAI7B,YACY,SAAmBC,SAAQ,OAC3B,UAAoBA,SAAQ,QAAM;AADlC,SAAA,SAAA;AACA,SAAA,UAAA;AALJ,SAAA,cAA0B,IAAI,WAAU;AACxC,SAAA,WAAW;AAYnB,SAAA,UAAU,CAAC,UAAiB;AACxB,WAAK,YAAY,OAAO,KAAK;AAC7B,WAAK,kBAAiB;IAC1B;AACA,SAAA,WAAW,CAAC,UAAgB;AACxB,WAAK,UAAU,KAAK;IACxB;EAbG;;;;EAkBH,MAAM,QAAK;AACP,QAAI,KAAK,UAAU;AACf,YAAM,IAAI,MACN,+GAA+G;IAEvH;AAEA,SAAK,WAAW;AAChB,SAAK,OAAO,GAAG,QAAQ,KAAK,OAAO;AACnC,SAAK,OAAO,GAAG,SAAS,KAAK,QAAQ;EACzC;EAEQ,oBAAiB;AACrB,WAAO,MAAM;AACT,UAAI;AACA,cAAM,UAAU,KAAK,YAAY,YAAW;AAC5C,YAAI,YAAY,MAAM;AAClB;QACJ;AAEA,aAAK,YAAY,OAAO;MAC5B,SAAS,OAAO;AACZ,aAAK,UAAU,KAAc;MACjC;IACJ;EACJ;EAEA,MAAM,QAAK;AAEP,SAAK,OAAO,IAAI,QAAQ,KAAK,OAAO;AACpC,SAAK,OAAO,IAAI,SAAS,KAAK,QAAQ;AAGtC,UAAM,yBAAyB,KAAK,OAAO,cAAc,MAAM;AAC/D,QAAI,2BAA2B,GAAG;AAG9B,WAAK,OAAO,MAAK;IACrB;AAGA,SAAK,YAAY,MAAK;AACtB,SAAK,UAAS;EAClB;EAEA,KAAK,SAAuB;AACxB,WAAO,IAAI,QAAQ,aAAU;AACzB,YAAM,OAAO,iBAAiB,OAAO;AACrC,UAAI,KAAK,QAAQ,MAAM,IAAI,GAAG;AAC1B,gBAAO;MACX,OAAO;AACH,aAAK,QAAQ,KAAK,SAAS,OAAO;MACtC;IACJ,CAAC;EACL;;;;AE9EJ,IAAM,aAAa,QAAQ,KAAK,QAAQ,YAAY;AACpD,IAAM,UAAU,cAAc,IAAI,QAAQ,KAAK,aAAa,CAAC,IAAI;AACjE,IAAM,WAAW,QAAQ,IAAI;AAC7B,IAAI,CAAC,WAAW,CAAC,UAAU;AACzB,UAAQ,OAAO,MAAM,oEAAoE;AACzF,UAAQ,KAAK,CAAC;AAChB;AACA,QAAQ,OAAO;AAAA,EACb,oCAAoC,QAAQ,GAAG,YAAY,OAAO,SAAS,QAAQ;AAAA;AACrF;AAEA,IAAM,iBAA2C;AAAA,EAC/C,gBAAgB,CAAC,YAAY,SAC3B,WAAW,UAAU;AAAA,IACnB;AAAA,IACA,QAAQ;AAAA,IACR,QAAS,QAAQ,CAAC;AAAA,EACpB,CAAC;AAAA,EACH,kBAAkB,CAAC,YAAY,SAC7B,WAAW,UAAU;AAAA,IACnB;AAAA,IACA,QAAQ;AAAA,IACR,QAAS,QAAQ,CAAC;AAAA,EACpB,CAAC;AAAA,EACH,kBAAkB,CAAC,YAAY,UAAU,SACvC,WAAW,UAAU;AAAA,IACnB;AAAA,IACA,QAAQ;AAAA,IACR,QAAQ,EAAE,GAAI,QAAQ,CAAC,GAAI,SAAS;AAAA,EACtC,CAAC;AAAA,EACH,mBAAmB,MACjB,WAAW,UAAU;AAAA,IACnB;AAAA,IACA,QAAQ;AAAA,IACR,QAAQ,CAAC;AAAA,EACX,CAAC;AAAA,EACH,aAAa,MACX,WAAW,UAAU;AAAA,IACnB;AAAA,IACA,QAAQ;AAAA,IACR,QAAQ,CAAC;AAAA,EACX,CAAC;AAAA,EACH,UAAU,MACR,WAAW,UAAU;AAAA,IACnB;AAAA,IACA,QAAQ;AAAA,IACR,QAAQ,CAAC;AAAA,EACX,CAAC;AAAA,EACH,aAAa,CAAC,UACZ,WAAW,UAAU;AAAA,IACnB;AAAA,IACA,QAAQ;AAAA,IACR,QAAQ;AAAA,EACV,CAAC;AACL;AAEA,IAAM,cAA2B;AAAA,EAC/B,YAAY,CAAC,SAAS,UACpB,WAAW,UAAU;AAAA,IACnB;AAAA,IACA,QAAQ;AAAA,IACR,QAAQ;AAAA,EACV,CAAC;AAAA,EACH,cAAc,CAAC,SAAS,UACtB,WAAW,UAAU;AAAA,IACnB;AAAA,IACA,QAAQ;AAAA,IACR,QAAQ;AAAA,EACV,CAAC;AAAA,EACH,cAAc,MACZ,WAAW,UAAU;AAAA,IACnB;AAAA,IACA,QAAQ;AAAA,IACR,QAAQ,CAAC;AAAA,EACX,CAAC;AACL;AAKA,IAAM,OAAO,MAAM,WAAW,UAAU,EAAE,SAAS,QAAQ,gBAAgB,QAAQ,CAAC,EAAE,CAAC,EACpF,KAAK,CAAC,MAAM,CAAa,EACzB,MAAM,MAAM,MAAS;AAExB,IAAM,SAAS,sBAAsB;AAAA,EACnC,SAAS,YAAY;AAAA,EACrB,cAAc,YAAY;AAAA,EAC1B;AACF,CAAC;AACD,MAAM,OAAO,QAAQ,IAAI,qBAAqB,CAAC;AAC/C,QAAQ,OAAO,MAAM,qCAAqC,OAAO;AAAA,CAAK;","names":["process","process"]}
|
|
@@ -21007,6 +21007,12 @@ var EMPTY_COMPLETION_RESULT = {
|
|
|
21007
21007
|
// src/mcp-server.ts
|
|
21008
21008
|
var MAX_LIMIT = 200;
|
|
21009
21009
|
var DEFAULT_LIMIT = 50;
|
|
21010
|
+
var CALLER_FROM_BINDING = {
|
|
21011
|
+
agentName: "",
|
|
21012
|
+
channelId: "",
|
|
21013
|
+
threadRoot: "",
|
|
21014
|
+
sessionKey: ""
|
|
21015
|
+
};
|
|
21010
21016
|
function buildContextMcpServer(opts) {
|
|
21011
21017
|
const server = new McpServer({ name: "zooid-context", version: "0.0.1" });
|
|
21012
21018
|
server.tool(
|
|
@@ -21019,10 +21025,45 @@ function buildContextMcpServer(opts) {
|
|
|
21019
21025
|
async ({ limit, before }) => {
|
|
21020
21026
|
const provider = await opts.resolve();
|
|
21021
21027
|
const clamped = Math.min(limit ?? DEFAULT_LIMIT, MAX_LIMIT);
|
|
21022
|
-
const page = await provider.getRoomHistory("", {
|
|
21028
|
+
const page = await provider.getRoomHistory("", {
|
|
21029
|
+
limit: clamped,
|
|
21030
|
+
before
|
|
21031
|
+
});
|
|
21023
21032
|
return { content: [{ type: "text", text: JSON.stringify(page) }] };
|
|
21024
21033
|
}
|
|
21025
21034
|
);
|
|
21035
|
+
if (opts.resolveTasks && opts.role?.can_start_task_threads) {
|
|
21036
|
+
server.tool(
|
|
21037
|
+
"zooid_start_task_threads",
|
|
21038
|
+
"Assign concurrent work to other agents in this room. Each task opens a separate thread. The return payload states how the result comes back \u2014 read `delivery` before deciding what to do next.",
|
|
21039
|
+
{
|
|
21040
|
+
tasks: external_exports.array(external_exports.object({ agent: external_exports.string(), prompt: external_exports.string() })).min(1),
|
|
21041
|
+
notify: external_exports.enum(["caller", "none"]).optional()
|
|
21042
|
+
},
|
|
21043
|
+
async ({ tasks, notify }) => {
|
|
21044
|
+
const out = await opts.resolveTasks().then(
|
|
21045
|
+
(actions) => actions.startTasks(CALLER_FROM_BINDING, {
|
|
21046
|
+
tasks,
|
|
21047
|
+
notify: notify ?? "caller"
|
|
21048
|
+
})
|
|
21049
|
+
);
|
|
21050
|
+
return { content: [{ type: "text", text: JSON.stringify(out) }] };
|
|
21051
|
+
}
|
|
21052
|
+
);
|
|
21053
|
+
}
|
|
21054
|
+
if (opts.resolveTasks && opts.role?.is_task_assignee) {
|
|
21055
|
+
server.tool(
|
|
21056
|
+
"zooid_complete_task",
|
|
21057
|
+
"Record an explicit result for the delegated task you were assigned.",
|
|
21058
|
+
{ summary: external_exports.string().min(1) },
|
|
21059
|
+
async ({ summary }) => {
|
|
21060
|
+
const out = await opts.resolveTasks().then(
|
|
21061
|
+
(actions) => actions.completeTask(CALLER_FROM_BINDING, { summary })
|
|
21062
|
+
);
|
|
21063
|
+
return { content: [{ type: "text", text: JSON.stringify(out) }] };
|
|
21064
|
+
}
|
|
21065
|
+
);
|
|
21066
|
+
}
|
|
21026
21067
|
server.tool(
|
|
21027
21068
|
"zooid_get_recent_threads",
|
|
21028
21069
|
"Scan-the-room overview: top-level messages and thread roots in the current room, newest first. Each entry has `reply_count` and `last_activity_at` so the agent can spot active conversations. Drill into a thread with `zooid_get_thread_history(thread_id)` where `thread_id` is the entry's `id`.",
|
|
@@ -21033,7 +21074,10 @@ function buildContextMcpServer(opts) {
|
|
|
21033
21074
|
async ({ limit, before }) => {
|
|
21034
21075
|
const provider = await opts.resolve();
|
|
21035
21076
|
const clamped = Math.min(limit ?? DEFAULT_LIMIT, MAX_LIMIT);
|
|
21036
|
-
const page = await provider.getRecentThreads("", {
|
|
21077
|
+
const page = await provider.getRecentThreads("", {
|
|
21078
|
+
limit: clamped,
|
|
21079
|
+
before
|
|
21080
|
+
});
|
|
21037
21081
|
return { content: [{ type: "text", text: JSON.stringify(page) }] };
|
|
21038
21082
|
}
|
|
21039
21083
|
);
|
|
@@ -21066,21 +21110,62 @@ function buildContextMcpServer(opts) {
|
|
|
21066
21110
|
}
|
|
21067
21111
|
);
|
|
21068
21112
|
server.tool(
|
|
21069
|
-
"
|
|
21113
|
+
"zooid_get_room_info",
|
|
21070
21114
|
"Describe the current room: id, display name, transport kind.",
|
|
21071
21115
|
{},
|
|
21072
21116
|
async () => {
|
|
21073
21117
|
const provider = await opts.resolve();
|
|
21074
|
-
const info = await provider.
|
|
21118
|
+
const info = await provider.getRoomInfo("");
|
|
21075
21119
|
return { content: [{ type: "text", text: JSON.stringify(info) }] };
|
|
21076
21120
|
}
|
|
21077
21121
|
);
|
|
21122
|
+
server.tool(
|
|
21123
|
+
"zooid_get_rooms",
|
|
21124
|
+
"List the rooms this agent is a member of. Valid targets for zooid_send_message.",
|
|
21125
|
+
{},
|
|
21126
|
+
async () => {
|
|
21127
|
+
const provider = await opts.resolve();
|
|
21128
|
+
const rooms = await provider.getRooms();
|
|
21129
|
+
return { content: [{ type: "text", text: JSON.stringify({ rooms }) }] };
|
|
21130
|
+
}
|
|
21131
|
+
);
|
|
21132
|
+
server.tool(
|
|
21133
|
+
"zooid_send_message",
|
|
21134
|
+
"Post a message into a room or thread this agent is bound to. Fire-and-forget: no assignee, no completion tracking, no notify. Use zooid_start_task_threads instead when the intent is delegation.",
|
|
21135
|
+
{
|
|
21136
|
+
room: external_exports.string(),
|
|
21137
|
+
thread_id: external_exports.string().optional(),
|
|
21138
|
+
text: external_exports.string()
|
|
21139
|
+
},
|
|
21140
|
+
async ({ room, thread_id, text }) => {
|
|
21141
|
+
const provider = await opts.resolve();
|
|
21142
|
+
const result = await provider.sendMessage({ room, thread_id, text });
|
|
21143
|
+
return { content: [{ type: "text", text: JSON.stringify(result) }] };
|
|
21144
|
+
}
|
|
21145
|
+
);
|
|
21078
21146
|
return server;
|
|
21079
21147
|
}
|
|
21080
21148
|
|
|
21149
|
+
// src/socket-paths.ts
|
|
21150
|
+
import { createHash } from "crypto";
|
|
21151
|
+
import { join } from "path";
|
|
21152
|
+
var SUN_PATH_MAX = process.platform === "darwin" ? 103 : 107;
|
|
21153
|
+
var BASENAME_LEN = 25;
|
|
21154
|
+
var MAX_RUN_DIR = SUN_PATH_MAX - 1 - BASENAME_LEN;
|
|
21155
|
+
function agentSocketPath(opts) {
|
|
21156
|
+
if (opts.runDir.length > MAX_RUN_DIR) {
|
|
21157
|
+
throw new Error(
|
|
21158
|
+
`[context-mcp] run dir ${opts.runDir} (${opts.runDir.length} bytes) exceeds the ${MAX_RUN_DIR}-byte limit \u2014 unix socket paths cap at ${SUN_PATH_MAX + 1} bytes. Move the data dir closer to the filesystem root.`
|
|
21159
|
+
);
|
|
21160
|
+
}
|
|
21161
|
+
const hash = createHash("sha256").update(opts.agentName).digest("hex").slice(0, 12);
|
|
21162
|
+
return join(opts.runDir, `context-${hash}.sock`);
|
|
21163
|
+
}
|
|
21164
|
+
|
|
21081
21165
|
// src/daemon-socket.ts
|
|
21082
21166
|
import { createServer, createConnection } from "net";
|
|
21083
21167
|
import { unlink } from "fs/promises";
|
|
21168
|
+
var NOT_OWNED = "binding not owned by caller";
|
|
21084
21169
|
async function startDaemonSocketServer(opts) {
|
|
21085
21170
|
await unlink(opts.sockPath).catch(() => {
|
|
21086
21171
|
});
|
|
@@ -21097,7 +21182,7 @@ async function startDaemonSocketServer(opts) {
|
|
|
21097
21182
|
const line = buf.slice(0, idx);
|
|
21098
21183
|
buf = buf.slice(idx + 1);
|
|
21099
21184
|
if (!line) continue;
|
|
21100
|
-
await handleLine(line, socket, opts.registry);
|
|
21185
|
+
await handleLine(line, socket, opts.registry, opts.agentName);
|
|
21101
21186
|
}
|
|
21102
21187
|
});
|
|
21103
21188
|
socket.on("error", () => {
|
|
@@ -21118,30 +21203,44 @@ async function startDaemonSocketServer(opts) {
|
|
|
21118
21203
|
})
|
|
21119
21204
|
};
|
|
21120
21205
|
}
|
|
21121
|
-
async function handleLine(line, socket, registry2) {
|
|
21206
|
+
async function handleLine(line, socket, registry2, callerAgent) {
|
|
21122
21207
|
let req;
|
|
21123
21208
|
try {
|
|
21124
21209
|
req = JSON.parse(line);
|
|
21125
21210
|
} catch {
|
|
21126
|
-
socket.write(
|
|
21211
|
+
socket.write(
|
|
21212
|
+
JSON.stringify({
|
|
21213
|
+
ok: false,
|
|
21214
|
+
error: "invalid json"
|
|
21215
|
+
}) + "\n"
|
|
21216
|
+
);
|
|
21127
21217
|
return;
|
|
21128
21218
|
}
|
|
21129
|
-
const binding = registry2.get(req.spawnId);
|
|
21219
|
+
const binding = req.spawnId ? registry2.get(req.spawnId) : req.acpSessionId ? registry2.getByAcpSession(req.acpSessionId) : void 0;
|
|
21130
21220
|
if (!binding) {
|
|
21221
|
+
const address = req.acpSessionId ? `session: ${req.acpSessionId}` : `spawn-id: ${req.spawnId ?? ""}`;
|
|
21131
21222
|
process.stderr.write(
|
|
21132
|
-
`[context-mcp] daemon: unknown
|
|
21223
|
+
`[context-mcp] daemon: unknown ${address} for method=${req.method}
|
|
21133
21224
|
`
|
|
21134
21225
|
);
|
|
21135
21226
|
socket.write(
|
|
21136
21227
|
JSON.stringify({
|
|
21137
21228
|
ok: false,
|
|
21138
|
-
error:
|
|
21229
|
+
error: NOT_OWNED
|
|
21139
21230
|
}) + "\n"
|
|
21140
21231
|
);
|
|
21141
21232
|
return;
|
|
21142
21233
|
}
|
|
21234
|
+
if (binding.agentName !== callerAgent) {
|
|
21235
|
+
process.stderr.write(
|
|
21236
|
+
`[context-mcp] daemon: refused ${req.method} \u2014 binding owned by ${binding.agentName}, caller is ${callerAgent}
|
|
21237
|
+
`
|
|
21238
|
+
);
|
|
21239
|
+
socket.write(JSON.stringify({ ok: false, error: NOT_OWNED }) + "\n");
|
|
21240
|
+
return;
|
|
21241
|
+
}
|
|
21143
21242
|
process.stderr.write(
|
|
21144
|
-
`[context-mcp] daemon: ${req.method} spawn=${
|
|
21243
|
+
`[context-mcp] daemon: ${req.method} spawn=${binding.spawnId.slice(0, 8)} agent=${binding.agentName}
|
|
21145
21244
|
`
|
|
21146
21245
|
);
|
|
21147
21246
|
try {
|
|
@@ -21156,8 +21255,32 @@ async function handleLine(line, socket, registry2) {
|
|
|
21156
21255
|
result = await binding.provider.getThreadHistory(channelId, threadId, req.params);
|
|
21157
21256
|
} else if (req.method === "getChannelMembers") {
|
|
21158
21257
|
result = await binding.provider.getChannelMembers(channelId);
|
|
21159
|
-
} else if (req.method === "
|
|
21160
|
-
result = await binding.provider.
|
|
21258
|
+
} else if (req.method === "getRoomInfo") {
|
|
21259
|
+
result = await binding.provider.getRoomInfo(channelId);
|
|
21260
|
+
} else if (req.method === "getRooms") {
|
|
21261
|
+
result = await binding.provider.getRooms();
|
|
21262
|
+
} else if (req.method === "sendMessage") {
|
|
21263
|
+
result = await binding.provider.sendMessage(
|
|
21264
|
+
req.params
|
|
21265
|
+
);
|
|
21266
|
+
} else if (req.method === "startTasks" || req.method === "completeTask" || req.method === "describeRole") {
|
|
21267
|
+
const actions = registry2.taskActions;
|
|
21268
|
+
if (!actions) {
|
|
21269
|
+
socket.write(
|
|
21270
|
+
JSON.stringify({
|
|
21271
|
+
ok: false,
|
|
21272
|
+
error: "task actions unavailable"
|
|
21273
|
+
}) + "\n"
|
|
21274
|
+
);
|
|
21275
|
+
return;
|
|
21276
|
+
}
|
|
21277
|
+
const caller = {
|
|
21278
|
+
agentName: binding.agentName,
|
|
21279
|
+
channelId,
|
|
21280
|
+
threadRoot: binding.threadRef.threadId,
|
|
21281
|
+
sessionKey: binding.sessionKey ?? binding.threadRef.threadId
|
|
21282
|
+
};
|
|
21283
|
+
result = req.method === "startTasks" ? await actions.startTasks(caller, req.params) : req.method === "completeTask" ? await actions.completeTask(caller, req.params) : await actions.describeRole(caller);
|
|
21161
21284
|
} else {
|
|
21162
21285
|
socket.write(
|
|
21163
21286
|
JSON.stringify({
|
|
@@ -21177,6 +21300,34 @@ async function handleLine(line, socket, registry2) {
|
|
|
21177
21300
|
);
|
|
21178
21301
|
}
|
|
21179
21302
|
}
|
|
21303
|
+
async function startAgentSocketServers(opts) {
|
|
21304
|
+
const listen = opts.listen ?? ((sockPath, agentName) => startDaemonSocketServer({ sockPath, registry: opts.registry, agentName }));
|
|
21305
|
+
const derived = opts.agentNames.map((agentName) => ({
|
|
21306
|
+
agentName,
|
|
21307
|
+
sockPath: agentSocketPath({ runDir: opts.runDir, agentName })
|
|
21308
|
+
}));
|
|
21309
|
+
const paths = {};
|
|
21310
|
+
const handles = [];
|
|
21311
|
+
for (const { agentName, sockPath } of derived) {
|
|
21312
|
+
try {
|
|
21313
|
+
const handle = await listen(sockPath, agentName);
|
|
21314
|
+
paths[agentName] = sockPath;
|
|
21315
|
+
handles.push({ handle, path: sockPath });
|
|
21316
|
+
} catch (err) {
|
|
21317
|
+
console.warn(`[context] socket bind failed for agent=${agentName}; context disabled for it:`, err);
|
|
21318
|
+
}
|
|
21319
|
+
}
|
|
21320
|
+
return {
|
|
21321
|
+
paths,
|
|
21322
|
+
close: async () => {
|
|
21323
|
+
for (const { handle, path } of handles) {
|
|
21324
|
+
await handle.close();
|
|
21325
|
+
await unlink(path).catch(() => {
|
|
21326
|
+
});
|
|
21327
|
+
}
|
|
21328
|
+
}
|
|
21329
|
+
};
|
|
21330
|
+
}
|
|
21180
21331
|
async function callDaemon(sockPath, req) {
|
|
21181
21332
|
return new Promise((resolve, reject) => {
|
|
21182
21333
|
const socket = createConnection(sockPath);
|
|
@@ -21207,7 +21358,10 @@ async function callDaemon(sockPath, req) {
|
|
|
21207
21358
|
export {
|
|
21208
21359
|
JSONRPCMessageSchema,
|
|
21209
21360
|
buildContextMcpServer,
|
|
21361
|
+
SUN_PATH_MAX,
|
|
21362
|
+
agentSocketPath,
|
|
21210
21363
|
startDaemonSocketServer,
|
|
21364
|
+
startAgentSocketServers,
|
|
21211
21365
|
callDaemon
|
|
21212
21366
|
};
|
|
21213
|
-
//# sourceMappingURL=chunk-
|
|
21367
|
+
//# sourceMappingURL=chunk-IZ2JCKE4.js.map
|