mandala-computer-mcp 0.4.0 → 0.5.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 (109) hide show
  1. package/README.md +450 -29
  2. package/dist/api.d.ts +12 -0
  3. package/dist/api.d.ts.map +1 -1
  4. package/dist/api.js +160 -15
  5. package/dist/api.js.map +1 -1
  6. package/dist/artifacts.d.ts +63 -0
  7. package/dist/artifacts.d.ts.map +1 -0
  8. package/dist/artifacts.js +81 -0
  9. package/dist/artifacts.js.map +1 -0
  10. package/dist/cli.d.ts +4 -0
  11. package/dist/cli.d.ts.map +1 -1
  12. package/dist/cli.js +35 -21
  13. package/dist/cli.js.map +1 -1
  14. package/dist/credentials.d.ts +33 -0
  15. package/dist/credentials.d.ts.map +1 -0
  16. package/dist/credentials.js +395 -0
  17. package/dist/credentials.js.map +1 -0
  18. package/dist/errors.d.ts +29 -9
  19. package/dist/errors.d.ts.map +1 -1
  20. package/dist/errors.js +71 -34
  21. package/dist/errors.js.map +1 -1
  22. package/dist/executions.d.ts +43 -0
  23. package/dist/executions.d.ts.map +1 -0
  24. package/dist/executions.js +162 -0
  25. package/dist/executions.js.map +1 -0
  26. package/dist/format.d.ts +11 -11
  27. package/dist/format.d.ts.map +1 -1
  28. package/dist/format.js +81 -15
  29. package/dist/format.js.map +1 -1
  30. package/dist/http.d.ts.map +1 -1
  31. package/dist/http.js +4 -0
  32. package/dist/http.js.map +1 -1
  33. package/dist/index.d.ts +2 -2
  34. package/dist/index.d.ts.map +1 -1
  35. package/dist/index.js +1 -1
  36. package/dist/index.js.map +1 -1
  37. package/dist/paths.d.ts +40 -0
  38. package/dist/paths.d.ts.map +1 -1
  39. package/dist/paths.js +50 -0
  40. package/dist/paths.js.map +1 -1
  41. package/dist/results.d.ts +97 -0
  42. package/dist/results.d.ts.map +1 -0
  43. package/dist/results.js +263 -0
  44. package/dist/results.js.map +1 -0
  45. package/dist/server.d.ts +3 -2
  46. package/dist/server.d.ts.map +1 -1
  47. package/dist/server.js +60 -9
  48. package/dist/server.js.map +1 -1
  49. package/dist/stdio.d.ts +5 -1
  50. package/dist/stdio.d.ts.map +1 -1
  51. package/dist/stdio.js +10 -4
  52. package/dist/stdio.js.map +1 -1
  53. package/dist/tool-filters.d.ts +38 -0
  54. package/dist/tool-filters.d.ts.map +1 -0
  55. package/dist/tool-filters.js +129 -0
  56. package/dist/tool-filters.js.map +1 -0
  57. package/dist/tools/account.d.ts +3 -0
  58. package/dist/tools/account.d.ts.map +1 -0
  59. package/dist/tools/account.js +122 -0
  60. package/dist/tools/account.js.map +1 -0
  61. package/dist/tools/activities.d.ts +3 -0
  62. package/dist/tools/activities.d.ts.map +1 -0
  63. package/dist/tools/activities.js +140 -0
  64. package/dist/tools/activities.js.map +1 -0
  65. package/dist/tools/agent.d.ts.map +1 -1
  66. package/dist/tools/agent.js +21 -9
  67. package/dist/tools/agent.js.map +1 -1
  68. package/dist/tools/artifacts.d.ts +3 -0
  69. package/dist/tools/artifacts.d.ts.map +1 -0
  70. package/dist/tools/artifacts.js +97 -0
  71. package/dist/tools/artifacts.js.map +1 -0
  72. package/dist/tools/chat.d.ts +6 -0
  73. package/dist/tools/chat.d.ts.map +1 -0
  74. package/dist/tools/chat.js +192 -0
  75. package/dist/tools/chat.js.map +1 -0
  76. package/dist/tools/computers.d.ts.map +1 -1
  77. package/dist/tools/computers.js +18 -7
  78. package/dist/tools/computers.js.map +1 -1
  79. package/dist/tools/directory.d.ts +13 -0
  80. package/dist/tools/directory.d.ts.map +1 -0
  81. package/dist/tools/directory.js +88 -0
  82. package/dist/tools/directory.js.map +1 -0
  83. package/dist/tools/executions.d.ts +3 -0
  84. package/dist/tools/executions.d.ts.map +1 -0
  85. package/dist/tools/executions.js +87 -0
  86. package/dist/tools/executions.js.map +1 -0
  87. package/dist/tools/guest.d.ts.map +1 -1
  88. package/dist/tools/guest.js +50 -15
  89. package/dist/tools/guest.js.map +1 -1
  90. package/dist/tools/results.d.ts +30 -0
  91. package/dist/tools/results.d.ts.map +1 -0
  92. package/dist/tools/results.js +106 -0
  93. package/dist/tools/results.js.map +1 -0
  94. package/dist/tools/secrets.d.ts +58 -0
  95. package/dist/tools/secrets.d.ts.map +1 -0
  96. package/dist/tools/secrets.js +204 -0
  97. package/dist/tools/secrets.js.map +1 -0
  98. package/dist/tools/signals.d.ts +3 -0
  99. package/dist/tools/signals.d.ts.map +1 -0
  100. package/dist/tools/signals.js +116 -0
  101. package/dist/tools/signals.js.map +1 -0
  102. package/dist/tools/snapshots.d.ts.map +1 -1
  103. package/dist/tools/snapshots.js +44 -8
  104. package/dist/tools/snapshots.js.map +1 -1
  105. package/dist/tools/ssh.d.ts +3 -0
  106. package/dist/tools/ssh.d.ts.map +1 -0
  107. package/dist/tools/ssh.js +186 -0
  108. package/dist/tools/ssh.js.map +1 -0
  109. package/package.json +1 -1
package/dist/stdio.d.ts CHANGED
@@ -1,4 +1,8 @@
1
1
  import { type ServerConfig } from './server.js';
2
+ export type StdioConfig = Omit<ServerConfig, 'apiKey'> & {
3
+ apiKey?: string;
4
+ profile?: string;
5
+ };
2
6
  /**
3
7
  * The local install: one process, one key, spawned by the MCP client.
4
8
  *
@@ -7,5 +11,5 @@ import { type ServerConfig } from './server.js';
7
11
  * here may ever write to stdout: that stream is the protocol, and one stray
8
12
  * console.log is a parse error at the other end. Diagnostics go to stderr.
9
13
  */
10
- export declare function runStdio(cfg: ServerConfig): Promise<void>;
14
+ export declare function runStdio(cfg?: StdioConfig): Promise<void>;
11
15
  //# sourceMappingURL=stdio.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"stdio.d.ts","sourceRoot":"","sources":["../src/stdio.ts"],"names":[],"mappings":"AAEA,OAAO,EAAgB,KAAK,YAAY,EAAE,MAAM,aAAa,CAAC;AAE9D;;;;;;;GAOG;AACH,wBAAsB,QAAQ,CAAC,GAAG,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAgC/D"}
1
+ {"version":3,"file":"stdio.d.ts","sourceRoot":"","sources":["../src/stdio.ts"],"names":[],"mappings":"AAEA,OAAO,EAAgB,KAAK,YAAY,EAAE,MAAM,aAAa,CAAC;AAE9D,MAAM,MAAM,WAAW,GAAG,IAAI,CAAC,YAAY,EAAE,QAAQ,CAAC,GAAG;IAAE,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AAE/F;;;;;;;GAOG;AACH,wBAAsB,QAAQ,CAAC,GAAG,GAAE,WAAgB,GAAG,OAAO,CAAC,IAAI,CAAC,CAoCnE"}
package/dist/stdio.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
2
- import { DEFAULT_BASE_URL } from './api.js';
2
+ import { resolveCredentials } from './credentials.js';
3
3
  import { createServer } from './server.js';
4
4
  /**
5
5
  * The local install: one process, one key, spawned by the MCP client.
@@ -9,8 +9,14 @@ import { createServer } from './server.js';
9
9
  * here may ever write to stdout: that stream is the protocol, and one stray
10
10
  * console.log is a parse error at the other end. Diagnostics go to stderr.
11
11
  */
12
- export async function runStdio(cfg) {
13
- const server = createServer(cfg);
12
+ export async function runStdio(cfg = {}) {
13
+ const credentials = resolveCredentials(cfg);
14
+ const resolved = {
15
+ ...cfg,
16
+ apiKey: credentials.apiKey,
17
+ baseUrl: credentials.baseUrl,
18
+ };
19
+ const server = createServer(resolved);
14
20
  const transport = new StdioServerTransport();
15
21
  await server.connect(transport);
16
22
  // The end of the client, and therefore the end of this process.
@@ -38,6 +44,6 @@ export async function runStdio(cfg) {
38
44
  const shutdown = () => void server.close().catch(() => { });
39
45
  process.stdin.once('end', shutdown);
40
46
  process.stdin.once('close', shutdown);
41
- console.error(`mandala-computer-mcp on stdio → ${new URL(cfg.baseUrl ?? DEFAULT_BASE_URL).origin}`);
47
+ console.error(`mandala-computer-mcp on stdio → ${new URL(credentials.baseUrl).origin}`);
42
48
  }
43
49
  //# sourceMappingURL=stdio.js.map
package/dist/stdio.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"stdio.js","sourceRoot":"","sources":["../src/stdio.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AACjF,OAAO,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AAC5C,OAAO,EAAE,YAAY,EAAqB,MAAM,aAAa,CAAC;AAE9D;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,QAAQ,CAAC,GAAiB;IAC9C,MAAM,MAAM,GAAG,YAAY,CAAC,GAAG,CAAC,CAAC;IACjC,MAAM,SAAS,GAAG,IAAI,oBAAoB,EAAE,CAAC;IAC7C,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IAChC,gEAAgE;IAChE,EAAE;IACF,+EAA+E;IAC/E,4EAA4E;IAC5E,6EAA6E;IAC7E,uEAAuE;IACvE,oEAAoE;IACpE,+EAA+E;IAC/E,iCAAiC;IACjC,EAAE;IACF,yEAAyE;IACzE,+EAA+E;IAC/E,4EAA4E;IAC5E,2EAA2E;IAC3E,2EAA2E;IAC3E,+DAA+D;IAC/D,EAAE;IACF,8EAA8E;IAC9E,4EAA4E;IAC5E,yEAAyE;IACzE,0EAA0E;IAC1E,qBAAqB;IACrB,MAAM,QAAQ,GAAG,GAAG,EAAE,CAAC,KAAK,MAAM,CAAC,KAAK,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;IAC3D,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;IACpC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;IACtC,OAAO,CAAC,KAAK,CACX,mCAAmC,IAAI,GAAG,CAAC,GAAG,CAAC,OAAO,IAAI,gBAAgB,CAAC,CAAC,MAAM,EAAE,CACrF,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"stdio.js","sourceRoot":"","sources":["../src/stdio.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AACjF,OAAO,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AACtD,OAAO,EAAE,YAAY,EAAqB,MAAM,aAAa,CAAC;AAI9D;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,QAAQ,CAAC,MAAmB,EAAE;IAClD,MAAM,WAAW,GAAG,kBAAkB,CAAC,GAAG,CAAC,CAAC;IAC5C,MAAM,QAAQ,GAAiB;QAC7B,GAAG,GAAG;QACN,MAAM,EAAE,WAAW,CAAC,MAAM;QAC1B,OAAO,EAAE,WAAW,CAAC,OAAO;KAC7B,CAAC;IACF,MAAM,MAAM,GAAG,YAAY,CAAC,QAAQ,CAAC,CAAC;IACtC,MAAM,SAAS,GAAG,IAAI,oBAAoB,EAAE,CAAC;IAC7C,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IAChC,gEAAgE;IAChE,EAAE;IACF,+EAA+E;IAC/E,4EAA4E;IAC5E,6EAA6E;IAC7E,uEAAuE;IACvE,oEAAoE;IACpE,+EAA+E;IAC/E,iCAAiC;IACjC,EAAE;IACF,yEAAyE;IACzE,+EAA+E;IAC/E,4EAA4E;IAC5E,2EAA2E;IAC3E,2EAA2E;IAC3E,+DAA+D;IAC/D,EAAE;IACF,8EAA8E;IAC9E,4EAA4E;IAC5E,yEAAyE;IACzE,0EAA0E;IAC1E,qBAAqB;IACrB,MAAM,QAAQ,GAAG,GAAG,EAAE,CAAC,KAAK,MAAM,CAAC,KAAK,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;IAC3D,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;IACpC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;IACtC,OAAO,CAAC,KAAK,CAAC,mCAAmC,IAAI,GAAG,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC;AAC1F,CAAC"}
@@ -0,0 +1,38 @@
1
+ import type { ToolAnnotations } from '@modelcontextprotocol/sdk/types.js';
2
+ /** Tags describe capabilities, not whether calling a tool is safe. */
3
+ export declare const TOOL_TAGS: {
4
+ readonly account: readonly ["get_account"];
5
+ readonly agent: readonly ["run_agent", "run_agent_chat"];
6
+ readonly activities: readonly ["list_activities", "get_activity", "get_activity_results"];
7
+ readonly signals: readonly ["read_signals"];
8
+ readonly artifacts: readonly ["publish_artifact", "get_artifact", "read_artifact", "delete_artifact"];
9
+ readonly computers: readonly ["list_computers", "get_computer", "use_computer", "wait_for_computer", "get_desktop_url", "list_sizes"];
10
+ readonly events: readonly ["wait_for_event", "poll_events", "wait_for_file_change"];
11
+ readonly executions: readonly ["get_execution", "read_execution_output"];
12
+ readonly files: readonly ["list_directory", "read_file", "write_file", "wait_for_file_change"];
13
+ readonly guest: readonly ["exec", "exec_poll", "exec_kill", "open_url", "list_windows", "window_action", "read_clipboard", "write_clipboard"];
14
+ readonly input: readonly ["screenshot", "click", "type_text", "press_key", "scroll", "drag", "move_mouse", "mouse_button", "cursor_position", "wait"];
15
+ readonly lifecycle: readonly ["create_computer", "start_computer", "stop_computer", "suspend_computer", "restart_computer", "update_computer", "clone_computer", "delete_computer", "move_computer", "list_moves"];
16
+ readonly results: readonly ["get_activity_results", "retain_execution_output", "get_result", "read_result_output", "delete_result"];
17
+ readonly snapshots: readonly ["list_snapshots", "snapshot_holdings", "create_snapshot", "restore_snapshot", "clone_snapshot", "snapshot_schedule", "get_retention", "delete_snapshot"];
18
+ readonly templates: readonly ["list_templates", "get_template_schema", "check_template", "publish_template", "get_template", "retire_template", "build_template", "list_builds", "get_build", "watch_build"];
19
+ readonly secrets: readonly ["get_computer_secrets", "set_computer_secrets"];
20
+ readonly ssh: readonly ["list_ssh_keys", "add_ssh_key", "remove_ssh_key", "get_computer_ssh", "set_computer_ssh"];
21
+ readonly usage: readonly ["get_usage"];
22
+ readonly webhooks: readonly ["list_webhooks", "create_webhook", "get_webhook", "update_webhook", "rotate_webhook_secret", "test_webhook", "list_webhook_deliveries", "delete_webhook"];
23
+ };
24
+ export type ToolTag = keyof typeof TOOL_TAGS;
25
+ export type ToolFilters = {
26
+ /** Keep only tools whose existing readOnlyHint is exactly true. */
27
+ readOnly?: boolean;
28
+ /** Union of these tags; absent or empty means all tags. Names are lowercase. */
29
+ tags?: readonly string[];
30
+ };
31
+ export declare const VALID_TAGS: ToolTag[];
32
+ export declare function parseToolTags(raw: string | undefined): ToolTag[];
33
+ /** Validate before constructing the session; never infer read-only from a name or verb. */
34
+ export declare function toolFilter(cfg: ToolFilters): {
35
+ filtered: boolean;
36
+ allows: (name: string, annotations?: ToolAnnotations) => boolean;
37
+ };
38
+ //# sourceMappingURL=tool-filters.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tool-filters.d.ts","sourceRoot":"","sources":["../src/tool-filters.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,oCAAoC,CAAC;AAE1E,sEAAsE;AACtE,eAAO,MAAM,SAAS;;;;;;;;;;;;;;;;;;;;CA6FZ,CAAC;AAEX,MAAM,MAAM,OAAO,GAAG,MAAM,OAAO,SAAS,CAAC;AAC7C,MAAM,MAAM,WAAW,GAAG;IACxB,mEAAmE;IACnE,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,gFAAgF;IAChF,IAAI,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CAC1B,CAAC;AAEF,eAAO,MAAM,UAAU,EAAoC,OAAO,EAAE,CAAC;AAcrE,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,EAAE,CAEhE;AAED,2FAA2F;AAC3F,wBAAgB,UAAU,CAAC,GAAG,EAAE,WAAW,GAAG;IAC5C,QAAQ,EAAE,OAAO,CAAC;IAClB,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,eAAe,KAAK,OAAO,CAAC;CAClE,CAmBA"}
@@ -0,0 +1,129 @@
1
+ /** Tags describe capabilities, not whether calling a tool is safe. */
2
+ export const TOOL_TAGS = {
3
+ account: ['get_account'],
4
+ agent: ['run_agent', 'run_agent_chat'],
5
+ activities: ['list_activities', 'get_activity', 'get_activity_results'],
6
+ signals: ['read_signals'],
7
+ artifacts: ['publish_artifact', 'get_artifact', 'read_artifact', 'delete_artifact'],
8
+ computers: [
9
+ 'list_computers',
10
+ 'get_computer',
11
+ 'use_computer',
12
+ 'wait_for_computer',
13
+ 'get_desktop_url',
14
+ 'list_sizes',
15
+ ],
16
+ events: ['wait_for_event', 'poll_events', 'wait_for_file_change'],
17
+ executions: ['get_execution', 'read_execution_output'],
18
+ files: ['list_directory', 'read_file', 'write_file', 'wait_for_file_change'],
19
+ guest: [
20
+ 'exec',
21
+ 'exec_poll',
22
+ 'exec_kill',
23
+ 'open_url',
24
+ 'list_windows',
25
+ 'window_action',
26
+ 'read_clipboard',
27
+ 'write_clipboard',
28
+ ],
29
+ input: [
30
+ 'screenshot',
31
+ 'click',
32
+ 'type_text',
33
+ 'press_key',
34
+ 'scroll',
35
+ 'drag',
36
+ 'move_mouse',
37
+ 'mouse_button',
38
+ 'cursor_position',
39
+ 'wait',
40
+ ],
41
+ lifecycle: [
42
+ 'create_computer',
43
+ 'start_computer',
44
+ 'stop_computer',
45
+ 'suspend_computer',
46
+ 'restart_computer',
47
+ 'update_computer',
48
+ 'clone_computer',
49
+ 'delete_computer',
50
+ 'move_computer',
51
+ 'list_moves',
52
+ ],
53
+ results: [
54
+ 'get_activity_results',
55
+ 'retain_execution_output',
56
+ 'get_result',
57
+ 'read_result_output',
58
+ 'delete_result',
59
+ ],
60
+ snapshots: [
61
+ 'list_snapshots',
62
+ 'snapshot_holdings',
63
+ 'create_snapshot',
64
+ 'restore_snapshot',
65
+ 'clone_snapshot',
66
+ 'snapshot_schedule',
67
+ 'get_retention',
68
+ 'delete_snapshot',
69
+ ],
70
+ templates: [
71
+ 'list_templates',
72
+ 'get_template_schema',
73
+ 'check_template',
74
+ 'publish_template',
75
+ 'get_template',
76
+ 'retire_template',
77
+ 'build_template',
78
+ 'list_builds',
79
+ 'get_build',
80
+ 'watch_build',
81
+ ],
82
+ secrets: ['get_computer_secrets', 'set_computer_secrets'],
83
+ ssh: ['list_ssh_keys', 'add_ssh_key', 'remove_ssh_key', 'get_computer_ssh', 'set_computer_ssh'],
84
+ usage: ['get_usage'],
85
+ webhooks: [
86
+ 'list_webhooks',
87
+ 'create_webhook',
88
+ 'get_webhook',
89
+ 'update_webhook',
90
+ 'rotate_webhook_secret',
91
+ 'test_webhook',
92
+ 'list_webhook_deliveries',
93
+ 'delete_webhook',
94
+ ],
95
+ };
96
+ export const VALID_TAGS = Object.keys(TOOL_TAGS).sort();
97
+ function validateTags(tags) {
98
+ const names = [...new Set(tags.map((tag) => tag.trim()).filter(Boolean))];
99
+ for (const name of names) {
100
+ if (!Object.hasOwn(TOOL_TAGS, name)) {
101
+ throw new Error(`Unknown MANDALA_TAGS tag "${name}". Valid tags (lowercase only): ${VALID_TAGS.join(', ')}`);
102
+ }
103
+ }
104
+ return names;
105
+ }
106
+ export function parseToolTags(raw) {
107
+ return validateTags(raw?.split(',') ?? []);
108
+ }
109
+ /** Validate before constructing the session; never infer read-only from a name or verb. */
110
+ export function toolFilter(cfg) {
111
+ if (cfg.readOnly !== undefined && typeof cfg.readOnly !== 'boolean') {
112
+ throw new Error('readOnly must be a boolean');
113
+ }
114
+ const tags = validateTags(cfg.tags ?? []);
115
+ const selected = new Set(tags.flatMap((tag) => [...TOOL_TAGS[tag]]));
116
+ const known = new Set(Object.values(TOOL_TAGS).flat());
117
+ const readOnly = cfg.readOnly === true;
118
+ return {
119
+ filtered: readOnly || tags.length > 0,
120
+ allows: (name, annotations) => {
121
+ // Even unfiltered startup must fail when a new tool lacks a tag, instead
122
+ // of silently hiding it only for clients who use filters.
123
+ if (!known.has(name))
124
+ throw new Error(`Tool "${name}" has no tag in TOOL_TAGS`);
125
+ return ((!tags.length || selected.has(name)) && (!readOnly || annotations?.readOnlyHint === true));
126
+ },
127
+ };
128
+ }
129
+ //# sourceMappingURL=tool-filters.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tool-filters.js","sourceRoot":"","sources":["../src/tool-filters.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { Registrar } from './types.js';
2
+ export declare const registerAccount: Registrar;
3
+ //# sourceMappingURL=account.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"account.d.ts","sourceRoot":"","sources":["../../src/tools/account.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AA4E5C,eAAO,MAAM,eAAe,EAAE,SAoD7B,CAAC"}
@@ -0,0 +1,122 @@
1
+ import { z } from 'zod';
2
+ import { APIError } from '../errors.js';
3
+ import { said } from '../format.js';
4
+ import * as P from '../paths.js';
5
+ import { count, label, metadata, metadataCall } from './directory.js';
6
+ import { readAnnotations } from './results.js';
7
+ // Every object projects only its public fields; a malformed report never becomes zero usage.
8
+ const report = z
9
+ .object({
10
+ scope: z.literal('account'),
11
+ advisory: z.literal(true),
12
+ observed_at: z.string().datetime(),
13
+ plan: z.object({ id: label, label }),
14
+ limits: z.object({
15
+ max_computers: count,
16
+ vcpu_pool: count,
17
+ ram_pool_mb: count,
18
+ disk_pool_gb: count,
19
+ snapshot_storage_bytes: count,
20
+ }),
21
+ per_computer: z.object({ max_vcpu: count, max_ram_mb: count, max_disk_gb: count }),
22
+ capabilities: z.object({ windows: z.boolean() }),
23
+ complete: z.object({ computers: z.boolean(), snapshots: z.boolean() }),
24
+ usage: z.object({
25
+ kept_computers: count.nullable(),
26
+ configured_vcpu: count.nullable(),
27
+ configured_disk_gb: count.nullable(),
28
+ running_or_reserved_computers: count.nullable(),
29
+ running_or_reserved_vcpu: count.nullable(),
30
+ running_or_reserved_ram_mb: count.nullable(),
31
+ snapshot_storage_bytes: count.nullable(),
32
+ }),
33
+ remaining: z.object({
34
+ kept_computers: count.nullable(),
35
+ configured_vcpu: count.nullable(),
36
+ configured_disk_gb: count.nullable(),
37
+ running_or_reserved_ram_mb: count.nullable(),
38
+ snapshot_storage_bytes: count.nullable(),
39
+ }),
40
+ })
41
+ .refine((data) => {
42
+ for (const group of [data.usage, data.remaining]) {
43
+ for (const [field, value] of Object.entries(group)) {
44
+ const complete = field === 'snapshot_storage_bytes' ? data.complete.snapshots : data.complete.computers;
45
+ if (complete !== (value !== null))
46
+ return false;
47
+ }
48
+ }
49
+ if (data.complete.computers) {
50
+ // Nullability was checked above. These are relationships within one observation,
51
+ // independent of plan ceilings: a consistent account can still be over quota.
52
+ const kept = data.usage.kept_computers;
53
+ const cpu = data.usage.configured_vcpu;
54
+ const disk = data.usage.configured_disk_gb;
55
+ const active = data.usage.running_or_reserved_computers;
56
+ const activeCPU = data.usage.running_or_reserved_vcpu;
57
+ const activeRAM = data.usage.running_or_reserved_ram_mb;
58
+ if (active > kept || activeCPU > cpu)
59
+ return false;
60
+ // Equal counts mean both CPU sums cover every kept computer.
61
+ if (active === kept && activeCPU !== cpu)
62
+ return false;
63
+ if (kept === 0 && (cpu !== 0 || disk !== 0))
64
+ return false;
65
+ if (active === 0 && (activeCPU !== 0 || activeRAM !== 0))
66
+ return false;
67
+ // Each active computer contributes positive integer MB, but its CPU may be zero.
68
+ if (activeRAM < active)
69
+ return false;
70
+ }
71
+ const ceilings = {
72
+ kept_computers: data.limits.max_computers,
73
+ configured_vcpu: data.limits.vcpu_pool,
74
+ configured_disk_gb: data.limits.disk_pool_gb,
75
+ running_or_reserved_ram_mb: data.limits.ram_pool_mb,
76
+ snapshot_storage_bytes: data.limits.snapshot_storage_bytes,
77
+ };
78
+ for (const field of Object.keys(ceilings)) {
79
+ const used = data.usage[field];
80
+ if (used !== null && data.remaining[field] !== Math.max(0, ceilings[field] - used))
81
+ return false;
82
+ }
83
+ return true;
84
+ });
85
+ export const registerAccount = (server, session) => {
86
+ server.registerTool('get_account', {
87
+ title: 'Read current account quota',
88
+ description: 'Read account-wide plan ceilings, per-computer maxima, current consumption and advisory remaining quota. Viewer or stronger; workspace-scoped keys receive aggregates without resource identities. No arguments, selected computer or model key. Incomplete computer/snapshot groups have null consumption and remaining values, meaning unknown. Snapshot headroom covers indexed stored bytes, excludes in-flight capture reservations and cannot promise that a capture will fit. This observation reserves nothing; later mutations still enforce quota.',
89
+ inputSchema: z.object({}).strict(),
90
+ annotations: readAnnotations,
91
+ }, (_args, extra) => metadataCall(async () => {
92
+ let raw;
93
+ try {
94
+ raw = await session.api.json('GET', P.ACCOUNT, { signal: extra.signal });
95
+ }
96
+ catch (error) {
97
+ if (error instanceof APIError) {
98
+ const refusal = z.object({ error: label.optional() }).safeParse(error.body);
99
+ throw new APIError(refusal.success && refusal.data.error
100
+ ? refusal.data.error
101
+ : 'Account quota request failed', error.status, error.body, error.retryAfterMs, error);
102
+ }
103
+ // JSON decoding failures can carry raw response text. Never print that text here.
104
+ throw new Error(extra.signal.aborted
105
+ ? 'Account quota read cancelled; no report was established.'
106
+ : 'Account quota could not be read; consumption and remaining quota are unknown.');
107
+ }
108
+ const data = metadata(report, raw);
109
+ const unknown = [
110
+ ...(!data.complete.computers ? ['computer'] : []),
111
+ ...(!data.complete.snapshots ? ['snapshot'] : []),
112
+ ];
113
+ return said((unknown.length
114
+ ? `UNKNOWN ${unknown.join(' and ')} consumption and remaining quota: null is not zero. `
115
+ : '') +
116
+ 'ADVISORY account observation; this reserves nothing and does not guarantee a later request will fit. ' +
117
+ 'Snapshot headroom is against indexed stored bytes only; in-flight capture reservations are not included. ' +
118
+ 'Configured CPU/disk cover kept computers; running or reserved RAM includes current reservations. ' +
119
+ 'Units are CPU, MB, GB and snapshot bytes as named. Use get_usage for historical metered consumption.', data);
120
+ }));
121
+ };
122
+ //# sourceMappingURL=account.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"account.js","sourceRoot":"","sources":["../../src/tools/account.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { Registrar } from './types.js';
2
+ export declare const registerActivities: Registrar;
3
+ //# sourceMappingURL=activities.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"activities.d.ts","sourceRoot":"","sources":["../../src/tools/activities.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAmG5C,eAAO,MAAM,kBAAkB,EAAE,SA+EhC,CAAC"}
@@ -0,0 +1,140 @@
1
+ import { z } from 'zod';
2
+ import { said } from '../format.js';
3
+ import * as P from '../paths.js';
4
+ import { count, executionId, exitCode, label, metadata, metadataCall } from './directory.js';
5
+ import { computerSchema, readAnnotations } from './results.js';
6
+ const activityId = z.string().regex(/^act_[a-f0-9]{32}$/);
7
+ const identity = { computer_id: computerSchema, activity_id: activityId };
8
+ const record = z.object({
9
+ activity_id: activityId,
10
+ account_id: label,
11
+ computer_id: label,
12
+ workspace_id: label.nullable(),
13
+ channel: label,
14
+ route: label,
15
+ action: label,
16
+ state: z.enum(['pending', 'acknowledged', 'exited', 'accepted', 'refused', 'unknown']),
17
+ received_at: label,
18
+ observed_at: label,
19
+ revision: count.min(1).optional(),
20
+ has_results: z.boolean().optional(),
21
+ dispatched_at: label.optional(),
22
+ elapsed_ms: count.optional(),
23
+ reason: label.optional(),
24
+ http_status: z.number().int().min(100).max(599).optional(),
25
+ exit_code: exitCode.optional(),
26
+ execution_id: executionId.optional(),
27
+ });
28
+ const health = z.object({
29
+ recording_started_at: label,
30
+ earliest_retained_at: label.nullable(),
31
+ count_truncated: z.boolean(),
32
+ age_truncated: z.boolean(),
33
+ capture: z.enum(['available', 'degraded']),
34
+ completeness: z.literal('best-effort'),
35
+ gap_at: label.nullable(),
36
+ recovered_at: label.nullable(),
37
+ });
38
+ const page = z.object({
39
+ items: z.array(record),
40
+ next_cursor: label.nullable(),
41
+ changes_cursor: label,
42
+ gap: z.boolean(),
43
+ health,
44
+ });
45
+ const observation = z.discriminatedUnion('status', [
46
+ z.object({ status: z.literal('running') }),
47
+ z.object({ status: z.literal('exited'), exit_code: exitCode }),
48
+ ]);
49
+ const stream = (sync) => z.object({
50
+ bytes: count.max(4 * 1024 * 1024),
51
+ retained_truncated: z.boolean(),
52
+ upstream_truncated: sync ? z.boolean() : z.null(),
53
+ });
54
+ const link = (kind, association, fields) => {
55
+ const base = {
56
+ id: z.string().regex(kind === 'artifact' ? /^art_[a-f0-9]{32}$/ : /^res_[a-f0-9]{32}$/),
57
+ kind: z.literal(kind),
58
+ association: z.literal(association),
59
+ };
60
+ return z.discriminatedUnion('availability', [
61
+ z.object({ ...base, availability: z.literal('unavailable') }),
62
+ z.object({
63
+ ...base,
64
+ availability: z.literal('available'),
65
+ captured_at: label,
66
+ expires_at: label,
67
+ ...fields,
68
+ }),
69
+ ]);
70
+ };
71
+ const resultLinks = z.object({
72
+ activity_id: activityId,
73
+ revision: count.min(1),
74
+ more: z.boolean(),
75
+ items: z
76
+ .array(z.union([
77
+ link('artifact', 'caller_selected_artifact', { bytes: count }),
78
+ link('background-output', 'background_execution_output', {
79
+ stdout: stream(false),
80
+ stderr: stream(false),
81
+ diagnostic: z.object({ bytes: count.max(65536), truncated: z.boolean() }),
82
+ observation,
83
+ }),
84
+ link('synchronous-output', 'synchronous_exec_response', {
85
+ stdout: stream(true),
86
+ stderr: stream(true),
87
+ diagnostic: z.null(),
88
+ observation: z.object({ status: z.literal('exited'), exit_code: exitCode }),
89
+ }),
90
+ ]))
91
+ .max(8),
92
+ });
93
+ const historyNote = 'Selected, retained, best-effort request history; not all guest work or an agent identity. Accepted background work is not completed execution; a dispatched error may have had effects. Activity IDs identify requests, never idempotency keys.';
94
+ export const registerActivities = (server, session) => {
95
+ server.registerTool('list_activities', {
96
+ title: 'Read one activity history page',
97
+ description: `${historyNote} History is newest first with a fixed watermark. Changes include late final updates to older rows. No automatic paging. A gap requires refreshing history.`,
98
+ inputSchema: {
99
+ computer_id: computerSchema,
100
+ cursor: z.string().min(1).max(2048).optional(),
101
+ changes: z.boolean().optional(),
102
+ },
103
+ annotations: readAnnotations,
104
+ }, ({ computer_id, cursor, changes }, extra) => metadataCall(async () => {
105
+ if (changes && !cursor)
106
+ throw new Error('changes=true requires a cursor.');
107
+ const id = session.resolve(computer_id);
108
+ const data = metadata(page, await session.api.json('GET', P.activities(id), {
109
+ query: { cursor, ...(changes ? { changes: 1 } : {}) },
110
+ signal: extra.signal,
111
+ }));
112
+ if (data.items.some((item) => item.computer_id !== id))
113
+ throw new Error('Activity history did not match the requested computer.');
114
+ return said(`${data.gap ? 'GAP: discard the change cursor and refresh history. ' : ''}${historyNote}`, data);
115
+ }));
116
+ server.registerTool('get_activity', {
117
+ title: 'Read one activity record',
118
+ description: historyNote,
119
+ inputSchema: identity,
120
+ annotations: readAnnotations,
121
+ }, ({ computer_id, activity_id }, extra) => metadataCall(async () => {
122
+ const id = session.resolve(computer_id);
123
+ const data = metadata(record, await session.api.json('GET', P.activity(id, activity_id), { signal: extra.signal }));
124
+ if (data.activity_id !== activity_id || data.computer_id !== id)
125
+ throw new Error('Activity response did not match the requested identity.');
126
+ return said(historyNote, data);
127
+ }));
128
+ server.registerTool('get_activity_results', {
129
+ title: 'Read passive result links for an activity',
130
+ description: 'Metadata only: at most eight newest links. more has no cursor and does not mean all versions were returned. No content reads, guest files, captures, execution polling or downloads. An unavailable link is not empty content. Caller-selected artifact association does not prove creation or command success.',
131
+ inputSchema: identity,
132
+ annotations: readAnnotations,
133
+ }, ({ computer_id, activity_id }, extra) => metadataCall(async () => {
134
+ const data = metadata(resultLinks, await session.api.json('GET', P.activityResults(session.resolve(computer_id), activity_id), { signal: extra.signal }));
135
+ if (data.activity_id !== activity_id)
136
+ throw new Error('Result links did not match the requested activity.');
137
+ return said(`${data.more ? 'More versions exist; this endpoint has no continuation cursor. ' : ''}Result links are metadata only. Availability and association do not establish command success.`, data);
138
+ }));
139
+ };
140
+ //# sourceMappingURL=activities.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"activities.js","sourceRoot":"","sources":["../../src/tools/activities.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"agent.d.ts","sourceRoot":"","sources":["../../src/tools/agent.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAE5C;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,aAAa,EAAE,SAiK3B,CAAC"}
1
+ {"version":3,"file":"agent.d.ts","sourceRoot":"","sources":["../../src/tools/agent.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAE5C;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,aAAa,EAAE,SAmL3B,CAAC"}
@@ -1,7 +1,9 @@
1
1
  import { z } from 'zod';
2
2
  import { MODEL_KEY_HEADER } from '../api.js';
3
- import { guarded, refused, said } from '../format.js';
3
+ import { APIError, authenticationAdvice, platformSaid } from '../errors.js';
4
+ import { errorMetadata, guarded, refused, said, withErrorMetadata } from '../format.js';
4
5
  import * as P from '../paths.js';
6
+ import { safeResult } from './chat.js';
5
7
  /**
6
8
  * The platform's own agent loop, as one tool.
7
9
  *
@@ -130,8 +132,19 @@ export const registerAgent = (server, session) => {
130
132
  // handed "the run failed" and a JSON blob does the natural thing,
131
133
  // which is to call this tool again with the same prompt — paying for
132
134
  // every completed step a second time to be refused the same way.
133
- return refused(`The run failed after ${steps.length} step(s).${stopReason(ev.data)}` +
134
- (steps.length ? `\n\nWhat it did, and is billed for:\n${steps.join('\n')}` : ''), ev.data);
135
+ const frame = isRecord(ev.data) ? ev.data : {};
136
+ const diagnostic = new APIError('', typeof frame.status === 'number' ? frame.status : 0, frame);
137
+ return withErrorMetadata(refused(`The run failed after ${steps.length} step(s).${stopReason(ev.data)}` +
138
+ (steps.length ? `\n\nWhat it did, and is billed for:\n${steps.join('\n')}` : ''), {
139
+ error: platformSaid(frame),
140
+ status: errorMetadata({ status: frame.status }).fields.status,
141
+ steps: frame.steps,
142
+ usage: frame.usage,
143
+ }), {
144
+ status: frame.status,
145
+ reason: diagnostic.reason,
146
+ request_id: diagnostic.requestId,
147
+ });
135
148
  }
136
149
  }
137
150
  if (!done) {
@@ -162,7 +175,7 @@ export const registerAgent = (server, session) => {
162
175
  : JSON.stringify(done.text);
163
176
  const result = `${verdict}\n\n${text}\n\nWhat it did:\n${steps.join('\n')}`;
164
177
  return stop === 'end_turn' ? said(result, done) : refused(result, done);
165
- }));
178
+ }).then((result) => safeResult(result, session.modelKey)));
166
179
  };
167
180
  /**
168
181
  * What an `error` frame says about whether calling this tool again can work.
@@ -185,17 +198,16 @@ export const registerAgent = (server, session) => {
185
198
  function stopReason(data) {
186
199
  const frame = isRecord(data) ? data : undefined;
187
200
  const status = typeof frame?.status === 'number' ? frame.status : undefined;
188
- const said = typeof frame?.error === 'string' && frame.error ? frame.error : undefined;
201
+ const said = platformSaid(frame);
189
202
  const why = said ? ` ${said}` : '';
190
203
  // 401 and 403 are split, because the recovery is not the same one. A shared
191
204
  // clause told a caller whose ROLE had been taken away to re-authenticate,
192
205
  // which restores nothing and sends it round the same refusal with another
193
206
  // prompt's worth of billed steps behind it (Codex review).
194
207
  if (status === 401) {
195
- return (` It was stopped because this server's credential is no longer accepted (HTTP ${status}) —` +
196
- ` not by anything wrong with the computer.${why} Do NOT call run_agent again with the same` +
197
- ` prompt: it is refused the same way until the credential is fixed. Once it is, read what` +
198
- ` the steps below already did before deciding what is left to do.`);
208
+ const reason = new APIError('', status, frame).reason;
209
+ return (` HTTP ${status}: ${authenticationAdvice(reason)}.${why} Do NOT call run_agent again with the same` +
210
+ ` prompt. Read what the steps below already did before deciding what is left to do.`);
199
211
  }
200
212
  if (status === 403) {
201
213
  return (` It was stopped because this account does not permit the run (HTTP ${status}) — a role that` +