@magnetoagents/mcp 0.2.0 → 0.3.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.
@@ -3,6 +3,96 @@
3
3
  import { readPackageVersion } from './package-version.js';
4
4
  export const MCP_PROTOCOL_VERSION = '2025-03-26';
5
5
  export const MCP_SERVER_VERSION = readPackageVersion();
6
+ /** ChatGPT reads this at initialize (InitializeResult.instructions). Front-load D3. */
7
+ export const MCP_SERVER_INSTRUCTIONS = `Magneto is an account companion. Never attempt to purchase, subscribe, or upgrade inside this plugin. If the user wants a plan, a marketplace skill purchase, credits, or checkout, describe the option and link to https://magnetoapp.io — never a checkout, upgrade, or payment deep-link. Runs and computer lifecycle actions bill the linked Magneto account's existing plan.
8
+
9
+ Typical flow: search or list the catalog (list_skills, search_marketplace, list_templates) → list or get the user's computers → create or start a computer if needed → install_skill only when the account already owns that skill → run a computer-use instruction → review with list_runs / get_run. Call get before a write when the computer id is uncertain.
10
+
11
+ Do not call bash, action, screenshot, gateway_url, chat, or any payment tool. Do not mint gateway credentials. If a skill is unowned or paid, refuse to install and point at https://magnetoapp.io. If the account's plan does not cover an action, name the state and point at https://magnetoapp.io as information — never an upgrade CTA.`;
12
+ export const HINT_READ = {
13
+ readOnlyHint: true,
14
+ destructiveHint: false,
15
+ openWorldHint: false,
16
+ };
17
+ export const HINT_WRITE = {
18
+ readOnlyHint: false,
19
+ destructiveHint: false,
20
+ openWorldHint: false,
21
+ };
22
+ export const HINT_DESTRUCTIVE = {
23
+ readOnlyHint: false,
24
+ destructiveHint: true,
25
+ openWorldHint: false,
26
+ };
27
+ export const HINT_OPEN_WORLD = {
28
+ readOnlyHint: false,
29
+ destructiveHint: false,
30
+ openWorldHint: true,
31
+ };
32
+ export const HINT_BASH = {
33
+ readOnlyHint: false,
34
+ destructiveHint: true,
35
+ openWorldHint: true,
36
+ };
37
+ const READ = { scheme: 'exact', usd: 0.01 };
38
+ const KEYLESS_READ = { scheme: 'exact', usd: 0.01, keyless: true };
39
+ const MUTATION = { scheme: 'exact', usd: 0.02 };
40
+ const UPTO_METERED = {
41
+ scheme: 'upto',
42
+ usd: 0.1,
43
+ note: 'ceiling = estimate × 1.25, floor $0.10 — Issue 6',
44
+ };
45
+ /** Inlined join of hosted `PRICES` via specMethod+specPath. Do not import `@/`. */
46
+ const STDIO_PRICES = {
47
+ 'POST /computers': {
48
+ scheme: 'quote',
49
+ note: 'shape-based provision fee (SHAPE_HOURLY_RATE_USD × prepaid hours) — Issue 8',
50
+ },
51
+ 'GET /computers': READ,
52
+ 'GET /computers/{id}': READ,
53
+ 'POST /computers/{id}/start': MUTATION,
54
+ 'POST /computers/{id}/stop': MUTATION,
55
+ 'POST /computers/{id}/restart': MUTATION,
56
+ 'DELETE /computers/{id}': MUTATION,
57
+ 'POST /computers/{id}/resize': MUTATION,
58
+ 'GET /computers/{id}/uptime': READ,
59
+ 'POST /computers/{id}/gateway': MUTATION,
60
+ 'POST /computers/{id}/actions/{action}': MUTATION,
61
+ 'POST /computers/{id}/bash': { scheme: 'exact', usd: 0.05 },
62
+ 'POST /computers/{id}/computer-use/run': UPTO_METERED,
63
+ 'POST /computers/{id}/computer-use/stop': READ,
64
+ 'GET /computers/{id}/runs': READ,
65
+ 'GET /computers/{id}/runs/{runId}': READ,
66
+ 'POST /computers/{id}/skills': {
67
+ scheme: 'quote',
68
+ note: 'free skill $0.01; unowned paid skill = catalog price — Issue 5',
69
+ },
70
+ 'DELETE /computers/{id}/skills/{skillId}': READ,
71
+ 'GET /skills': KEYLESS_READ,
72
+ 'GET /templates': KEYLESS_READ,
73
+ 'GET /files': READ,
74
+ 'GET /account': 'free',
75
+ 'POST /chat/completions': UPTO_METERED,
76
+ };
77
+ function withX402(def) {
78
+ const key = `${def.specMethod.toUpperCase()} ${def.specPath}`;
79
+ const x402 = STDIO_PRICES[key];
80
+ if (x402 === undefined) {
81
+ throw new Error(`MCP tool '${def.name}' has no inlined PriceEntry for ${key}`);
82
+ }
83
+ return { ...def, x402 };
84
+ }
85
+ export function toListedTool(def) {
86
+ return {
87
+ name: def.name,
88
+ title: def.title,
89
+ description: def.description,
90
+ inputSchema: def.inputSchema,
91
+ annotations: def.annotations,
92
+ ...(def.outputSchema ? { outputSchema: def.outputSchema } : {}),
93
+ _meta: { x402: def.x402 },
94
+ };
95
+ }
6
96
  export const DESKTOP_ACTION_ENUM = [
7
97
  'screenshot',
8
98
  'click',
@@ -15,10 +105,252 @@ export const DESKTOP_ACTION_ENUM = [
15
105
  'drag',
16
106
  'wait',
17
107
  ];
18
- export const MCP_TOOL_CATALOG = [
108
+ const COMPUTER_PUBLIC_SCHEMA = {
109
+ type: 'object',
110
+ additionalProperties: false,
111
+ required: ['id'],
112
+ properties: {
113
+ id: { type: 'string' },
114
+ name: { type: ['string', 'null'] },
115
+ kind: { type: 'string', enum: ['agent', 'desktop'] },
116
+ state: { type: 'string' },
117
+ cpu: { type: ['integer', 'null'] },
118
+ ram_gb: { type: ['integer', 'null'] },
119
+ disk_gb: { type: ['integer', 'null'] },
120
+ os: { type: ['string', 'null'] },
121
+ always_on: { type: 'boolean' },
122
+ llm_mode: { type: ['string', 'null'] },
123
+ template_id: { type: ['integer', 'null'] },
124
+ region: { type: ['string', 'null'] },
125
+ provider: { type: 'string' },
126
+ },
127
+ };
128
+ const LIST_OUTPUT_SCHEMA = {
129
+ type: 'object',
130
+ additionalProperties: false,
131
+ required: ['items'],
132
+ properties: {
133
+ items: { type: 'array', items: COMPUTER_PUBLIC_SCHEMA },
134
+ },
135
+ };
136
+ const AGENT_RUN_PUBLIC_SCHEMA = {
137
+ type: 'object',
138
+ additionalProperties: false,
139
+ required: ['id', 'computer_id', 'status', 'model'],
140
+ properties: {
141
+ id: { type: 'string' },
142
+ computer_id: { type: 'string' },
143
+ status: { type: 'string' },
144
+ model: { type: 'string' },
145
+ steps: { type: ['integer', 'null'] },
146
+ input_tokens: { type: ['integer', 'null'] },
147
+ output_tokens: { type: ['integer', 'null'] },
148
+ cost_usd: { type: ['string', 'number', 'null'] },
149
+ key_source: { type: ['string', 'null'] },
150
+ provider: { type: ['string', 'null'] },
151
+ instruction: { type: ['string', 'null'] },
152
+ started_at: { type: ['string', 'null'] },
153
+ completed_at: { type: ['string', 'null'] },
154
+ duration_seconds: { type: ['number', 'null'] },
155
+ },
156
+ };
157
+ const LIST_RUNS_OUTPUT_SCHEMA = {
158
+ type: 'object',
159
+ additionalProperties: false,
160
+ required: ['items', 'total', 'limit', 'offset'],
161
+ properties: {
162
+ items: { type: 'array', items: AGENT_RUN_PUBLIC_SCHEMA },
163
+ total: { type: 'integer' },
164
+ limit: { type: 'integer' },
165
+ offset: { type: 'integer' },
166
+ },
167
+ };
168
+ const AGENT_RUN_EVENT_PUBLIC_SCHEMA = {
169
+ type: 'object',
170
+ additionalProperties: false,
171
+ required: ['id', 'run_id', 'seq', 'type'],
172
+ properties: {
173
+ id: { type: 'string' },
174
+ run_id: { type: 'string' },
175
+ seq: { type: 'integer' },
176
+ type: { type: 'string' },
177
+ created_at: { type: ['string', 'null'] },
178
+ },
179
+ };
180
+ const GET_RUN_OUTPUT_SCHEMA = {
181
+ type: 'object',
182
+ additionalProperties: false,
183
+ required: ['run', 'events'],
184
+ properties: {
185
+ run: AGENT_RUN_PUBLIC_SCHEMA,
186
+ events: { type: 'array', items: AGENT_RUN_EVENT_PUBLIC_SCHEMA },
187
+ },
188
+ };
189
+ const SKILL_PUBLIC_SCHEMA = {
190
+ type: 'object',
191
+ additionalProperties: false,
192
+ required: ['id', 'name', 'description', 'price', 'category', 'created_at'],
193
+ properties: {
194
+ id: { type: 'integer' },
195
+ name: { type: 'string' },
196
+ description: { type: 'string' },
197
+ price: { type: 'number' },
198
+ category: { type: ['string', 'null'] },
199
+ created_at: { type: 'string' },
200
+ },
201
+ };
202
+ const LIST_SKILLS_OUTPUT_SCHEMA = {
203
+ type: 'object',
204
+ additionalProperties: false,
205
+ required: ['items'],
206
+ properties: {
207
+ items: { type: 'array', items: SKILL_PUBLIC_SCHEMA },
208
+ },
209
+ };
210
+ const SEARCH_MARKETPLACE_OUTPUT_SCHEMA = {
211
+ type: 'object',
212
+ additionalProperties: false,
213
+ required: ['items'],
214
+ properties: {
215
+ items: { type: 'array', items: SKILL_PUBLIC_SCHEMA },
216
+ exact: {
217
+ ...SKILL_PUBLIC_SCHEMA,
218
+ type: ['object', 'null'],
219
+ },
220
+ },
221
+ };
222
+ const TEMPLATE_PUBLIC_SCHEMA = {
223
+ type: 'object',
224
+ additionalProperties: false,
225
+ required: ['id', 'name', 'description', 'category'],
226
+ properties: {
227
+ id: { type: 'integer' },
228
+ name: { type: 'string' },
229
+ description: { type: 'string' },
230
+ category: { type: 'string' },
231
+ image_url: { type: 'string' },
232
+ },
233
+ };
234
+ const LIST_TEMPLATES_OUTPUT_SCHEMA = {
235
+ type: 'object',
236
+ additionalProperties: false,
237
+ required: ['items'],
238
+ properties: {
239
+ items: { type: 'array', items: TEMPLATE_PUBLIC_SCHEMA },
240
+ },
241
+ };
242
+ const FILE_PUBLIC_SCHEMA = {
243
+ type: 'object',
244
+ additionalProperties: false,
245
+ required: ['id', 'filename', 'size_bytes', 'content_type', 'created_at'],
246
+ properties: {
247
+ id: { type: 'string' },
248
+ filename: { type: 'string' },
249
+ size_bytes: { type: 'integer' },
250
+ content_type: { type: 'string' },
251
+ created_at: { type: 'string' },
252
+ },
253
+ };
254
+ const LIST_FILES_OUTPUT_SCHEMA = {
255
+ type: 'object',
256
+ additionalProperties: false,
257
+ required: ['items'],
258
+ properties: {
259
+ items: { type: 'array', items: FILE_PUBLIC_SCHEMA },
260
+ },
261
+ };
262
+ const ACCOUNT_OUTPUT_SCHEMA = {
263
+ type: 'object',
264
+ additionalProperties: false,
265
+ required: ['workspace', 'subscription', 'usage', 'key', 'rate_limit', 'spend', 'mandates'],
266
+ properties: {
267
+ workspace: {
268
+ type: 'object',
269
+ additionalProperties: false,
270
+ required: ['id'],
271
+ properties: {
272
+ id: { type: 'string' },
273
+ name: { type: ['string', 'null'] },
274
+ },
275
+ },
276
+ subscription: {
277
+ type: ['object', 'null'],
278
+ additionalProperties: true,
279
+ },
280
+ usage: {
281
+ type: 'object',
282
+ additionalProperties: false,
283
+ required: ['cu', 'llm', 'requests_today'],
284
+ properties: {
285
+ cu: { type: ['object', 'null'], additionalProperties: true },
286
+ llm: { type: ['object', 'null'], additionalProperties: true },
287
+ requests_today: { type: ['integer', 'null'] },
288
+ },
289
+ },
290
+ key: {
291
+ type: 'object',
292
+ additionalProperties: false,
293
+ required: ['prefix', 'scopes', 'expires_at', 'last_used_at'],
294
+ properties: {
295
+ prefix: { type: 'string' },
296
+ scopes: {
297
+ type: 'array',
298
+ items: {
299
+ type: 'string',
300
+ enum: ['computers', 'exec', 'runs', 'files', 'catalog', 'account'],
301
+ },
302
+ },
303
+ expires_at: { type: ['string', 'null'] },
304
+ last_used_at: { type: ['string', 'null'] },
305
+ },
306
+ },
307
+ rate_limit: {
308
+ type: 'object',
309
+ additionalProperties: false,
310
+ required: ['limit', 'window_s'],
311
+ properties: {
312
+ limit: { type: 'integer' },
313
+ window_s: { type: 'integer' },
314
+ },
315
+ },
316
+ spend: {
317
+ type: ['object', 'null'],
318
+ additionalProperties: false,
319
+ required: ['limit_usd', 'window_days', 'spent_usd', 'remaining_usd'],
320
+ properties: {
321
+ limit_usd: { type: 'number' },
322
+ window_days: { type: 'integer' },
323
+ spent_usd: { type: 'number' },
324
+ remaining_usd: { type: 'number' },
325
+ },
326
+ },
327
+ mandates: {
328
+ type: 'array',
329
+ items: {
330
+ type: 'object',
331
+ additionalProperties: false,
332
+ required: ['id', 'name', 'max_amount_usd', 'remaining_budget_usd', 'expires_at'],
333
+ properties: {
334
+ id: { type: 'string' },
335
+ name: { type: 'string' },
336
+ max_amount_usd: { type: 'number' },
337
+ remaining_budget_usd: { type: ['number', 'null'] },
338
+ expires_at: { type: ['string', 'null'] },
339
+ },
340
+ },
341
+ },
342
+ warnings: {
343
+ type: 'array',
344
+ items: { type: 'string' },
345
+ },
346
+ },
347
+ };
348
+ const MCP_TOOL_DEFS = [
19
349
  {
20
350
  name: 'create',
21
- description: 'Create a Magneto computer in the API key workspace. Scope computers. Works for both desktop and agent flavors (default flavor is agent; use flavor=desktop for CU machines). workspace_id is forced from the key; client-supplied workspace_id is ignored.',
351
+ title: 'Create computer',
352
+ annotations: HINT_WRITE,
353
+ description: "Use this when the user wants a new Magneto computer provisioned into their linked account's existing plan. Do not use for buying a plan, upgrading, or checkout — if the plan cannot cover the create, name the state and link to https://magnetoapp.io. Scope computers. Works for both desktop and agent flavors (default flavor is agent; use flavor=desktop for CU machines). workspace_id is forced from the key; client-supplied workspace_id is ignored.",
22
354
  inputSchema: {
23
355
  type: 'object',
24
356
  properties: {
@@ -42,8 +374,11 @@ export const MCP_TOOL_CATALOG = [
42
374
  },
43
375
  {
44
376
  name: 'list',
45
- description: 'List computers for the API key minting user. Scope computers. Returns both desktop and agent computers.',
377
+ title: 'List computers',
378
+ annotations: HINT_READ,
379
+ description: 'Use this when the user asks which Magneto computers they have or you need a computer_id before a write. Do not use for marketplace catalog browsing (list_skills, search_marketplace, list_templates) or run history (list_runs). Scope computers. Returns both desktop and agent computers.',
46
380
  inputSchema: { type: 'object', properties: {} },
381
+ outputSchema: LIST_OUTPUT_SCHEMA,
47
382
  requiredScope: 'computers',
48
383
  kinds: 'both',
49
384
  specMethod: 'get',
@@ -51,12 +386,15 @@ export const MCP_TOOL_CATALOG = [
51
386
  },
52
387
  {
53
388
  name: 'get',
54
- description: 'Get one computer by id. Scope computers. Works for both desktop and agent computers.',
389
+ title: 'Get computer',
390
+ annotations: HINT_READ,
391
+ description: "Use this when you need one computer's status by id, especially before a write when the computer_id is uncertain. Do not use for listing every computer (list) or for run replay (get_run). Scope computers. Works for both desktop and agent computers.",
55
392
  inputSchema: {
56
393
  type: 'object',
57
394
  required: ['computer_id'],
58
395
  properties: { computer_id: { type: 'string' } },
59
396
  },
397
+ outputSchema: COMPUTER_PUBLIC_SCHEMA,
60
398
  requiredScope: 'computers',
61
399
  kinds: 'both',
62
400
  specMethod: 'get',
@@ -64,7 +402,9 @@ export const MCP_TOOL_CATALOG = [
64
402
  },
65
403
  {
66
404
  name: 'start',
67
- description: 'Start a stopped computer. Scope computers. Works for both desktop and agent computers.',
405
+ title: 'Start computer',
406
+ annotations: HINT_WRITE,
407
+ description: 'Use this when the user wants to start a stopped Magneto computer they already own. Do not use for create (new machine) or run (computer-use loop). Scope computers. Works for both desktop and agent computers.',
68
408
  inputSchema: {
69
409
  type: 'object',
70
410
  required: ['computer_id'],
@@ -77,7 +417,9 @@ export const MCP_TOOL_CATALOG = [
77
417
  },
78
418
  {
79
419
  name: 'stop',
80
- description: 'Stop a computer. Scope computers. Works for both desktop and agent computers.',
420
+ title: 'Stop computer',
421
+ annotations: HINT_WRITE,
422
+ description: 'Use this when the user wants to stop a running Magneto computer they already own. Do not use for delete (irreversible deprovision) or stop_run (halt a CU loop only). Scope computers. Works for both desktop and agent computers.',
81
423
  inputSchema: {
82
424
  type: 'object',
83
425
  required: ['computer_id'],
@@ -90,7 +432,9 @@ export const MCP_TOOL_CATALOG = [
90
432
  },
91
433
  {
92
434
  name: 'restart',
93
- description: 'Restart a running or degraded computer. Scope computers. Works for both desktop and agent computers.',
435
+ title: 'Restart computer',
436
+ annotations: HINT_WRITE,
437
+ description: 'Use this when the user wants to restart a running or degraded Magneto computer they already own. Do not use for start of a stopped computer or for stop_run. Scope computers. Works for both desktop and agent computers.',
94
438
  inputSchema: {
95
439
  type: 'object',
96
440
  required: ['computer_id'],
@@ -103,7 +447,9 @@ export const MCP_TOOL_CATALOG = [
103
447
  },
104
448
  {
105
449
  name: 'delete',
106
- description: 'DESTRUCTIVE. Irreversible deprovision. confirm must equal the computer name. Scope computers. Works for both desktop and agent computers.',
450
+ title: 'Delete computer',
451
+ annotations: HINT_DESTRUCTIVE,
452
+ description: 'Use this when the user asks to permanently deprovision a Magneto computer they already own. Do not use for stop (reversible power-off) or uninstall_skill. DESTRUCTIVE and irreversible; confirm must equal the computer name. Scope computers. Works for both desktop and agent computers. Never refund or sell in-plugin.',
107
453
  inputSchema: {
108
454
  type: 'object',
109
455
  required: ['computer_id', 'confirm'],
@@ -119,7 +465,9 @@ export const MCP_TOOL_CATALOG = [
119
465
  },
120
466
  {
121
467
  name: 'resize',
122
- description: 'Resize a desktop computer (grow-only: vcpu, ram_gb, disk_gb). Scope computers. Desktop grow-only; agent or shrink returns 422 passthrough.',
468
+ title: 'Resize computer',
469
+ annotations: HINT_WRITE,
470
+ description: 'Use this when the user wants to grow a desktop computer (vcpu, ram_gb, disk_gb). Do not use for shrinking, for agent computers (422), or as a plan-upgrade path — over-plan 402/403 is informational; link https://magnetoapp.io. Scope computers. Desktop grow-only.',
123
471
  inputSchema: {
124
472
  type: 'object',
125
473
  required: ['computer_id'],
@@ -137,7 +485,9 @@ export const MCP_TOOL_CATALOG = [
137
485
  },
138
486
  {
139
487
  name: 'uptime',
140
- description: 'Get Fly Prometheus uptime for a computer. Scope computers. Works for both desktop and agent computers. Optional window_seconds.',
488
+ title: 'Get computer uptime',
489
+ annotations: HINT_READ,
490
+ description: 'Use this when the user asks Fly Prometheus uptime for a computer. Do not use as a substitute for get or list, and do not use it to start or stop a machine. Scope computers. Works for both desktop and agent computers. Optional window_seconds.',
141
491
  inputSchema: {
142
492
  type: 'object',
143
493
  required: ['computer_id'],
@@ -153,7 +503,9 @@ export const MCP_TOOL_CATALOG = [
153
503
  },
154
504
  {
155
505
  name: 'gateway_url',
156
- description: 'Mint a 60-second signed gateway URL. Scope computers. Desktop uses /desk; agent uses /connect. target=terminal is desktop-only. Do not log the url.',
506
+ title: 'Mint gateway URL',
507
+ annotations: HINT_WRITE,
508
+ description: 'Use this when a keyed client needs a 60-second signed gateway URL. Do not use for plugin-surface workflows, do not log the url, and do not mint credentials for ChatGPT. Scope computers. Desktop uses /desk; agent uses /connect. target=terminal is desktop-only.',
157
509
  inputSchema: {
158
510
  type: 'object',
159
511
  required: ['computer_id'],
@@ -169,7 +521,9 @@ export const MCP_TOOL_CATALOG = [
169
521
  },
170
522
  {
171
523
  name: 'screenshot',
172
- description: 'Take a screenshot of a desktop computer. Scope computers. Desktop-gui: real screenshot. Agent computers return structured status (screenshot: null, no action call).',
524
+ title: 'Take screenshot',
525
+ annotations: HINT_READ,
526
+ description: 'Use this when a keyed client needs a single desktop screenshot. Do not use for multi-step computer-use (run / get_run) or as a ChatGPT plugin tool. Scope computers. Desktop-gui: real screenshot. Agent computers return structured status (screenshot: null, no action call). Agent stub is not charged; desktop-gui is exact $0.02.',
173
527
  inputSchema: {
174
528
  type: 'object',
175
529
  required: ['computer_id'],
@@ -182,7 +536,9 @@ export const MCP_TOOL_CATALOG = [
182
536
  },
183
537
  {
184
538
  name: 'action',
185
- description: 'Dispatch one desktop GUI action (screenshot, click, double_click, right_click, move, type, key, scroll, drag, wait). Scope computers. Desktop-gui only. Agent computers return structured status (action: null, no helper call).',
539
+ title: 'Dispatch desktop action',
540
+ annotations: HINT_OPEN_WORLD,
541
+ description: 'Use this when a keyed client needs one desktop GUI primitive (screenshot, click, double_click, right_click, move, type, key, scroll, drag, wait). Do not use for multi-step computer-use (run) or as a ChatGPT plugin tool. Scope computers. Desktop-gui only. Agent computers return structured status (action: null, no helper call). Agent stub is not charged; desktop-gui is exact $0.02.',
186
542
  inputSchema: {
187
543
  type: 'object',
188
544
  required: ['computer_id', 'action'],
@@ -213,7 +569,9 @@ export const MCP_TOOL_CATALOG = [
213
569
  },
214
570
  {
215
571
  name: 'bash',
216
- description: 'Run a shell command on a computer. Scope exec (opt-in, not in DEFAULT_SCOPES). Allowed on desktop and agent. Output capped 1 MiB; timeout 1–300 s.',
572
+ title: 'Run shell command',
573
+ annotations: HINT_BASH,
574
+ description: 'Use this when a keyed client with opt-in exec scope needs a shell command on a computer. Do not use as a substitute for run, and do not call it from ChatGPT plugin workflows. Scope exec (opt-in, not in DEFAULT_SCOPES). Allowed on desktop and agent. Output capped 1 MiB; timeout 1–300 s. DESTRUCTIVE and open-world.',
217
575
  inputSchema: {
218
576
  type: 'object',
219
577
  required: ['computer_id', 'command'],
@@ -230,7 +588,9 @@ export const MCP_TOOL_CATALOG = [
230
588
  },
231
589
  {
232
590
  name: 'run',
233
- description: 'Run a computer-use instruction on a desktop computer (streaming CU loop). Scope runs. Desktop only. Burns the platform CU spend cap or the single named BYO secret. Concurrent-run ceiling applies (429). Agent computers return 422.',
591
+ title: 'Run computer-use agent',
592
+ annotations: HINT_OPEN_WORLD,
593
+ description: "Use this when the user wants an agentic computer-use instruction executed on a desktop they already own. Do not use for agent-flavor computers (422), for a single GUI primitive (action), or to purchase credits — runs bill the linked account's existing CU/LLM plan (platform CU spend cap or the single named BYO secret). Scope runs. Desktop only. Concurrent-run ceiling applies (429).",
234
594
  inputSchema: {
235
595
  type: 'object',
236
596
  required: ['computer_id', 'instruction'],
@@ -248,7 +608,9 @@ export const MCP_TOOL_CATALOG = [
248
608
  },
249
609
  {
250
610
  name: 'stop_run',
251
- description: 'Hard-stop a computer-use run. Scope runs. Desktop-cu. Body run_id. 404 if already finished.',
611
+ title: 'Stop computer-use run',
612
+ annotations: HINT_WRITE,
613
+ description: 'Use this when the user wants to hard-stop an in-flight computer-use run. Do not use for stop (power off the computer) or delete. Scope runs. Desktop-cu. Body run_id. 404 if already finished.',
252
614
  inputSchema: {
253
615
  type: 'object',
254
616
  required: ['computer_id', 'run_id'],
@@ -264,7 +626,9 @@ export const MCP_TOOL_CATALOG = [
264
626
  },
265
627
  {
266
628
  name: 'list_runs',
267
- description: 'List computer-use run history for a computer. Scope runs. Desktop-cu. Optional limit and offset.',
629
+ title: 'List computer-use runs',
630
+ annotations: HINT_READ,
631
+ description: 'Use this when the user asks for computer-use run history on a computer. Do not use for listing computers (list) or marketplace skills (list_skills). Scope runs. Desktop-cu. Optional limit and offset.',
268
632
  inputSchema: {
269
633
  type: 'object',
270
634
  required: ['computer_id'],
@@ -274,6 +638,7 @@ export const MCP_TOOL_CATALOG = [
274
638
  offset: { type: 'number' },
275
639
  },
276
640
  },
641
+ outputSchema: LIST_RUNS_OUTPUT_SCHEMA,
277
642
  requiredScope: 'runs',
278
643
  kinds: 'desktop-cu',
279
644
  specMethod: 'get',
@@ -281,7 +646,9 @@ export const MCP_TOOL_CATALOG = [
281
646
  },
282
647
  {
283
648
  name: 'get_run',
284
- description: 'Get a computer-use run and its step events. Scope runs. Desktop-cu. Signed screenshot URLs are credentials — do not log them.',
649
+ title: 'Get computer-use run',
650
+ annotations: HINT_READ,
651
+ description: 'Use this when the user wants one computer-use run and its step events. Do not use for live control (run / stop_run) or for listing all runs. Scope runs. Desktop-cu. Signed screenshot URLs are credentials — do not log them.',
285
652
  inputSchema: {
286
653
  type: 'object',
287
654
  required: ['computer_id', 'run_id'],
@@ -290,6 +657,7 @@ export const MCP_TOOL_CATALOG = [
290
657
  run_id: { type: 'string' },
291
658
  },
292
659
  },
660
+ outputSchema: GET_RUN_OUTPUT_SCHEMA,
293
661
  requiredScope: 'runs',
294
662
  kinds: 'desktop-cu',
295
663
  specMethod: 'get',
@@ -297,7 +665,9 @@ export const MCP_TOOL_CATALOG = [
297
665
  },
298
666
  {
299
667
  name: 'install_skill',
300
- description: 'Install a marketplace skill onto a computer by numeric skill_id. Scope computers. Works for both desktop and agent computers.',
668
+ title: 'Install skill',
669
+ annotations: HINT_WRITE,
670
+ description: 'Use this when the linked account already owns the marketplace skill and the user wants it installed on a computer. Do not use for buying, quoting, or fulfilling an unowned or paid skill — refuse and link to https://magnetoapp.io. Scope computers. Works for both desktop and agent computers. Requires computer_id and numeric skill_id.',
301
671
  inputSchema: {
302
672
  type: 'object',
303
673
  required: ['computer_id', 'skill_id'],
@@ -313,7 +683,9 @@ export const MCP_TOOL_CATALOG = [
313
683
  },
314
684
  {
315
685
  name: 'uninstall_skill',
316
- description: 'Uninstall a marketplace skill from a computer. Scope computers. Works for both desktop and agent computers. Missing install is a no-op.',
686
+ title: 'Uninstall skill',
687
+ annotations: HINT_DESTRUCTIVE,
688
+ description: 'Use this when the user wants a marketplace skill removed from one computer. Do not use for delete (deprovision the computer) or as a purchase refund. DESTRUCTIVE and irreversible for that computer; missing install is a no-op. Scope computers. Works for both desktop and agent computers.',
317
689
  inputSchema: {
318
690
  type: 'object',
319
691
  required: ['computer_id', 'skill_id'],
@@ -329,7 +701,9 @@ export const MCP_TOOL_CATALOG = [
329
701
  },
330
702
  {
331
703
  name: 'list_skills',
332
- description: 'List marketplace skills (GET /skills). Scope catalog. Not the per-computer installed list. REST has no search query.',
704
+ title: 'List marketplace skills',
705
+ annotations: HINT_READ,
706
+ description: 'Use this when the user wants to browse the public marketplace skill catalog. Do not use to purchase, subscribe, or checkout — browse only; buying is https://magnetoapp.io. Scope catalog. Not the per-computer installed list. REST has no search query.',
333
707
  inputSchema: {
334
708
  type: 'object',
335
709
  properties: {
@@ -337,6 +711,7 @@ export const MCP_TOOL_CATALOG = [
337
711
  limit: { type: 'number' },
338
712
  },
339
713
  },
714
+ outputSchema: LIST_SKILLS_OUTPUT_SCHEMA,
340
715
  requiredScope: 'catalog',
341
716
  kinds: 'both',
342
717
  specMethod: 'get',
@@ -344,7 +719,9 @@ export const MCP_TOOL_CATALOG = [
344
719
  },
345
720
  {
346
721
  name: 'search_marketplace',
347
- description: 'Search the marketplace skill page in-tool (name/description filter). Scope catalog. REST has no ?q= — this is a tool-side filter over GET /skills. A numeric query also fetches GET /skills/{id}.',
722
+ title: 'Search marketplace',
723
+ annotations: HINT_READ,
724
+ description: 'Use this when the user wants to search skills by name or description. Do not use to purchase or to scan the full catalog — matches outside the fetched marketplace skill page window (GET /skills skip/limit; default page size 100) are omitted. Scope catalog. REST has no ?q=. A numeric query also fetches GET /skills/{id} unfiltered. Buying is https://magnetoapp.io.',
348
725
  inputSchema: {
349
726
  type: 'object',
350
727
  properties: {
@@ -353,6 +730,7 @@ export const MCP_TOOL_CATALOG = [
353
730
  limit: { type: 'number' },
354
731
  },
355
732
  },
733
+ outputSchema: SEARCH_MARKETPLACE_OUTPUT_SCHEMA,
356
734
  requiredScope: 'catalog',
357
735
  kinds: 'both',
358
736
  specMethod: 'get',
@@ -360,7 +738,9 @@ export const MCP_TOOL_CATALOG = [
360
738
  },
361
739
  {
362
740
  name: 'list_templates',
363
- description: 'List marketplace computer templates. Scope catalog.',
741
+ title: 'List templates',
742
+ annotations: HINT_READ,
743
+ description: "Use this when the user wants to browse marketplace computer templates before create. Do not use to purchase a plan or as a substitute for list (the user's computers). Scope catalog. Browse only; link https://magnetoapp.io for paid plans.",
364
744
  inputSchema: {
365
745
  type: 'object',
366
746
  properties: {
@@ -370,6 +750,7 @@ export const MCP_TOOL_CATALOG = [
370
750
  featured: { type: 'boolean' },
371
751
  },
372
752
  },
753
+ outputSchema: LIST_TEMPLATES_OUTPUT_SCHEMA,
373
754
  requiredScope: 'catalog',
374
755
  kinds: 'both',
375
756
  specMethod: 'get',
@@ -377,8 +758,11 @@ export const MCP_TOOL_CATALOG = [
377
758
  },
378
759
  {
379
760
  name: 'list_files',
380
- description: 'List workspace files. Scope files.',
761
+ title: 'List files',
762
+ annotations: HINT_READ,
763
+ description: 'Use this when the user wants an account-scoped workspace file listing. Do not use for upload, delete, or skill catalog browse. Scope files.',
381
764
  inputSchema: { type: 'object', properties: {} },
765
+ outputSchema: LIST_FILES_OUTPUT_SCHEMA,
382
766
  requiredScope: 'files',
383
767
  kinds: 'both',
384
768
  specMethod: 'get',
@@ -386,8 +770,11 @@ export const MCP_TOOL_CATALOG = [
386
770
  },
387
771
  {
388
772
  name: 'account',
389
- description: 'Read-only self-budget snapshot (workspace, subscription, CU/LLM usage, key scopes). Scope account.',
773
+ title: 'Account snapshot',
774
+ annotations: HINT_READ,
775
+ description: 'Use this when the user asks about their linked Magneto plan, usage, or key scopes. Do not use to purchase, subscribe, upgrade, or checkout — describe entitlements only and link https://magnetoapp.io for those. Scope account. Read-only self-budget snapshot (workspace, subscription, CU/LLM usage, key scopes).',
390
776
  inputSchema: { type: 'object', properties: {} },
777
+ outputSchema: ACCOUNT_OUTPUT_SCHEMA,
391
778
  requiredScope: 'account',
392
779
  kinds: 'both',
393
780
  specMethod: 'get',
@@ -395,7 +782,9 @@ export const MCP_TOOL_CATALOG = [
395
782
  },
396
783
  {
397
784
  name: 'chat',
398
- description: 'OpenAI-compatible chat completion over computer-use (non-stream). Scope runs. Desktop only. Burns the platform CU spend cap or the single named BYO secret. Concurrent-run ceiling applies (429). Accepts messages or a single instruction. stream is coerced to false. Agent computers return 422.',
785
+ title: 'Chat completion',
786
+ annotations: HINT_OPEN_WORLD,
787
+ description: 'Use this when a keyed client wants an OpenAI-compatible chat completion over computer-use (non-stream). Do not use as a second ChatGPT plugin CU entry (use run) and do not purchase credits in-plugin. Scope runs. Desktop only. Burns the platform CU spend cap or the single named BYO secret. Concurrent-run ceiling applies (429). Accepts messages or a single instruction. stream is coerced to false. Agent computers return 422.',
399
788
  inputSchema: {
400
789
  type: 'object',
401
790
  required: ['computer_id'],
@@ -418,6 +807,7 @@ export const MCP_TOOL_CATALOG = [
418
807
  specPath: '/chat/completions',
419
808
  },
420
809
  ];
810
+ export const MCP_TOOL_CATALOG = MCP_TOOL_DEFS.map(withX402);
421
811
  export function listToolsForScopes(scopes) {
422
812
  return MCP_TOOL_CATALOG.filter((tool) => scopes.includes(tool.requiredScope));
423
813
  }