@sensigo/realm-mcp 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (50) hide show
  1. package/README.md +67 -0
  2. package/dist/index.d.ts +6 -0
  3. package/dist/index.d.ts.map +1 -0
  4. package/dist/index.js +5 -0
  5. package/dist/index.js.map +1 -0
  6. package/dist/json-trace-buffer-store.d.ts +17 -0
  7. package/dist/json-trace-buffer-store.d.ts.map +1 -0
  8. package/dist/json-trace-buffer-store.js +128 -0
  9. package/dist/json-trace-buffer-store.js.map +1 -0
  10. package/dist/protocol/generator.d.ts +37 -0
  11. package/dist/protocol/generator.d.ts.map +1 -0
  12. package/dist/protocol/generator.js +99 -0
  13. package/dist/protocol/generator.js.map +1 -0
  14. package/dist/server.d.ts +39 -0
  15. package/dist/server.d.ts.map +1 -0
  16. package/dist/server.js +72 -0
  17. package/dist/server.js.map +1 -0
  18. package/dist/tools/append-trace.d.ts +30 -0
  19. package/dist/tools/append-trace.d.ts.map +1 -0
  20. package/dist/tools/append-trace.js +125 -0
  21. package/dist/tools/append-trace.js.map +1 -0
  22. package/dist/tools/create-workflow.d.ts +30 -0
  23. package/dist/tools/create-workflow.d.ts.map +1 -0
  24. package/dist/tools/create-workflow.js +228 -0
  25. package/dist/tools/create-workflow.js.map +1 -0
  26. package/dist/tools/execute-step.d.ts +51 -0
  27. package/dist/tools/execute-step.d.ts.map +1 -0
  28. package/dist/tools/execute-step.js +91 -0
  29. package/dist/tools/execute-step.js.map +1 -0
  30. package/dist/tools/get-run-state.d.ts +31 -0
  31. package/dist/tools/get-run-state.d.ts.map +1 -0
  32. package/dist/tools/get-run-state.js +63 -0
  33. package/dist/tools/get-run-state.js.map +1 -0
  34. package/dist/tools/get-workflow-protocol.d.ts +13 -0
  35. package/dist/tools/get-workflow-protocol.d.ts.map +1 -0
  36. package/dist/tools/get-workflow-protocol.js +30 -0
  37. package/dist/tools/get-workflow-protocol.js.map +1 -0
  38. package/dist/tools/list-workflows.d.ts +20 -0
  39. package/dist/tools/list-workflows.d.ts.map +1 -0
  40. package/dist/tools/list-workflows.js +21 -0
  41. package/dist/tools/list-workflows.js.map +1 -0
  42. package/dist/tools/start-run.d.ts +26 -0
  43. package/dist/tools/start-run.d.ts.map +1 -0
  44. package/dist/tools/start-run.js +90 -0
  45. package/dist/tools/start-run.js.map +1 -0
  46. package/dist/tools/submit-human-response.d.ts +15 -0
  47. package/dist/tools/submit-human-response.d.ts.map +1 -0
  48. package/dist/tools/submit-human-response.js +63 -0
  49. package/dist/tools/submit-human-response.js.map +1 -0
  50. package/package.json +57 -0
package/README.md ADDED
@@ -0,0 +1,67 @@
1
+ # @sensigo/realm-mcp
2
+
3
+ `@sensigo/realm-mcp` — the Realm MCP server. Exposes 7 workflow tools over stdio or HTTP for AI agent connections (VS Code Copilot, Cursor, Claude, and any MCP-compatible agent).
4
+
5
+ ## Installation
6
+
7
+ ```
8
+ # Standalone binary (for AI agent MCP config)
9
+ npm install -g @sensigo/realm-mcp
10
+
11
+ # Embedded library (for custom application integration)
12
+ npm install @sensigo/realm-mcp
13
+ ```
14
+
15
+ ## Usage — Standalone MCP server
16
+
17
+ Add `realm-mcp` to your MCP client configuration (VS Code, Claude Desktop, Cursor, etc.):
18
+
19
+ ```json
20
+ {
21
+ "mcpServers": {
22
+ "realm": {
23
+ "command": "realm-mcp"
24
+ }
25
+ }
26
+ }
27
+ ```
28
+
29
+ Requires workflows to be registered first via `realm workflow register`.
30
+
31
+ ## Usage — Embedded MCP server
32
+
33
+ Create and connect a Realm MCP server inside your own application using any MCP-compatible transport.
34
+
35
+ ```ts
36
+ import { createRealmMcpServer } from '@sensigo/realm-mcp';
37
+ // StdioServerTransport comes from the MCP SDK, not from @sensigo/realm-mcp
38
+ import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
39
+
40
+ const server = createRealmMcpServer(); // options?: RealmMcpServerOptions
41
+ const transport = new StdioServerTransport();
42
+ await server.connect(transport);
43
+ ```
44
+
45
+ ## API Reference
46
+
47
+ | Symbol | Description |
48
+ | ---------------------------------- | ------------------------------------------------------------------------------- |
49
+ | `createRealmMcpServer(options?)` | Creates the MCP server with all 7 tools pre-registered. Returns `McpServer`. |
50
+ | `createDefaultRegistry()` | Returns an `ExtensionRegistry` pre-populated with built-in adapters. |
51
+ | `generateProtocol(workflow)` | Generates a structured protocol description for a workflow. |
52
+ | `RealmMcpServerOptions` | Type — optional config: `registry?`, `secrets?`, `workflowStore?`, `runStore?`. |
53
+ | `WorkflowProtocol`, `ProtocolStep` | Types — output shape of `generateProtocol`. |
54
+
55
+ ## MCP tools exposed
56
+
57
+ - `list_workflows` — list registered workflows
58
+ - `get_workflow_protocol` — get step-by-step protocol for a workflow
59
+ - `start_run` — start a new workflow run
60
+ - `execute_step` — submit agent output for a step and advance the run
61
+ - `submit_human_response` — resolve a human gate
62
+ - `get_run_state` — check current run state
63
+ - `create_workflow` — dynamically register and start a workflow in one call
64
+
65
+ ## Full documentation
66
+
67
+ Full documentation: https://github.com/sensigo-hq/realm
@@ -0,0 +1,6 @@
1
+ export { createRealmMcpServer, createDefaultRegistry } from './server.js';
2
+ export type { RealmMcpServerOptions } from './server.js';
3
+ export { generateProtocol } from './protocol/generator.js';
4
+ export type { WorkflowProtocol, ProtocolStep } from './protocol/generator.js';
5
+ export declare const VERSION = "0.1.0";
6
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,oBAAoB,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAC;AAC1E,YAAY,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAC;AACzD,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAC3D,YAAY,EAAE,gBAAgB,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAC9E,eAAO,MAAM,OAAO,UAAU,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,5 @@
1
+ // @sensigo/realm-mcp — MCP server for AI agent connections
2
+ export { createRealmMcpServer, createDefaultRegistry } from './server.js';
3
+ export { generateProtocol } from './protocol/generator.js';
4
+ export const VERSION = '0.1.0';
5
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,2DAA2D;AAC3D,OAAO,EAAE,oBAAoB,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAC;AAE1E,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAE3D,MAAM,CAAC,MAAM,OAAO,GAAG,OAAO,CAAC"}
@@ -0,0 +1,17 @@
1
+ import { type TraceBufferStore, type BufferedEntry, type AppendResult } from '@sensigo/realm';
2
+ import type { AgentTraceEntry } from '@sensigo/realm';
3
+ /**
4
+ * File-based TraceBufferStore that persists WAL entries to JSONL files on disk.
5
+ * WAL file path: <runsDir>/trace-buffer-<runId>-<base64url(stepId)>.jsonl
6
+ */
7
+ export declare class JsonTraceBufferStore implements TraceBufferStore {
8
+ private readonly runsDir;
9
+ constructor(runsDir: string);
10
+ private walPath;
11
+ private readWal;
12
+ append(runId: string, stepId: string, entries: AgentTraceEntry[]): Promise<AppendResult>;
13
+ read(runId: string, stepId: string): Promise<BufferedEntry[]>;
14
+ delete(runId: string, stepId: string): Promise<void>;
15
+ deleteAllForRun(runId: string): Promise<void>;
16
+ }
17
+ //# sourceMappingURL=json-trace-buffer-store.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"json-trace-buffer-store.d.ts","sourceRoot":"","sources":["../src/json-trace-buffer-store.ts"],"names":[],"mappings":"AAKA,OAAO,EACL,KAAK,gBAAgB,EACrB,KAAK,aAAa,EAClB,KAAK,YAAY,EAMlB,MAAM,gBAAgB,CAAC;AACxB,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAStD;;;GAGG;AACH,qBAAa,oBAAqB,YAAW,gBAAgB;IAC3D,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;gBAErB,OAAO,EAAE,MAAM;IAI3B,OAAO,CAAC,OAAO;YAKD,OAAO;IAqBf,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,eAAe,EAAE,GAAG,OAAO,CAAC,YAAY,CAAC;IA6ExF,IAAI,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,EAAE,CAAC;IAQ7D,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAKpD,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAcpD"}
@@ -0,0 +1,128 @@
1
+ // json-trace-buffer-store.ts — File-based TraceBufferStore using JSONL WAL files.
2
+ import { existsSync } from 'node:fs';
3
+ import { readFile, appendFile, unlink, readdir } from 'node:fs/promises';
4
+ import { join } from 'node:path';
5
+ import lockfile from 'proper-lockfile';
6
+ import { normalizeEntryForBuffer, BUFFER_LIMIT_COUNT, BUFFER_LIMIT_BYTES, FINAL_LIMIT_ENTRIES, FINAL_LIMIT_BYTES, } from '@sensigo/realm';
7
+ import { WorkflowError } from '@sensigo/realm';
8
+ /**
9
+ * File-based TraceBufferStore that persists WAL entries to JSONL files on disk.
10
+ * WAL file path: <runsDir>/trace-buffer-<runId>-<base64url(stepId)>.jsonl
11
+ */
12
+ export class JsonTraceBufferStore {
13
+ runsDir;
14
+ constructor(runsDir) {
15
+ this.runsDir = runsDir;
16
+ }
17
+ walPath(runId, stepId) {
18
+ const safeStepId = Buffer.from(stepId).toString('base64url');
19
+ return join(this.runsDir, `trace-buffer-${runId}-${safeStepId}.jsonl`);
20
+ }
21
+ async readWal(walPath) {
22
+ if (!existsSync(walPath)) {
23
+ return { count: 0, bytes: 0, lines: [] };
24
+ }
25
+ try {
26
+ const content = await readFile(walPath, 'utf8');
27
+ const lines = content
28
+ .split('\n')
29
+ .filter((l) => l.trim().length > 0)
30
+ .map((l) => JSON.parse(l));
31
+ const count = lines.reduce((acc, l) => acc + l.entries.length, 0);
32
+ const bytes = Buffer.byteLength(content);
33
+ return { count, bytes, lines };
34
+ }
35
+ catch {
36
+ // Treat corrupted WAL as empty.
37
+ return { count: 0, bytes: 0, lines: [] };
38
+ }
39
+ }
40
+ async append(runId, stepId, entries) {
41
+ const walPath = this.walPath(runId, stepId);
42
+ if (entries.length === 0) {
43
+ const { count, bytes } = await this.readWal(walPath);
44
+ return {
45
+ buffer_count: count,
46
+ buffer_bytes: bytes,
47
+ limit_count: BUFFER_LIMIT_COUNT,
48
+ limit_bytes: BUFFER_LIMIT_BYTES,
49
+ final_limit_entries: FINAL_LIMIT_ENTRIES,
50
+ final_limit_bytes: FINAL_LIMIT_BYTES,
51
+ };
52
+ }
53
+ // Acquire lock (realpath: false because file may not yet exist).
54
+ // Create a placeholder file if needed so proper-lockfile has a target.
55
+ if (!existsSync(walPath)) {
56
+ await appendFile(walPath, '');
57
+ }
58
+ let release;
59
+ try {
60
+ release = await lockfile.lock(walPath, { retries: 10, stale: 5000, realpath: false });
61
+ const { count: existingCount, bytes: existingBytes } = await this.readWal(walPath);
62
+ const normalized = entries
63
+ .map((e) => normalizeEntryForBuffer(e))
64
+ .filter((e) => e !== null);
65
+ if (normalized.length === 0) {
66
+ return {
67
+ buffer_count: existingCount,
68
+ buffer_bytes: existingBytes,
69
+ limit_count: BUFFER_LIMIT_COUNT,
70
+ limit_bytes: BUFFER_LIMIT_BYTES,
71
+ final_limit_entries: FINAL_LIMIT_ENTRIES,
72
+ final_limit_bytes: FINAL_LIMIT_BYTES,
73
+ };
74
+ }
75
+ const newLine = JSON.stringify({ ts: Date.now(), entries: normalized });
76
+ const newBytes = Buffer.byteLength(newLine + '\n');
77
+ if (existingCount + normalized.length > BUFFER_LIMIT_COUNT ||
78
+ existingBytes + newBytes > BUFFER_LIMIT_BYTES) {
79
+ throw new WorkflowError('Trace buffer full for step', {
80
+ code: 'BUFFER_FULL',
81
+ category: 'ENGINE',
82
+ agentAction: 'provide_input',
83
+ retryable: false,
84
+ details: { buffer_count: existingCount, buffer_bytes: existingBytes },
85
+ });
86
+ }
87
+ await appendFile(walPath, newLine + '\n', 'utf8');
88
+ const updatedCount = existingCount + normalized.length;
89
+ const updatedBytes = existingBytes + newBytes;
90
+ return {
91
+ buffer_count: updatedCount,
92
+ buffer_bytes: updatedBytes,
93
+ limit_count: BUFFER_LIMIT_COUNT,
94
+ limit_bytes: BUFFER_LIMIT_BYTES,
95
+ final_limit_entries: FINAL_LIMIT_ENTRIES,
96
+ final_limit_bytes: FINAL_LIMIT_BYTES,
97
+ };
98
+ }
99
+ finally {
100
+ if (release !== undefined) {
101
+ await release();
102
+ }
103
+ }
104
+ }
105
+ async read(runId, stepId) {
106
+ const walPath = this.walPath(runId, stepId);
107
+ const { lines } = await this.readWal(walPath);
108
+ return lines.flatMap((line) => line.entries.map((entry) => ({ ...entry, _internalTs: line.ts })));
109
+ }
110
+ async delete(runId, stepId) {
111
+ const walPath = this.walPath(runId, stepId);
112
+ await unlink(walPath).catch(() => { });
113
+ }
114
+ async deleteAllForRun(runId) {
115
+ const prefix = `trace-buffer-${runId}-`;
116
+ let files;
117
+ try {
118
+ files = await readdir(this.runsDir);
119
+ }
120
+ catch {
121
+ return;
122
+ }
123
+ await Promise.all(files
124
+ .filter((f) => f.startsWith(prefix) && f.endsWith('.jsonl'))
125
+ .map((f) => unlink(join(this.runsDir, f)).catch(() => { })));
126
+ }
127
+ }
128
+ //# sourceMappingURL=json-trace-buffer-store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"json-trace-buffer-store.js","sourceRoot":"","sources":["../src/json-trace-buffer-store.ts"],"names":[],"mappings":"AAAA,kFAAkF;AAClF,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AACzE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,QAAQ,MAAM,iBAAiB,CAAC;AACvC,OAAO,EAIL,uBAAuB,EACvB,kBAAkB,EAClB,kBAAkB,EAClB,mBAAmB,EACnB,iBAAiB,GAClB,MAAM,gBAAgB,CAAC;AAExB,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAQ/C;;;GAGG;AACH,MAAM,OAAO,oBAAoB;IACd,OAAO,CAAS;IAEjC,YAAY,OAAe;QACzB,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;IACzB,CAAC;IAEO,OAAO,CAAC,KAAa,EAAE,MAAc;QAC3C,MAAM,UAAU,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC;QAC7D,OAAO,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,gBAAgB,KAAK,IAAI,UAAU,QAAQ,CAAC,CAAC;IACzE,CAAC;IAEO,KAAK,CAAC,OAAO,CACnB,OAAe;QAEf,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;YACzB,OAAO,EAAE,KAAK,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC;QAC3C,CAAC;QACD,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,MAAM,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;YAChD,MAAM,KAAK,GAAc,OAAO;iBAC7B,KAAK,CAAC,IAAI,CAAC;iBACX,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,CAAC;iBAClC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAY,CAAC,CAAC;YACxC,MAAM,KAAK,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,GAAG,GAAG,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;YAClE,MAAM,KAAK,GAAG,MAAM,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;YACzC,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC;QACjC,CAAC;QAAC,MAAM,CAAC;YACP,gCAAgC;YAChC,OAAO,EAAE,KAAK,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC;QAC3C,CAAC;IACH,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,KAAa,EAAE,MAAc,EAAE,OAA0B;QACpE,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;QAE5C,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACzB,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;YACrD,OAAO;gBACL,YAAY,EAAE,KAAK;gBACnB,YAAY,EAAE,KAAK;gBACnB,WAAW,EAAE,kBAAkB;gBAC/B,WAAW,EAAE,kBAAkB;gBAC/B,mBAAmB,EAAE,mBAAmB;gBACxC,iBAAiB,EAAE,iBAAiB;aACrC,CAAC;QACJ,CAAC;QAED,iEAAiE;QACjE,uEAAuE;QACvE,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;YACzB,MAAM,UAAU,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;QAChC,CAAC;QAED,IAAI,OAA0C,CAAC;QAC/C,IAAI,CAAC;YACH,OAAO,GAAG,MAAM,QAAQ,CAAC,IAAI,CAAC,OAAO,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC,CAAC;YAEtF,MAAM,EAAE,KAAK,EAAE,aAAa,EAAE,KAAK,EAAE,aAAa,EAAE,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;YAEnF,MAAM,UAAU,GAAG,OAAO;iBACvB,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,uBAAuB,CAAC,CAAC,CAAC,CAAC;iBACtC,MAAM,CAAC,CAAC,CAAC,EAAwB,EAAE,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC;YAEnD,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBAC5B,OAAO;oBACL,YAAY,EAAE,aAAa;oBAC3B,YAAY,EAAE,aAAa;oBAC3B,WAAW,EAAE,kBAAkB;oBAC/B,WAAW,EAAE,kBAAkB;oBAC/B,mBAAmB,EAAE,mBAAmB;oBACxC,iBAAiB,EAAE,iBAAiB;iBACrC,CAAC;YACJ,CAAC;YAED,MAAM,OAAO,GAAG,IAAI,CAAC,SAAS,CAAC,EAAE,EAAE,EAAE,IAAI,CAAC,GAAG,EAAE,EAAE,OAAO,EAAE,UAAU,EAAE,CAAC,CAAC;YACxE,MAAM,QAAQ,GAAG,MAAM,CAAC,UAAU,CAAC,OAAO,GAAG,IAAI,CAAC,CAAC;YAEnD,IACE,aAAa,GAAG,UAAU,CAAC,MAAM,GAAG,kBAAkB;gBACtD,aAAa,GAAG,QAAQ,GAAG,kBAAkB,EAC7C,CAAC;gBACD,MAAM,IAAI,aAAa,CAAC,4BAA4B,EAAE;oBACpD,IAAI,EAAE,aAAa;oBACnB,QAAQ,EAAE,QAAQ;oBAClB,WAAW,EAAE,eAAe;oBAC5B,SAAS,EAAE,KAAK;oBAChB,OAAO,EAAE,EAAE,YAAY,EAAE,aAAa,EAAE,YAAY,EAAE,aAAa,EAAE;iBACtE,CAAC,CAAC;YACL,CAAC;YAED,MAAM,UAAU,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,EAAE,MAAM,CAAC,CAAC;YAElD,MAAM,YAAY,GAAG,aAAa,GAAG,UAAU,CAAC,MAAM,CAAC;YACvD,MAAM,YAAY,GAAG,aAAa,GAAG,QAAQ,CAAC;YAC9C,OAAO;gBACL,YAAY,EAAE,YAAY;gBAC1B,YAAY,EAAE,YAAY;gBAC1B,WAAW,EAAE,kBAAkB;gBAC/B,WAAW,EAAE,kBAAkB;gBAC/B,mBAAmB,EAAE,mBAAmB;gBACxC,iBAAiB,EAAE,iBAAiB;aACrC,CAAC;QACJ,CAAC;gBAAS,CAAC;YACT,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;gBAC1B,MAAM,OAAO,EAAE,CAAC;YAClB,CAAC;QACH,CAAC;IACH,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,KAAa,EAAE,MAAc;QACtC,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;QAC5C,MAAM,EAAE,KAAK,EAAE,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;QAC9C,OAAO,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE,CAC5B,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,KAAK,EAAE,WAAW,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC,CAClE,CAAC;IACJ,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,KAAa,EAAE,MAAc;QACxC,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;QAC5C,MAAM,MAAM,CAAC,OAAO,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;IACxC,CAAC;IAED,KAAK,CAAC,eAAe,CAAC,KAAa;QACjC,MAAM,MAAM,GAAG,gBAAgB,KAAK,GAAG,CAAC;QACxC,IAAI,KAAe,CAAC;QACpB,IAAI,CAAC;YACH,KAAK,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACtC,CAAC;QAAC,MAAM,CAAC;YACP,OAAO;QACT,CAAC;QACD,MAAM,OAAO,CAAC,GAAG,CACf,KAAK;aACF,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;aAC3D,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC,CAC7D,CAAC;IACJ,CAAC;CACF"}
@@ -0,0 +1,37 @@
1
+ import type { WorkflowDefinition, JsonSchema } from '@sensigo/realm';
2
+ export interface ProtocolStepGate {
3
+ choices: string[];
4
+ }
5
+ export interface ProtocolStep {
6
+ id: string;
7
+ description: string;
8
+ execution: string;
9
+ /** Plain-English description of the agent's role at this step. */
10
+ agent_involvement: string;
11
+ input_schema?: JsonSchema;
12
+ /** Step-level instructions for the agent, if defined. */
13
+ instructions?: string;
14
+ /** Present when the step may open a human gate. */
15
+ possible_gate?: ProtocolStepGate;
16
+ /** Step IDs this step depends on before it becomes eligible. */
17
+ depends_on?: string[];
18
+ /** Specialist profile instructions for the agent at this step. Present when the step
19
+ * declares agent_profile and the profile was resolved at register time. */
20
+ agent_profile_instructions?: string;
21
+ }
22
+ export interface WorkflowProtocol {
23
+ workflow_id: string;
24
+ name: string;
25
+ params_schema?: JsonSchema;
26
+ steps: ProtocolStep[];
27
+ /** e.g. "2 of 4 steps require agent action. 2 are handled automatically." */
28
+ agent_steps_summary: string;
29
+ rules: string[];
30
+ error_handling: Record<string, string>;
31
+ quick_start: string;
32
+ }
33
+ /**
34
+ * Generates the full agent protocol briefing from a WorkflowDefinition.
35
+ */
36
+ export declare function generateProtocol(definition: WorkflowDefinition): WorkflowProtocol;
37
+ //# sourceMappingURL=generator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generator.d.ts","sourceRoot":"","sources":["../../src/protocol/generator.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,kBAAkB,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAErE,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB;AAED,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,kEAAkE;IAClE,iBAAiB,EAAE,MAAM,CAAC;IAC1B,YAAY,CAAC,EAAE,UAAU,CAAC;IAC1B,yDAAyD;IACzD,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,mDAAmD;IACnD,aAAa,CAAC,EAAE,gBAAgB,CAAC;IACjC,gEAAgE;IAChE,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB;gFAC4E;IAC5E,0BAA0B,CAAC,EAAE,MAAM,CAAC;CACrC;AAED,MAAM,WAAW,gBAAgB;IAC/B,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,aAAa,CAAC,EAAE,UAAU,CAAC;IAC3B,KAAK,EAAE,YAAY,EAAE,CAAC;IACtB,6EAA6E;IAC7E,mBAAmB,EAAE,MAAM,CAAC;IAC5B,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACvC,WAAW,EAAE,MAAM,CAAC;CACrB;AAuBD;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,UAAU,EAAE,kBAAkB,GAAG,gBAAgB,CA+FjF"}
@@ -0,0 +1,99 @@
1
+ const DEFAULT_RULES = [
2
+ 'Follow the next_action instruction in each response exactly.',
3
+ "When you receive status 'confirm_required', read gate.agent_hint for instructions, present gate.display to the user verbatim, wait for their response, then call submit_human_response with their choice and the gate_id.",
4
+ 'Do NOT auto-confirm any human gate. The user must decide.',
5
+ 'Do NOT ask the user for permission between steps unless the system tells you to.',
6
+ ];
7
+ const ERROR_HANDLING = {
8
+ provide_input: 'The engine rejected your input. Read the error details — they tell you exactly what was wrong. Fix the input and call the step again.',
9
+ report_to_user: 'Something failed that you cannot fix automatically. Show the error message to the user and wait for their guidance.',
10
+ resolve_precondition: 'A prerequisite step has not completed. The error includes which precondition failed and what step to call. Follow the suggestion.',
11
+ stop: 'A critical error occurred. Report it to the user and do not attempt any further steps.',
12
+ wait_for_human: 'An external service is unavailable and cannot be retried automatically (e.g. network unreachable, upstream server error). Show the error to the user and wait for them to confirm the issue is resolved — the run cannot continue until the external dependency is back.',
13
+ wait_and_proceed: 'The upstream service returned a rate-limit response. retry_after in the envelope gives the number of seconds to wait. After that delay, follow next_actions without human involvement — the step has already failed; if a recovery branch exists it will appear in next_actions. This action only appears when engine-level retry is not configured for the step; when retry is configured, the engine retries internally and surfaces STEP_RETRY_EXHAUSTED (report_to_user) on exhaustion.',
14
+ };
15
+ /**
16
+ * Generates the full agent protocol briefing from a WorkflowDefinition.
17
+ */
18
+ export function generateProtocol(definition) {
19
+ const steps = [];
20
+ let agentStepCount = 0;
21
+ let autoStepCount = 0;
22
+ for (const [id, step] of Object.entries(definition.steps)) {
23
+ const hasGate = step.trust === 'human_confirmed' || step.trust === 'human_reviewed';
24
+ let agent_involvement;
25
+ let possible_gate;
26
+ if (step.execution === 'auto' && !hasGate) {
27
+ agent_involvement = 'none — engine handles this automatically';
28
+ autoStepCount++;
29
+ }
30
+ else if (step.execution === 'auto' && hasGate) {
31
+ agent_involvement =
32
+ 'YOU will receive `status: confirm_required` after this step runs — the engine executes it automatically, then opens a gate. Read `gate.agent_hint` for presentation instructions, present `gate.display` to the user verbatim, collect their choice from `gate.response_spec.choices`, and call `submit_human_response`.';
33
+ possible_gate = { choices: ['approve', 'reject'] };
34
+ autoStepCount++;
35
+ }
36
+ else if (step.execution === 'agent' && !hasGate) {
37
+ agent_involvement = `YOU execute this step. Call execute_step with command '${id}' and the required params.`;
38
+ // If an immediate downstream auto+gate step depends only on this step, warn the
39
+ // agent that they will receive confirm_required rather than ok after submitting.
40
+ const immediateGateStep = Object.entries(definition.steps).find(([, s]) => s.execution === 'auto' &&
41
+ (s.trust === 'human_confirmed' || s.trust === 'human_reviewed') &&
42
+ Array.isArray(s.depends_on) &&
43
+ s.depends_on.length === 1 &&
44
+ s.depends_on[0] === id);
45
+ if (immediateGateStep !== undefined) {
46
+ agent_involvement += ` After you submit, you will receive status: confirm_required directly in response to this call — the engine runs '${immediateGateStep[0]}' automatically before returning.`;
47
+ }
48
+ agentStepCount++;
49
+ }
50
+ else {
51
+ // execution === 'agent' with gate
52
+ agent_involvement = `YOU execute this step. Call execute_step with command '${id}'. The engine will run your dispatcher, then pause for human confirmation of your output.`;
53
+ possible_gate = { choices: ['approve', 'reject'] };
54
+ agentStepCount++;
55
+ }
56
+ const protocolStep = {
57
+ id,
58
+ description: step.description,
59
+ execution: step.execution,
60
+ agent_involvement,
61
+ };
62
+ if (step.input_schema !== undefined) {
63
+ protocolStep.input_schema = step.input_schema;
64
+ }
65
+ if (step.instructions !== undefined) {
66
+ protocolStep.instructions = step.instructions;
67
+ }
68
+ if (possible_gate !== undefined) {
69
+ protocolStep.possible_gate = possible_gate;
70
+ }
71
+ if (step.depends_on !== undefined && step.depends_on.length > 0) {
72
+ protocolStep.depends_on = step.depends_on;
73
+ }
74
+ const profile = step.agent_profile;
75
+ if (profile !== undefined && definition.resolved_profiles?.[profile] !== undefined) {
76
+ protocolStep.agent_profile_instructions = definition.resolved_profiles[profile].content;
77
+ }
78
+ steps.push(protocolStep);
79
+ }
80
+ const totalSteps = steps.length;
81
+ const agent_steps_summary = `${agentStepCount} of ${totalSteps} steps require agent action. ${autoStepCount} are handled automatically.`;
82
+ const rules = definition.protocol?.rules ?? DEFAULT_RULES;
83
+ const quick_start = definition.protocol?.quick_start ??
84
+ `Call start_run with workflow_id '${definition.id}'. ${agentStepCount > 0 ? `The engine will run auto steps automatically and return control at the first step requiring agent action.` : `The engine handles all steps automatically.`} Follow the next_action in each response until the workflow completes.`;
85
+ const protocol = {
86
+ workflow_id: definition.id,
87
+ name: definition.name,
88
+ steps,
89
+ agent_steps_summary,
90
+ rules,
91
+ error_handling: ERROR_HANDLING,
92
+ quick_start,
93
+ };
94
+ if (definition.params_schema !== undefined) {
95
+ protocol.params_schema = definition.params_schema;
96
+ }
97
+ return protocol;
98
+ }
99
+ //# sourceMappingURL=generator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generator.js","sourceRoot":"","sources":["../../src/protocol/generator.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,39 @@
1
+ #!/usr/bin/env node
2
+ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
3
+ import { ExtensionRegistry, JsonWorkflowStore, JsonFileStore, createDefaultRegistry } from '@sensigo/realm';
4
+ export interface RealmMcpServerOptions {
5
+ /** Extension registry for resolving service adapters and step handlers at runtime. */
6
+ registry?: ExtensionRegistry;
7
+ /** Resolved secrets to pass to adapter configs (e.g. API tokens). */
8
+ secrets?: Record<string, string>;
9
+ /** Pre-populated workflow store. When provided, tools use this instead of creating
10
+ * a new JsonWorkflowStore() pointing at ~/.realm/workflows/. */
11
+ workflowStore?: JsonWorkflowStore;
12
+ /** Run store. When provided, tools use this instead of creating a new JsonFileStore(). */
13
+ runStore?: JsonFileStore;
14
+ }
15
+ /**
16
+ * Returns an ExtensionRegistry pre-populated with Realm's built-in adapters.
17
+ * `FileSystemAdapter` is registered under the name `'filesystem'`.
18
+ *
19
+ * Use this as a starting point when you need to add your own handlers or adapters on top:
20
+ * ```ts
21
+ * const registry = createDefaultRegistry();
22
+ * registry.register('handler', 'my_handler', myHandler);
23
+ * const server = createRealmMcpServer({ workflowStore, registry });
24
+ * ```
25
+ *
26
+ * When no registry is passed to `createRealmMcpServer`, the engine uses built-in adapters
27
+ * automatically — you only need this if you are adding custom extensions.
28
+ */
29
+ export { createDefaultRegistry };
30
+ /**
31
+ * Creates and configures the Realm MCP server with all 7 workflow tools.
32
+ *
33
+ * When no `registry` is provided, `FileSystemAdapter` is pre-registered automatically
34
+ * under the name `filesystem`. Pass a custom `registry` to add your own handlers and
35
+ * adapters — when you do, include `FileSystemAdapter` explicitly if your workflows use it,
36
+ * or start from `createDefaultRegistry()` and add your extensions on top.
37
+ */
38
+ export declare function createRealmMcpServer(options?: RealmMcpServerOptions): McpServer;
39
+ //# sourceMappingURL=server.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEpE,OAAO,EACL,iBAAiB,EACjB,iBAAiB,EACjB,aAAa,EACb,qBAAqB,EACtB,MAAM,gBAAgB,CAAC;AAWxB,MAAM,WAAW,qBAAqB;IACpC,sFAAsF;IACtF,QAAQ,CAAC,EAAE,iBAAiB,CAAC;IAC7B,qEAAqE;IACrE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC;qEACiE;IACjE,aAAa,CAAC,EAAE,iBAAiB,CAAC;IAClC,0FAA0F;IAC1F,QAAQ,CAAC,EAAE,aAAa,CAAC;CAC1B;AAED;;;;;;;;;;;;;GAaG;AACH,OAAO,EAAE,qBAAqB,EAAE,CAAC;AAEjC;;;;;;;GAOG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,CAAC,EAAE,qBAAqB,GAAG,SAAS,CA+B/E"}
package/dist/server.js ADDED
@@ -0,0 +1,72 @@
1
+ #!/usr/bin/env node
2
+ // realm-mcp — MCP server exposing the Realm workflow engine to AI agents.
3
+ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
4
+ import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
5
+ import { JsonFileStore, createDefaultRegistry, } from '@sensigo/realm';
6
+ import { JsonTraceBufferStore } from './json-trace-buffer-store.js';
7
+ import { registerListWorkflows } from './tools/list-workflows.js';
8
+ import { registerGetWorkflowProtocol } from './tools/get-workflow-protocol.js';
9
+ import { registerStartRun } from './tools/start-run.js';
10
+ import { registerExecuteStep } from './tools/execute-step.js';
11
+ import { registerSubmitHumanResponse } from './tools/submit-human-response.js';
12
+ import { registerGetRunState } from './tools/get-run-state.js';
13
+ import { registerCreateWorkflow } from './tools/create-workflow.js';
14
+ import { registerAppendTrace } from './tools/append-trace.js';
15
+ /**
16
+ * Returns an ExtensionRegistry pre-populated with Realm's built-in adapters.
17
+ * `FileSystemAdapter` is registered under the name `'filesystem'`.
18
+ *
19
+ * Use this as a starting point when you need to add your own handlers or adapters on top:
20
+ * ```ts
21
+ * const registry = createDefaultRegistry();
22
+ * registry.register('handler', 'my_handler', myHandler);
23
+ * const server = createRealmMcpServer({ workflowStore, registry });
24
+ * ```
25
+ *
26
+ * When no registry is passed to `createRealmMcpServer`, the engine uses built-in adapters
27
+ * automatically — you only need this if you are adding custom extensions.
28
+ */
29
+ export { createDefaultRegistry };
30
+ /**
31
+ * Creates and configures the Realm MCP server with all 7 workflow tools.
32
+ *
33
+ * When no `registry` is provided, `FileSystemAdapter` is pre-registered automatically
34
+ * under the name `filesystem`. Pass a custom `registry` to add your own handlers and
35
+ * adapters — when you do, include `FileSystemAdapter` explicitly if your workflows use it,
36
+ * or start from `createDefaultRegistry()` and add your extensions on top.
37
+ */
38
+ export function createRealmMcpServer(options) {
39
+ const server = new McpServer({
40
+ name: 'realm',
41
+ version: '0.1.0',
42
+ });
43
+ // When no registry is provided, use the default registry that pre-registers built-in
44
+ // adapters. When a registry is provided, the caller is responsible for its contents.
45
+ const effectiveRegistry = options?.registry ?? createDefaultRegistry();
46
+ const effectiveOptions = { ...options, registry: effectiveRegistry };
47
+ // Shared trace buffer store: one instance used by both append_trace and execute_step so
48
+ // WAL entries written by append_trace are visible when execute_step finalizes the step.
49
+ const effectiveRunStore = options?.runStore ?? new JsonFileStore();
50
+ const traceBufferStore = new JsonTraceBufferStore(effectiveRunStore.runsDirPath);
51
+ registerListWorkflows(server, effectiveOptions);
52
+ registerGetWorkflowProtocol(server, effectiveOptions);
53
+ registerStartRun(server, effectiveOptions);
54
+ registerExecuteStep(server, { ...effectiveOptions, traceBufferStore });
55
+ registerSubmitHumanResponse(server, effectiveOptions);
56
+ registerGetRunState(server, effectiveOptions);
57
+ registerCreateWorkflow(server, effectiveOptions);
58
+ registerAppendTrace(server, {
59
+ runStore: effectiveRunStore,
60
+ ...(options?.workflowStore !== undefined ? { workflowStore: options.workflowStore } : {}),
61
+ traceBufferStore,
62
+ });
63
+ return server;
64
+ }
65
+ // Entry point: start the MCP server on stdio when run directly.
66
+ if (process.argv[1] !== undefined &&
67
+ import.meta.url.endsWith(process.argv[1].replace(/\\/g, '/'))) {
68
+ const server = createRealmMcpServer();
69
+ const transport = new StdioServerTransport();
70
+ await server.connect(transport);
71
+ }
72
+ //# sourceMappingURL=server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":";AACA,0EAA0E;AAC1E,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACpE,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AACjF,OAAO,EAGL,aAAa,EACb,qBAAqB,GACtB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,oBAAoB,EAAE,MAAM,8BAA8B,CAAC;AACpE,OAAO,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAC;AAClE,OAAO,EAAE,2BAA2B,EAAE,MAAM,kCAAkC,CAAC;AAC/E,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AACxD,OAAO,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAC9D,OAAO,EAAE,2BAA2B,EAAE,MAAM,kCAAkC,CAAC;AAC/E,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAC/D,OAAO,EAAE,sBAAsB,EAAE,MAAM,4BAA4B,CAAC;AACpE,OAAO,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAc9D;;;;;;;;;;;;;GAaG;AACH,OAAO,EAAE,qBAAqB,EAAE,CAAC;AAEjC;;;;;;;GAOG;AACH,MAAM,UAAU,oBAAoB,CAAC,OAA+B;IAClE,MAAM,MAAM,GAAG,IAAI,SAAS,CAAC;QAC3B,IAAI,EAAE,OAAO;QACb,OAAO,EAAE,OAAO;KACjB,CAAC,CAAC;IAEH,qFAAqF;IACrF,qFAAqF;IACrF,MAAM,iBAAiB,GAAG,OAAO,EAAE,QAAQ,IAAI,qBAAqB,EAAE,CAAC;IAEvE,MAAM,gBAAgB,GAA0B,EAAE,GAAG,OAAO,EAAE,QAAQ,EAAE,iBAAiB,EAAE,CAAC;IAE5F,wFAAwF;IACxF,wFAAwF;IACxF,MAAM,iBAAiB,GAAG,OAAO,EAAE,QAAQ,IAAI,IAAI,aAAa,EAAE,CAAC;IACnE,MAAM,gBAAgB,GAAG,IAAI,oBAAoB,CAAC,iBAAiB,CAAC,WAAW,CAAC,CAAC;IAEjF,qBAAqB,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC;IAChD,2BAA2B,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC;IACtD,gBAAgB,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC;IAC3C,mBAAmB,CAAC,MAAM,EAAE,EAAE,GAAG,gBAAgB,EAAE,gBAAgB,EAAE,CAAC,CAAC;IACvE,2BAA2B,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC;IACtD,mBAAmB,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC;IAC9C,sBAAsB,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC;IACjD,mBAAmB,CAAC,MAAM,EAAE;QAC1B,QAAQ,EAAE,iBAAiB;QAC3B,GAAG,CAAC,OAAO,EAAE,aAAa,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,aAAa,EAAE,OAAO,CAAC,aAAa,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACzF,gBAAgB;KACjB,CAAC,CAAC;IAEH,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,gEAAgE;AAChE,IACE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,SAAS;IAC7B,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,EAC7D,CAAC;IACD,MAAM,MAAM,GAAG,oBAAoB,EAAE,CAAC;IACtC,MAAM,SAAS,GAAG,IAAI,oBAAoB,EAAE,CAAC;IAC7C,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;AAClC,CAAC"}
@@ -0,0 +1,30 @@
1
+ import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
+ import { JsonWorkflowStore, JsonFileStore, type AppendResult, type TraceBufferStore, type AgentTraceEntry } from '@sensigo/realm';
3
+ export interface HandleAppendTraceStores {
4
+ runStore?: JsonFileStore;
5
+ workflowStore?: JsonWorkflowStore;
6
+ traceBufferStore?: TraceBufferStore;
7
+ }
8
+ export type AppendTraceOkResult = {
9
+ status: 'ok';
10
+ } & AppendResult;
11
+ /**
12
+ * Business logic for the append_trace tool.
13
+ * Buffers trace entries to the WAL for (runId, stepId). Entries are merged with
14
+ * any entries submitted at execute_step finalization.
15
+ *
16
+ * Throws WorkflowError for all error conditions. Callers (typically
17
+ * registerAppendTrace) catch and convert to ResponseEnvelope.
18
+ */
19
+ export declare function handleAppendTrace(args: {
20
+ run_id: string;
21
+ step_id: string;
22
+ entries: AgentTraceEntry[];
23
+ }, stores?: HandleAppendTraceStores): Promise<AppendTraceOkResult>;
24
+ /** Registers the append_trace MCP tool on the server. */
25
+ export declare function registerAppendTrace(server: McpServer, opts?: {
26
+ runStore?: JsonFileStore;
27
+ workflowStore?: JsonWorkflowStore;
28
+ traceBufferStore?: TraceBufferStore;
29
+ }): void;
30
+ //# sourceMappingURL=append-trace.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"append-trace.d.ts","sourceRoot":"","sources":["../../src/tools/append-trace.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACzE,OAAO,EACL,iBAAiB,EACjB,aAAa,EAGb,KAAK,YAAY,EACjB,KAAK,gBAAgB,EACrB,KAAK,eAAe,EAErB,MAAM,gBAAgB,CAAC;AAGxB,MAAM,WAAW,uBAAuB;IACtC,QAAQ,CAAC,EAAE,aAAa,CAAC;IACzB,aAAa,CAAC,EAAE,iBAAiB,CAAC;IAClC,gBAAgB,CAAC,EAAE,gBAAgB,CAAC;CACrC;AAED,MAAM,MAAM,mBAAmB,GAAG;IAAE,MAAM,EAAE,IAAI,CAAA;CAAE,GAAG,YAAY,CAAC;AAElE;;;;;;;GAOG;AACH,wBAAsB,iBAAiB,CACrC,IAAI,EAAE;IACJ,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,eAAe,EAAE,CAAC;CAC5B,EACD,MAAM,CAAC,EAAE,uBAAuB,GAC/B,OAAO,CAAC,mBAAmB,CAAC,CA+E9B;AAED,yDAAyD;AACzD,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,SAAS,EACjB,IAAI,CAAC,EAAE;IACL,QAAQ,CAAC,EAAE,aAAa,CAAC;IACzB,aAAa,CAAC,EAAE,iBAAiB,CAAC;IAClC,gBAAgB,CAAC,EAAE,gBAAgB,CAAC;CACrC,GACA,IAAI,CAyDN"}