@powerhousedao/reactor-mcp 6.1.0-dev.1 → 6.1.0-dev.10

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/cli.mjs CHANGED
@@ -1,4 +1,4 @@
1
- import { t as createServer$1, v as logger } from "./server-B68G2N1-.mjs";
1
+ import { t as createServer$1, v as logger } from "./server-BXN-R-gg.mjs";
2
2
  import { childLogger, documentModelDocumentModelModule } from "document-model";
3
3
  import { ReactorBuilder, ReactorClientBuilder } from "@powerhousedao/reactor";
4
4
  import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
package/dist/index.d.mts CHANGED
@@ -218,7 +218,7 @@ declare const getDocumentModelsTool: {
218
218
  type ToolRecord<T extends readonly ToolSchema[]> = { [K in T[number]["name"]]: ToolWithCallback<Extract<T[number], {
219
219
  name: K;
220
220
  }>> };
221
- declare const allTools: readonly [{
221
+ declare const _allTools: readonly [{
222
222
  readonly name: "getDocument";
223
223
  readonly description: "Retrieve a document by its ID";
224
224
  readonly inputSchema: {
@@ -366,7 +366,7 @@ declare const allTools: readonly [{
366
366
  }, z.core.$strip>>;
367
367
  };
368
368
  }];
369
- type ReactorMcpTools = ToolRecord<typeof allTools>;
369
+ type ReactorMcpTools = ToolRecord<typeof _allTools>;
370
370
  declare function createReactorMcpProvider(options: ReactorMcpProviderOptions): Promise<{
371
371
  readonly tools: {
372
372
  readonly getDocument: {
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.mts","names":[],"sources":["../src/mcp-routes.ts","../src/server.ts","../src/tools/types.ts","../src/tools/reactor.ts","../src/tools/utils.ts"],"mappings":";;;;;;;;;;;UAKU,gBAAA;EACR,cAAA,CACE,MAAA,6BACA,IAAA,UACA,OAAA,GACE,GAAA,EAAK,eAAA,EACL,GAAA,EAAK,cAAA,EACL,IAAA,sBACU,OAAA;AAAA;AAAA,UAMC,qBAAA;EACf,MAAA,EAAQ,cAAA;EACR,WAAA,GAAc,YAAA;AAAA;;KAgBX,gBAAA,IAAoB,IAAA;EACvB,kBAAA;AAAA,MACI,YAAA,QAAoB,6BAAA;AAAA,iBAEJ,cAAA,CACpB,OAAA,EAAS,qBAAA,EACT,WAAA,EAAa,gBAAA,EAGb,eAAA,GAAiB,gBAAA,GAEhB,OAAA;;;UC5Cc,mBAAA;EACf,MAAA,EAAQ,cAAA;EACR,WAAA,GAAc,YAAA;AAAA;AAAA,iBAmBM,YAAA,CACpB,OAAA,EAAS,mBAAA,GACR,OAAA,CAAQ,SAAA;;;KCnBC,uBAAA,WAAkC,UAAA,IAAc,CAAA;EAC1D,WAAA;AAAA,IAEE,YAAA,CAAa,CAAA,SAAU,WAAA,GAAc,CAAA,gBACrC,YAAA;AAAA,KAEQ,gBAAA,WAA2B,UAAA,GAAa,UAAA,IAAc,CAAA;EAChE,QAAA,EAAU,uBAAA,CAAwB,CAAA;AAAA;AAAA,KAGxB,UAAA,mBACQ,WAAA,GAAc,WAAA,qBACb,WAAA,GAAc,WAAA;EAEjC,IAAA;EACA,KAAA;EACA,WAAA;EACA,WAAA,GAAc,SAAA;EACd,YAAA,GAAe,UAAA;EACf,WAAA,GAAc,eAAA;AAAA;AAAA,KAGJ,gBAAA,MAAsB,CAAA,SAAU,CAAA,CAAE,WAAA,GAC1C,CAAA,CAAE,KAAA,CAAM,CAAA,CAAE,SAAA,CAAU,CAAA,KACpB,CAAA;AAAA,UAEa,YAAA,WACL,gBAAA,GAAmB,gBAAA,YACnB,QAAA,GAAW,QAAA,YACX,MAAA,GAAS,MAAA;EAEnB,KAAA,EAAO,MAAA,CAAO,CAAA,UAAW,gBAAA,CAAiB,CAAA;EAC1C,SAAA,EAAW,MAAA,CAAO,CAAA,UAAW,CAAA;EAC7B,OAAA,EAAS,MAAA,CAAO,CAAA,UAAW,CAAA;AAAA;;;KC1BjB,yBAAA;EACV,MAAA,EAAQ,cAAA;EACR,WAAA,GAAc,YAAA;AAAA;AAAA,cAGH,kBAAA;EAAA;;;;;;;;;;;;cA+BA,eAAA;EAAA;;;iBASkB,CAAA,CAAA,SAAA;EAAA;EAAA;uBAAA,CAAA,CAAA,UAAA;EAAA;AAAA;AAAA,cAElB,gBAAA;EAAA;;;;;;;;;cAWA,kBAAA;EAAA;;;yBASkB,CAAA,CAAA,SAAA;EAAA;EAAA;sBAAA,CAAA,CAAA,UAAA;EAAA;AAAA;AAAA,cAElB,cAAA;EAAA;;;;;;;;;;;;;;;cA2EA,aAAA;EAAA;;;;uBAOkB,CAAA,CAAA,QAAA,CAAA,CAAA,CAAA,SAAA;EAAA;AAAA;AAAA,cAElB,YAAA;EAAA;;;;;;;;;;;;;;;;;;;;;cA4CA,YAAA;EAAA;;;;;;;;;;;;;cAsBA,eAAA;EAAA;;;sBASkB,CAAA,CAAA,SAAA;EAAA;EAAA;sBAAA,CAAA,CAAA,UAAA;EAAA;AAAA;AAAA,cAElB,kBAAA;EAAA;;;;;;;;;;;;;;;;;;;;cAgDA,0BAAA;EAAA;;;mBASkB,CAAA,CAAA,SAAA;EAAA;EAAA;qBAAA,CAAA,CAAA,UAAA;EAAA;AAAA;AAAA,cAElB,qBAAA;EAAA;;;;;;;;;;;;;;KAsBR,UAAA,oBAA8B,UAAA,cAC3B,CAAA,mBAAoB,gBAAA,CAAiB,OAAA,CAAQ,CAAA;EAAa,IAAA,EAAM,CAAA;AAAA;AAAA,cAIlE,QAAA;EAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KAiBM,eAAA,GAAkB,UAAA,QAAkB,QAAA;AAAA,iBAE1B,wBAAA,CACpB,OAAA,EAAS,yBAAA,GAAyB,OAAA;EAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;cCrVvB,sBAAA,SAA+B,KAAA;cAC9B,QAAA,EAAU,CAAA,CAAE,QAAA;AAAA;;;;AJTuC;;;;;iBIwBjD,gBAAA,WAA2B,UAAA,CAAA,CACzC,IAAA,EAAM,CAAA,EACN,YAAA,GACE,IAAA,EAAM,gBAAA,CAAiB,CAAA,qBAErB,gBAAA,CAAiB,CAAA,oBACjB,OAAA,CAAQ,gBAAA,CAAiB,CAAA,qBAAmB,CAAA;mBAGxC,gBAAA,CAAiB,CAAA,qBACtB,OAAA,CAAQ,cAAA;AAAA;AAAA,iBAgCG,2BAAA,CACd,mBAAA,EAAqB,mBAAA,EACrB,MAAA,EAAQ,MAAA;EACL,OAAA;EAAkB,MAAA;AAAA"}
1
+ {"version":3,"file":"index.d.mts","names":[],"sources":["../src/mcp-routes.ts","../src/server.ts","../src/tools/types.ts","../src/tools/reactor.ts","../src/tools/utils.ts"],"mappings":"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"}
package/dist/index.mjs CHANGED
@@ -1,4 +1,4 @@
1
- import { _ as validateDocumentModelAction, a as createDocumentTool, c as deleteDriveTool, d as getDocumentTool, f as getDocumentsTool, g as toolWithCallback, h as InvalidToolOutputError, i as addRemoteDriveTool, l as getDocumentModelSchemaTool, m as getDrivesTool, n as addActionsTool, o as createReactorMcpProvider, p as getDriveTool, r as addDriveTool, s as deleteDocumentTool, t as createServer, u as getDocumentModelsTool, v as logger } from "./server-B68G2N1-.mjs";
1
+ import { _ as validateDocumentModelAction, a as createDocumentTool, c as deleteDriveTool, d as getDocumentTool, f as getDocumentsTool, g as toolWithCallback, h as InvalidToolOutputError, i as addRemoteDriveTool, l as getDocumentModelSchemaTool, m as getDrivesTool, n as addActionsTool, o as createReactorMcpProvider, p as getDriveTool, r as addDriveTool, s as deleteDocumentTool, t as createServer, u as getDocumentModelsTool, v as logger } from "./server-BXN-R-gg.mjs";
2
2
  import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
3
3
  //#region src/mcp-routes.ts
4
4
  const METHOD_NOT_ALLOWED = JSON.stringify({
@@ -17,7 +17,7 @@ const INTERNAL_SERVER_ERROR = JSON.stringify({
17
17
  },
18
18
  id: null
19
19
  });
20
- async function setupMcpServer(options, httpAdapter, createTransport = (opts) => new StreamableHTTPServerTransport(opts)) {
20
+ function setupMcpServer(options, httpAdapter, createTransport = (opts) => new StreamableHTTPServerTransport(opts)) {
21
21
  httpAdapter.mountNodeRoute("POST", "/mcp", async (req, res, body) => {
22
22
  try {
23
23
  const server = await createServer(options);
@@ -39,6 +39,7 @@ async function setupMcpServer(options, httpAdapter, createTransport = (opts) =>
39
39
  httpAdapter.mountNodeRoute("DELETE", "/mcp", (_req, res) => {
40
40
  res.writeHead(405).end(METHOD_NOT_ALLOWED);
41
41
  });
42
+ return Promise.resolve();
42
43
  }
43
44
  //#endregion
44
45
  export { InvalidToolOutputError, addActionsTool, addDriveTool, addRemoteDriveTool, createDocumentTool, createReactorMcpProvider, createServer, deleteDocumentTool, deleteDriveTool, getDocumentModelSchemaTool, getDocumentModelsTool, getDocumentTool, getDocumentsTool, getDriveTool, getDrivesTool, setupMcpServer, toolWithCallback, validateDocumentModelAction };
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","names":[],"sources":["../src/mcp-routes.ts"],"sourcesContent":["import { StreamableHTTPServerTransport } from \"@modelcontextprotocol/sdk/server/streamableHttp.js\";\nimport type { IReactorClient, ISyncManager } from \"@powerhousedao/reactor\";\nimport type { IncomingMessage, ServerResponse } from \"node:http\";\n\n/** Minimal interface for an HTTP adapter that supports Node.js-style route handlers. */\ninterface NodeRouteAdapter {\n mountNodeRoute(\n method: \"DELETE\" | \"GET\" | \"POST\",\n path: string,\n handler: (\n req: IncomingMessage,\n res: ServerResponse,\n body?: unknown,\n ) => void | Promise<void>,\n ): void;\n}\nimport { logger } from \"./logger.js\";\nimport { createServer } from \"./server.js\";\n\nexport interface SetupMcpServerOptions {\n client: IReactorClient;\n syncManager?: ISyncManager;\n}\n\nconst METHOD_NOT_ALLOWED = JSON.stringify({\n jsonrpc: \"2.0\",\n error: { code: -32000, message: \"Method not allowed.\" },\n id: null,\n});\n\nconst INTERNAL_SERVER_ERROR = JSON.stringify({\n jsonrpc: \"2.0\",\n error: { code: -32603, message: \"Internal server error\" },\n id: null,\n});\n\n/** @internal Injected in tests to avoid relying on constructor mock semantics. */\ntype TransportFactory = (opts: {\n sessionIdGenerator: undefined;\n}) => InstanceType<typeof StreamableHTTPServerTransport>;\n\nexport async function setupMcpServer(\n options: SetupMcpServerOptions,\n httpAdapter: NodeRouteAdapter,\n // Allow tests to inject a factory function instead of relying on `new vi.fn()`\n // constructor semantics, which differ between macOS and Linux environments.\n createTransport: TransportFactory = (opts) =>\n new StreamableHTTPServerTransport(opts),\n): Promise<void> {\n httpAdapter.mountNodeRoute(\n \"POST\",\n \"/mcp\",\n async (req: IncomingMessage, res: ServerResponse, body?: unknown) => {\n // Stateless mode: every request owns its McpServer + transport so\n // concurrent or slow handlers cannot collide on a shared Protocol\n // instance (which throws \"Already connected to a transport\").\n try {\n const server = await createServer(options);\n const transport = createTransport({ sessionIdGenerator: undefined });\n res.on(\"close\", () => {\n void transport.close();\n void server.close();\n });\n await server.connect(transport);\n await transport.handleRequest(req, res, body);\n } catch (error) {\n logger.error(\"Error handling MCP request: @error\", error);\n if (!res.headersSent) {\n res\n .writeHead(500, { \"Content-Type\": \"application/json\" })\n .end(INTERNAL_SERVER_ERROR);\n }\n }\n },\n );\n\n // SSE notifications not supported in stateless mode\n httpAdapter.mountNodeRoute(\n \"GET\",\n \"/mcp\",\n (_req: IncomingMessage, res: ServerResponse) => {\n res.writeHead(405).end(METHOD_NOT_ALLOWED);\n },\n );\n\n // Session termination not needed in stateless mode\n httpAdapter.mountNodeRoute(\n \"DELETE\",\n \"/mcp\",\n (_req: IncomingMessage, res: ServerResponse) => {\n res.writeHead(405).end(METHOD_NOT_ALLOWED);\n },\n );\n}\n"],"mappings":";;;AAwBA,MAAM,qBAAqB,KAAK,UAAU;CACxC,SAAS;CACT,OAAO;EAAE,MAAM;EAAQ,SAAS;EAAuB;CACvD,IAAI;CACL,CAAC;AAEF,MAAM,wBAAwB,KAAK,UAAU;CAC3C,SAAS;CACT,OAAO;EAAE,MAAM;EAAQ,SAAS;EAAyB;CACzD,IAAI;CACL,CAAC;AAOF,eAAsB,eACpB,SACA,aAGA,mBAAqC,SACnC,IAAI,8BAA8B,KAAK,EAC1B;AACf,aAAY,eACV,QACA,QACA,OAAO,KAAsB,KAAqB,SAAmB;AAInE,MAAI;GACF,MAAM,SAAS,MAAM,aAAa,QAAQ;GAC1C,MAAM,YAAY,gBAAgB,EAAE,oBAAoB,KAAA,GAAW,CAAC;AACpE,OAAI,GAAG,eAAe;AACf,cAAU,OAAO;AACjB,WAAO,OAAO;KACnB;AACF,SAAM,OAAO,QAAQ,UAAU;AAC/B,SAAM,UAAU,cAAc,KAAK,KAAK,KAAK;WACtC,OAAO;AACd,UAAO,MAAM,sCAAsC,MAAM;AACzD,OAAI,CAAC,IAAI,YACP,KACG,UAAU,KAAK,EAAE,gBAAgB,oBAAoB,CAAC,CACtD,IAAI,sBAAsB;;GAIpC;AAGD,aAAY,eACV,OACA,SACC,MAAuB,QAAwB;AAC9C,MAAI,UAAU,IAAI,CAAC,IAAI,mBAAmB;GAE7C;AAGD,aAAY,eACV,UACA,SACC,MAAuB,QAAwB;AAC9C,MAAI,UAAU,IAAI,CAAC,IAAI,mBAAmB;GAE7C"}
1
+ {"version":3,"file":"index.mjs","names":[],"sources":["../src/mcp-routes.ts"],"sourcesContent":["import { StreamableHTTPServerTransport } from \"@modelcontextprotocol/sdk/server/streamableHttp.js\";\nimport type { IReactorClient, ISyncManager } from \"@powerhousedao/reactor\";\nimport type { IncomingMessage, ServerResponse } from \"node:http\";\n\n/** Minimal interface for an HTTP adapter that supports Node.js-style route handlers. */\ninterface NodeRouteAdapter {\n mountNodeRoute(\n method: \"DELETE\" | \"GET\" | \"POST\",\n path: string,\n handler: (\n req: IncomingMessage,\n res: ServerResponse,\n body?: unknown,\n ) => void | Promise<void>,\n ): void;\n}\nimport { logger } from \"./logger.js\";\nimport { createServer } from \"./server.js\";\n\nexport interface SetupMcpServerOptions {\n client: IReactorClient;\n syncManager?: ISyncManager;\n}\n\nconst METHOD_NOT_ALLOWED = JSON.stringify({\n jsonrpc: \"2.0\",\n error: { code: -32000, message: \"Method not allowed.\" },\n id: null,\n});\n\nconst INTERNAL_SERVER_ERROR = JSON.stringify({\n jsonrpc: \"2.0\",\n error: { code: -32603, message: \"Internal server error\" },\n id: null,\n});\n\n/** @internal Injected in tests to avoid relying on constructor mock semantics. */\ntype TransportFactory = (opts: {\n sessionIdGenerator: undefined;\n}) => InstanceType<typeof StreamableHTTPServerTransport>;\n\nexport function setupMcpServer(\n options: SetupMcpServerOptions,\n httpAdapter: NodeRouteAdapter,\n // Allow tests to inject a factory function instead of relying on `new vi.fn()`\n // constructor semantics, which differ between macOS and Linux environments.\n createTransport: TransportFactory = (opts) =>\n new StreamableHTTPServerTransport(opts),\n): Promise<void> {\n httpAdapter.mountNodeRoute(\n \"POST\",\n \"/mcp\",\n async (req: IncomingMessage, res: ServerResponse, body?: unknown) => {\n // Stateless mode: every request owns its McpServer + transport so\n // concurrent or slow handlers cannot collide on a shared Protocol\n // instance (which throws \"Already connected to a transport\").\n try {\n const server = await createServer(options);\n const transport = createTransport({ sessionIdGenerator: undefined });\n res.on(\"close\", () => {\n void transport.close();\n void server.close();\n });\n await server.connect(transport);\n await transport.handleRequest(req, res, body);\n } catch (error) {\n logger.error(\"Error handling MCP request: @error\", error);\n if (!res.headersSent) {\n res\n .writeHead(500, { \"Content-Type\": \"application/json\" })\n .end(INTERNAL_SERVER_ERROR);\n }\n }\n },\n );\n\n // SSE notifications not supported in stateless mode\n httpAdapter.mountNodeRoute(\n \"GET\",\n \"/mcp\",\n (_req: IncomingMessage, res: ServerResponse) => {\n res.writeHead(405).end(METHOD_NOT_ALLOWED);\n },\n );\n\n // Session termination not needed in stateless mode\n httpAdapter.mountNodeRoute(\n \"DELETE\",\n \"/mcp\",\n (_req: IncomingMessage, res: ServerResponse) => {\n res.writeHead(405).end(METHOD_NOT_ALLOWED);\n },\n );\n return Promise.resolve();\n}\n"],"mappings":";;;AAwBA,MAAM,qBAAqB,KAAK,UAAU;CACxC,SAAS;CACT,OAAO;EAAE,MAAM;EAAQ,SAAS;EAAuB;CACvD,IAAI;CACL,CAAC;AAEF,MAAM,wBAAwB,KAAK,UAAU;CAC3C,SAAS;CACT,OAAO;EAAE,MAAM;EAAQ,SAAS;EAAyB;CACzD,IAAI;CACL,CAAC;AAOF,SAAgB,eACd,SACA,aAGA,mBAAqC,SACnC,IAAI,8BAA8B,KAAK,EAC1B;AACf,aAAY,eACV,QACA,QACA,OAAO,KAAsB,KAAqB,SAAmB;AAInE,MAAI;GACF,MAAM,SAAS,MAAM,aAAa,QAAQ;GAC1C,MAAM,YAAY,gBAAgB,EAAE,oBAAoB,KAAA,GAAW,CAAC;AACpE,OAAI,GAAG,eAAe;AACf,cAAU,OAAO;AACjB,WAAO,OAAO;KACnB;AACF,SAAM,OAAO,QAAQ,UAAU;AAC/B,SAAM,UAAU,cAAc,KAAK,KAAK,KAAK;WACtC,OAAO;AACd,UAAO,MAAM,sCAAsC,MAAM;AACzD,OAAI,CAAC,IAAI,YACP,KACG,UAAU,KAAK,EAAE,gBAAgB,oBAAoB,CAAC,CACtD,IAAI,sBAAsB;;GAIpC;AAGD,aAAY,eACV,OACA,SACC,MAAuB,QAAwB;AAC9C,MAAI,UAAU,IAAI,CAAC,IAAI,mBAAmB;GAE7C;AAGD,aAAY,eACV,UACA,SACC,MAAuB,QAAwB;AAC9C,MAAI,UAAU,IAAI,CAAC,IAAI,mBAAmB;GAE7C;AACD,QAAO,QAAQ,SAAS"}
@@ -225,116 +225,117 @@ const getDocumentModelsTool = {
225
225
  authorWebsite: z.string().describe("Author website of the document model")
226
226
  })).describe("List of available document models") }
227
227
  };
228
- async function createReactorMcpProvider(options) {
228
+ function createReactorMcpProvider(options) {
229
229
  const { client, syncManager } = options;
230
- async function getDocumentModelModule(documentType) {
230
+ function getDocumentModelModule(documentType) {
231
231
  return client.getDocumentModelModule(documentType);
232
232
  }
233
- return {
234
- tools: {
235
- getDocument: toolWithCallback(getDocumentTool, async (params) => {
236
- const document = await client.get(params.id);
237
- return { document: {
238
- header: document.header,
239
- state: document.state
240
- } };
241
- }),
242
- createDocument: toolWithCallback(createDocumentTool, async (params) => {
243
- if (params.driveId) {
244
- const module = await getDocumentModelModule(params.documentType);
245
- if (!module) throw new Error(`Document model for type '${params.documentType}' not found`);
246
- const document = module.utils.createDocument();
247
- if (params.name) document.header.name = params.name;
248
- return { documentId: (await client.drives.addFile(params.driveId, document, params.parentFolder)).header.id };
249
- }
250
- return { documentId: (await client.createEmpty(params.documentType, {})).header.id };
251
- }),
252
- getDocuments: toolWithCallback(getDocumentsTool, async (params) => {
253
- return { documentIds: (await client.getOutgoingRelationships(params.parentId, "child")).results.map((doc) => doc.header.id) };
254
- }),
255
- deleteDocument: toolWithCallback(deleteDocumentTool, async (params) => {
256
- try {
257
- const driveParent = (await client.getIncomingRelationships(params.documentId, "child")).results.find((p) => p.header.documentType === DRIVE_DOCUMENT_TYPE);
258
- if (driveParent) await client.drives.removeNode(driveParent.header.id, params.documentId);
259
- else await client.deleteDocument(params.documentId);
260
- return { success: true };
261
- } catch {
262
- return { success: false };
263
- }
264
- }),
265
- addActions: toolWithCallback(addActionsTool, async (params) => {
266
- const document = await client.get(params.documentId);
267
- const documentModel = await getDocumentModelModule(document.header.documentType);
268
- if (!documentModel) throw new Error(`Document model for document type '${document.header.documentType}' not found`);
269
- const actions = params.actions.map((paramAction) => {
270
- const action = createAction(paramAction.type, paramAction.input ?? {}, void 0, void 0, paramAction.scope);
271
- const actionValidation = validateDocumentModelAction(documentModel, action);
272
- if (!actionValidation.isValid) throw new Error(`Invalid action ${JSON.stringify(action)}: ${actionValidation.errors.join(", ")}`);
273
- return action;
274
- });
275
- await client.execute(params.documentId, "main", actions);
233
+ const tools = {
234
+ getDocument: toolWithCallback(getDocumentTool, async (params) => {
235
+ const document = await client.get(params.id);
236
+ return { document: {
237
+ header: document.header,
238
+ state: document.state
239
+ } };
240
+ }),
241
+ createDocument: toolWithCallback(createDocumentTool, async (params) => {
242
+ if (params.driveId) {
243
+ const module = await getDocumentModelModule(params.documentType);
244
+ if (!module) throw new Error(`Document model for type '${params.documentType}' not found`);
245
+ const document = module.utils.createDocument();
246
+ if (params.name) document.header.name = params.name;
247
+ return { documentId: (await client.drives.addFile(params.driveId, document, params.parentFolder)).header.id };
248
+ }
249
+ return { documentId: (await client.createEmpty(params.documentType, {})).header.id };
250
+ }),
251
+ getDocuments: toolWithCallback(getDocumentsTool, async (params) => {
252
+ return { documentIds: (await client.getOutgoingRelationships(params.parentId, "child")).results.map((doc) => doc.header.id) };
253
+ }),
254
+ deleteDocument: toolWithCallback(deleteDocumentTool, async (params) => {
255
+ try {
256
+ const driveParent = (await client.getIncomingRelationships(params.documentId, "child")).results.find((p) => p.header.documentType === DRIVE_DOCUMENT_TYPE);
257
+ if (driveParent) await client.drives.removeNode(driveParent.header.id, params.documentId);
258
+ else await client.deleteDocument(params.documentId);
276
259
  return { success: true };
277
- }),
278
- getDrives: toolWithCallback(getDrivesTool, async () => {
279
- return { driveIds: (await client.find({ type: DRIVE_DOCUMENT_TYPE })).results.map((doc) => doc.header.id) };
280
- }),
281
- addDrive: toolWithCallback(addDriveTool, async (params) => {
282
- const drive = await client.createEmpty(DRIVE_DOCUMENT_TYPE, {});
283
- if (params.driveInput.global?.name) await client.rename(drive.header.id, params.driveInput.global.name);
284
- return { driveId: drive.header.id };
285
- }),
286
- getDrive: toolWithCallback(getDriveTool, async (params) => {
287
- const drive = await client.get(params.driveId);
288
- return { drive: {
289
- header: drive.header,
290
- state: drive.state
291
- } };
292
- }),
293
- deleteDrive: toolWithCallback(deleteDriveTool, async (params) => {
294
- try {
295
- await client.deleteDocument(params.driveId);
296
- return { success: true };
297
- } catch {
298
- return { success: false };
299
- }
300
- }),
301
- addRemoteDrive: toolWithCallback(addRemoteDriveTool, async (params) => {
302
- if (!syncManager) throw new Error("Remote drive management is not available. SyncManager was not configured for this MCP server.");
303
- const response = await fetch(params.url);
304
- if (!response.ok) throw new Error(`Failed to resolve drive info from ${params.url}`);
305
- const driveInfo = await response.json();
306
- const resolvedDriveId = driveInfo.id;
307
- const collectionId = driveCollectionId("main", resolvedDriveId);
308
- if (syncManager.list().find((remote) => remote.collectionId === collectionId)) return { driveId: resolvedDriveId };
309
- const remoteName = `mcp-remote-${crypto.randomUUID()}`;
310
- await syncManager.add(remoteName, collectionId, {
311
- type: "gql",
312
- parameters: { url: driveInfo.graphqlEndpoint }
313
- });
314
- return { driveId: resolvedDriveId };
315
- }),
316
- getDocumentModels: toolWithCallback(getDocumentModelsTool, async () => {
317
- return { documentModels: (await client.getDocumentModelModules()).results.map((model) => {
318
- const schemaGlobal = model.documentModel.global;
319
- return {
320
- name: schemaGlobal.name,
321
- type: schemaGlobal.id,
322
- description: schemaGlobal.description,
323
- extension: schemaGlobal.extension,
324
- authorName: schemaGlobal.author.name,
325
- authorWebsite: schemaGlobal.author.website ?? ""
326
- };
327
- }) };
328
- }),
329
- getDocumentModelSchema: toolWithCallback(getDocumentModelSchemaTool, async (params) => {
330
- const schema = (await getDocumentModelModule(params.type))?.documentModel.global;
331
- if (!schema) throw new Error(`Document model '${params.type}' not found`);
332
- return { schema };
333
- })
334
- },
260
+ } catch {
261
+ return { success: false };
262
+ }
263
+ }),
264
+ addActions: toolWithCallback(addActionsTool, async (params) => {
265
+ const document = await client.get(params.documentId);
266
+ const documentModel = await getDocumentModelModule(document.header.documentType);
267
+ if (!documentModel) throw new Error(`Document model for document type '${document.header.documentType}' not found`);
268
+ const actions = params.actions.map((paramAction) => {
269
+ const action = createAction(paramAction.type, paramAction.input ?? {}, void 0, void 0, paramAction.scope);
270
+ const actionValidation = validateDocumentModelAction(documentModel, action);
271
+ if (!actionValidation.isValid) throw new Error(`Invalid action ${JSON.stringify(action)}: ${actionValidation.errors.join(", ")}`);
272
+ return action;
273
+ });
274
+ await client.execute(params.documentId, "main", actions);
275
+ return { success: true };
276
+ }),
277
+ getDrives: toolWithCallback(getDrivesTool, async () => {
278
+ return { driveIds: (await client.find({ type: DRIVE_DOCUMENT_TYPE })).results.map((doc) => doc.header.id) };
279
+ }),
280
+ addDrive: toolWithCallback(addDriveTool, async (params) => {
281
+ const drive = await client.createEmpty(DRIVE_DOCUMENT_TYPE, {});
282
+ if (params.driveInput.global?.name) await client.rename(drive.header.id, params.driveInput.global.name);
283
+ return { driveId: drive.header.id };
284
+ }),
285
+ getDrive: toolWithCallback(getDriveTool, async (params) => {
286
+ const drive = await client.get(params.driveId);
287
+ return { drive: {
288
+ header: drive.header,
289
+ state: drive.state
290
+ } };
291
+ }),
292
+ deleteDrive: toolWithCallback(deleteDriveTool, async (params) => {
293
+ try {
294
+ await client.deleteDocument(params.driveId);
295
+ return { success: true };
296
+ } catch {
297
+ return { success: false };
298
+ }
299
+ }),
300
+ addRemoteDrive: toolWithCallback(addRemoteDriveTool, async (params) => {
301
+ if (!syncManager) throw new Error("Remote drive management is not available. SyncManager was not configured for this MCP server.");
302
+ const response = await fetch(params.url);
303
+ if (!response.ok) throw new Error(`Failed to resolve drive info from ${params.url}`);
304
+ const driveInfo = await response.json();
305
+ const resolvedDriveId = driveInfo.id;
306
+ const collectionId = driveCollectionId("main", resolvedDriveId);
307
+ if (syncManager.list().find((remote) => remote.collectionId === collectionId)) return { driveId: resolvedDriveId };
308
+ const remoteName = `mcp-remote-${crypto.randomUUID()}`;
309
+ await syncManager.add(remoteName, collectionId, {
310
+ type: "gql",
311
+ parameters: { url: driveInfo.graphqlEndpoint }
312
+ });
313
+ return { driveId: resolvedDriveId };
314
+ }),
315
+ getDocumentModels: toolWithCallback(getDocumentModelsTool, async () => {
316
+ return { documentModels: (await client.getDocumentModelModules()).results.map((model) => {
317
+ const schemaGlobal = model.documentModel.global;
318
+ return {
319
+ name: schemaGlobal.name,
320
+ type: schemaGlobal.id,
321
+ description: schemaGlobal.description,
322
+ extension: schemaGlobal.extension,
323
+ authorName: schemaGlobal.author.name,
324
+ authorWebsite: schemaGlobal.author.website ?? ""
325
+ };
326
+ }) };
327
+ }),
328
+ getDocumentModelSchema: toolWithCallback(getDocumentModelSchemaTool, async (params) => {
329
+ const schema = (await getDocumentModelModule(params.type))?.documentModel.global;
330
+ if (!schema) throw new Error(`Document model '${params.type}' not found`);
331
+ return { schema };
332
+ })
333
+ };
334
+ return Promise.resolve({
335
+ tools,
335
336
  resources: {},
336
337
  prompts: {}
337
- };
338
+ });
338
339
  }
339
340
  //#endregion
340
341
  //#region src/server.ts
@@ -379,7 +380,6 @@ async function createServer(options) {
379
380
  client,
380
381
  syncManager
381
382
  });
382
- const { callback, ...toolSchema } = reactorProvider.tools.getDocumentModels;
383
383
  Object.entries(reactorProvider.tools).forEach(([toolName, { callback, ...schema }]) => {
384
384
  server.registerTool(toolName, schema, callback);
385
385
  });
@@ -388,4 +388,4 @@ async function createServer(options) {
388
388
  //#endregion
389
389
  export { validateDocumentModelAction as _, createDocumentTool as a, deleteDriveTool as c, getDocumentTool as d, getDocumentsTool as f, toolWithCallback as g, InvalidToolOutputError as h, addRemoteDriveTool as i, getDocumentModelSchemaTool as l, getDrivesTool as m, addActionsTool as n, createReactorMcpProvider as o, getDriveTool as p, addDriveTool as r, deleteDocumentTool as s, createServer as t, getDocumentModelsTool as u, logger as v };
390
390
 
391
- //# sourceMappingURL=server-B68G2N1-.mjs.map
391
+ //# sourceMappingURL=server-BXN-R-gg.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"server-B68G2N1-.mjs","names":[],"sources":["../src/logger.ts","../src/tools/utils.ts","../src/tools/reactor.ts","../src/server.ts"],"sourcesContent":["import { childLogger, type ILogger } from \"document-model\";\n\nexport const logger: ILogger = childLogger([\"reactor-mcp\"]);\n","import type { CallToolResult } from \"@modelcontextprotocol/sdk/types.js\";\nimport { camelCase } from \"change-case\";\nimport type {\n Action,\n DocumentModelModule,\n Operation,\n} from \"@powerhousedao/shared/document-model\";\nimport type { z } from \"zod\";\nimport type { ResolveZodSchema, ToolSchema } from \"./types.js\";\n\nexport class InvalidToolOutputError extends Error {\n constructor(zodError: z.ZodError) {\n super(\"Invalid tool output\\n\" + zodError.message);\n this.name = \"InvalidToolOutputError\";\n this.cause = zodError;\n }\n}\n\n/**\n * Creates a tool with a callback function that handles the tool execution,\n * ensuring the output is valid and errors are handled and returned correctly.\n * @param tool The tool schema to wrap.\n * @param toolCallback The callback function to execute when the tool is called.\n * @returns A CallToolResult with structuredContent if OutputSchema is defined or content if undefined. If the\n * callback throws an error, the result will have isError set to true and the error message in the content.\n */\nexport function toolWithCallback<T extends ToolSchema>(\n tool: T,\n toolCallback: (\n args: ResolveZodSchema<T[\"inputSchema\"]>,\n ) =>\n | ResolveZodSchema<T[\"outputSchema\"]>\n | Promise<ResolveZodSchema<T[\"outputSchema\"]>>,\n) {\n const wrappedCallback = async (\n args: ResolveZodSchema<T[\"inputSchema\"]>,\n ): Promise<CallToolResult> => {\n try {\n const result = await toolCallback(args);\n return {\n content: [\n {\n type: \"text\",\n text: JSON.stringify(result),\n },\n ],\n structuredContent: result,\n } as const satisfies CallToolResult;\n } catch (error) {\n const errorString =\n error instanceof Error ? error.message : String(error);\n return {\n isError: true,\n content: [\n {\n type: \"text\",\n text: `Error: ${errorString}`,\n },\n ],\n } as const satisfies CallToolResult;\n }\n };\n return {\n ...tool,\n callback: wrappedCallback,\n };\n}\n\nexport function validateDocumentModelAction(\n documentModelModule: DocumentModelModule,\n action: Action,\n): { isValid: boolean; errors: string[] } {\n const errors: string[] = [];\n\n const globalState = documentModelModule.documentModel.global;\n\n // Get the latest specification\n if (!globalState.specifications || globalState.specifications.length === 0) {\n errors.push(\"Document model has no specifications\");\n return { isValid: false, errors };\n }\n\n const latestSpec =\n globalState.specifications[globalState.specifications.length - 1];\n\n // Search through modules to find the operation that matches the action type (in SCREAMING_SNAKE_CASE)\n let operation: (Operation & { scope: string }) | null = null;\n\n for (const module of latestSpec.modules) {\n const unsafeOperationOrActionOrSomething = module.operations.find(\n (op) => op.name === action.type,\n ) as unknown as Operation & { scope: string };\n if (unsafeOperationOrActionOrSomething) {\n operation = unsafeOperationOrActionOrSomething;\n break;\n }\n }\n\n if (!operation) {\n errors.push(\n `Operation \"${action.type}\" is not defined in any module of the document model`,\n );\n return { isValid: false, errors };\n }\n\n // Convert action type from SCREAMING_SNAKE_CASE to camelCase to match action creators\n const camelCaseActionType = camelCase(action.type);\n\n // Check if action creator exists in documentModelModule.actions\n const actionCreator = documentModelModule.actions[camelCaseActionType];\n\n if (!actionCreator) {\n errors.push(\n `Action creator \"${camelCaseActionType}\" for action type \"${action.type}\" is not defined in documentModelDocumentModelModule.actions`,\n );\n return { isValid: false, errors };\n }\n\n // Validate the operation using the action creator. TODO: Use document model exported validators directly\n let inputError: Error | null = null;\n try {\n actionCreator(action.input);\n } catch (e) {\n inputError = e instanceof Error ? e : new Error(JSON.stringify(e));\n }\n\n if (inputError) {\n errors.push(`Input validation error: ${inputError.message}`);\n }\n\n // Validate scope if operation defines one\n if (operation.scope && action.scope !== operation.scope) {\n errors.push(\n `Action scope \"${action.scope}\" does not match operation scope \"${operation.scope}\"`,\n );\n }\n\n return {\n isValid: errors.length === 0,\n errors,\n };\n}\n","import type { IReactorClient, ISyncManager } from \"@powerhousedao/reactor\";\nimport { driveCollectionId } from \"@powerhousedao/reactor\";\nimport type { DocumentDriveDocument } from \"@powerhousedao/shared/document-drive\";\nimport type {\n Action,\n DocumentModelModule,\n PHDocument,\n} from \"@powerhousedao/shared/document-model\";\nimport { createAction } from \"@powerhousedao/shared/document-model\";\nimport { z } from \"zod\";\nimport type { ToolSchema, ToolWithCallback } from \"./types.js\";\nimport { toolWithCallback, validateDocumentModelAction } from \"./utils.js\";\n\nconst DRIVE_DOCUMENT_TYPE = \"powerhouse/document-drive\";\n\nexport type ReactorMcpProviderOptions = {\n client: IReactorClient;\n syncManager?: ISyncManager;\n};\n\nexport const createDocumentTool = {\n name: \"createDocument\",\n description: `Create a new document.\n Unless the user specifies otherwise, and a drive named \"vetra\" is available, add the document to that drive by providing the drive's ID in the \"driveId\" parameter.\n When \"driveId\" is provided, the document is created and added to the drive atomically — no separate \"addActions\" call with \"ADD_FILE\" is needed.`,\n inputSchema: {\n documentType: z.string().describe(\"Type of the document to create\"),\n name: z\n .string()\n .optional()\n .describe(\n \"Optional name for the document. Used as both the document name and the drive node name when driveId is provided.\",\n ),\n driveId: z\n .string()\n .optional()\n .describe(\n \"Optional drive ID or slug. When provided, the document is created and added to the drive atomically.\",\n ),\n parentFolder: z\n .string()\n .optional()\n .describe(\n \"Optional folder ID within the drive to place the document in. Only used when driveId is provided.\",\n ),\n },\n outputSchema: {\n documentId: z.string().describe(\"ID of the created document\"),\n },\n} as const satisfies ToolSchema;\n\nexport const getDocumentTool = {\n name: \"getDocument\",\n description: \"Retrieve a document by its ID\",\n inputSchema: {\n id: z.string().describe(\"ID of the document to retrieve\"),\n },\n outputSchema: {\n document: z.unknown().describe(\"The retrieved Document\"),\n },\n} as const satisfies ToolSchema;\n\nexport const getDocumentsTool = {\n name: \"getDocuments\",\n description: \"List documents in a drive\",\n inputSchema: {\n parentId: z.string().describe(\"ID of the drive\"),\n },\n outputSchema: {\n documentIds: z.array(z.string()).describe(\"Array of document IDs\"),\n },\n} as const satisfies ToolSchema;\n\nexport const deleteDocumentTool = {\n name: \"deleteDocument\",\n description: \"Delete a document\",\n inputSchema: {\n documentId: z.string().describe(\"ID of the document to delete\"),\n },\n outputSchema: {\n success: z.boolean().describe(\"Whether the deletion was successful\"),\n },\n} as const satisfies ToolSchema;\n\nexport const addActionsTool = {\n name: \"addActions\",\n description:\n \"Adds actions to a document. Prefer adding multiples actions at once to reduce the number of steps.\",\n inputSchema: {\n documentId: z.string().describe(\"ID of the document\"),\n actions: z\n .array(\n z\n .object({\n type: z.string().describe(\"The name of the action\"),\n input: z.unknown().describe(\"The payload of the action\"),\n scope: z.string().describe(\"The scope of the action\"),\n context: z\n .record(z.string(), z.unknown())\n .optional()\n .describe(\"Optional action context\"), // TODO: Define context schema\n })\n .strict(),\n )\n .describe(\"Action to add to the document\"),\n },\n outputSchema: {\n success: z.boolean().describe(\"Whether the actions were added\"),\n },\n} as const satisfies ToolSchema;\n\n// export const addOperationTool = {\n// name: \"addOperation\",\n// description: \"Add an operation to a document\",\n// inputSchema: {\n// documentId: z.string().describe(\"ID of the document\"),\n// operation: z\n// .object({\n// type: z.string().describe(\"The name of the action\"),\n// input: z.unknown().describe(\"The payload of the action\"),\n// scope: z.string().describe(\"The scope of the action\"),\n// index: z.number().describe(\"Position of the operation in the history\"),\n// timestampUtcMs: z\n// .string()\n// .describe(\"Timestamp of when the operation was added\"),\n// hash: z.string().describe(\"Hash of the resulting document data\"),\n// skip: z.number().describe(\"The number of operations skipped\"),\n// error: z\n// .string()\n// .optional()\n// .describe(\"Error message for a failed action\"),\n// id: z.string().optional().describe(\"Unique operation id\"),\n// context: z.object({}).optional().describe(\"Optional action context\"), // TODO: Define context schema\n// })\n// .strict()\n// .describe(\"Operation to add to the document\"),\n// },\n// outputSchema: {\n// result: z\n// .object({\n// status: z\n// .enum([\"SUCCESS\", \"CONFLICT\", \"MISSING\", \"ERROR\"])\n// .describe(\"Operation status\"),\n// error: z\n// .string()\n// .optional()\n// .describe(\"Error details if operation failed\"), // TODO: Define error schema\n// operations: z\n// .array(z.object({}))\n// .describe(\"Array of operations created\"), // TODO: Define operation schema\n// document: z.object({}).optional().describe(\"Updated document\"), // TODO: Define document schema\n// signals: z.array(z.object({})).describe(\"Array of signals generated\"), // TODO: Define signal schema\n// })\n// .describe(\"Operation result\"),\n// },\n// } as const satisfies ToolSchema;\n\n// Drive Operation Tools\n\nexport const getDrivesTool = {\n name: \"getDrives\",\n description: \"List all drives\",\n inputSchema: {},\n outputSchema: {\n driveIds: z.array(z.string()).describe(\"Array of drive IDs\"),\n },\n} as const satisfies ToolSchema;\n\nexport const addDriveTool = {\n name: \"addDrive\",\n description: \"Create a new drive\",\n inputSchema: {\n driveInput: z\n .object({\n global: z\n .object({\n name: z.string().describe(\"Name of the drive\"),\n icon: z\n .string()\n .nullable()\n .optional()\n .describe(\"Optional icon for the drive\"),\n })\n .describe(\"Global drive properties\"),\n id: z.string().optional().describe(\"Optional drive ID\"),\n slug: z.string().optional().describe(\"Optional drive slug\"),\n preferredEditor: z\n .string()\n .optional()\n .describe(\"Optional preferred editor\"),\n local: z\n .object({\n availableOffline: z\n .boolean()\n .optional()\n .describe(\"Whether drive is available offline\"),\n sharingType: z\n .string()\n .nullable()\n .optional()\n .describe(\"Sharing type\"),\n })\n .optional()\n .describe(\"Optional local state properties\"),\n })\n .describe(\"Drive configuration\"),\n },\n outputSchema: {\n driveId: z.string().describe(\"ID of the created drive\"),\n },\n} as const satisfies ToolSchema;\n\nexport const getDriveTool = {\n name: \"getDrive\",\n description: \"Get a specific drive\",\n inputSchema: {\n driveId: z.string().describe(\"ID of the drive to retrieve\"),\n options: z\n .object({\n revisions: z\n .record(z.string(), z.number())\n .optional()\n .describe(\"Optional revision filter\"),\n checkHashes: z.boolean().optional().describe(\"Whether to check hashes\"),\n // TODO: Add other ReducerOptions if needed\n })\n .optional()\n .describe(\"Optional get document options\"),\n },\n outputSchema: {\n drive: z.unknown().describe(\"Drive document\"), // TODO: Define DocumentDriveDocument schema\n },\n} as const satisfies ToolSchema;\n\nexport const deleteDriveTool = {\n name: \"deleteDrive\",\n description: \"Delete a drive\",\n inputSchema: {\n driveId: z.string().describe(\"ID of the drive to delete\"),\n },\n outputSchema: {\n success: z.boolean().describe(\"Whether the deletion was successful\"),\n },\n} as const satisfies ToolSchema;\n\nexport const addRemoteDriveTool = {\n name: \"addRemoteDrive\",\n description: \"Connect to a remote drive\",\n inputSchema: {\n url: z.string().describe(\"URL of the remote drive\"),\n options: z\n .object({\n availableOffline: z\n .boolean()\n .describe(\"Whether drive is available offline\"),\n sharingType: z.string().nullable().optional().describe(\"Sharing type\"),\n pullFilter: z\n .object({\n branch: z\n .array(z.string())\n .nullable()\n .optional()\n .describe(\"Branch filter\"),\n documentId: z\n .array(z.string())\n .nullable()\n .optional()\n .describe(\"Document ID filter\"),\n documentType: z\n .array(z.string())\n .nullable()\n .optional()\n .describe(\"Document type filter\"),\n scope: z\n .array(z.string())\n .nullable()\n .optional()\n .describe(\"Scope filter\"),\n })\n .optional()\n .describe(\"Optional pull filter\"),\n pullInterval: z\n .number()\n .optional()\n .describe(\"Pull interval in milliseconds\"),\n })\n .describe(\"Remote drive options\"),\n },\n outputSchema: {\n driveId: z.string().describe(\"ID of the added remote drive\"),\n },\n} as const satisfies ToolSchema;\n\nexport const getDocumentModelSchemaTool = {\n name: \"getDocumentModelSchema\",\n description: \"Get the schema of a document model\",\n inputSchema: {\n type: z.string().describe(\"Type of the document model\"),\n },\n outputSchema: {\n schema: z.unknown().describe(\"Schema of the document model\"),\n },\n} as const satisfies ToolSchema;\n\nexport const getDocumentModelsTool = {\n name: \"getDocumentModels\",\n description: \"Get the list of document models\",\n inputSchema: {},\n outputSchema: {\n documentModels: z\n .array(\n z.object({\n name: z.string().describe(\"Name of the document model\"),\n type: z.string().describe(\"Type of the document model\"),\n description: z.string().describe(\"Description of the document model\"),\n extension: z.string().describe(\"Extension of the document model\"),\n authorName: z.string().describe(\"Author name of the document model\"),\n authorWebsite: z\n .string()\n .describe(\"Author website of the document model\"),\n }),\n )\n .describe(\"List of available document models\"),\n },\n} as const satisfies ToolSchema;\n\ntype ToolRecord<T extends readonly ToolSchema[]> = {\n [K in T[number][\"name\"]]: ToolWithCallback<Extract<T[number], { name: K }>>;\n};\n\n// All tools array for type inference\nconst allTools = [\n getDocumentTool,\n createDocumentTool,\n getDocumentsTool,\n deleteDocumentTool,\n addActionsTool,\n // addOperationTool,\n getDrivesTool,\n addDriveTool,\n getDriveTool,\n deleteDriveTool,\n addRemoteDriveTool,\n getDocumentModelSchemaTool,\n getDocumentModelsTool,\n] as const;\n\n// Inferred interface from tools\nexport type ReactorMcpTools = ToolRecord<typeof allTools>;\n\nexport async function createReactorMcpProvider(\n options: ReactorMcpProviderOptions,\n) {\n const { client, syncManager } = options;\n // No initialization needed - client is already initialized\n\n async function getDocumentModelModule(documentType: string) {\n return client.getDocumentModelModule(documentType);\n }\n\n const tools = {\n getDocument: toolWithCallback(getDocumentTool, async (params) => {\n const document = await client.get<PHDocument>(params.id);\n return { document: { header: document.header, state: document.state } };\n }),\n\n createDocument: toolWithCallback(createDocumentTool, async (params) => {\n if (params.driveId) {\n const module = await getDocumentModelModule(params.documentType);\n if (!module) {\n throw new Error(\n `Document model for type '${params.documentType}' not found`,\n );\n }\n const document = module.utils.createDocument();\n if (params.name) {\n document.header.name = params.name;\n }\n const created = await client.drives.addFile(\n params.driveId,\n document,\n params.parentFolder,\n );\n return { documentId: created.header.id };\n }\n\n const created = await client.createEmpty(params.documentType, {});\n return { documentId: created.header.id };\n }),\n\n getDocuments: toolWithCallback(getDocumentsTool, async (params) => {\n const result = await client.getOutgoingRelationships(\n params.parentId,\n \"child\",\n );\n const documentIds = result.results.map((doc) => doc.header.id);\n return { documentIds };\n }),\n\n deleteDocument: toolWithCallback(deleteDocumentTool, async (params) => {\n try {\n const incoming = await client.getIncomingRelationships(\n params.documentId,\n \"child\",\n );\n const driveParent = incoming.results.find(\n (p) => p.header.documentType === DRIVE_DOCUMENT_TYPE,\n );\n if (driveParent) {\n await client.drives.removeNode(\n driveParent.header.id,\n params.documentId,\n );\n } else {\n await client.deleteDocument(params.documentId);\n }\n return { success: true };\n } catch {\n return { success: false };\n }\n }),\n\n addActions: toolWithCallback(addActionsTool, async (params) => {\n const document = await client.get<PHDocument>(params.documentId);\n const documentModel = await getDocumentModelModule(\n document.header.documentType,\n );\n if (!documentModel) {\n throw new Error(\n `Document model for document type '${document.header.documentType}' not found`,\n );\n }\n const actions: Action[] = params.actions.map((paramAction) => {\n const action: Action = createAction(\n paramAction.type,\n paramAction.input ?? {},\n undefined,\n undefined,\n paramAction.scope,\n );\n const actionValidation = validateDocumentModelAction(\n documentModel,\n action,\n );\n if (!actionValidation.isValid) {\n throw new Error(\n `Invalid action ${JSON.stringify(action)}: ${actionValidation.errors.join(\", \")}`,\n );\n }\n return action;\n });\n\n // Execute actions on the document using the \"main\" branch\n await client.execute(params.documentId, \"main\", actions);\n\n return {\n success: true,\n };\n }),\n\n // Drive operation implementations\n getDrives: toolWithCallback(getDrivesTool, async () => {\n // Find all documents of type \"powerhouse/document-drive\"\n const result = await client.find({ type: DRIVE_DOCUMENT_TYPE });\n const driveIds = result.results.map((doc: PHDocument) => doc.header.id);\n return { driveIds };\n }),\n\n addDrive: toolWithCallback(addDriveTool, async (params) => {\n // Create an empty drive document\n const drive = await client.createEmpty<DocumentDriveDocument>(\n DRIVE_DOCUMENT_TYPE,\n {},\n );\n\n // If name is provided, set it using an action\n if (params.driveInput.global?.name) {\n await client.rename(drive.header.id, params.driveInput.global.name);\n }\n\n return { driveId: drive.header.id };\n }),\n\n getDrive: toolWithCallback(getDriveTool, async (params) => {\n const drive = await client.get<DocumentDriveDocument>(params.driveId);\n return { drive: { header: drive.header, state: drive.state } };\n }),\n\n deleteDrive: toolWithCallback(deleteDriveTool, async (params) => {\n try {\n // Use CASCADE to delete the drive and all its contents\n await client.deleteDocument(params.driveId);\n return { success: true };\n } catch {\n return { success: false };\n }\n }),\n\n addRemoteDrive: toolWithCallback(addRemoteDriveTool, async (params) => {\n if (!syncManager) {\n throw new Error(\n \"Remote drive management is not available. \" +\n \"SyncManager was not configured for this MCP server.\",\n );\n }\n\n // Fetch drive info from the REST endpoint to get both id and graphqlEndpoint\n const response = await fetch(params.url);\n if (!response.ok) {\n throw new Error(`Failed to resolve drive info from ${params.url}`);\n }\n const driveInfo = (await response.json()) as {\n id: string;\n graphqlEndpoint: string;\n };\n\n const resolvedDriveId = driveInfo.id;\n const collectionId = driveCollectionId(\"main\", resolvedDriveId);\n\n // Check if remote already exists\n const existingRemote = syncManager\n .list()\n .find((remote) => remote.collectionId === collectionId);\n if (existingRemote) {\n return { driveId: resolvedDriveId };\n }\n\n // Add the remote via SyncManager\n const remoteName = `mcp-remote-${crypto.randomUUID()}`;\n await syncManager.add(remoteName, collectionId, {\n type: \"gql\",\n parameters: {\n url: driveInfo.graphqlEndpoint,\n },\n });\n\n return { driveId: resolvedDriveId };\n }),\n\n getDocumentModels: toolWithCallback(getDocumentModelsTool, async () => {\n const result = await client.getDocumentModelModules();\n return {\n documentModels: result.results.map((model: DocumentModelModule) => {\n const schemaGlobal = model.documentModel.global;\n return {\n name: schemaGlobal.name,\n type: schemaGlobal.id,\n description: schemaGlobal.description,\n extension: schemaGlobal.extension,\n authorName: schemaGlobal.author.name,\n authorWebsite: schemaGlobal.author.website ?? \"\",\n };\n }),\n };\n }),\n\n getDocumentModelSchema: toolWithCallback(\n getDocumentModelSchemaTool,\n async (params) => {\n const documentModel = await getDocumentModelModule(params.type);\n const schema = documentModel?.documentModel.global;\n if (!schema) {\n throw new Error(`Document model '${params.type}' not found`);\n }\n return { schema };\n },\n ),\n } as const;\n\n const resources = {};\n\n const prompts = {};\n\n return {\n tools,\n resources,\n prompts,\n } as const;\n}\n","import { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport type { IReactorClient, ISyncManager } from \"@powerhousedao/reactor\";\nimport { createReactorMcpProvider } from \"./tools/reactor.js\";\n\nexport interface CreateServerOptions {\n client: IReactorClient;\n syncManager?: ISyncManager;\n}\n\nexport const ReactorMcpInstructions = `MUST BE USED when handling documents or document-models for the Powerhouse/Vetra ecosystem.\nThere are 5 main concepts to know of: \n- Document Model: A template for creating documents. It defines the schema and allowed operations for a type of document.\n- Document: An instance of a document model. It contains actual data following the structure defined by the document model and can be changed using operations.\n- Drive: A document of type \"powerhouse/document-drive\" which represents a collection of documents and folders. To create a document inside a drive, use the \"createDocument\" tool with the \"driveId\" parameter — this handles everything atomically. Use \"addActions\" with \"ADD_FILE\" only when adding an existing document to a drive.\n- Action: A proposed change to a document. It is a JSON object with the action name and input that defines the action to be taken on the document. Should be dispatched by calling the \"addActions\" tool.\n- Operation: A change done to a document. It contains the action object plus additional metadata such as the index of the operation in the document history, the timestamp it was added, the hash of the resulting document data, the number of operations skipped, and the error message if the operation failed. Actions dispatched with \"addActions\" get converted into an operation.\n\nWhen planning to add multiple actions to a document, try to reduce the number of \"addActions\" calls to a minimum by adding multiple actions at once.\nUnless the user specifies otherwise, and a drive with slug \"vetra\" is available, create new documents inside it by passing its ID as the \"driveId\" parameter to \"createDocument\".\n\nExamples:\n<example>Context: User needs to create a new document model for their application. user: 'I need to create a user profile document model with fields for name, email, and preferences' assistant: 'I'll use the reactor-mcp-server to help you create this document model.' <commentary>Since the user is requesting document model creation, use the reactor-mcp-document-expert agent to ensure proper reactor-mcp tool usage.</commentary></example> <example>Context: User is building a content management system and needs create documents for certain types of document models. user: 'Can you help me create example documents for blog posts and categories document models?' assistant: 'Let me use the reactor-mcp-server to create these documents using the appropriate reactor-mcp tool calls.' <commentary>Document model creation requires the reactor-mcp-server tool calls to ensure compliance.</commentary></example>\n<example>Context: User needs to create a new document instance of a given document model. user: 'I need to create a demo user profile document' assistant: 'I'll use the reactor-mcp-server to help you create this document with example values.' <commentary>Since the user is requesting document model creation, use the reactor-mcp-document-expert agent to ensure proper reactor-mcp tool usage.</commentary></example> <example>Context: User is building a content management system and needs create documents for certain types of document models. user: 'Can you help me create example documents for blog posts and categories document models?' assistant: 'Let me use the reactor-mcp-server to create these documents using the appropriate reactor-mcp tool calls.' <commentary>Document creation requires the reactor-mcp-server tool calls to ensure compliance.</commentary></example>\n`;\n\nexport async function createServer(\n options: CreateServerOptions,\n): Promise<McpServer> {\n const { client, syncManager } = options;\n const server = new McpServer(\n {\n name: \"reactor-mcp-server\",\n version: \"1.0.0\",\n description: ReactorMcpInstructions,\n },\n {\n capabilities: {\n tools: {},\n resources: {\n subscribe: true,\n listChanged: true,\n },\n prompts: {\n listChanged: true,\n },\n },\n },\n );\n\n server.registerResource(\n \"instructions\",\n \"reactor://instructions\",\n {\n title: \"Instructions\",\n description: \"General instructions on how to use the tools of this MCP\",\n mimeType: \"text/plain\",\n },\n (uri) => ({\n contents: [\n {\n uri: uri.href,\n text: ReactorMcpInstructions,\n },\n ],\n }),\n );\n\n const reactorProvider = await createReactorMcpProvider({\n client,\n syncManager,\n });\n\n const { callback, ...toolSchema } = reactorProvider.tools.getDocumentModels;\n // server.registerTool(\"getDocumentModels\", toolSchema, callback);\n Object.entries(reactorProvider.tools).forEach(\n ([toolName, { callback, ...schema }]) => {\n server.registerTool(toolName, schema as any, callback as any);\n },\n );\n\n return server;\n}\n"],"mappings":";;;;;;;AAEA,MAAa,SAAkB,YAAY,CAAC,cAAc,CAAC;;;ACQ3D,IAAa,yBAAb,cAA4C,MAAM;CAChD,YAAY,UAAsB;AAChC,QAAM,0BAA0B,SAAS,QAAQ;AACjD,OAAK,OAAO;AACZ,OAAK,QAAQ;;;;;;;;;;;AAYjB,SAAgB,iBACd,MACA,cAKA;CACA,MAAM,kBAAkB,OACtB,SAC4B;AAC5B,MAAI;GACF,MAAM,SAAS,MAAM,aAAa,KAAK;AACvC,UAAO;IACL,SAAS,CACP;KACE,MAAM;KACN,MAAM,KAAK,UAAU,OAAO;KAC7B,CACF;IACD,mBAAmB;IACpB;WACM,OAAO;AAGd,UAAO;IACL,SAAS;IACT,SAAS,CACP;KACE,MAAM;KACN,MAAM,UANV,iBAAiB,QAAQ,MAAM,UAAU,OAAO,MAAM;KAOnD,CACF;IACF;;;AAGL,QAAO;EACL,GAAG;EACH,UAAU;EACX;;AAGH,SAAgB,4BACd,qBACA,QACwC;CACxC,MAAM,SAAmB,EAAE;CAE3B,MAAM,cAAc,oBAAoB,cAAc;AAGtD,KAAI,CAAC,YAAY,kBAAkB,YAAY,eAAe,WAAW,GAAG;AAC1E,SAAO,KAAK,uCAAuC;AACnD,SAAO;GAAE,SAAS;GAAO;GAAQ;;CAGnC,MAAM,aACJ,YAAY,eAAe,YAAY,eAAe,SAAS;CAGjE,IAAI,YAAoD;AAExD,MAAK,MAAM,UAAU,WAAW,SAAS;EACvC,MAAM,qCAAqC,OAAO,WAAW,MAC1D,OAAO,GAAG,SAAS,OAAO,KAC5B;AACD,MAAI,oCAAoC;AACtC,eAAY;AACZ;;;AAIJ,KAAI,CAAC,WAAW;AACd,SAAO,KACL,cAAc,OAAO,KAAK,sDAC3B;AACD,SAAO;GAAE,SAAS;GAAO;GAAQ;;CAInC,MAAM,sBAAsB,UAAU,OAAO,KAAK;CAGlD,MAAM,gBAAgB,oBAAoB,QAAQ;AAElD,KAAI,CAAC,eAAe;AAClB,SAAO,KACL,mBAAmB,oBAAoB,qBAAqB,OAAO,KAAK,8DACzE;AACD,SAAO;GAAE,SAAS;GAAO;GAAQ;;CAInC,IAAI,aAA2B;AAC/B,KAAI;AACF,gBAAc,OAAO,MAAM;UACpB,GAAG;AACV,eAAa,aAAa,QAAQ,IAAI,IAAI,MAAM,KAAK,UAAU,EAAE,CAAC;;AAGpE,KAAI,WACF,QAAO,KAAK,2BAA2B,WAAW,UAAU;AAI9D,KAAI,UAAU,SAAS,OAAO,UAAU,UAAU,MAChD,QAAO,KACL,iBAAiB,OAAO,MAAM,oCAAoC,UAAU,MAAM,GACnF;AAGH,QAAO;EACL,SAAS,OAAO,WAAW;EAC3B;EACD;;;;AC/HH,MAAM,sBAAsB;AAO5B,MAAa,qBAAqB;CAChC,MAAM;CACN,aAAa;;;CAGb,aAAa;EACX,cAAc,EAAE,QAAQ,CAAC,SAAS,iCAAiC;EACnE,MAAM,EACH,QAAQ,CACR,UAAU,CACV,SACC,mHACD;EACH,SAAS,EACN,QAAQ,CACR,UAAU,CACV,SACC,uGACD;EACH,cAAc,EACX,QAAQ,CACR,UAAU,CACV,SACC,oGACD;EACJ;CACD,cAAc,EACZ,YAAY,EAAE,QAAQ,CAAC,SAAS,6BAA6B,EAC9D;CACF;AAED,MAAa,kBAAkB;CAC7B,MAAM;CACN,aAAa;CACb,aAAa,EACX,IAAI,EAAE,QAAQ,CAAC,SAAS,iCAAiC,EAC1D;CACD,cAAc,EACZ,UAAU,EAAE,SAAS,CAAC,SAAS,yBAAyB,EACzD;CACF;AAED,MAAa,mBAAmB;CAC9B,MAAM;CACN,aAAa;CACb,aAAa,EACX,UAAU,EAAE,QAAQ,CAAC,SAAS,kBAAkB,EACjD;CACD,cAAc,EACZ,aAAa,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC,SAAS,wBAAwB,EACnE;CACF;AAED,MAAa,qBAAqB;CAChC,MAAM;CACN,aAAa;CACb,aAAa,EACX,YAAY,EAAE,QAAQ,CAAC,SAAS,+BAA+B,EAChE;CACD,cAAc,EACZ,SAAS,EAAE,SAAS,CAAC,SAAS,sCAAsC,EACrE;CACF;AAED,MAAa,iBAAiB;CAC5B,MAAM;CACN,aACE;CACF,aAAa;EACX,YAAY,EAAE,QAAQ,CAAC,SAAS,qBAAqB;EACrD,SAAS,EACN,MACC,EACG,OAAO;GACN,MAAM,EAAE,QAAQ,CAAC,SAAS,yBAAyB;GACnD,OAAO,EAAE,SAAS,CAAC,SAAS,4BAA4B;GACxD,OAAO,EAAE,QAAQ,CAAC,SAAS,0BAA0B;GACrD,SAAS,EACN,OAAO,EAAE,QAAQ,EAAE,EAAE,SAAS,CAAC,CAC/B,UAAU,CACV,SAAS,0BAA0B;GACvC,CAAC,CACD,QAAQ,CACZ,CACA,SAAS,gCAAgC;EAC7C;CACD,cAAc,EACZ,SAAS,EAAE,SAAS,CAAC,SAAS,iCAAiC,EAChE;CACF;AAkDD,MAAa,gBAAgB;CAC3B,MAAM;CACN,aAAa;CACb,aAAa,EAAE;CACf,cAAc,EACZ,UAAU,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC,SAAS,qBAAqB,EAC7D;CACF;AAED,MAAa,eAAe;CAC1B,MAAM;CACN,aAAa;CACb,aAAa,EACX,YAAY,EACT,OAAO;EACN,QAAQ,EACL,OAAO;GACN,MAAM,EAAE,QAAQ,CAAC,SAAS,oBAAoB;GAC9C,MAAM,EACH,QAAQ,CACR,UAAU,CACV,UAAU,CACV,SAAS,8BAA8B;GAC3C,CAAC,CACD,SAAS,0BAA0B;EACtC,IAAI,EAAE,QAAQ,CAAC,UAAU,CAAC,SAAS,oBAAoB;EACvD,MAAM,EAAE,QAAQ,CAAC,UAAU,CAAC,SAAS,sBAAsB;EAC3D,iBAAiB,EACd,QAAQ,CACR,UAAU,CACV,SAAS,4BAA4B;EACxC,OAAO,EACJ,OAAO;GACN,kBAAkB,EACf,SAAS,CACT,UAAU,CACV,SAAS,qCAAqC;GACjD,aAAa,EACV,QAAQ,CACR,UAAU,CACV,UAAU,CACV,SAAS,eAAe;GAC5B,CAAC,CACD,UAAU,CACV,SAAS,kCAAkC;EAC/C,CAAC,CACD,SAAS,sBAAsB,EACnC;CACD,cAAc,EACZ,SAAS,EAAE,QAAQ,CAAC,SAAS,0BAA0B,EACxD;CACF;AAED,MAAa,eAAe;CAC1B,MAAM;CACN,aAAa;CACb,aAAa;EACX,SAAS,EAAE,QAAQ,CAAC,SAAS,8BAA8B;EAC3D,SAAS,EACN,OAAO;GACN,WAAW,EACR,OAAO,EAAE,QAAQ,EAAE,EAAE,QAAQ,CAAC,CAC9B,UAAU,CACV,SAAS,2BAA2B;GACvC,aAAa,EAAE,SAAS,CAAC,UAAU,CAAC,SAAS,0BAA0B;GAExE,CAAC,CACD,UAAU,CACV,SAAS,gCAAgC;EAC7C;CACD,cAAc,EACZ,OAAO,EAAE,SAAS,CAAC,SAAS,iBAAiB,EAC9C;CACF;AAED,MAAa,kBAAkB;CAC7B,MAAM;CACN,aAAa;CACb,aAAa,EACX,SAAS,EAAE,QAAQ,CAAC,SAAS,4BAA4B,EAC1D;CACD,cAAc,EACZ,SAAS,EAAE,SAAS,CAAC,SAAS,sCAAsC,EACrE;CACF;AAED,MAAa,qBAAqB;CAChC,MAAM;CACN,aAAa;CACb,aAAa;EACX,KAAK,EAAE,QAAQ,CAAC,SAAS,0BAA0B;EACnD,SAAS,EACN,OAAO;GACN,kBAAkB,EACf,SAAS,CACT,SAAS,qCAAqC;GACjD,aAAa,EAAE,QAAQ,CAAC,UAAU,CAAC,UAAU,CAAC,SAAS,eAAe;GACtE,YAAY,EACT,OAAO;IACN,QAAQ,EACL,MAAM,EAAE,QAAQ,CAAC,CACjB,UAAU,CACV,UAAU,CACV,SAAS,gBAAgB;IAC5B,YAAY,EACT,MAAM,EAAE,QAAQ,CAAC,CACjB,UAAU,CACV,UAAU,CACV,SAAS,qBAAqB;IACjC,cAAc,EACX,MAAM,EAAE,QAAQ,CAAC,CACjB,UAAU,CACV,UAAU,CACV,SAAS,uBAAuB;IACnC,OAAO,EACJ,MAAM,EAAE,QAAQ,CAAC,CACjB,UAAU,CACV,UAAU,CACV,SAAS,eAAe;IAC5B,CAAC,CACD,UAAU,CACV,SAAS,uBAAuB;GACnC,cAAc,EACX,QAAQ,CACR,UAAU,CACV,SAAS,gCAAgC;GAC7C,CAAC,CACD,SAAS,uBAAuB;EACpC;CACD,cAAc,EACZ,SAAS,EAAE,QAAQ,CAAC,SAAS,+BAA+B,EAC7D;CACF;AAED,MAAa,6BAA6B;CACxC,MAAM;CACN,aAAa;CACb,aAAa,EACX,MAAM,EAAE,QAAQ,CAAC,SAAS,6BAA6B,EACxD;CACD,cAAc,EACZ,QAAQ,EAAE,SAAS,CAAC,SAAS,+BAA+B,EAC7D;CACF;AAED,MAAa,wBAAwB;CACnC,MAAM;CACN,aAAa;CACb,aAAa,EAAE;CACf,cAAc,EACZ,gBAAgB,EACb,MACC,EAAE,OAAO;EACP,MAAM,EAAE,QAAQ,CAAC,SAAS,6BAA6B;EACvD,MAAM,EAAE,QAAQ,CAAC,SAAS,6BAA6B;EACvD,aAAa,EAAE,QAAQ,CAAC,SAAS,oCAAoC;EACrE,WAAW,EAAE,QAAQ,CAAC,SAAS,kCAAkC;EACjE,YAAY,EAAE,QAAQ,CAAC,SAAS,oCAAoC;EACpE,eAAe,EACZ,QAAQ,CACR,SAAS,uCAAuC;EACpD,CAAC,CACH,CACA,SAAS,oCAAoC,EACjD;CACF;AA0BD,eAAsB,yBACpB,SACA;CACA,MAAM,EAAE,QAAQ,gBAAgB;CAGhC,eAAe,uBAAuB,cAAsB;AAC1D,SAAO,OAAO,uBAAuB,aAAa;;AAwNpD,QAAO;EACL,OAtNY;GACZ,aAAa,iBAAiB,iBAAiB,OAAO,WAAW;IAC/D,MAAM,WAAW,MAAM,OAAO,IAAgB,OAAO,GAAG;AACxD,WAAO,EAAE,UAAU;KAAE,QAAQ,SAAS;KAAQ,OAAO,SAAS;KAAO,EAAE;KACvE;GAEF,gBAAgB,iBAAiB,oBAAoB,OAAO,WAAW;AACrE,QAAI,OAAO,SAAS;KAClB,MAAM,SAAS,MAAM,uBAAuB,OAAO,aAAa;AAChE,SAAI,CAAC,OACH,OAAM,IAAI,MACR,4BAA4B,OAAO,aAAa,aACjD;KAEH,MAAM,WAAW,OAAO,MAAM,gBAAgB;AAC9C,SAAI,OAAO,KACT,UAAS,OAAO,OAAO,OAAO;AAOhC,YAAO,EAAE,aALO,MAAM,OAAO,OAAO,QAClC,OAAO,SACP,UACA,OAAO,aACR,EAC4B,OAAO,IAAI;;AAI1C,WAAO,EAAE,aADO,MAAM,OAAO,YAAY,OAAO,cAAc,EAAE,CAAC,EACpC,OAAO,IAAI;KACxC;GAEF,cAAc,iBAAiB,kBAAkB,OAAO,WAAW;AAMjE,WAAO,EAAE,cALM,MAAM,OAAO,yBAC1B,OAAO,UACP,QACD,EAC0B,QAAQ,KAAK,QAAQ,IAAI,OAAO,GAAG,EACxC;KACtB;GAEF,gBAAgB,iBAAiB,oBAAoB,OAAO,WAAW;AACrE,QAAI;KAKF,MAAM,eAJW,MAAM,OAAO,yBAC5B,OAAO,YACP,QACD,EAC4B,QAAQ,MAClC,MAAM,EAAE,OAAO,iBAAiB,oBAClC;AACD,SAAI,YACF,OAAM,OAAO,OAAO,WAClB,YAAY,OAAO,IACnB,OAAO,WACR;SAED,OAAM,OAAO,eAAe,OAAO,WAAW;AAEhD,YAAO,EAAE,SAAS,MAAM;YAClB;AACN,YAAO,EAAE,SAAS,OAAO;;KAE3B;GAEF,YAAY,iBAAiB,gBAAgB,OAAO,WAAW;IAC7D,MAAM,WAAW,MAAM,OAAO,IAAgB,OAAO,WAAW;IAChE,MAAM,gBAAgB,MAAM,uBAC1B,SAAS,OAAO,aACjB;AACD,QAAI,CAAC,cACH,OAAM,IAAI,MACR,qCAAqC,SAAS,OAAO,aAAa,aACnE;IAEH,MAAM,UAAoB,OAAO,QAAQ,KAAK,gBAAgB;KAC5D,MAAM,SAAiB,aACrB,YAAY,MACZ,YAAY,SAAS,EAAE,EACvB,KAAA,GACA,KAAA,GACA,YAAY,MACb;KACD,MAAM,mBAAmB,4BACvB,eACA,OACD;AACD,SAAI,CAAC,iBAAiB,QACpB,OAAM,IAAI,MACR,kBAAkB,KAAK,UAAU,OAAO,CAAC,IAAI,iBAAiB,OAAO,KAAK,KAAK,GAChF;AAEH,YAAO;MACP;AAGF,UAAM,OAAO,QAAQ,OAAO,YAAY,QAAQ,QAAQ;AAExD,WAAO,EACL,SAAS,MACV;KACD;GAGF,WAAW,iBAAiB,eAAe,YAAY;AAIrD,WAAO,EAAE,WAFM,MAAM,OAAO,KAAK,EAAE,MAAM,qBAAqB,CAAC,EACvC,QAAQ,KAAK,QAAoB,IAAI,OAAO,GAAG,EACpD;KACnB;GAEF,UAAU,iBAAiB,cAAc,OAAO,WAAW;IAEzD,MAAM,QAAQ,MAAM,OAAO,YACzB,qBACA,EAAE,CACH;AAGD,QAAI,OAAO,WAAW,QAAQ,KAC5B,OAAM,OAAO,OAAO,MAAM,OAAO,IAAI,OAAO,WAAW,OAAO,KAAK;AAGrE,WAAO,EAAE,SAAS,MAAM,OAAO,IAAI;KACnC;GAEF,UAAU,iBAAiB,cAAc,OAAO,WAAW;IACzD,MAAM,QAAQ,MAAM,OAAO,IAA2B,OAAO,QAAQ;AACrE,WAAO,EAAE,OAAO;KAAE,QAAQ,MAAM;KAAQ,OAAO,MAAM;KAAO,EAAE;KAC9D;GAEF,aAAa,iBAAiB,iBAAiB,OAAO,WAAW;AAC/D,QAAI;AAEF,WAAM,OAAO,eAAe,OAAO,QAAQ;AAC3C,YAAO,EAAE,SAAS,MAAM;YAClB;AACN,YAAO,EAAE,SAAS,OAAO;;KAE3B;GAEF,gBAAgB,iBAAiB,oBAAoB,OAAO,WAAW;AACrE,QAAI,CAAC,YACH,OAAM,IAAI,MACR,gGAED;IAIH,MAAM,WAAW,MAAM,MAAM,OAAO,IAAI;AACxC,QAAI,CAAC,SAAS,GACZ,OAAM,IAAI,MAAM,qCAAqC,OAAO,MAAM;IAEpE,MAAM,YAAa,MAAM,SAAS,MAAM;IAKxC,MAAM,kBAAkB,UAAU;IAClC,MAAM,eAAe,kBAAkB,QAAQ,gBAAgB;AAM/D,QAHuB,YACpB,MAAM,CACN,MAAM,WAAW,OAAO,iBAAiB,aAAa,CAEvD,QAAO,EAAE,SAAS,iBAAiB;IAIrC,MAAM,aAAa,cAAc,OAAO,YAAY;AACpD,UAAM,YAAY,IAAI,YAAY,cAAc;KAC9C,MAAM;KACN,YAAY,EACV,KAAK,UAAU,iBAChB;KACF,CAAC;AAEF,WAAO,EAAE,SAAS,iBAAiB;KACnC;GAEF,mBAAmB,iBAAiB,uBAAuB,YAAY;AAErE,WAAO,EACL,iBAFa,MAAM,OAAO,yBAAyB,EAE5B,QAAQ,KAAK,UAA+B;KACjE,MAAM,eAAe,MAAM,cAAc;AACzC,YAAO;MACL,MAAM,aAAa;MACnB,MAAM,aAAa;MACnB,aAAa,aAAa;MAC1B,WAAW,aAAa;MACxB,YAAY,aAAa,OAAO;MAChC,eAAe,aAAa,OAAO,WAAW;MAC/C;MACD,EACH;KACD;GAEF,wBAAwB,iBACtB,4BACA,OAAO,WAAW;IAEhB,MAAM,UADgB,MAAM,uBAAuB,OAAO,KAAK,GACjC,cAAc;AAC5C,QAAI,CAAC,OACH,OAAM,IAAI,MAAM,mBAAmB,OAAO,KAAK,aAAa;AAE9D,WAAO,EAAE,QAAQ;KAEpB;GACF;EAQC,WANgB,EAAE;EAOlB,SALc,EAAE;EAMjB;;;;ACxjBH,MAAa,yBAAyB;;;;;;;;;;;;;;;AAgBtC,eAAsB,aACpB,SACoB;CACpB,MAAM,EAAE,QAAQ,gBAAgB;CAChC,MAAM,SAAS,IAAI,UACjB;EACE,MAAM;EACN,SAAS;EACT,aAAa;EACd,EACD,EACE,cAAc;EACZ,OAAO,EAAE;EACT,WAAW;GACT,WAAW;GACX,aAAa;GACd;EACD,SAAS,EACP,aAAa,MACd;EACF,EACF,CACF;AAED,QAAO,iBACL,gBACA,0BACA;EACE,OAAO;EACP,aAAa;EACb,UAAU;EACX,GACA,SAAS,EACR,UAAU,CACR;EACE,KAAK,IAAI;EACT,MAAM;EACP,CACF,EACF,EACF;CAED,MAAM,kBAAkB,MAAM,yBAAyB;EACrD;EACA;EACD,CAAC;CAEF,MAAM,EAAE,UAAU,GAAG,eAAe,gBAAgB,MAAM;AAE1D,QAAO,QAAQ,gBAAgB,MAAM,CAAC,SACnC,CAAC,UAAU,EAAE,UAAU,GAAG,cAAc;AACvC,SAAO,aAAa,UAAU,QAAe,SAAgB;GAEhE;AAED,QAAO"}
1
+ {"version":3,"file":"server-BXN-R-gg.mjs","names":[],"sources":["../src/logger.ts","../src/tools/utils.ts","../src/tools/reactor.ts","../src/server.ts"],"sourcesContent":["import { childLogger, type ILogger } from \"document-model\";\n\nexport const logger: ILogger = childLogger([\"reactor-mcp\"]);\n","import type { CallToolResult } from \"@modelcontextprotocol/sdk/types.js\";\nimport { camelCase } from \"change-case\";\nimport type {\n Action,\n DocumentModelModule,\n Operation,\n} from \"@powerhousedao/shared/document-model\";\nimport type { z } from \"zod\";\nimport type { ResolveZodSchema, ToolSchema } from \"./types.js\";\n\nexport class InvalidToolOutputError extends Error {\n constructor(zodError: z.ZodError) {\n super(\"Invalid tool output\\n\" + zodError.message);\n this.name = \"InvalidToolOutputError\";\n this.cause = zodError;\n }\n}\n\n/**\n * Creates a tool with a callback function that handles the tool execution,\n * ensuring the output is valid and errors are handled and returned correctly.\n * @param tool The tool schema to wrap.\n * @param toolCallback The callback function to execute when the tool is called.\n * @returns A CallToolResult with structuredContent if OutputSchema is defined or content if undefined. If the\n * callback throws an error, the result will have isError set to true and the error message in the content.\n */\nexport function toolWithCallback<T extends ToolSchema>(\n tool: T,\n toolCallback: (\n args: ResolveZodSchema<T[\"inputSchema\"]>,\n ) =>\n | ResolveZodSchema<T[\"outputSchema\"]>\n | Promise<ResolveZodSchema<T[\"outputSchema\"]>>,\n) {\n const wrappedCallback = async (\n args: ResolveZodSchema<T[\"inputSchema\"]>,\n ): Promise<CallToolResult> => {\n try {\n const result = await toolCallback(args);\n return {\n content: [\n {\n type: \"text\",\n text: JSON.stringify(result),\n },\n ],\n structuredContent: result,\n } as const satisfies CallToolResult;\n } catch (error) {\n const errorString =\n error instanceof Error ? error.message : String(error);\n return {\n isError: true,\n content: [\n {\n type: \"text\",\n text: `Error: ${errorString}`,\n },\n ],\n } as const satisfies CallToolResult;\n }\n };\n return {\n ...tool,\n callback: wrappedCallback,\n };\n}\n\nexport function validateDocumentModelAction(\n documentModelModule: DocumentModelModule,\n action: Action,\n): { isValid: boolean; errors: string[] } {\n const errors: string[] = [];\n\n const globalState = documentModelModule.documentModel.global;\n\n // Get the latest specification\n if (!globalState.specifications || globalState.specifications.length === 0) {\n errors.push(\"Document model has no specifications\");\n return { isValid: false, errors };\n }\n\n const latestSpec =\n globalState.specifications[globalState.specifications.length - 1];\n\n // Search through modules to find the operation that matches the action type (in SCREAMING_SNAKE_CASE)\n let operation: (Operation & { scope: string }) | null = null;\n\n for (const module of latestSpec.modules) {\n const unsafeOperationOrActionOrSomething = module.operations.find(\n (op) => op.name === action.type,\n ) as unknown as Operation & { scope: string };\n if (unsafeOperationOrActionOrSomething) {\n operation = unsafeOperationOrActionOrSomething;\n break;\n }\n }\n\n if (!operation) {\n errors.push(\n `Operation \"${action.type}\" is not defined in any module of the document model`,\n );\n return { isValid: false, errors };\n }\n\n // Convert action type from SCREAMING_SNAKE_CASE to camelCase to match action creators\n const camelCaseActionType = camelCase(action.type);\n\n // Check if action creator exists in documentModelModule.actions\n const actionCreator = documentModelModule.actions[camelCaseActionType];\n\n if (!actionCreator) {\n errors.push(\n `Action creator \"${camelCaseActionType}\" for action type \"${action.type}\" is not defined in documentModelDocumentModelModule.actions`,\n );\n return { isValid: false, errors };\n }\n\n // Validate the operation using the action creator. TODO: Use document model exported validators directly\n let inputError: Error | null = null;\n try {\n actionCreator(action.input);\n } catch (e) {\n inputError = e instanceof Error ? e : new Error(JSON.stringify(e));\n }\n\n if (inputError) {\n errors.push(`Input validation error: ${inputError.message}`);\n }\n\n // Validate scope if operation defines one\n if (operation.scope && action.scope !== operation.scope) {\n errors.push(\n `Action scope \"${action.scope}\" does not match operation scope \"${operation.scope}\"`,\n );\n }\n\n return {\n isValid: errors.length === 0,\n errors,\n };\n}\n","import type { IReactorClient, ISyncManager } from \"@powerhousedao/reactor\";\nimport { driveCollectionId } from \"@powerhousedao/reactor\";\nimport type { DocumentDriveDocument } from \"@powerhousedao/shared/document-drive\";\nimport type {\n Action,\n DocumentModelModule,\n PHDocument,\n} from \"@powerhousedao/shared/document-model\";\nimport { createAction } from \"@powerhousedao/shared/document-model\";\nimport { z } from \"zod\";\nimport type { ToolSchema, ToolWithCallback } from \"./types.js\";\nimport { toolWithCallback, validateDocumentModelAction } from \"./utils.js\";\n\nconst DRIVE_DOCUMENT_TYPE = \"powerhouse/document-drive\";\n\nexport type ReactorMcpProviderOptions = {\n client: IReactorClient;\n syncManager?: ISyncManager;\n};\n\nexport const createDocumentTool = {\n name: \"createDocument\",\n description: `Create a new document.\n Unless the user specifies otherwise, and a drive named \"vetra\" is available, add the document to that drive by providing the drive's ID in the \"driveId\" parameter.\n When \"driveId\" is provided, the document is created and added to the drive atomically — no separate \"addActions\" call with \"ADD_FILE\" is needed.`,\n inputSchema: {\n documentType: z.string().describe(\"Type of the document to create\"),\n name: z\n .string()\n .optional()\n .describe(\n \"Optional name for the document. Used as both the document name and the drive node name when driveId is provided.\",\n ),\n driveId: z\n .string()\n .optional()\n .describe(\n \"Optional drive ID or slug. When provided, the document is created and added to the drive atomically.\",\n ),\n parentFolder: z\n .string()\n .optional()\n .describe(\n \"Optional folder ID within the drive to place the document in. Only used when driveId is provided.\",\n ),\n },\n outputSchema: {\n documentId: z.string().describe(\"ID of the created document\"),\n },\n} as const satisfies ToolSchema;\n\nexport const getDocumentTool = {\n name: \"getDocument\",\n description: \"Retrieve a document by its ID\",\n inputSchema: {\n id: z.string().describe(\"ID of the document to retrieve\"),\n },\n outputSchema: {\n document: z.unknown().describe(\"The retrieved Document\"),\n },\n} as const satisfies ToolSchema;\n\nexport const getDocumentsTool = {\n name: \"getDocuments\",\n description: \"List documents in a drive\",\n inputSchema: {\n parentId: z.string().describe(\"ID of the drive\"),\n },\n outputSchema: {\n documentIds: z.array(z.string()).describe(\"Array of document IDs\"),\n },\n} as const satisfies ToolSchema;\n\nexport const deleteDocumentTool = {\n name: \"deleteDocument\",\n description: \"Delete a document\",\n inputSchema: {\n documentId: z.string().describe(\"ID of the document to delete\"),\n },\n outputSchema: {\n success: z.boolean().describe(\"Whether the deletion was successful\"),\n },\n} as const satisfies ToolSchema;\n\nexport const addActionsTool = {\n name: \"addActions\",\n description:\n \"Adds actions to a document. Prefer adding multiples actions at once to reduce the number of steps.\",\n inputSchema: {\n documentId: z.string().describe(\"ID of the document\"),\n actions: z\n .array(\n z\n .object({\n type: z.string().describe(\"The name of the action\"),\n input: z.unknown().describe(\"The payload of the action\"),\n scope: z.string().describe(\"The scope of the action\"),\n context: z\n .record(z.string(), z.unknown())\n .optional()\n .describe(\"Optional action context\"), // TODO: Define context schema\n })\n .strict(),\n )\n .describe(\"Action to add to the document\"),\n },\n outputSchema: {\n success: z.boolean().describe(\"Whether the actions were added\"),\n },\n} as const satisfies ToolSchema;\n\n// export const addOperationTool = {\n// name: \"addOperation\",\n// description: \"Add an operation to a document\",\n// inputSchema: {\n// documentId: z.string().describe(\"ID of the document\"),\n// operation: z\n// .object({\n// type: z.string().describe(\"The name of the action\"),\n// input: z.unknown().describe(\"The payload of the action\"),\n// scope: z.string().describe(\"The scope of the action\"),\n// index: z.number().describe(\"Position of the operation in the history\"),\n// timestampUtcMs: z\n// .string()\n// .describe(\"Timestamp of when the operation was added\"),\n// hash: z.string().describe(\"Hash of the resulting document data\"),\n// skip: z.number().describe(\"The number of operations skipped\"),\n// error: z\n// .string()\n// .optional()\n// .describe(\"Error message for a failed action\"),\n// id: z.string().optional().describe(\"Unique operation id\"),\n// context: z.object({}).optional().describe(\"Optional action context\"), // TODO: Define context schema\n// })\n// .strict()\n// .describe(\"Operation to add to the document\"),\n// },\n// outputSchema: {\n// result: z\n// .object({\n// status: z\n// .enum([\"SUCCESS\", \"CONFLICT\", \"MISSING\", \"ERROR\"])\n// .describe(\"Operation status\"),\n// error: z\n// .string()\n// .optional()\n// .describe(\"Error details if operation failed\"), // TODO: Define error schema\n// operations: z\n// .array(z.object({}))\n// .describe(\"Array of operations created\"), // TODO: Define operation schema\n// document: z.object({}).optional().describe(\"Updated document\"), // TODO: Define document schema\n// signals: z.array(z.object({})).describe(\"Array of signals generated\"), // TODO: Define signal schema\n// })\n// .describe(\"Operation result\"),\n// },\n// } as const satisfies ToolSchema;\n\n// Drive Operation Tools\n\nexport const getDrivesTool = {\n name: \"getDrives\",\n description: \"List all drives\",\n inputSchema: {},\n outputSchema: {\n driveIds: z.array(z.string()).describe(\"Array of drive IDs\"),\n },\n} as const satisfies ToolSchema;\n\nexport const addDriveTool = {\n name: \"addDrive\",\n description: \"Create a new drive\",\n inputSchema: {\n driveInput: z\n .object({\n global: z\n .object({\n name: z.string().describe(\"Name of the drive\"),\n icon: z\n .string()\n .nullable()\n .optional()\n .describe(\"Optional icon for the drive\"),\n })\n .describe(\"Global drive properties\"),\n id: z.string().optional().describe(\"Optional drive ID\"),\n slug: z.string().optional().describe(\"Optional drive slug\"),\n preferredEditor: z\n .string()\n .optional()\n .describe(\"Optional preferred editor\"),\n local: z\n .object({\n availableOffline: z\n .boolean()\n .optional()\n .describe(\"Whether drive is available offline\"),\n sharingType: z\n .string()\n .nullable()\n .optional()\n .describe(\"Sharing type\"),\n })\n .optional()\n .describe(\"Optional local state properties\"),\n })\n .describe(\"Drive configuration\"),\n },\n outputSchema: {\n driveId: z.string().describe(\"ID of the created drive\"),\n },\n} as const satisfies ToolSchema;\n\nexport const getDriveTool = {\n name: \"getDrive\",\n description: \"Get a specific drive\",\n inputSchema: {\n driveId: z.string().describe(\"ID of the drive to retrieve\"),\n options: z\n .object({\n revisions: z\n .record(z.string(), z.number())\n .optional()\n .describe(\"Optional revision filter\"),\n checkHashes: z.boolean().optional().describe(\"Whether to check hashes\"),\n // TODO: Add other ReducerOptions if needed\n })\n .optional()\n .describe(\"Optional get document options\"),\n },\n outputSchema: {\n drive: z.unknown().describe(\"Drive document\"), // TODO: Define DocumentDriveDocument schema\n },\n} as const satisfies ToolSchema;\n\nexport const deleteDriveTool = {\n name: \"deleteDrive\",\n description: \"Delete a drive\",\n inputSchema: {\n driveId: z.string().describe(\"ID of the drive to delete\"),\n },\n outputSchema: {\n success: z.boolean().describe(\"Whether the deletion was successful\"),\n },\n} as const satisfies ToolSchema;\n\nexport const addRemoteDriveTool = {\n name: \"addRemoteDrive\",\n description: \"Connect to a remote drive\",\n inputSchema: {\n url: z.string().describe(\"URL of the remote drive\"),\n options: z\n .object({\n availableOffline: z\n .boolean()\n .describe(\"Whether drive is available offline\"),\n sharingType: z.string().nullable().optional().describe(\"Sharing type\"),\n pullFilter: z\n .object({\n branch: z\n .array(z.string())\n .nullable()\n .optional()\n .describe(\"Branch filter\"),\n documentId: z\n .array(z.string())\n .nullable()\n .optional()\n .describe(\"Document ID filter\"),\n documentType: z\n .array(z.string())\n .nullable()\n .optional()\n .describe(\"Document type filter\"),\n scope: z\n .array(z.string())\n .nullable()\n .optional()\n .describe(\"Scope filter\"),\n })\n .optional()\n .describe(\"Optional pull filter\"),\n pullInterval: z\n .number()\n .optional()\n .describe(\"Pull interval in milliseconds\"),\n })\n .describe(\"Remote drive options\"),\n },\n outputSchema: {\n driveId: z.string().describe(\"ID of the added remote drive\"),\n },\n} as const satisfies ToolSchema;\n\nexport const getDocumentModelSchemaTool = {\n name: \"getDocumentModelSchema\",\n description: \"Get the schema of a document model\",\n inputSchema: {\n type: z.string().describe(\"Type of the document model\"),\n },\n outputSchema: {\n schema: z.unknown().describe(\"Schema of the document model\"),\n },\n} as const satisfies ToolSchema;\n\nexport const getDocumentModelsTool = {\n name: \"getDocumentModels\",\n description: \"Get the list of document models\",\n inputSchema: {},\n outputSchema: {\n documentModels: z\n .array(\n z.object({\n name: z.string().describe(\"Name of the document model\"),\n type: z.string().describe(\"Type of the document model\"),\n description: z.string().describe(\"Description of the document model\"),\n extension: z.string().describe(\"Extension of the document model\"),\n authorName: z.string().describe(\"Author name of the document model\"),\n authorWebsite: z\n .string()\n .describe(\"Author website of the document model\"),\n }),\n )\n .describe(\"List of available document models\"),\n },\n} as const satisfies ToolSchema;\n\ntype ToolRecord<T extends readonly ToolSchema[]> = {\n [K in T[number][\"name\"]]: ToolWithCallback<Extract<T[number], { name: K }>>;\n};\n\n// All tools array for type inference\nconst _allTools = [\n getDocumentTool,\n createDocumentTool,\n getDocumentsTool,\n deleteDocumentTool,\n addActionsTool,\n // addOperationTool,\n getDrivesTool,\n addDriveTool,\n getDriveTool,\n deleteDriveTool,\n addRemoteDriveTool,\n getDocumentModelSchemaTool,\n getDocumentModelsTool,\n] as const;\n\n// Inferred interface from tools\nexport type ReactorMcpTools = ToolRecord<typeof _allTools>;\n\nexport function createReactorMcpProvider(options: ReactorMcpProviderOptions) {\n const { client, syncManager } = options;\n // No initialization needed - client is already initialized\n\n function getDocumentModelModule(documentType: string) {\n return client.getDocumentModelModule(documentType);\n }\n\n const tools = {\n getDocument: toolWithCallback(getDocumentTool, async (params) => {\n const document = await client.get<PHDocument>(params.id);\n return { document: { header: document.header, state: document.state } };\n }),\n\n createDocument: toolWithCallback(createDocumentTool, async (params) => {\n if (params.driveId) {\n const module = await getDocumentModelModule(params.documentType);\n if (!module) {\n throw new Error(\n `Document model for type '${params.documentType}' not found`,\n );\n }\n const document = module.utils.createDocument();\n if (params.name) {\n document.header.name = params.name;\n }\n const created = await client.drives.addFile(\n params.driveId,\n document,\n params.parentFolder,\n );\n return { documentId: created.header.id };\n }\n\n const created = await client.createEmpty(params.documentType, {});\n return { documentId: created.header.id };\n }),\n\n getDocuments: toolWithCallback(getDocumentsTool, async (params) => {\n const result = await client.getOutgoingRelationships(\n params.parentId,\n \"child\",\n );\n const documentIds = result.results.map((doc) => doc.header.id);\n return { documentIds };\n }),\n\n deleteDocument: toolWithCallback(deleteDocumentTool, async (params) => {\n try {\n const incoming = await client.getIncomingRelationships(\n params.documentId,\n \"child\",\n );\n const driveParent = incoming.results.find(\n (p) => p.header.documentType === DRIVE_DOCUMENT_TYPE,\n );\n if (driveParent) {\n await client.drives.removeNode(\n driveParent.header.id,\n params.documentId,\n );\n } else {\n await client.deleteDocument(params.documentId);\n }\n return { success: true };\n } catch {\n return { success: false };\n }\n }),\n\n addActions: toolWithCallback(addActionsTool, async (params) => {\n const document = await client.get<PHDocument>(params.documentId);\n const documentModel = await getDocumentModelModule(\n document.header.documentType,\n );\n if (!documentModel) {\n throw new Error(\n `Document model for document type '${document.header.documentType}' not found`,\n );\n }\n const actions: Action[] = params.actions.map((paramAction) => {\n const action: Action = createAction(\n paramAction.type,\n paramAction.input ?? {},\n undefined,\n undefined,\n paramAction.scope,\n );\n const actionValidation = validateDocumentModelAction(\n documentModel,\n action,\n );\n if (!actionValidation.isValid) {\n throw new Error(\n `Invalid action ${JSON.stringify(action)}: ${actionValidation.errors.join(\", \")}`,\n );\n }\n return action;\n });\n\n // Execute actions on the document using the \"main\" branch\n await client.execute(params.documentId, \"main\", actions);\n\n return {\n success: true,\n };\n }),\n\n // Drive operation implementations\n getDrives: toolWithCallback(getDrivesTool, async () => {\n // Find all documents of type \"powerhouse/document-drive\"\n const result = await client.find({ type: DRIVE_DOCUMENT_TYPE });\n const driveIds = result.results.map((doc: PHDocument) => doc.header.id);\n return { driveIds };\n }),\n\n addDrive: toolWithCallback(addDriveTool, async (params) => {\n // Create an empty drive document\n const drive = await client.createEmpty<DocumentDriveDocument>(\n DRIVE_DOCUMENT_TYPE,\n {},\n );\n\n // If name is provided, set it using an action\n if (params.driveInput.global?.name) {\n await client.rename(drive.header.id, params.driveInput.global.name);\n }\n\n return { driveId: drive.header.id };\n }),\n\n getDrive: toolWithCallback(getDriveTool, async (params) => {\n const drive = await client.get<DocumentDriveDocument>(params.driveId);\n return { drive: { header: drive.header, state: drive.state } };\n }),\n\n deleteDrive: toolWithCallback(deleteDriveTool, async (params) => {\n try {\n // Use CASCADE to delete the drive and all its contents\n await client.deleteDocument(params.driveId);\n return { success: true };\n } catch {\n return { success: false };\n }\n }),\n\n addRemoteDrive: toolWithCallback(addRemoteDriveTool, async (params) => {\n if (!syncManager) {\n throw new Error(\n \"Remote drive management is not available. \" +\n \"SyncManager was not configured for this MCP server.\",\n );\n }\n\n // Fetch drive info from the REST endpoint to get both id and graphqlEndpoint\n const response = await fetch(params.url);\n if (!response.ok) {\n throw new Error(`Failed to resolve drive info from ${params.url}`);\n }\n const driveInfo = (await response.json()) as {\n id: string;\n graphqlEndpoint: string;\n };\n\n const resolvedDriveId = driveInfo.id;\n const collectionId = driveCollectionId(\"main\", resolvedDriveId);\n\n // Check if remote already exists\n const existingRemote = syncManager\n .list()\n .find((remote) => remote.collectionId === collectionId);\n if (existingRemote) {\n return { driveId: resolvedDriveId };\n }\n\n // Add the remote via SyncManager\n const remoteName = `mcp-remote-${crypto.randomUUID()}`;\n await syncManager.add(remoteName, collectionId, {\n type: \"gql\",\n parameters: {\n url: driveInfo.graphqlEndpoint,\n },\n });\n\n return { driveId: resolvedDriveId };\n }),\n\n getDocumentModels: toolWithCallback(getDocumentModelsTool, async () => {\n const result = await client.getDocumentModelModules();\n return {\n documentModels: result.results.map((model: DocumentModelModule) => {\n const schemaGlobal = model.documentModel.global;\n return {\n name: schemaGlobal.name,\n type: schemaGlobal.id,\n description: schemaGlobal.description,\n extension: schemaGlobal.extension,\n authorName: schemaGlobal.author.name,\n authorWebsite: schemaGlobal.author.website ?? \"\",\n };\n }),\n };\n }),\n\n getDocumentModelSchema: toolWithCallback(\n getDocumentModelSchemaTool,\n async (params) => {\n const documentModel = await getDocumentModelModule(params.type);\n const schema = documentModel?.documentModel.global;\n if (!schema) {\n throw new Error(`Document model '${params.type}' not found`);\n }\n return { schema };\n },\n ),\n } as const;\n\n const resources = {};\n\n const prompts = {};\n\n return Promise.resolve({\n tools,\n resources,\n prompts,\n } as const);\n}\n","import { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport type { IReactorClient, ISyncManager } from \"@powerhousedao/reactor\";\nimport { createReactorMcpProvider } from \"./tools/reactor.js\";\n\nexport interface CreateServerOptions {\n client: IReactorClient;\n syncManager?: ISyncManager;\n}\n\nexport const ReactorMcpInstructions = `MUST BE USED when handling documents or document-models for the Powerhouse/Vetra ecosystem.\nThere are 5 main concepts to know of: \n- Document Model: A template for creating documents. It defines the schema and allowed operations for a type of document.\n- Document: An instance of a document model. It contains actual data following the structure defined by the document model and can be changed using operations.\n- Drive: A document of type \"powerhouse/document-drive\" which represents a collection of documents and folders. To create a document inside a drive, use the \"createDocument\" tool with the \"driveId\" parameter — this handles everything atomically. Use \"addActions\" with \"ADD_FILE\" only when adding an existing document to a drive.\n- Action: A proposed change to a document. It is a JSON object with the action name and input that defines the action to be taken on the document. Should be dispatched by calling the \"addActions\" tool.\n- Operation: A change done to a document. It contains the action object plus additional metadata such as the index of the operation in the document history, the timestamp it was added, the hash of the resulting document data, the number of operations skipped, and the error message if the operation failed. Actions dispatched with \"addActions\" get converted into an operation.\n\nWhen planning to add multiple actions to a document, try to reduce the number of \"addActions\" calls to a minimum by adding multiple actions at once.\nUnless the user specifies otherwise, and a drive with slug \"vetra\" is available, create new documents inside it by passing its ID as the \"driveId\" parameter to \"createDocument\".\n\nExamples:\n<example>Context: User needs to create a new document model for their application. user: 'I need to create a user profile document model with fields for name, email, and preferences' assistant: 'I'll use the reactor-mcp-server to help you create this document model.' <commentary>Since the user is requesting document model creation, use the reactor-mcp-document-expert agent to ensure proper reactor-mcp tool usage.</commentary></example> <example>Context: User is building a content management system and needs create documents for certain types of document models. user: 'Can you help me create example documents for blog posts and categories document models?' assistant: 'Let me use the reactor-mcp-server to create these documents using the appropriate reactor-mcp tool calls.' <commentary>Document model creation requires the reactor-mcp-server tool calls to ensure compliance.</commentary></example>\n<example>Context: User needs to create a new document instance of a given document model. user: 'I need to create a demo user profile document' assistant: 'I'll use the reactor-mcp-server to help you create this document with example values.' <commentary>Since the user is requesting document model creation, use the reactor-mcp-document-expert agent to ensure proper reactor-mcp tool usage.</commentary></example> <example>Context: User is building a content management system and needs create documents for certain types of document models. user: 'Can you help me create example documents for blog posts and categories document models?' assistant: 'Let me use the reactor-mcp-server to create these documents using the appropriate reactor-mcp tool calls.' <commentary>Document creation requires the reactor-mcp-server tool calls to ensure compliance.</commentary></example>\n`;\n\nexport async function createServer(\n options: CreateServerOptions,\n): Promise<McpServer> {\n const { client, syncManager } = options;\n const server = new McpServer(\n {\n name: \"reactor-mcp-server\",\n version: \"1.0.0\",\n description: ReactorMcpInstructions,\n },\n {\n capabilities: {\n tools: {},\n resources: {\n subscribe: true,\n listChanged: true,\n },\n prompts: {\n listChanged: true,\n },\n },\n },\n );\n\n server.registerResource(\n \"instructions\",\n \"reactor://instructions\",\n {\n title: \"Instructions\",\n description: \"General instructions on how to use the tools of this MCP\",\n mimeType: \"text/plain\",\n },\n (uri) => ({\n contents: [\n {\n uri: uri.href,\n text: ReactorMcpInstructions,\n },\n ],\n }),\n );\n\n const reactorProvider = await createReactorMcpProvider({\n client,\n syncManager,\n });\n\n // const { callback, ...toolSchema } = reactorProvider.tools.getDocumentModels;\n // server.registerTool(\"getDocumentModels\", toolSchema, callback);\n Object.entries(reactorProvider.tools).forEach(\n ([toolName, { callback, ...schema }]) => {\n server.registerTool(toolName, schema as any, callback as any);\n },\n );\n\n return server;\n}\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@powerhousedao/reactor-mcp",
3
- "version": "6.1.0-dev.1",
3
+ "version": "6.1.0-dev.10",
4
4
  "description": "MCP server for document model operations in the Powerhouse ecosystem. For document model creation tasks, consider using the document-model-creator agent which provides a more guided experience.",
5
5
  "type": "module",
6
6
  "repository": {
@@ -35,10 +35,10 @@
35
35
  "change-case": "5.4.4",
36
36
  "vite": "8.0.8",
37
37
  "zod": "4.3.6",
38
- "@powerhousedao/reactor": "6.1.0-dev.1",
39
- "@powerhousedao/reactor-drive": "6.1.0-dev.1",
40
- "@powerhousedao/shared": "6.1.0-dev.1",
41
- "document-model": "6.1.0-dev.1"
38
+ "@powerhousedao/shared": "6.1.0-dev.10",
39
+ "@powerhousedao/reactor": "6.1.0-dev.10",
40
+ "document-model": "6.1.0-dev.10",
41
+ "@powerhousedao/reactor-drive": "6.1.0-dev.10"
42
42
  },
43
43
  "devDependencies": {
44
44
  "@openfeature/core": "1.9.1",