mandala-computer-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.
- package/LICENSE +21 -0
- package/README.md +544 -0
- package/dist/api.d.ts +186 -0
- package/dist/api.d.ts.map +1 -0
- package/dist/api.js +932 -0
- package/dist/api.js.map +1 -0
- package/dist/cli.d.ts +55 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +292 -0
- package/dist/cli.js.map +1 -0
- package/dist/errors.d.ts +560 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +873 -0
- package/dist/errors.js.map +1 -0
- package/dist/events.d.ts +406 -0
- package/dist/events.d.ts.map +1 -0
- package/dist/events.js +1679 -0
- package/dist/events.js.map +1 -0
- package/dist/format.d.ts +125 -0
- package/dist/format.d.ts.map +1 -0
- package/dist/format.js +180 -0
- package/dist/format.js.map +1 -0
- package/dist/http.d.ts +46 -0
- package/dist/http.d.ts.map +1 -0
- package/dist/http.js +792 -0
- package/dist/http.js.map +1 -0
- package/dist/index.d.ts +13 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +12 -0
- package/dist/index.js.map +1 -0
- package/dist/paths.d.ts +394 -0
- package/dist/paths.d.ts.map +1 -0
- package/dist/paths.js +677 -0
- package/dist/paths.js.map +1 -0
- package/dist/server.d.ts +18 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +97 -0
- package/dist/server.js.map +1 -0
- package/dist/session.d.ts +78 -0
- package/dist/session.d.ts.map +1 -0
- package/dist/session.js +166 -0
- package/dist/session.js.map +1 -0
- package/dist/stdio.d.ts +11 -0
- package/dist/stdio.d.ts.map +1 -0
- package/dist/stdio.js +43 -0
- package/dist/stdio.js.map +1 -0
- package/dist/tools/agent.d.ts +16 -0
- package/dist/tools/agent.d.ts.map +1 -0
- package/dist/tools/agent.js +147 -0
- package/dist/tools/agent.js.map +1 -0
- package/dist/tools/computers.d.ts +3 -0
- package/dist/tools/computers.d.ts.map +1 -0
- package/dist/tools/computers.js +1037 -0
- package/dist/tools/computers.js.map +1 -0
- package/dist/tools/events.d.ts +3 -0
- package/dist/tools/events.d.ts.map +1 -0
- package/dist/tools/events.js +1077 -0
- package/dist/tools/events.js.map +1 -0
- package/dist/tools/guest.d.ts +3 -0
- package/dist/tools/guest.d.ts.map +1 -0
- package/dist/tools/guest.js +761 -0
- package/dist/tools/guest.js.map +1 -0
- package/dist/tools/input.d.ts +3 -0
- package/dist/tools/input.d.ts.map +1 -0
- package/dist/tools/input.js +240 -0
- package/dist/tools/input.js.map +1 -0
- package/dist/tools/snapshots.d.ts +3 -0
- package/dist/tools/snapshots.d.ts.map +1 -0
- package/dist/tools/snapshots.js +333 -0
- package/dist/tools/snapshots.js.map +1 -0
- package/dist/tools/templates.d.ts +3 -0
- package/dist/tools/templates.d.ts.map +1 -0
- package/dist/tools/templates.js +492 -0
- package/dist/tools/templates.js.map +1 -0
- package/dist/tools/types.d.ts +18 -0
- package/dist/tools/types.d.ts.map +1 -0
- package/dist/tools/types.js +2 -0
- package/dist/tools/types.js.map +1 -0
- package/dist/tools/webhooks.d.ts +3 -0
- package/dist/tools/webhooks.d.ts.map +1 -0
- package/dist/tools/webhooks.js +260 -0
- package/dist/tools/webhooks.js.map +1 -0
- package/package.json +59 -0
|
@@ -0,0 +1,492 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { CancelledError, isTransientForPoll } from '../errors.js';
|
|
3
|
+
import { guarded, incompleteWarning, json, refused, said } from '../format.js';
|
|
4
|
+
import * as P from '../paths.js';
|
|
5
|
+
/**
|
|
6
|
+
* The template store, and the builds that compile documents into images.
|
|
7
|
+
*
|
|
8
|
+
* Its own module rather than lines in computers.ts, because none of this is
|
|
9
|
+
* about a computer: a template is a document the account owns, and a build is a
|
|
10
|
+
* job that outlives the request that started it. Nothing here reads or writes
|
|
11
|
+
* the session's selected computer.
|
|
12
|
+
*
|
|
13
|
+
* WHAT A MODEL HAS TO BE TOLD, and the reason these descriptions are long. Two
|
|
14
|
+
* of these tools are irreversible in a way that is not obvious from their names.
|
|
15
|
+
* `retire_template` without a version takes EVERY version, and a retired ref can
|
|
16
|
+
* never be published again — so the description says both, in the tool the model
|
|
17
|
+
* reads before deciding, rather than in a 409 it reads afterwards.
|
|
18
|
+
*/
|
|
19
|
+
const namespaceArg = {
|
|
20
|
+
namespace: z
|
|
21
|
+
.string()
|
|
22
|
+
.describe('The account id the template is published under. READ IT OFF A `ref`: every row of list_templates carries one shaped `<namespace>/<name>@<version>`, and the part before the slash is the namespace. Rows reading `system` are the templates we publish; anything else is your own account id. There is no separate `namespace` field on a template — the ref is where it lives.'),
|
|
23
|
+
name: z.string().describe('The template name, without the namespace or the version.'),
|
|
24
|
+
};
|
|
25
|
+
const versionArg = z
|
|
26
|
+
.string()
|
|
27
|
+
.optional()
|
|
28
|
+
.describe('A specific MAJOR.MINOR.PATCH. Send it or omit it entirely — an empty string is refused, because omitting it does not mean the same thing on both tools.');
|
|
29
|
+
export const registerTemplates = (server, session, opts) => {
|
|
30
|
+
// What to call the thing that launches a template, when there IS one.
|
|
31
|
+
//
|
|
32
|
+
// `create_computer` is not registered under MANDALA_NO_LIFECYCLE, and a name
|
|
33
|
+
// in a neighbouring tool's description is the same idea by a different route
|
|
34
|
+
// as a tool in the list: the model reads it and tries it. The server
|
|
35
|
+
// instructions were already parameterised on this; the descriptions were not.
|
|
36
|
+
const launcher = opts.lifecycle ? 'create_computer' : 'whatever creates computers on this setup';
|
|
37
|
+
server.registerTool('get_template_schema', {
|
|
38
|
+
title: 'Get the template document schema',
|
|
39
|
+
description: 'The JSON Schema for a `mandala/v1` template document — the declarative form a template is written in. Read this before writing one: it describes the ref, the image family, what the template is layered onto, and the shape a computer gets when a create names no numbers.',
|
|
40
|
+
inputSchema: {},
|
|
41
|
+
annotations: { readOnlyHint: true },
|
|
42
|
+
}, (_args, extra) => guarded(async () => json(await session.api.with(extra.signal).json('GET', P.TEMPLATE_SCHEMA))));
|
|
43
|
+
server.registerTool('check_template', {
|
|
44
|
+
title: 'Check a template document',
|
|
45
|
+
description: 'Check a document against the SCHEMA, without publishing it. Nothing is stored and no ref is claimed, so this is safe on a draft and safe to call repeatedly, and every problem comes back at once. Always check before publishing: a ref is immutable, so a document published with a mistake in it cannot be corrected under that version. WHAT IT CANNOT SEE: this reads the document alone and knows nothing about your account, so `valid: true` does not mean publish_template will succeed. Whether the namespace is yours, whether the family is yours, whether your plan may publish at all, and whether the ref is already taken or retired are all decided at publish time and can still refuse a document that checks out here.',
|
|
46
|
+
inputSchema: {
|
|
47
|
+
document: z
|
|
48
|
+
.string()
|
|
49
|
+
.describe('The document itself, as JSON or YAML — the file contents, not a wrapper.'),
|
|
50
|
+
},
|
|
51
|
+
annotations: { readOnlyHint: true },
|
|
52
|
+
}, ({ document }, extra) => guarded(async () => {
|
|
53
|
+
const body = await session.api
|
|
54
|
+
.with(extra.signal)
|
|
55
|
+
.json('POST', P.TEMPLATE_VALIDATE, {
|
|
56
|
+
raw: P.templateDocument(document),
|
|
57
|
+
});
|
|
58
|
+
// `valid` READ AS A BOOLEAN, not for truthiness (adversarial review,
|
|
59
|
+
// OPL-3835). `json<T>` is a cast and checks nothing at run time, so a
|
|
60
|
+
// body answering `{"valid": "false"}` — a proxy stringifying, a field
|
|
61
|
+
// that changes type — is truthy, and this tool then reported a document
|
|
62
|
+
// the platform had just rejected as valid. The one answer a check tool
|
|
63
|
+
// must never get wrong is "yes".
|
|
64
|
+
if (typeof body.valid !== 'boolean') {
|
|
65
|
+
return refused('POST /templates/validate answered without a boolean `valid`, so this says NOTHING about the document — do not publish on the strength of it. Check it again.', body);
|
|
66
|
+
}
|
|
67
|
+
// NOT `refused` for an invalid document. That is the answer to the
|
|
68
|
+
// question this tool asks — the platform says so with a 200 — and
|
|
69
|
+
// marking it isError would tell the model its request failed when what
|
|
70
|
+
// it actually got is the list of problems it asked for.
|
|
71
|
+
return body.valid
|
|
72
|
+
? said('The document is valid — against the schema. Publishing can still refuse it for something only your account decides: the namespace, the family, your plan, or a ref already taken. `doc_digest` identifies the document and changes with anything that changes what it MEANS — a label included. Comments, key order, indentation and YAML-versus-JSON do not reach it: the digest is over the canonical re-marshalling of the parsed document, not over your file. `build_digest` covers only what decides the image, so comparing it against a previous check tells you whether an edit means a rebuild — but it is present ONLY for a document with no `spec.from`, and a document that declares build steps must have one, so a buildable document gets `build_digest_needs` instead, naming the parent whose digest would be required.', body)
|
|
73
|
+
: said('The document is NOT valid. Every problem is listed — fix them all and check again rather than one at a time.', body);
|
|
74
|
+
}));
|
|
75
|
+
server.registerTool('publish_template', {
|
|
76
|
+
title: 'Publish a template document',
|
|
77
|
+
description: `Store a document under a ref of your own, so ${launcher} can launch it by name. ` +
|
|
78
|
+
'THE NAMESPACE IS YOUR ACCOUNT: `metadata.namespace` has to be your account id, and anything else is refused rather than rewritten — `system` included. A REF IS IMMUTABLE: publishing the identical document again succeeds and changes nothing, but publishing a DIFFERENT document under the same ref is refused, and the fix is to bump `metadata.version`. What counts as different is the digest, so a changed label is a change. Check the document first — a mistake published under a version can never be corrected under that version.',
|
|
79
|
+
inputSchema: {
|
|
80
|
+
document: z
|
|
81
|
+
.string()
|
|
82
|
+
.describe('The document itself, as JSON or YAML — the file contents, not a wrapper.'),
|
|
83
|
+
},
|
|
84
|
+
annotations: { openWorldHint: true },
|
|
85
|
+
}, ({ document }, extra) => guarded(async () => {
|
|
86
|
+
const body = await session.api
|
|
87
|
+
.with(extra.signal)
|
|
88
|
+
.json('POST', P.TEMPLATES, {
|
|
89
|
+
raw: P.templateDocument(document),
|
|
90
|
+
});
|
|
91
|
+
// The ref, checked rather than interpolated. This is a WRITE, so a
|
|
92
|
+
// malformed 2xx is the one answer that cannot be shrugged off:
|
|
93
|
+
// `Published undefined` reads as a success and names a ref nothing can
|
|
94
|
+
// resolve, and a model that responds by bumping `metadata.version` and
|
|
95
|
+
// publishing again has claimed two refs for one document — neither of
|
|
96
|
+
// which it can take back (adversarial review, OPL-3835).
|
|
97
|
+
if (typeof body.ref !== 'string' || !body.ref.trim()) {
|
|
98
|
+
return refused('POST /templates answered without a `ref`, so this server cannot say what was stored. THE PUBLISH MAY HAVE SUCCEEDED — read the name with get_template before publishing again, because a ref is immutable and a second version claims a second ref.', body);
|
|
99
|
+
}
|
|
100
|
+
// What it takes to LAUNCH the thing, rather than the flat "Launch it
|
|
101
|
+
// with create_computer" this used to end on. That sentence contradicted
|
|
102
|
+
// build_template's own description two tools down: a document declaring
|
|
103
|
+
// `spec.build` names a family the fleet does not advertise, so following
|
|
104
|
+
// this line led straight into a refusal the server already knew about
|
|
105
|
+
// (adversarial review, OPL-3835). Publishing and being launchable are
|
|
106
|
+
// different questions and this says so, without claiming to know which
|
|
107
|
+
// of the two this document is — the store answers the first, and only
|
|
108
|
+
// the document says whether it declares build steps.
|
|
109
|
+
return said(`Published ${body.ref}. A published template is named by its ref and by nothing else, so its short name still means one of ours. ` +
|
|
110
|
+
`WHETHER IT LAUNCHES depends on the document: pass the ref to ${launcher} as ` +
|
|
111
|
+
'`template` if it layers onto a family the fleet ships, but one declaring `spec.build` steps names a family that has to be built first — that is build_template — and the fleet does not yet advertise a family it built rather than shipped, so a create naming such a ref is still refused.', body);
|
|
112
|
+
}));
|
|
113
|
+
server.registerTool('get_template', {
|
|
114
|
+
title: 'Read a template document',
|
|
115
|
+
description: 'One template as the document it was written as — the lineage, the build steps and the digest, which list_templates drops. Works for your own namespace and for `system`, so you can read what you are layering onto before writing a document of your own. Without `version` this is the newest, which is also what a create naming the unpinned `namespace/name` resolves to.',
|
|
116
|
+
inputSchema: { ...namespaceArg, version: versionArg },
|
|
117
|
+
annotations: { readOnlyHint: true },
|
|
118
|
+
}, ({ namespace, name, version }, extra) => guarded(async () => json(await session.api.with(extra.signal).json('GET', P.templateRef(namespace, name), {
|
|
119
|
+
query: P.templateVersionQuery(version),
|
|
120
|
+
}))));
|
|
121
|
+
server.registerTool('retire_template', {
|
|
122
|
+
title: 'Retire a template you published',
|
|
123
|
+
description: 'Stop a template resolving, and give its row back against your ceiling. WITHOUT `version` THIS RETIRES EVERY VERSION OF THE NAME — that is what retiring a template means here, and it is deliberately not get_template\'s "the newest". Pass `version` to take exactly one. THIS CANNOT BE UNDONE: a retired ref is refused for ever, identical bytes included, so the version you retire can never be published again — publish the next version instead. Computers are NOT affected: a computer is built from the image the ref resolved to and holds no reference to the document, so anything already running, stopped or suspended keeps working. What a retire breaks is resolution — a NEW create naming the ref is refused. Say what it costs before you call it.',
|
|
124
|
+
inputSchema: {
|
|
125
|
+
...namespaceArg,
|
|
126
|
+
version: versionArg,
|
|
127
|
+
// The same gate delete_computer, restore_snapshot and delete_snapshot
|
|
128
|
+
// take. This is strictly LESS recoverable than any of them — a deleted
|
|
129
|
+
// snapshot's name can be used again, a retired ref never can — and it
|
|
130
|
+
// was the only unrecoverable tool here without one. `destructiveHint`
|
|
131
|
+
// delegates the question to the host application; this asks it here.
|
|
132
|
+
confirm: z
|
|
133
|
+
.literal(true)
|
|
134
|
+
.describe('Must be true. Retiring cannot be undone, and without `version` it takes every version of the name.'),
|
|
135
|
+
},
|
|
136
|
+
annotations: { destructiveHint: true, idempotentHint: false },
|
|
137
|
+
}, ({ namespace, name, version }, extra) => guarded(async () => {
|
|
138
|
+
const body = await session.api
|
|
139
|
+
.with(extra.signal)
|
|
140
|
+
.json('DELETE', P.templateRef(namespace, name), {
|
|
141
|
+
query: P.templateVersionQuery(version),
|
|
142
|
+
});
|
|
143
|
+
// The one unreadable response in this module that must not be smoothed
|
|
144
|
+
// over. `Array.isArray(body.retired) ? … : []` turned a body this
|
|
145
|
+
// server could not read into "Retired 0 version(s)" — a confident report
|
|
146
|
+
// that nothing happened, about an irreversible DELETE the platform
|
|
147
|
+
// answered 2xx to and which may well have just taken every version of
|
|
148
|
+
// the name (adversarial review, OPL-3835).
|
|
149
|
+
if (!Array.isArray(body.retired) || !Array.isArray(body.versions)) {
|
|
150
|
+
return refused('The retire answered without the `retired` and `versions` lists, so this server cannot say what went. THE RETIRE MAY HAVE HAPPENED, and it cannot be undone — read the name with get_template before concluding anything, and do not repeat the call on the assumption that nothing was taken.', body);
|
|
151
|
+
}
|
|
152
|
+
const gone = body.retired;
|
|
153
|
+
const left = body.versions;
|
|
154
|
+
const templates = body.templates;
|
|
155
|
+
const claimed = body.refs_claimed;
|
|
156
|
+
// The lists above are the sentence that must not be wrong about an
|
|
157
|
+
// irreversible DELETE. The account totals are detail: interpolating
|
|
158
|
+
// them untyped turned a 2xx that had the lists but omitted the
|
|
159
|
+
// counters into "undefined template(s)" / "undefined ref(s)" in the
|
|
160
|
+
// prose a model reads first (adversarial review, OPL-4314). Omit the
|
|
161
|
+
// clause rather than invent a number; the JSON is still attached.
|
|
162
|
+
const totals = typeof templates === 'number' &&
|
|
163
|
+
Number.isFinite(templates) &&
|
|
164
|
+
typeof claimed === 'number' &&
|
|
165
|
+
Number.isFinite(claimed)
|
|
166
|
+
? ` The account now holds ${templates} template(s), and has claimed ${claimed} ref(s) — that second number does not go down, because a retired ref still counts.`
|
|
167
|
+
: '';
|
|
168
|
+
return said(`Retired ${gone.length} version(s): ${gone.join(', ')}. ` +
|
|
169
|
+
(left.length
|
|
170
|
+
? `${left.join(', ')} ${left.length === 1 ? 'is' : 'are'} still published under this name.`
|
|
171
|
+
: 'Nothing is published under this name any more.') +
|
|
172
|
+
totals, body);
|
|
173
|
+
}));
|
|
174
|
+
server.registerTool('build_template', {
|
|
175
|
+
title: 'Compile a template document into an image',
|
|
176
|
+
description: 'Compile a document that declares `spec.build` steps into a golden image. Returns IMMEDIATELY with a job — a build takes minutes, an agent image roughly fifteen — and watch_build is how you follow it. THE NAMESPACE AND THE FAMILY BOTH HAVE TO BE YOURS: `spec.family` is what the image is called on a hypervisor, in a directory shared with every computer on that machine, so a build may only write into `golden-<your account id>` or that and a `-` and a name of your choosing. A refusal saying a host is busy is not a problem with your document — one build runs per hypervisor — and is worth retrying. What you build is NOT launchable yet: the fleet does not advertise a family it built rather than shipped, so a create naming such a ref is still refused.',
|
|
177
|
+
inputSchema: {
|
|
178
|
+
document: z
|
|
179
|
+
.string()
|
|
180
|
+
.describe('The document itself, as JSON or YAML — the file contents, not a wrapper.'),
|
|
181
|
+
no_reuse: z
|
|
182
|
+
.boolean()
|
|
183
|
+
.optional()
|
|
184
|
+
.describe("Build again even when an image already carries this document's build digest. Identical documents normally share an image, which is what makes a repeated build cheap — so leave this off unless you specifically want the work done twice."),
|
|
185
|
+
},
|
|
186
|
+
annotations: { openWorldHint: true },
|
|
187
|
+
}, ({ document, no_reuse }, extra) => guarded(async () => {
|
|
188
|
+
const body = await session.api
|
|
189
|
+
.with(extra.signal)
|
|
190
|
+
.json('POST', P.BUILDS, {
|
|
191
|
+
raw: P.templateDocument(document),
|
|
192
|
+
query: P.buildQuery(no_reuse),
|
|
193
|
+
});
|
|
194
|
+
// The id, checked: it is the only handle on a job that outlives this
|
|
195
|
+
// request, and `Build undefined started` sends a model to watch_build
|
|
196
|
+
// with a build_id it cannot have (adversarial review, OPL-3835).
|
|
197
|
+
if (typeof body.id !== 'string' || !body.id.trim()) {
|
|
198
|
+
return refused('POST /builds answered without an `id`, so there is no handle to follow this build with. THE BUILD MAY HAVE STARTED — call list_builds to find it rather than building again, since a build is minutes of work on a hypervisor that runs one at a time.', body);
|
|
199
|
+
}
|
|
200
|
+
// The ref is named only when the platform sent one. Unchecked, a 2xx
|
|
201
|
+
// without it read `Build bld-1 started for undefined` — the same
|
|
202
|
+
// sentence-level failure the `id` guard above was added for
|
|
203
|
+
// (OPL-3835), and the one publish_template already guards its own ref
|
|
204
|
+
// against. The build handle is the checked `id` either way, so a
|
|
205
|
+
// missing ref costs nothing but the clause that names the document.
|
|
206
|
+
const ref = typeof body.ref === 'string' && body.ref.trim() ? body.ref : undefined;
|
|
207
|
+
return said(`Build ${body.id} started${ref ? ` for ${ref}` : ''}. It is not finished — call watch_build with that id, or get_build to check once.`, body);
|
|
208
|
+
}));
|
|
209
|
+
server.registerTool('list_builds', {
|
|
210
|
+
title: 'List builds',
|
|
211
|
+
description: 'Every build this account has started that the fleet still holds a record of, newest first. A build lives on the hypervisor that ran it, so this asks all of them — and WITHOUT allow_partial, one that cannot be reached makes the platform refuse rather than answer short, so an empty or small list is the truth rather than an outage. Pass allow_partial and that stops being so: you get the short answer, opening with an INCOMPLETE line, and nothing else in the result says how much is missing.',
|
|
212
|
+
inputSchema: {
|
|
213
|
+
allow_partial: z
|
|
214
|
+
.boolean()
|
|
215
|
+
.optional()
|
|
216
|
+
.describe('Accept a short list when a hypervisor cannot be reached, instead of the 503 the platform answers by default. Nothing in the rows will say the answer was partial — a short build list has no marker in it at all, so the INCOMPLETE line is the whole of the evidence. Read it before concluding anything about what this account has built.'),
|
|
217
|
+
},
|
|
218
|
+
annotations: { readOnlyHint: true },
|
|
219
|
+
}, ({ allow_partial }, extra) => guarded(async () => {
|
|
220
|
+
// `listing`, not `json` (OPL-3840). This route fans out, and like every
|
|
221
|
+
// other fan-out on the v1 surface it FAILS CLOSED: `forward` in
|
|
222
|
+
// lib/surface turns a response carrying X-GC-Incomplete into a 503. So
|
|
223
|
+
// without the flag a short list still cannot arrive — but WITH it one
|
|
224
|
+
// can, and then the header is the only news there is.
|
|
225
|
+
//
|
|
226
|
+
// The platform read `allow_partial` here from the day this route
|
|
227
|
+
// started fanning out and did not DOCUMENT it until OPL-3840, which is
|
|
228
|
+
// why this tool sent nothing and why the comment that stood here said a
|
|
229
|
+
// short list could not arrive at all. What that cost was a build
|
|
230
|
+
// listing being strictly less available than a computer listing.
|
|
231
|
+
const { items, incomplete } = await session.api
|
|
232
|
+
.with(extra.signal)
|
|
233
|
+
.listing(P.BUILDS, {
|
|
234
|
+
query: { allow_partial: allow_partial ? 1 : undefined },
|
|
235
|
+
});
|
|
236
|
+
if (!Array.isArray(items)) {
|
|
237
|
+
const got = items === undefined ? 'no body at all' : items === null ? 'null' : typeof items;
|
|
238
|
+
return refused(`GET /builds answered with ${got}, not a list of builds. This is not an empty list — do not conclude anything about what exists from it.`, items);
|
|
239
|
+
}
|
|
240
|
+
// Each ROW checked too, which list_computers and list_snapshots do and
|
|
241
|
+
// this one did not (adversarial review, OPL-3835). `Array.isArray`
|
|
242
|
+
// alone passed `[null]` and `["bad projection"]` through as an
|
|
243
|
+
// inventory, and a model reading a build row that is a string gets
|
|
244
|
+
// `undefined` for every field it asks about with nothing saying the row
|
|
245
|
+
// was never a build.
|
|
246
|
+
const malformed = items.filter((item) => item === null || typeof item !== 'object' || Array.isArray(item)).length;
|
|
247
|
+
const builds = items.filter((item) => item !== null && typeof item === 'object' && !Array.isArray(item));
|
|
248
|
+
const warning = incompleteWarning('builds', incomplete) +
|
|
249
|
+
(malformed
|
|
250
|
+
? `WARNING: ignored ${malformed} malformed build entr${malformed === 1 ? 'y' : 'ies'} from the platform.\n\n`
|
|
251
|
+
: '');
|
|
252
|
+
if (!builds.length && malformed) {
|
|
253
|
+
return refused(`${warning}No valid builds remained. This is not an empty build list — do not conclude anything about what exists from it.`, items);
|
|
254
|
+
}
|
|
255
|
+
// `json`, with nothing to say, ONLY when there is nothing to say. The
|
|
256
|
+
// fast path used to be `if (!malformed) return json(builds)`, which
|
|
257
|
+
// returns bare data — so a warning added above it would have been
|
|
258
|
+
// dropped on exactly the answers that most needed it.
|
|
259
|
+
if (!warning)
|
|
260
|
+
return json(builds);
|
|
261
|
+
// An empty answer from a fleet that could not all be asked is not an
|
|
262
|
+
// empty account, and the two are told apart here rather than left to
|
|
263
|
+
// the model: with no rows and no stub rows there is nothing at all in
|
|
264
|
+
// the payload to suggest a hypervisor is away.
|
|
265
|
+
if (!builds.length) {
|
|
266
|
+
return said(`${warning}No builds came back from the part of the fleet that answered. This is NOT "no builds" — retry in a moment for a complete answer.`);
|
|
267
|
+
}
|
|
268
|
+
return said(`${warning}${builds.length} build(s).`, builds);
|
|
269
|
+
}));
|
|
270
|
+
server.registerTool('get_build', {
|
|
271
|
+
title: 'Get a build',
|
|
272
|
+
description: 'What became of one build, which template it was for, and which step it is on. Reads once and returns; watch_build is what follows a running one. It stays readable after the build has finished, so this is also how you find out which step failed on a build nobody was watching.',
|
|
273
|
+
inputSchema: { build_id: z.string().describe('The id build_template returned.') },
|
|
274
|
+
annotations: { readOnlyHint: true },
|
|
275
|
+
}, ({ build_id }, extra) => guarded(async () => {
|
|
276
|
+
// BOTH routes, because neither answer contains the other. The two
|
|
277
|
+
// projectors in the platform's lib/projection overlap only on `id`,
|
|
278
|
+
// `status` and `error`: publicTemplateBuild carries `ref` and both
|
|
279
|
+
// timestamps, publicBuildProgress carries the phase and the steps. This
|
|
280
|
+
// tool was pinned as "progress is a superset", which was simply untrue —
|
|
281
|
+
// read that way it could not tell a model WHICH TEMPLATE a build was for
|
|
282
|
+
// (/code-review, OPL-3835).
|
|
283
|
+
//
|
|
284
|
+
// One tool rather than two, still. An MCP client pays for every tool in
|
|
285
|
+
// the model's context before any is called, and "get_build" and
|
|
286
|
+
// "get_build_progress" differing by a word is how a model picks the
|
|
287
|
+
// wrong one. Two requests inside one call is the cheaper trade.
|
|
288
|
+
const api = session.api.with(extra.signal);
|
|
289
|
+
// allSettled, not all: the two legs are INDEPENDENT fleet walks — the job
|
|
290
|
+
// read forwards through hvAny, the progress read is a local handler that
|
|
291
|
+
// does its own — so one can fail while the other succeeds, and
|
|
292
|
+
// Promise.all threw the good half away. Progress is the half a model
|
|
293
|
+
// calls this for after a build nobody watched (the status, the phase, the
|
|
294
|
+
// failed step), so it is required and the job read is best effort: a
|
|
295
|
+
// fleet hiccup costs `ref` and the timestamps rather than the whole
|
|
296
|
+
// answer (/code-review, OPL-3835).
|
|
297
|
+
const [jobRead, progressRead] = await Promise.allSettled([
|
|
298
|
+
api.json('GET', P.build(build_id)),
|
|
299
|
+
api.json('GET', P.buildAction(build_id, 'progress')),
|
|
300
|
+
]);
|
|
301
|
+
if (progressRead.status === 'rejected')
|
|
302
|
+
throw progressRead.reason;
|
|
303
|
+
const progress = progressRead.value;
|
|
304
|
+
// Best effort means AVAILABILITY, not everything (adversarial review,
|
|
305
|
+
// OPL-3835). `status === 'fulfilled' ? … : undefined` swallowed the
|
|
306
|
+
// rejection whatever it was, so a 401, a 403, a 404 or the caller's own
|
|
307
|
+
// cancellation came back as a successful partial answer with a note
|
|
308
|
+
// about the fleet — the shape a caller reading `isError` to decide
|
|
309
|
+
// whether it may act on the result cannot see through. Only the
|
|
310
|
+
// statuses that clear on their own are worth losing `ref` and the
|
|
311
|
+
// timestamps for; the rest are decisions, and a decision suppressed is a
|
|
312
|
+
// decision the model never learns about.
|
|
313
|
+
//
|
|
314
|
+
// `isTransientForPoll` rather than a list here, because it is the same
|
|
315
|
+
// question the wait loops in computers.ts ask and this is the same kind
|
|
316
|
+
// of call: a read, where replaying costs nothing, so a 52x during an
|
|
317
|
+
// outage counts as a hiccup too. It says no to CancelledError, which is
|
|
318
|
+
// the one that must never be suppressed — nobody is waiting for this
|
|
319
|
+
// answer.
|
|
320
|
+
if (jobRead.status === 'rejected' && !isTransientForPoll(jobRead.reason)) {
|
|
321
|
+
throw jobRead.reason;
|
|
322
|
+
}
|
|
323
|
+
let job = jobRead.status === 'fulfilled' ? jobRead.value : undefined;
|
|
324
|
+
// The two reads land at different instants, so a build that finishes
|
|
325
|
+
// between them would otherwise merge into a record contradicting itself.
|
|
326
|
+
// Progress owns `status` and `done` because that is what a model
|
|
327
|
+
// branches on.
|
|
328
|
+
//
|
|
329
|
+
// BOTH ORDERS, and the first fix only had one of them (adversarial
|
|
330
|
+
// review, OPL-3835). Job-then-finish-then-progress gives `running`
|
|
331
|
+
// beside a populated `finished_at`, which the delete below handles.
|
|
332
|
+
// Progress-then-finish-then-job gives the mirror image — `succeeded`,
|
|
333
|
+
// `done: true`, and no finish time at all, a build that completed
|
|
334
|
+
// without ever ending — and that one cannot be fixed by dropping a
|
|
335
|
+
// field, because the field that is missing is the true one. So the job
|
|
336
|
+
// record is read again: one extra request, only inside the race window,
|
|
337
|
+
// and by the time it is made the record it asks for has settled.
|
|
338
|
+
if (job && progress.done === true && job.finished_at === undefined) {
|
|
339
|
+
try {
|
|
340
|
+
job = await api.json('GET', P.build(build_id));
|
|
341
|
+
}
|
|
342
|
+
catch (err) {
|
|
343
|
+
// The first read already succeeded, so a second failure costs the
|
|
344
|
+
// reconciliation rather than the call. Except a cancellation, which
|
|
345
|
+
// means there is nobody left to answer.
|
|
346
|
+
if (err instanceof CancelledError)
|
|
347
|
+
throw err;
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
const merged = { ...job, ...progress };
|
|
351
|
+
if (job && progress.done !== true)
|
|
352
|
+
delete merged.finished_at;
|
|
353
|
+
if (!job) {
|
|
354
|
+
merged.partial = 'the build record could not be read; ref and timestamps are missing';
|
|
355
|
+
}
|
|
356
|
+
return json(merged);
|
|
357
|
+
}));
|
|
358
|
+
server.registerTool('watch_build', {
|
|
359
|
+
title: 'Watch a build until it finishes',
|
|
360
|
+
description: "Follow a build to its end and report what happened. Streams the platform's own progress — each event is sent only when something actually moved — and logs each one as it arrives, so a long build is visibly alive rather than indistinguishable from a hang. A build that FAILED is a normal answer here, not an error: read `status` and the failed step. Attaching to a build that has already finished is fine and returns immediately.",
|
|
361
|
+
inputSchema: { build_id: z.string().describe('The id build_template returned.') },
|
|
362
|
+
annotations: { readOnlyHint: true, openWorldHint: true },
|
|
363
|
+
}, ({ build_id }, extra) => guarded(async () => {
|
|
364
|
+
let last;
|
|
365
|
+
// The token the CLIENT sends when it wants progress. Without one there
|
|
366
|
+
// is nothing to address a progress notification to, and this falls back
|
|
367
|
+
// to logging alone.
|
|
368
|
+
const progressToken = extra._meta?.progressToken;
|
|
369
|
+
let sent = 0;
|
|
370
|
+
// Whether a well-formed `done` actually arrived, as against whether any
|
|
371
|
+
// event did (adversarial review, OPL-3835). Without it a stream that
|
|
372
|
+
// reached EOF after a `progress` — a proxy cutting it, a host going away
|
|
373
|
+
// — fell out of the loop with `last` set and was reported through
|
|
374
|
+
// `said(...)` as a finished build whose status happened to be `running`.
|
|
375
|
+
// A tool whose whole promise is "watch until it finishes" must not
|
|
376
|
+
// answer that way when it did not.
|
|
377
|
+
let sawDone = false;
|
|
378
|
+
for await (const ev of session.api.sse('GET', P.buildAction(build_id, 'events'), {
|
|
379
|
+
signal: extra.signal,
|
|
380
|
+
})) {
|
|
381
|
+
if (ev.event === 'error') {
|
|
382
|
+
// The STREAM failed, not the build. Said as such, because a model
|
|
383
|
+
// told "the build failed" would go and rewrite a document that is
|
|
384
|
+
// fine — and the build is very likely still running.
|
|
385
|
+
return refused(`The event stream for ${build_id} ended. This says nothing about the build itself, which is probably still running — call get_build to find out.`, ev.data);
|
|
386
|
+
}
|
|
387
|
+
if (ev.event !== 'progress' && ev.event !== 'done')
|
|
388
|
+
continue;
|
|
389
|
+
if (!isRecord(ev.data))
|
|
390
|
+
continue;
|
|
391
|
+
// An event about ANOTHER build is not this build's news. The stream is
|
|
392
|
+
// per-build so this should never arrive, but `id` is one of the three
|
|
393
|
+
// fields both of the platform's build projectors carry, so checking it
|
|
394
|
+
// is free — and a misrouted frame reported as this build's outcome is
|
|
395
|
+
// the kind of wrong answer nobody could spot afterwards.
|
|
396
|
+
if (typeof ev.data.id === 'string' && ev.data.id !== build_id)
|
|
397
|
+
continue;
|
|
398
|
+
if (ev.event === 'done') {
|
|
399
|
+
// A `done` is terminal only if it SAYS SO (adversarial review,
|
|
400
|
+
// OPL-3835). `isRecord` alone called `event: done\ndata: {}`
|
|
401
|
+
// well-formed, set the flag, and answered `Build bld-1 undefined.`;
|
|
402
|
+
// it accepted `{status: "running", done: false}` as a completed
|
|
403
|
+
// watch too, which is the very misreport `sawDone` was added to
|
|
404
|
+
// prevent, reached from the other side.
|
|
405
|
+
//
|
|
406
|
+
// `done: true` and a status that is a non-empty string, rather than
|
|
407
|
+
// a list of the statuses a build may end in. The platform owns that
|
|
408
|
+
// vocabulary — `succeeded` and `failed` are the two this server has
|
|
409
|
+
// seen and a cancelled build would be a third — so an enum here
|
|
410
|
+
// would refuse a real outcome the first time one was added, while
|
|
411
|
+
// these two facts are exactly what the sentence at the end reads.
|
|
412
|
+
if (ev.data.done !== true || typeof ev.data.status !== 'string' || !ev.data.status) {
|
|
413
|
+
continue;
|
|
414
|
+
}
|
|
415
|
+
sawDone = true;
|
|
416
|
+
}
|
|
417
|
+
last = ev.data;
|
|
418
|
+
const line = `${ev.data.phase ?? '?'} ${ev.data.step ?? 0}/${ev.data.of ?? 0} ${ev.data.note ?? ''}`.trim();
|
|
419
|
+
// A PROGRESS notification, not only a logging one, because it is the
|
|
420
|
+
// only frame that CAN hold a long request open: `_onprogress` in the
|
|
421
|
+
// SDK's shared/protocol.js resets a pending request's timer, and
|
|
422
|
+
// `notifications/message` — what sendLoggingMessage emits — never
|
|
423
|
+
// touches it.
|
|
424
|
+
//
|
|
425
|
+
// IT IS NOT SUFFICIENT ON ITS OWN, and the first version of this
|
|
426
|
+
// comment claimed it was (/code-review, OPL-3835). protocol.js reads
|
|
427
|
+
// `options?.resetTimeoutOnProgress ?? false`, so the reset happens only
|
|
428
|
+
// for a client that asked for it when it made the call. One that mints
|
|
429
|
+
// a progressToken and leaves that option alone is still cancelled at
|
|
430
|
+
// the 60s default on a build that takes fifteen minutes. What this does
|
|
431
|
+
// is make the keepalive AVAILABLE — without it no client could hold the
|
|
432
|
+
// request open at all; with it, one that opts in can. The rest is the
|
|
433
|
+
// client's to set, and get_build is the answer for a client that cannot.
|
|
434
|
+
if (progressToken !== undefined) {
|
|
435
|
+
sent += 1;
|
|
436
|
+
await extra
|
|
437
|
+
.sendNotification({
|
|
438
|
+
method: 'notifications/progress',
|
|
439
|
+
params: {
|
|
440
|
+
progressToken,
|
|
441
|
+
// `of` is the step count, which is 0 until the build reaches
|
|
442
|
+
// its first step — sent only once it means something, since a
|
|
443
|
+
// total of 0 renders as a finished bar.
|
|
444
|
+
// The event COUNT, not the step index. The SDK's ProgressSchema
|
|
445
|
+
// asks that this increase every time, and `step` is 0 for every
|
|
446
|
+
// pre-step phase — planning, staging, the multi-gigabyte base
|
|
447
|
+
// copy — and stays 0 for the whole life of a document with no
|
|
448
|
+
// build steps, so successive frames repeated `progress: 0`.
|
|
449
|
+
progress: sent,
|
|
450
|
+
message: line,
|
|
451
|
+
},
|
|
452
|
+
})
|
|
453
|
+
.catch(() => { });
|
|
454
|
+
}
|
|
455
|
+
// Kept as well: this is what a person watching a terminal sees, and it
|
|
456
|
+
// is the only channel when the client asked for no progress.
|
|
457
|
+
await server.server.sendLoggingMessage({ level: 'info', data: line }).catch(() => { });
|
|
458
|
+
if (ev.event === 'done')
|
|
459
|
+
break;
|
|
460
|
+
}
|
|
461
|
+
// `|| !last` as well, which is unreachable — a `done` sets both in the
|
|
462
|
+
// same breath — and is what lets the compiler narrow `last` below.
|
|
463
|
+
if (!sawDone || !last) {
|
|
464
|
+
// Both halves of the same failure, and both are refusals: the stream
|
|
465
|
+
// is the platform's contract that `done` is the last event, so one
|
|
466
|
+
// that ends without a well-formed one has been CUT rather than
|
|
467
|
+
// completed. Saying so points the model at the poll that can still
|
|
468
|
+
// answer, instead of letting it act on a status that was true
|
|
469
|
+
// whenever the connection died.
|
|
470
|
+
return refused(last
|
|
471
|
+
? `The event stream for ${build_id} ended before the build did. This is the stream failing, not the build — it is probably still running. Call get_build for where it has got to.`
|
|
472
|
+
: `The event stream for ${build_id} ended without sending anything. Call get_build for the outcome.`, last);
|
|
473
|
+
}
|
|
474
|
+
// Not `refused` for a failed build. It is an outcome with a remedy —
|
|
475
|
+
// the failed step names what to fix — and marking it isError would tell
|
|
476
|
+
// the model its request failed rather than that its document did.
|
|
477
|
+
const failed = Array.isArray(last.steps)
|
|
478
|
+
? last.steps.find((s) => s?.status === 'failed')
|
|
479
|
+
: undefined;
|
|
480
|
+
return said(last.status === 'succeeded'
|
|
481
|
+
? `Build ${build_id} succeeded. The image exists, but the fleet does not yet advertise a family it built rather than shipped, so a create naming this ref is still refused.`
|
|
482
|
+
: `Build ${build_id} ${last.status}.` +
|
|
483
|
+
(failed
|
|
484
|
+
? ` Step ${failed.n} (${failed.kind}: ${failed.label}) is the one that failed.`
|
|
485
|
+
: '') +
|
|
486
|
+
(last.error ? ` ${last.error}` : ''), last);
|
|
487
|
+
}));
|
|
488
|
+
};
|
|
489
|
+
function isRecord(v) {
|
|
490
|
+
return typeof v === 'object' && v !== null && !Array.isArray(v);
|
|
491
|
+
}
|
|
492
|
+
//# sourceMappingURL=templates.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"templates.js","sourceRoot":"","sources":["../../src/tools/templates.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
2
|
+
import type { Session } from '../session.js';
|
|
3
|
+
/** Knobs that change which tools exist, rather than what they do. */
|
|
4
|
+
export type ToolOptions = {
|
|
5
|
+
/**
|
|
6
|
+
* Whether this server may make and destroy computers.
|
|
7
|
+
*
|
|
8
|
+
* A knob rather than a constant because creation from inside an agent loop is
|
|
9
|
+
* where a runaway turns into an invoice. The tools are registered by default —
|
|
10
|
+
* a one-line install that cannot produce a desktop is not much of a demo — but
|
|
11
|
+
* an operator standing this up for somebody else can turn them off, and then
|
|
12
|
+
* they are absent from the tool list rather than present and refusing. A tool
|
|
13
|
+
* a model can see is a tool it will try.
|
|
14
|
+
*/
|
|
15
|
+
lifecycle: boolean;
|
|
16
|
+
};
|
|
17
|
+
export type Registrar = (server: McpServer, session: Session, opts: ToolOptions) => void;
|
|
18
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/tools/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACzE,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAE7C,qEAAqE;AACrE,MAAM,MAAM,WAAW,GAAG;IACxB;;;;;;;;;OASG;IACH,SAAS,EAAE,OAAO,CAAC;CACpB,CAAC;AAEF,MAAM,MAAM,SAAS,GAAG,CAAC,MAAM,EAAE,SAAS,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,WAAW,KAAK,IAAI,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/tools/types.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"webhooks.d.ts","sourceRoot":"","sources":["../../src/tools/webhooks.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAyK5C,eAAO,MAAM,gBAAgB,EAAE,SA6M9B,CAAC"}
|