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.
Files changed (83) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +544 -0
  3. package/dist/api.d.ts +186 -0
  4. package/dist/api.d.ts.map +1 -0
  5. package/dist/api.js +932 -0
  6. package/dist/api.js.map +1 -0
  7. package/dist/cli.d.ts +55 -0
  8. package/dist/cli.d.ts.map +1 -0
  9. package/dist/cli.js +292 -0
  10. package/dist/cli.js.map +1 -0
  11. package/dist/errors.d.ts +560 -0
  12. package/dist/errors.d.ts.map +1 -0
  13. package/dist/errors.js +873 -0
  14. package/dist/errors.js.map +1 -0
  15. package/dist/events.d.ts +406 -0
  16. package/dist/events.d.ts.map +1 -0
  17. package/dist/events.js +1679 -0
  18. package/dist/events.js.map +1 -0
  19. package/dist/format.d.ts +125 -0
  20. package/dist/format.d.ts.map +1 -0
  21. package/dist/format.js +180 -0
  22. package/dist/format.js.map +1 -0
  23. package/dist/http.d.ts +46 -0
  24. package/dist/http.d.ts.map +1 -0
  25. package/dist/http.js +792 -0
  26. package/dist/http.js.map +1 -0
  27. package/dist/index.d.ts +13 -0
  28. package/dist/index.d.ts.map +1 -0
  29. package/dist/index.js +12 -0
  30. package/dist/index.js.map +1 -0
  31. package/dist/paths.d.ts +394 -0
  32. package/dist/paths.d.ts.map +1 -0
  33. package/dist/paths.js +677 -0
  34. package/dist/paths.js.map +1 -0
  35. package/dist/server.d.ts +18 -0
  36. package/dist/server.d.ts.map +1 -0
  37. package/dist/server.js +97 -0
  38. package/dist/server.js.map +1 -0
  39. package/dist/session.d.ts +78 -0
  40. package/dist/session.d.ts.map +1 -0
  41. package/dist/session.js +166 -0
  42. package/dist/session.js.map +1 -0
  43. package/dist/stdio.d.ts +11 -0
  44. package/dist/stdio.d.ts.map +1 -0
  45. package/dist/stdio.js +43 -0
  46. package/dist/stdio.js.map +1 -0
  47. package/dist/tools/agent.d.ts +16 -0
  48. package/dist/tools/agent.d.ts.map +1 -0
  49. package/dist/tools/agent.js +147 -0
  50. package/dist/tools/agent.js.map +1 -0
  51. package/dist/tools/computers.d.ts +3 -0
  52. package/dist/tools/computers.d.ts.map +1 -0
  53. package/dist/tools/computers.js +1037 -0
  54. package/dist/tools/computers.js.map +1 -0
  55. package/dist/tools/events.d.ts +3 -0
  56. package/dist/tools/events.d.ts.map +1 -0
  57. package/dist/tools/events.js +1077 -0
  58. package/dist/tools/events.js.map +1 -0
  59. package/dist/tools/guest.d.ts +3 -0
  60. package/dist/tools/guest.d.ts.map +1 -0
  61. package/dist/tools/guest.js +761 -0
  62. package/dist/tools/guest.js.map +1 -0
  63. package/dist/tools/input.d.ts +3 -0
  64. package/dist/tools/input.d.ts.map +1 -0
  65. package/dist/tools/input.js +240 -0
  66. package/dist/tools/input.js.map +1 -0
  67. package/dist/tools/snapshots.d.ts +3 -0
  68. package/dist/tools/snapshots.d.ts.map +1 -0
  69. package/dist/tools/snapshots.js +333 -0
  70. package/dist/tools/snapshots.js.map +1 -0
  71. package/dist/tools/templates.d.ts +3 -0
  72. package/dist/tools/templates.d.ts.map +1 -0
  73. package/dist/tools/templates.js +492 -0
  74. package/dist/tools/templates.js.map +1 -0
  75. package/dist/tools/types.d.ts +18 -0
  76. package/dist/tools/types.d.ts.map +1 -0
  77. package/dist/tools/types.js +2 -0
  78. package/dist/tools/types.js.map +1 -0
  79. package/dist/tools/webhooks.d.ts +3 -0
  80. package/dist/tools/webhooks.d.ts.map +1 -0
  81. package/dist/tools/webhooks.js +260 -0
  82. package/dist/tools/webhooks.js.map +1 -0
  83. package/package.json +59 -0
package/dist/api.d.ts ADDED
@@ -0,0 +1,186 @@
1
+ export declare const DEFAULT_BASE_URL = "https://app.mandala.computer/api/v1";
2
+ /** Anthropic's own key, forwarded for the one route that runs a model. */
3
+ export declare const MODEL_KEY_HEADER = "X-Model-Key";
4
+ export type RequestOptions = {
5
+ query?: Record<string, string | number | boolean | undefined>;
6
+ body?: unknown;
7
+ /** Raw bytes as the request body, for the file upload. Mutually exclusive with `body`. */
8
+ raw?: Uint8Array;
9
+ /** Extra headers for this call only — currently just the model key. */
10
+ headers?: Record<string, string>;
11
+ signal?: AbortSignal;
12
+ };
13
+ export type Bytes = {
14
+ bytes: Uint8Array;
15
+ contentType: string;
16
+ /** From Content-Disposition, when the platform named the file. */
17
+ filename?: string;
18
+ /** True when the response was deliberately stopped at the caller's cap. */
19
+ truncated: boolean;
20
+ /**
21
+ * Exact size when the response declared one, or when it fitted in full.
22
+ *
23
+ * On a `206` this is the WHOLE file's length, off `Content-Range`, and not
24
+ * the length of the window that came back — which is the number a caller
25
+ * paging through a file needs and the only place it appears.
26
+ */
27
+ totalBytes?: number;
28
+ /**
29
+ * Which bytes of the file these are, when the platform served a window.
30
+ *
31
+ * Present only on a `206`, because that status is the only promise that the
32
+ * `Range` was honoured. A `200` may perfectly well be a response to a request
33
+ * that carried one — an unmeasurable file has no byte positions to name, so
34
+ * the platform ignores the header and sends the whole thing — and reporting
35
+ * the head of a file as the window somebody asked for is how a paging loop
36
+ * reads the same bytes forever.
37
+ *
38
+ * `total` is absent for a `Content-Range` whose total is `*`: the window is
39
+ * known and the file's length is not.
40
+ */
41
+ window?: {
42
+ start: number;
43
+ end: number;
44
+ total?: number;
45
+ };
46
+ /**
47
+ * True when the response said this file cannot be served in windows at all.
48
+ *
49
+ * `Accept-Ranges: none`, which the platform sets for a file whose length the
50
+ * guest could not measure — a `/proc` entry, say. Worth keeping apart from a
51
+ * merely absent window, because it is the difference between "ask again
52
+ * differently" and "there is no offset that will work on this file".
53
+ */
54
+ unrangeable: boolean;
55
+ };
56
+ /**
57
+ * The longest guest exec waits 300 seconds before it answers. Node's bundled
58
+ * fetch also gives response headers 300 seconds by default, so the client can
59
+ * lose that race while the command is still finishing in the guest. Keep the
60
+ * public exec limit and give the platform enough time to report its timeout.
61
+ *
62
+ * The body is a different clock. undici's default `bodyTimeout` is 300 seconds
63
+ * of silence *between chunks*, and `run_agent` SSE (or a long exec that has
64
+ * already sent headers) can sit quiet after that. Raising only the header
65
+ * allowance left those streams aborting on the default idle limit. Zero
66
+ * disables it: a quiet gap is not a dead connection, and the caller's
67
+ * AbortSignal is what ends a request nobody is waiting for.
68
+ */
69
+ export declare const PLATFORM_HEADERS_TIMEOUT_MS = 330000;
70
+ /** Disabled. A finite idle limit is what used to kill a quiet SSE stream. */
71
+ export declare const PLATFORM_BODY_TIMEOUT_MS = 0;
72
+ /**
73
+ * The fetch a platform request actually goes through, and why it is not simply
74
+ * `fetch`.
75
+ *
76
+ * The dispatcher above is an Agent from the `undici` PACKAGE, and Node's
77
+ * built-in fetch is a DIFFERENT COPY of undici — the one bundled with the
78
+ * runtime. Handing one's Agent to the other's fetch works only while the two
79
+ * agree on the internal handler interface, and they have stopped agreeing:
80
+ * Node 26 bundles undici 8.9, whose fetch passes a handler that undici 6's
81
+ * Agent rejects outright with `invalid onError method`. That surfaces here as
82
+ * `fetch failed`, which this class then wraps as "could not reach
83
+ * app.mandala.computer" — so on Node 26 every call this server makes reported
84
+ * the platform as down, before a packet was sent.
85
+ *
86
+ * NOT FIXABLE BY A VERSION BUMP, which is the thing worth writing down: npm's
87
+ * newest undici is 7.x and Node 26 bundles 8.x, so no dependency this package
88
+ * can declare matches what the runtime carries — and even if one did, matching
89
+ * Node 26 would mean mismatching Node 20, which `engines` still admits. Two
90
+ * undicis is the bug; using one of them for both halves is the fix.
91
+ *
92
+ * So the request goes through undici's OWN fetch, which understands its own
93
+ * Agent on every Node. The global is still preferred when something has
94
+ * replaced it: that is how the tests stand a stub in front of the platform, and
95
+ * an embedder that installs an instrumented fetch means it to be used.
96
+ */
97
+ export declare const platformFetch: () => typeof globalThis.fetch;
98
+ /** One server-sent event off the agent route. */
99
+ export type SSEEvent = {
100
+ event: string;
101
+ data: unknown;
102
+ };
103
+ /**
104
+ * The transport for one API key.
105
+ *
106
+ * One per MCP session rather than one per process, because the HTTP transport
107
+ * authenticates each caller with their own `com_…` key and two sessions must
108
+ * never share a client. See `src/session.ts`.
109
+ *
110
+ * The key lives in this object's closure and is never put on an error, a log
111
+ * line, or a tool result. That is not paranoia about our own code: an MCP tool
112
+ * result goes into a model's context and from there into transcripts, and an
113
+ * API key is every computer on the account, forever.
114
+ */
115
+ export declare class Api {
116
+ #private;
117
+ readonly baseUrl: string;
118
+ constructor(apiKey: string, baseUrl?: string, signal?: AbortSignal);
119
+ /**
120
+ * This same client, with every request bound to one tool call's cancellation.
121
+ *
122
+ * MCP hands a tool handler an `AbortSignal` that fires when the client gives
123
+ * up on the call, and a request nobody is waiting for is one this server
124
+ * should stop making — most of all in the tools that poll. A cancelled
125
+ * `wait_for_computer` would otherwise go on asking the platform about a
126
+ * computer for the rest of its `timeout_s`, which reaches fifteen minutes.
127
+ *
128
+ * Bound per call rather than per session, because a session serves many calls
129
+ * at once and one of them being abandoned says nothing about the others.
130
+ */
131
+ with(signal: AbortSignal | undefined): Api;
132
+ /**
133
+ * A JSON body, from a route that is supposed to have one.
134
+ *
135
+ * An empty answer here is a failure, not a value, and it has to be said so
136
+ * rather than cast away. `as T` was a lie the compiler could not catch: a 204
137
+ * on a route that should have answered handed every caller `undefined` typed
138
+ * as present, and what a caller does with that is either `text: undefined` —
139
+ * which is not a valid tool result, so the client rejects the whole call with
140
+ * a schema error naming nothing useful — or a TypeError reading a field off
141
+ * it. Both report the platform's silence as this server's own bug.
142
+ *
143
+ * Routes where an empty body IS the answer use `send`.
144
+ */
145
+ json<T = unknown>(method: string, path: string, opts?: RequestOptions): Promise<T>;
146
+ /**
147
+ * A request whose answer may legitimately be nothing.
148
+ *
149
+ * The DELETEs and the acknowledgements: /api/v1 answers some of them with a
150
+ * body worth repeating and some with a 204, and both are correct. Typed as
151
+ * possibly-absent so a caller has to decide what to say when it is.
152
+ */
153
+ send<T = unknown>(method: string, path: string, opts?: RequestOptions): Promise<T | undefined>;
154
+ /**
155
+ * A collection read that the platform may have had to answer short.
156
+ *
157
+ * `GET /computers` and `GET /snapshots` are fan-outs across the fleet, so a
158
+ * hypervisor nobody can reach makes the answer incomplete. /api/v1 fails
159
+ * closed about that — without `allow_partial` a short listing is a 503, not a
160
+ * short 200 — but a caller that opts in gets the list plus `X-GC-Incomplete`,
161
+ * and a header is only a warning if something reads it.
162
+ *
163
+ * It is the count of what the placement cache could account for, and it is
164
+ * legitimately `0`: a computer created during the outage was never cached
165
+ * against the host now holding it. So presence is the signal and the number is
166
+ * detail, which is why this returns `null` versus a number rather than a
167
+ * count that means nothing at zero.
168
+ */
169
+ listing<T>(path: string, opts?: RequestOptions): Promise<{
170
+ items: T | undefined;
171
+ incomplete: number | null;
172
+ }>;
173
+ /** For the two routes whose body is not JSON: the screenshot and the download. */
174
+ bytes(method: string, path: string, opts?: RequestOptions, maxBytes?: number | ((contentType: string) => number)): Promise<Bytes>;
175
+ /**
176
+ * The agent route, which answers with a stream of steps rather than a result.
177
+ *
178
+ * Yielded rather than collected so the caller can report progress while the
179
+ * run is going. A run is minutes of clicking; a tool that says nothing until
180
+ * it is over is one the person watching cannot tell from a hang.
181
+ */
182
+ sse(method: string, path: string, opts?: RequestOptions): AsyncGenerator<SSEEvent>;
183
+ }
184
+ /** The filename the platform put on a download, if it put one there. */
185
+ export declare function filenameFrom(disposition: string | null): string | undefined;
186
+ //# sourceMappingURL=api.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../src/api.ts"],"names":[],"mappings":"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"}