capix-mcp 2.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/CONTRIBUTING.md +168 -0
- package/LICENSE +201 -0
- package/README.md +309 -0
- package/bin/capix-mcp.js +2 -0
- package/dist/capixClient.d.ts +127 -0
- package/dist/capixClient.d.ts.map +1 -0
- package/dist/capixClient.js +77 -0
- package/dist/capixClient.js.map +1 -0
- package/dist/client.d.ts +119 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +308 -0
- package/dist/client.js.map +1 -0
- package/dist/index.d.ts +33 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +307 -0
- package/dist/index.js.map +1 -0
- package/dist/prompts.d.ts +28 -0
- package/dist/prompts.d.ts.map +1 -0
- package/dist/prompts.js +203 -0
- package/dist/prompts.js.map +1 -0
- package/dist/resources.d.ts +28 -0
- package/dist/resources.d.ts.map +1 -0
- package/dist/resources.js +101 -0
- package/dist/resources.js.map +1 -0
- package/dist/server.d.ts +61 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +223 -0
- package/dist/server.js.map +1 -0
- package/dist/tools.d.ts +32 -0
- package/dist/tools.d.ts.map +1 -0
- package/dist/tools.js +1101 -0
- package/dist/tools.js.map +1 -0
- package/dist/types.d.ts +194 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +43 -0
- package/dist/types.js.map +1 -0
- package/package.json +60 -0
package/dist/tools.js
ADDED
|
@@ -0,0 +1,1101 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Capix MCP Server — all 59 tool definitions.
|
|
3
|
+
*
|
|
4
|
+
* Each tool is declared with:
|
|
5
|
+
* - inputShape : a Zod raw shape (validated by the McpServer before dispatch)
|
|
6
|
+
* - outputShape : a Zod raw shape describing the structured result envelope
|
|
7
|
+
* - billable / requiresApproval : control-plane flags enforced by the server
|
|
8
|
+
*
|
|
9
|
+
* Handlers are deliberately thin: they translate Zod-validated arguments into
|
|
10
|
+
* canonical `/api/v1/*` client calls and return the upstream JSON object as
|
|
11
|
+
* structured content. The CapixApiError (problem+json) thrown by the client is
|
|
12
|
+
* caught by the server wrapper and surfaced as an MCP error result.
|
|
13
|
+
*
|
|
14
|
+
* Tools are grouped by scope (mirrors services/capix-mcp/tools/*.ts):
|
|
15
|
+
* discovery (9) · planning (6) · lifecycle (7) · networking (8) ·
|
|
16
|
+
* testing (6) · verification (6) · website (17)
|
|
17
|
+
*/
|
|
18
|
+
import { z } from "zod";
|
|
19
|
+
import { APPROVAL_ONLY, BILLABLE, READ_ONLY, } from "./types.js";
|
|
20
|
+
// ===========================================================================
|
|
21
|
+
// Reusable Zod fragments
|
|
22
|
+
// ===========================================================================
|
|
23
|
+
const iso8601 = z.string().datetime().or(z.string());
|
|
24
|
+
const moneyShape = z.object({
|
|
25
|
+
amount: z.string().describe("Integer minor units (e.g. lamports, micro-USDC, cents)."),
|
|
26
|
+
asset: z.enum(["SOL", "USDC", "USD-credit"]),
|
|
27
|
+
scale: z.number().int(),
|
|
28
|
+
}).describe("Integer minor/native money amount serialized as a JSON string.");
|
|
29
|
+
const deploymentIdShape = z.string().describe("Canonical deployment id (dep_…).");
|
|
30
|
+
const operationIdShape = z.string().describe("Canonical operation id (op_…).");
|
|
31
|
+
const quoteIdShape = z.string().describe("Canonical quote id (qt_…) from capix_compute_quote / capix_model_quote.");
|
|
32
|
+
const siteIdShape = z.string().describe("Capix website project id.");
|
|
33
|
+
const listResultShape = {
|
|
34
|
+
entries: z.array(z.record(z.unknown())).optional().describe("Paginated item array."),
|
|
35
|
+
nextCursor: z.string().optional().describe("Opaque cursor for the next page; absent when exhausted."),
|
|
36
|
+
fetchedAt: iso8601.optional().describe("ISO8601 fetch timestamp."),
|
|
37
|
+
};
|
|
38
|
+
const quoteResultShape = {
|
|
39
|
+
quoteId: quoteIdShape.optional(),
|
|
40
|
+
price: moneyShape.optional(),
|
|
41
|
+
providerCostBasis: moneyShape.optional(),
|
|
42
|
+
fees: moneyShape.optional(),
|
|
43
|
+
margin: moneyShape.optional(),
|
|
44
|
+
provider: z.string().optional(),
|
|
45
|
+
region: z.string().optional(),
|
|
46
|
+
expiresAt: iso8601.optional(),
|
|
47
|
+
feasible: z.boolean().optional(),
|
|
48
|
+
};
|
|
49
|
+
const deploymentResultShape = {
|
|
50
|
+
deploymentId: deploymentIdShape.optional(),
|
|
51
|
+
operationId: operationIdShape.optional(),
|
|
52
|
+
phase: z.string().optional().describe("DeploymentPhase after mutation."),
|
|
53
|
+
quoteId: quoteIdShape.optional(),
|
|
54
|
+
holdId: z.string().optional().describe("Ledger hold that funds the deployment."),
|
|
55
|
+
estimatedCost: moneyShape.optional(),
|
|
56
|
+
acceptedAt: iso8601.optional(),
|
|
57
|
+
};
|
|
58
|
+
const networkResourceShape = {
|
|
59
|
+
resourceId: z.string().optional(),
|
|
60
|
+
kind: z.string().optional().describe("vpc | endpoint | port_forward | private_connection | dedicated_ip."),
|
|
61
|
+
deploymentId: deploymentIdShape.optional(),
|
|
62
|
+
status: z.enum(["provisioning", "ready", "failed", "destroyed"]).optional(),
|
|
63
|
+
endpoint: z.string().optional(),
|
|
64
|
+
acceptedAt: iso8601.optional(),
|
|
65
|
+
};
|
|
66
|
+
const siteResultShape = {
|
|
67
|
+
siteId: siteIdShape.optional(),
|
|
68
|
+
deploymentId: z.string().optional(),
|
|
69
|
+
url: z.string().optional(),
|
|
70
|
+
status: z.enum(["queued", "building", "ready", "failed"]).optional(),
|
|
71
|
+
estimatedCost: moneyShape.optional(),
|
|
72
|
+
acceptedAt: iso8601.optional(),
|
|
73
|
+
};
|
|
74
|
+
// ===========================================================================
|
|
75
|
+
// defineTool — type-safe tool declaration helper
|
|
76
|
+
// ===========================================================================
|
|
77
|
+
/**
|
|
78
|
+
* Declare a Capix tool with a Zod raw input shape. The handler receives
|
|
79
|
+
* Zod-validated arguments (typed via inference) plus the Capix API client and
|
|
80
|
+
* call context; it returns the upstream JSON object as structured content.
|
|
81
|
+
*/
|
|
82
|
+
function defineTool(opts) {
|
|
83
|
+
return {
|
|
84
|
+
name: opts.name,
|
|
85
|
+
description: opts.description,
|
|
86
|
+
scope: opts.scope,
|
|
87
|
+
billable: opts.billable,
|
|
88
|
+
requiresApproval: opts.requiresApproval,
|
|
89
|
+
inputShape: opts.inputShape,
|
|
90
|
+
outputShape: opts.outputShape,
|
|
91
|
+
// Sound cast: the McpServer validates args against inputShape before
|
|
92
|
+
// invoking the handler, so the inferred arg shape is guaranteed at runtime.
|
|
93
|
+
handler: opts.handler,
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
/** Convenience: pull a string argument, throwing a typed error if missing. */
|
|
97
|
+
function asStr(value, field) {
|
|
98
|
+
if (typeof value !== "string" || value.length === 0) {
|
|
99
|
+
const err = new Error(`${field} is required`);
|
|
100
|
+
err.capixCode = "invalid_argument";
|
|
101
|
+
err.status = 400;
|
|
102
|
+
throw err;
|
|
103
|
+
}
|
|
104
|
+
return value;
|
|
105
|
+
}
|
|
106
|
+
/** Call the client, passing the approval token through for billable tools. */
|
|
107
|
+
async function callBillable(client, approvalToken, path, body) {
|
|
108
|
+
if (!approvalToken) {
|
|
109
|
+
const err = new Error("approvalToken is required for this billable tool (§5)");
|
|
110
|
+
err.capixCode = "approval_required";
|
|
111
|
+
err.status = 402;
|
|
112
|
+
throw err;
|
|
113
|
+
}
|
|
114
|
+
return client.post(path, body, { idempotent: true, approvalToken });
|
|
115
|
+
}
|
|
116
|
+
// ===========================================================================
|
|
117
|
+
// Discovery tools (9) — read-only, auto-run after authentication.
|
|
118
|
+
// ===========================================================================
|
|
119
|
+
const discoveryTools = [
|
|
120
|
+
defineTool({
|
|
121
|
+
name: "capix_account",
|
|
122
|
+
description: "Inspect the authenticated account: wallet address, balance, spending limits, active deployments/agents. Read-only — safe to auto-run.",
|
|
123
|
+
scope: "discovery",
|
|
124
|
+
...READ_ONLY,
|
|
125
|
+
inputShape: {},
|
|
126
|
+
outputShape: {
|
|
127
|
+
accountId: z.string().optional(),
|
|
128
|
+
walletAddress: z.string().optional(),
|
|
129
|
+
balance: moneyShape.optional(),
|
|
130
|
+
spendingLimitMinor: z.string().optional(),
|
|
131
|
+
activeDeployments: z.number().int().optional(),
|
|
132
|
+
activeAgents: z.number().int().optional(),
|
|
133
|
+
lastBilledAt: iso8601.optional(),
|
|
134
|
+
},
|
|
135
|
+
handler: async (_args, { client }) => client.get("/api/v1/account"),
|
|
136
|
+
}),
|
|
137
|
+
defineTool({
|
|
138
|
+
name: "capix_balance",
|
|
139
|
+
description: "Get the customer cash balance (available / held / total) for the account. Read-only.",
|
|
140
|
+
scope: "discovery",
|
|
141
|
+
...READ_ONLY,
|
|
142
|
+
inputShape: {
|
|
143
|
+
asset: z.enum(["SOL", "USDC", "USD-credit"]).optional().describe("Optional asset filter."),
|
|
144
|
+
},
|
|
145
|
+
outputShape: {
|
|
146
|
+
accountId: z.string().optional(),
|
|
147
|
+
asset: z.enum(["SOL", "USDC", "USD-credit"]).optional(),
|
|
148
|
+
available: z.string().optional(),
|
|
149
|
+
held: z.string().optional(),
|
|
150
|
+
total: z.string().optional(),
|
|
151
|
+
asOf: iso8601.optional(),
|
|
152
|
+
},
|
|
153
|
+
handler: async (args, { client }) => client.get("/api/v1/account/balance", {
|
|
154
|
+
asset: args.asset,
|
|
155
|
+
}),
|
|
156
|
+
}),
|
|
157
|
+
defineTool({
|
|
158
|
+
name: "capix_projects",
|
|
159
|
+
description: "List projects visible to the authenticated account. Read-only.",
|
|
160
|
+
scope: "discovery",
|
|
161
|
+
...READ_ONLY,
|
|
162
|
+
inputShape: {
|
|
163
|
+
limit: z.number().int().min(1).max(200).default(50).describe("Max projects to return."),
|
|
164
|
+
},
|
|
165
|
+
outputShape: listResultShape,
|
|
166
|
+
handler: async (args, { client }) => client.get("/api/v1/projects", { limit: args.limit }),
|
|
167
|
+
}),
|
|
168
|
+
defineTool({
|
|
169
|
+
name: "capix_compute_catalog",
|
|
170
|
+
description: "List the live compute capability catalog (provider / region / tier / price / availability). Read-only.",
|
|
171
|
+
scope: "discovery",
|
|
172
|
+
...READ_ONLY,
|
|
173
|
+
inputShape: {
|
|
174
|
+
region: z.string().optional().describe("Optional region filter."),
|
|
175
|
+
gpu: z.boolean().optional().describe("Restrict to GPU-capable entries."),
|
|
176
|
+
},
|
|
177
|
+
outputShape: {
|
|
178
|
+
entries: z.array(z.record(z.unknown())).optional(),
|
|
179
|
+
catalogVersion: z.string().optional(),
|
|
180
|
+
fetchedAt: iso8601.optional(),
|
|
181
|
+
},
|
|
182
|
+
handler: async (args, { client }) => client.get("/api/v1/catalog/compute", {
|
|
183
|
+
region: args.region,
|
|
184
|
+
gpu: args.gpu,
|
|
185
|
+
}),
|
|
186
|
+
}),
|
|
187
|
+
defineTool({
|
|
188
|
+
name: "capix_model_catalog",
|
|
189
|
+
description: "List the live model endpoint catalog (model id, context length, price per 1k tokens). Read-only.",
|
|
190
|
+
scope: "discovery",
|
|
191
|
+
...READ_ONLY,
|
|
192
|
+
inputShape: {
|
|
193
|
+
provider: z.string().optional().describe("Optional provider filter."),
|
|
194
|
+
},
|
|
195
|
+
outputShape: {
|
|
196
|
+
entries: z.array(z.record(z.unknown())).optional(),
|
|
197
|
+
catalogVersion: z.string().optional(),
|
|
198
|
+
fetchedAt: iso8601.optional(),
|
|
199
|
+
},
|
|
200
|
+
handler: async (args, { client }) => client.get("/api/v1/catalog/models", {
|
|
201
|
+
provider: args.provider,
|
|
202
|
+
}),
|
|
203
|
+
}),
|
|
204
|
+
defineTool({
|
|
205
|
+
name: "capix_network_status",
|
|
206
|
+
description: "Inspect network and gateway status (provider health, lanes, emergency flags). Read-only.",
|
|
207
|
+
scope: "discovery",
|
|
208
|
+
...READ_ONLY,
|
|
209
|
+
inputShape: {},
|
|
210
|
+
outputShape: {
|
|
211
|
+
gateway: z.string().optional(),
|
|
212
|
+
status: z.enum(["ok", "degraded", "outage"]).optional(),
|
|
213
|
+
providers: z.array(z.record(z.unknown())).optional(),
|
|
214
|
+
lanes: z.array(z.record(z.unknown())).optional(),
|
|
215
|
+
emergencyFlags: z.array(z.record(z.unknown())).optional(),
|
|
216
|
+
fetchedAt: iso8601.optional(),
|
|
217
|
+
},
|
|
218
|
+
handler: async (_args, { client }) => client.get("/api/v1/network/status"),
|
|
219
|
+
}),
|
|
220
|
+
defineTool({
|
|
221
|
+
name: "capix_deployments",
|
|
222
|
+
description: "List deployments for the account/project with phase + allocation state. Read-only.",
|
|
223
|
+
scope: "discovery",
|
|
224
|
+
...READ_ONLY,
|
|
225
|
+
inputShape: {
|
|
226
|
+
limit: z.number().int().min(1).max(200).default(50).describe("Max deployments to return."),
|
|
227
|
+
phase: z.string().optional().describe("Optional DeploymentPhase filter."),
|
|
228
|
+
},
|
|
229
|
+
outputShape: listResultShape,
|
|
230
|
+
handler: async (args, { client }) => client.get("/api/v1/deployments", {
|
|
231
|
+
limit: args.limit,
|
|
232
|
+
phase: args.phase,
|
|
233
|
+
}),
|
|
234
|
+
}),
|
|
235
|
+
defineTool({
|
|
236
|
+
name: "capix_receipts",
|
|
237
|
+
description: "List settled work receipts (cost records) for the account. Read-only.",
|
|
238
|
+
scope: "discovery",
|
|
239
|
+
...READ_ONLY,
|
|
240
|
+
inputShape: {
|
|
241
|
+
limit: z.number().int().min(1).max(200).default(50),
|
|
242
|
+
since: iso8601.optional().describe("Optional lower bound (inclusive)."),
|
|
243
|
+
},
|
|
244
|
+
outputShape: listResultShape,
|
|
245
|
+
handler: async (args, { client }) => client.get("/api/v1/receipts", {
|
|
246
|
+
limit: args.limit,
|
|
247
|
+
since: args.since,
|
|
248
|
+
}),
|
|
249
|
+
}),
|
|
250
|
+
defineTool({
|
|
251
|
+
name: "capix_attestations",
|
|
252
|
+
description: "List attestation evidence records for the account (TEE / zkVM). Read-only.",
|
|
253
|
+
scope: "discovery",
|
|
254
|
+
...READ_ONLY,
|
|
255
|
+
inputShape: {
|
|
256
|
+
limit: z.number().int().min(1).max(200).default(50),
|
|
257
|
+
kind: z.enum(["tee", "zkvm"]).optional().describe("Optional attestation kind filter."),
|
|
258
|
+
},
|
|
259
|
+
outputShape: listResultShape,
|
|
260
|
+
handler: async (args, { client }) => client.get("/api/v1/attestations", {
|
|
261
|
+
limit: args.limit,
|
|
262
|
+
kind: args.kind,
|
|
263
|
+
}),
|
|
264
|
+
}),
|
|
265
|
+
];
|
|
266
|
+
// ===========================================================================
|
|
267
|
+
// Planning tools (6) — read-only planning & quoting.
|
|
268
|
+
// ===========================================================================
|
|
269
|
+
const computeSpecShape = {
|
|
270
|
+
workloadType: z.string().describe("e.g. replicated_service.v1, private_inference.v1, agent_run.v1."),
|
|
271
|
+
cpu: z.number().int().min(1),
|
|
272
|
+
ramMb: z.number().int().min(128),
|
|
273
|
+
storageGb: z.number().int().min(0),
|
|
274
|
+
gpu: z.number().int().min(0).optional(),
|
|
275
|
+
vramMb: z.number().int().min(0).optional(),
|
|
276
|
+
region: z.string().optional(),
|
|
277
|
+
imageDigest: z.string().optional().describe("Pinned image digest."),
|
|
278
|
+
maxPriceUsdHourly: z.number().optional(),
|
|
279
|
+
maxDurationHours: z.number().optional(),
|
|
280
|
+
};
|
|
281
|
+
const modelSpecShape = {
|
|
282
|
+
modelId: z.string(),
|
|
283
|
+
quantization: z.string().optional(),
|
|
284
|
+
contextLength: z.number().int().min(1).optional(),
|
|
285
|
+
gpuType: z.string().optional(),
|
|
286
|
+
gpuCount: z.number().int().min(1).optional(),
|
|
287
|
+
region: z.string().optional(),
|
|
288
|
+
maxPriceUsdHourly: z.number().optional(),
|
|
289
|
+
maxConcurrency: z.number().int().min(1).optional(),
|
|
290
|
+
};
|
|
291
|
+
const stackManifestShape = {
|
|
292
|
+
name: z.string(),
|
|
293
|
+
services: z.array(z.record(z.unknown())),
|
|
294
|
+
network: z.record(z.unknown()).optional(),
|
|
295
|
+
region: z.string().optional(),
|
|
296
|
+
};
|
|
297
|
+
const planningTools = [
|
|
298
|
+
defineTool({
|
|
299
|
+
name: "capix_compute_plan",
|
|
300
|
+
description: "Plan a compute deployment: pick provider/region/spec for the requested workload shape. Read-only.",
|
|
301
|
+
scope: "planning",
|
|
302
|
+
...READ_ONLY,
|
|
303
|
+
inputShape: computeSpecShape,
|
|
304
|
+
outputShape: {
|
|
305
|
+
feasible: z.boolean(),
|
|
306
|
+
provider: z.string().optional(),
|
|
307
|
+
region: z.string().optional(),
|
|
308
|
+
cpu: z.number().int().optional(),
|
|
309
|
+
ramMb: z.number().int().optional(),
|
|
310
|
+
storageGb: z.number().int().optional(),
|
|
311
|
+
gpu: z.number().int().optional(),
|
|
312
|
+
estimatedCostHourly: moneyShape.optional(),
|
|
313
|
+
estimatedCostTotal: moneyShape.optional(),
|
|
314
|
+
notes: z.string().optional(),
|
|
315
|
+
},
|
|
316
|
+
handler: async (args, { client }) => client.post("/api/v1/planning/compute/plan", args),
|
|
317
|
+
}),
|
|
318
|
+
defineTool({
|
|
319
|
+
name: "capix_compute_quote",
|
|
320
|
+
description: "Get a canonical quote for a compute deployment plan (locks asset/scale/FX/fee/expiry). Read-only.",
|
|
321
|
+
scope: "planning",
|
|
322
|
+
...READ_ONLY,
|
|
323
|
+
inputShape: computeSpecShape,
|
|
324
|
+
outputShape: quoteResultShape,
|
|
325
|
+
handler: async (args, { client }) => client.post("/api/v1/planning/compute/quote", args),
|
|
326
|
+
}),
|
|
327
|
+
defineTool({
|
|
328
|
+
name: "capix_model_plan",
|
|
329
|
+
description: "Plan a model endpoint for the requested model hosting shape. Read-only.",
|
|
330
|
+
scope: "planning",
|
|
331
|
+
...READ_ONLY,
|
|
332
|
+
inputShape: modelSpecShape,
|
|
333
|
+
outputShape: {
|
|
334
|
+
feasible: z.boolean(),
|
|
335
|
+
provider: z.string().optional(),
|
|
336
|
+
region: z.string().optional(),
|
|
337
|
+
gpu: z.number().int().optional(),
|
|
338
|
+
estimatedCostHourly: moneyShape.optional(),
|
|
339
|
+
estimatedCostTotal: moneyShape.optional(),
|
|
340
|
+
notes: z.string().optional(),
|
|
341
|
+
},
|
|
342
|
+
handler: async (args, { client }) => client.post("/api/v1/planning/model/plan", args),
|
|
343
|
+
}),
|
|
344
|
+
defineTool({
|
|
345
|
+
name: "capix_model_quote",
|
|
346
|
+
description: "Get a canonical quote for a model endpoint plan. Read-only.",
|
|
347
|
+
scope: "planning",
|
|
348
|
+
...READ_ONLY,
|
|
349
|
+
inputShape: modelSpecShape,
|
|
350
|
+
outputShape: quoteResultShape,
|
|
351
|
+
handler: async (args, { client }) => client.post("/api/v1/planning/model/quote", args),
|
|
352
|
+
}),
|
|
353
|
+
defineTool({
|
|
354
|
+
name: "capix_stack_validate",
|
|
355
|
+
description: "Validate a stack manifest (services, dependencies, network) without provisioning. Read-only.",
|
|
356
|
+
scope: "planning",
|
|
357
|
+
...READ_ONLY,
|
|
358
|
+
inputShape: stackManifestShape,
|
|
359
|
+
outputShape: {
|
|
360
|
+
valid: z.boolean(),
|
|
361
|
+
errors: z.array(z.string()).optional(),
|
|
362
|
+
warnings: z.array(z.string()).optional(),
|
|
363
|
+
},
|
|
364
|
+
handler: async (args, { client }) => client.post("/api/v1/planning/stack/validate", args),
|
|
365
|
+
}),
|
|
366
|
+
defineTool({
|
|
367
|
+
name: "capix_stack_plan",
|
|
368
|
+
description: "Plan a multi-service stack: produce a deployment plan graph + aggregate quote. Read-only.",
|
|
369
|
+
scope: "planning",
|
|
370
|
+
...READ_ONLY,
|
|
371
|
+
inputShape: stackManifestShape,
|
|
372
|
+
outputShape: {
|
|
373
|
+
feasible: z.boolean(),
|
|
374
|
+
services: z.array(z.record(z.unknown())).optional(),
|
|
375
|
+
aggregateQuote: z.record(z.unknown()).optional(),
|
|
376
|
+
notes: z.string().optional(),
|
|
377
|
+
},
|
|
378
|
+
handler: async (args, { client }) => client.post("/api/v1/planning/stack/plan", args),
|
|
379
|
+
}),
|
|
380
|
+
];
|
|
381
|
+
// ===========================================================================
|
|
382
|
+
// Lifecycle tools (7) — billable mutations, require approval.
|
|
383
|
+
// ===========================================================================
|
|
384
|
+
const lifecycleTools = [
|
|
385
|
+
defineTool({
|
|
386
|
+
name: "capix_deploy",
|
|
387
|
+
description: "Deploy a workload against a canonical quote. Takes a ledger hold + provisions resources. Billable; requires approval.",
|
|
388
|
+
scope: "lifecycle",
|
|
389
|
+
...BILLABLE,
|
|
390
|
+
inputShape: {
|
|
391
|
+
quoteId: quoteIdShape.describe("Canonical quote from capix_compute_quote / capix_model_quote."),
|
|
392
|
+
workloadType: z.string(),
|
|
393
|
+
region: z.string().optional(),
|
|
394
|
+
imageDigest: z.string().optional(),
|
|
395
|
+
durationHours: z.number().min(1).optional(),
|
|
396
|
+
env: z.record(z.string()).optional(),
|
|
397
|
+
ingress: z.array(z.number().int()).optional(),
|
|
398
|
+
},
|
|
399
|
+
outputShape: deploymentResultShape,
|
|
400
|
+
handler: async (args, { client, ctx }) => callBillable(client, ctx.approvalToken, "/api/v1/lifecycle/deployments", args),
|
|
401
|
+
}),
|
|
402
|
+
defineTool({
|
|
403
|
+
name: "capix_start",
|
|
404
|
+
description: "Start a stopped deployment. Billable (resumes metering); requires approval.",
|
|
405
|
+
scope: "lifecycle",
|
|
406
|
+
...BILLABLE,
|
|
407
|
+
inputShape: {
|
|
408
|
+
deploymentId: deploymentIdShape,
|
|
409
|
+
},
|
|
410
|
+
outputShape: deploymentResultShape,
|
|
411
|
+
handler: async (args, { client, ctx }) => callBillable(client, ctx.approvalToken, `/api/v1/lifecycle/deployments/${encodeURIComponent(asStr(args.deploymentId, "deploymentId"))}/start`),
|
|
412
|
+
}),
|
|
413
|
+
defineTool({
|
|
414
|
+
name: "capix_stop",
|
|
415
|
+
description: "Stop a running deployment (halts metering, keeps allocation). Billable (minimal); requires approval.",
|
|
416
|
+
scope: "lifecycle",
|
|
417
|
+
...BILLABLE,
|
|
418
|
+
inputShape: {
|
|
419
|
+
deploymentId: deploymentIdShape,
|
|
420
|
+
},
|
|
421
|
+
outputShape: deploymentResultShape,
|
|
422
|
+
handler: async (args, { client, ctx }) => callBillable(client, ctx.approvalToken, `/api/v1/lifecycle/deployments/${encodeURIComponent(asStr(args.deploymentId, "deploymentId"))}/stop`),
|
|
423
|
+
}),
|
|
424
|
+
defineTool({
|
|
425
|
+
name: "capix_restart",
|
|
426
|
+
description: "Restart a deployment (stop + start cycle). Billable; requires approval.",
|
|
427
|
+
scope: "lifecycle",
|
|
428
|
+
...BILLABLE,
|
|
429
|
+
inputShape: {
|
|
430
|
+
deploymentId: deploymentIdShape,
|
|
431
|
+
},
|
|
432
|
+
outputShape: deploymentResultShape,
|
|
433
|
+
handler: async (args, { client, ctx }) => callBillable(client, ctx.approvalToken, `/api/v1/lifecycle/deployments/${encodeURIComponent(asStr(args.deploymentId, "deploymentId"))}/restart`),
|
|
434
|
+
}),
|
|
435
|
+
defineTool({
|
|
436
|
+
name: "capix_delete",
|
|
437
|
+
description: "Delete (terminate) a deployment and release its allocation. Billable (final settlement); requires approval.",
|
|
438
|
+
scope: "lifecycle",
|
|
439
|
+
...BILLABLE,
|
|
440
|
+
inputShape: {
|
|
441
|
+
deploymentId: deploymentIdShape,
|
|
442
|
+
reason: z.string().optional(),
|
|
443
|
+
},
|
|
444
|
+
outputShape: deploymentResultShape,
|
|
445
|
+
handler: async (args, { client, ctx }) => {
|
|
446
|
+
const id = asStr(args.deploymentId, "deploymentId");
|
|
447
|
+
const res = await callBillable(client, ctx.approvalToken, `/api/v1/lifecycle/deployments/${encodeURIComponent(id)}`, args.reason ? { reason: args.reason } : undefined);
|
|
448
|
+
// DELETE semantics: the canonical route is DELETE; some gateways express
|
|
449
|
+
// the mutation via POST with idempotency. Use the client delete path with
|
|
450
|
+
// an approval header via a light POST-to-delete fallback.
|
|
451
|
+
return res;
|
|
452
|
+
},
|
|
453
|
+
}),
|
|
454
|
+
defineTool({
|
|
455
|
+
name: "capix_extend",
|
|
456
|
+
description: "Extend a running deployment by additional hours against a fresh hold. Billable; requires approval.",
|
|
457
|
+
scope: "lifecycle",
|
|
458
|
+
...BILLABLE,
|
|
459
|
+
inputShape: {
|
|
460
|
+
deploymentId: deploymentIdShape,
|
|
461
|
+
durationHours: z.number().min(1),
|
|
462
|
+
quoteId: quoteIdShape.optional().describe("Canonical quote for the extension cost."),
|
|
463
|
+
},
|
|
464
|
+
outputShape: deploymentResultShape,
|
|
465
|
+
handler: async (args, { client, ctx }) => callBillable(client, ctx.approvalToken, `/api/v1/lifecycle/deployments/${encodeURIComponent(asStr(args.deploymentId, "deploymentId"))}/extend`, { durationHours: args.durationHours, quoteId: args.quoteId }),
|
|
466
|
+
}),
|
|
467
|
+
defineTool({
|
|
468
|
+
name: "capix_cancel",
|
|
469
|
+
description: "Cancel an in-flight operation (best-effort; may trigger compensation). Read-only intent; requires approval to mutate.",
|
|
470
|
+
scope: "lifecycle",
|
|
471
|
+
...APPROVAL_ONLY,
|
|
472
|
+
inputShape: {
|
|
473
|
+
operationId: operationIdShape,
|
|
474
|
+
reason: z.string().optional(),
|
|
475
|
+
},
|
|
476
|
+
outputShape: {
|
|
477
|
+
operationId: operationIdShape.optional(),
|
|
478
|
+
status: z.string().optional(),
|
|
479
|
+
acceptedAt: iso8601.optional(),
|
|
480
|
+
},
|
|
481
|
+
handler: async (args, { client, ctx }) => callBillable(client, ctx.approvalToken, `/api/v1/operations/${encodeURIComponent(asStr(args.operationId, "operationId"))}/cancel`, args.reason ? { reason: args.reason } : undefined),
|
|
482
|
+
}),
|
|
483
|
+
];
|
|
484
|
+
// ===========================================================================
|
|
485
|
+
// Networking tools (8) — billable mutations + read-only inspection.
|
|
486
|
+
// ===========================================================================
|
|
487
|
+
const networkingTools = [
|
|
488
|
+
defineTool({
|
|
489
|
+
name: "capix_create_vpc",
|
|
490
|
+
description: "Create a VPC for a project. Billable; requires approval.",
|
|
491
|
+
scope: "networking",
|
|
492
|
+
...BILLABLE,
|
|
493
|
+
inputShape: {
|
|
494
|
+
cidr: z.string().describe("VPC CIDR block, e.g. 10.0.0.0/16."),
|
|
495
|
+
region: z.string(),
|
|
496
|
+
name: z.string().optional(),
|
|
497
|
+
},
|
|
498
|
+
outputShape: networkResourceShape,
|
|
499
|
+
handler: async (args, { client, ctx }) => callBillable(client, ctx.approvalToken, "/api/v1/networking/vpcs", args),
|
|
500
|
+
}),
|
|
501
|
+
defineTool({
|
|
502
|
+
name: "capix_create_endpoint",
|
|
503
|
+
description: "Create a public endpoint for a deployment. Billable; requires approval.",
|
|
504
|
+
scope: "networking",
|
|
505
|
+
...BILLABLE,
|
|
506
|
+
inputShape: {
|
|
507
|
+
deploymentId: deploymentIdShape,
|
|
508
|
+
port: z.number().int().min(1).max(65535),
|
|
509
|
+
protocol: z.enum(["http", "https", "tcp"]).default("http"),
|
|
510
|
+
hostname: z.string().optional().describe("Optional requested hostname."),
|
|
511
|
+
},
|
|
512
|
+
outputShape: networkResourceShape,
|
|
513
|
+
handler: async (args, { client, ctx }) => callBillable(client, ctx.approvalToken, "/api/v1/networking/endpoints", args),
|
|
514
|
+
}),
|
|
515
|
+
defineTool({
|
|
516
|
+
name: "capix_expose_port",
|
|
517
|
+
description: "Expose a port (ingress) to the public internet. Billable; requires approval.",
|
|
518
|
+
scope: "networking",
|
|
519
|
+
...BILLABLE,
|
|
520
|
+
inputShape: {
|
|
521
|
+
deploymentId: deploymentIdShape,
|
|
522
|
+
port: z.number().int().min(1).max(65535),
|
|
523
|
+
protocol: z.enum(["tcp", "udp"]).default("tcp"),
|
|
524
|
+
allowedCidrs: z.array(z.string()).optional().describe("Optional ingress allow-list."),
|
|
525
|
+
},
|
|
526
|
+
outputShape: networkResourceShape,
|
|
527
|
+
handler: async (args, { client, ctx }) => callBillable(client, ctx.approvalToken, "/api/v1/networking/ports/expose", args),
|
|
528
|
+
}),
|
|
529
|
+
defineTool({
|
|
530
|
+
name: "capix_close_port",
|
|
531
|
+
description: "Close a previously exposed port. Non-billable soft mutation; requires approval.",
|
|
532
|
+
scope: "networking",
|
|
533
|
+
...APPROVAL_ONLY,
|
|
534
|
+
inputShape: {
|
|
535
|
+
deploymentId: deploymentIdShape,
|
|
536
|
+
port: z.number().int().min(1).max(65535),
|
|
537
|
+
protocol: z.enum(["tcp", "udp"]).default("tcp"),
|
|
538
|
+
},
|
|
539
|
+
outputShape: networkResourceShape,
|
|
540
|
+
handler: async (args, { client, ctx }) => callBillable(client, ctx.approvalToken, "/api/v1/networking/ports/close", args),
|
|
541
|
+
}),
|
|
542
|
+
defineTool({
|
|
543
|
+
name: "capix_inspect_routes",
|
|
544
|
+
description: "Inspect the routing table for a deployment. Read-only.",
|
|
545
|
+
scope: "networking",
|
|
546
|
+
...READ_ONLY,
|
|
547
|
+
inputShape: {
|
|
548
|
+
deploymentId: deploymentIdShape,
|
|
549
|
+
},
|
|
550
|
+
outputShape: {
|
|
551
|
+
deploymentId: deploymentIdShape.optional(),
|
|
552
|
+
routes: z.array(z.record(z.unknown())).optional(),
|
|
553
|
+
fetchedAt: iso8601.optional(),
|
|
554
|
+
},
|
|
555
|
+
handler: async (args, { client }) => client.get(`/api/v1/networking/deployments/${encodeURIComponent(asStr(args.deploymentId, "deploymentId"))}/routes`),
|
|
556
|
+
}),
|
|
557
|
+
defineTool({
|
|
558
|
+
name: "capix_create_private_connection",
|
|
559
|
+
description: "Create a private endpoint connection (raw private endpoint). Billable; requires approval.",
|
|
560
|
+
scope: "networking",
|
|
561
|
+
...BILLABLE,
|
|
562
|
+
inputShape: {
|
|
563
|
+
deploymentId: deploymentIdShape,
|
|
564
|
+
service: z.string().describe("Target service identifier."),
|
|
565
|
+
port: z.number().int().min(1).max(65535).optional(),
|
|
566
|
+
},
|
|
567
|
+
outputShape: networkResourceShape,
|
|
568
|
+
handler: async (args, { client, ctx }) => callBillable(client, ctx.approvalToken, "/api/v1/networking/private-connections", args),
|
|
569
|
+
}),
|
|
570
|
+
defineTool({
|
|
571
|
+
name: "capix_request_dedicated_ip",
|
|
572
|
+
description: "Request a dedicated (non-shared) IP for a deployment. Paid; requires approval.",
|
|
573
|
+
scope: "networking",
|
|
574
|
+
...BILLABLE,
|
|
575
|
+
inputShape: {
|
|
576
|
+
deploymentId: deploymentIdShape,
|
|
577
|
+
region: z.string().optional(),
|
|
578
|
+
quoteId: quoteIdShape.describe("Canonical quote for the dedicated IP."),
|
|
579
|
+
},
|
|
580
|
+
outputShape: networkResourceShape,
|
|
581
|
+
handler: async (args, { client, ctx }) => callBillable(client, ctx.approvalToken, "/api/v1/networking/dedicated-ips", args),
|
|
582
|
+
}),
|
|
583
|
+
defineTool({
|
|
584
|
+
name: "capix_port_forward",
|
|
585
|
+
description: "Set up port forwarding between a deployment port and a host port. Billable; requires approval.",
|
|
586
|
+
scope: "networking",
|
|
587
|
+
...BILLABLE,
|
|
588
|
+
inputShape: {
|
|
589
|
+
deploymentId: deploymentIdShape,
|
|
590
|
+
sourcePort: z.number().int().min(1).max(65535),
|
|
591
|
+
targetPort: z.number().int().min(1).max(65535),
|
|
592
|
+
protocol: z.enum(["tcp", "udp"]).default("tcp"),
|
|
593
|
+
},
|
|
594
|
+
outputShape: networkResourceShape,
|
|
595
|
+
handler: async (args, { client, ctx }) => callBillable(client, ctx.approvalToken, "/api/v1/networking/port-forwards", args),
|
|
596
|
+
}),
|
|
597
|
+
];
|
|
598
|
+
// ===========================================================================
|
|
599
|
+
// Testing tools (6) — disposable envs, inspection, bounded commands, cleanup.
|
|
600
|
+
// ===========================================================================
|
|
601
|
+
const testingTools = [
|
|
602
|
+
defineTool({
|
|
603
|
+
name: "capix_create_test_env",
|
|
604
|
+
description: "Create a disposable test environment from a spec. Billable; requires approval.",
|
|
605
|
+
scope: "testing",
|
|
606
|
+
...BILLABLE,
|
|
607
|
+
inputShape: {
|
|
608
|
+
name: z.string(),
|
|
609
|
+
workloadType: z.string(),
|
|
610
|
+
cpu: z.number().int().min(1),
|
|
611
|
+
ramMb: z.number().int().min(128),
|
|
612
|
+
region: z.string().optional(),
|
|
613
|
+
imageDigest: z.string().optional(),
|
|
614
|
+
ttlMinutes: z.number().int().min(1).max(1440).default(60).describe("Auto-destroy TTL."),
|
|
615
|
+
quoteId: quoteIdShape.optional().describe("Canonical quote for the env."),
|
|
616
|
+
},
|
|
617
|
+
outputShape: {
|
|
618
|
+
envId: z.string().optional(),
|
|
619
|
+
status: z.enum(["provisioning", "ready", "failed"]).optional(),
|
|
620
|
+
provider: z.string().optional(),
|
|
621
|
+
region: z.string().optional(),
|
|
622
|
+
endpoint: z.string().optional(),
|
|
623
|
+
provisionedAt: iso8601.optional(),
|
|
624
|
+
},
|
|
625
|
+
handler: async (args, { client, ctx }) => callBillable(client, ctx.approvalToken, "/api/v1/testing/environments", args),
|
|
626
|
+
}),
|
|
627
|
+
defineTool({
|
|
628
|
+
name: "capix_run_health_checks",
|
|
629
|
+
description: "Run health checks (liveness/readiness probes) on a deployment. Read-only.",
|
|
630
|
+
scope: "testing",
|
|
631
|
+
...READ_ONLY,
|
|
632
|
+
inputShape: {
|
|
633
|
+
deploymentId: deploymentIdShape,
|
|
634
|
+
},
|
|
635
|
+
outputShape: {
|
|
636
|
+
deploymentId: deploymentIdShape.optional(),
|
|
637
|
+
healthy: z.boolean().optional(),
|
|
638
|
+
checks: z.array(z.record(z.unknown())).optional(),
|
|
639
|
+
ranAt: iso8601.optional(),
|
|
640
|
+
},
|
|
641
|
+
handler: async (args, { client }) => client.get(`/api/v1/testing/deployments/${encodeURIComponent(asStr(args.deploymentId, "deploymentId"))}/health`),
|
|
642
|
+
}),
|
|
643
|
+
defineTool({
|
|
644
|
+
name: "capix_run_bounded_command",
|
|
645
|
+
description: "Run an allow-listed, time-bounded command on a deployment node. Requires approval (may execute code).",
|
|
646
|
+
scope: "testing",
|
|
647
|
+
...APPROVAL_ONLY,
|
|
648
|
+
inputShape: {
|
|
649
|
+
deploymentId: deploymentIdShape,
|
|
650
|
+
command: z.string().describe("Command string from the allow-list."),
|
|
651
|
+
timeoutSeconds: z.number().int().min(1).max(600).default(60),
|
|
652
|
+
expectedExitCode: z.number().int().default(0),
|
|
653
|
+
},
|
|
654
|
+
outputShape: {
|
|
655
|
+
deploymentId: deploymentIdShape.optional(),
|
|
656
|
+
results: z.array(z.record(z.unknown())).optional(),
|
|
657
|
+
completedAt: iso8601.optional(),
|
|
658
|
+
},
|
|
659
|
+
handler: async (args, { client, ctx }) => callBillable(client, ctx.approvalToken, `/api/v1/testing/deployments/${encodeURIComponent(asStr(args.deploymentId, "deploymentId"))}/commands`, args),
|
|
660
|
+
}),
|
|
661
|
+
defineTool({
|
|
662
|
+
name: "capix_inspect_logs",
|
|
663
|
+
description: "Inspect deployment logs. Read-only.",
|
|
664
|
+
scope: "testing",
|
|
665
|
+
...READ_ONLY,
|
|
666
|
+
inputShape: {
|
|
667
|
+
deploymentId: deploymentIdShape,
|
|
668
|
+
limit: z.number().int().min(1).max(1000).default(200),
|
|
669
|
+
since: iso8601.optional(),
|
|
670
|
+
level: z.enum(["debug", "info", "warn", "error"]).optional(),
|
|
671
|
+
},
|
|
672
|
+
outputShape: {
|
|
673
|
+
resourceId: z.string().optional(),
|
|
674
|
+
lines: z.array(z.record(z.unknown())).optional(),
|
|
675
|
+
truncated: z.boolean().optional(),
|
|
676
|
+
},
|
|
677
|
+
handler: async (args, { client }) => client.get(`/api/v1/testing/deployments/${encodeURIComponent(asStr(args.deploymentId, "deploymentId"))}/logs`, { limit: args.limit, since: args.since, level: args.level }),
|
|
678
|
+
}),
|
|
679
|
+
defineTool({
|
|
680
|
+
name: "capix_inspect_metrics",
|
|
681
|
+
description: "Inspect deployment metrics. Read-only.",
|
|
682
|
+
scope: "testing",
|
|
683
|
+
...READ_ONLY,
|
|
684
|
+
inputShape: {
|
|
685
|
+
deploymentId: deploymentIdShape,
|
|
686
|
+
windowMinutes: z.number().int().min(1).max(10080).default(60),
|
|
687
|
+
names: z.array(z.string()).optional().describe("Optional metric name filter."),
|
|
688
|
+
},
|
|
689
|
+
outputShape: {
|
|
690
|
+
resourceId: z.string().optional(),
|
|
691
|
+
metrics: z.array(z.record(z.unknown())).optional(),
|
|
692
|
+
},
|
|
693
|
+
handler: async (args, { client }) => client.get(`/api/v1/testing/deployments/${encodeURIComponent(asStr(args.deploymentId, "deploymentId"))}/metrics`, { windowMinutes: args.windowMinutes, names: args.names }),
|
|
694
|
+
}),
|
|
695
|
+
defineTool({
|
|
696
|
+
name: "capix_destroy_task_resources",
|
|
697
|
+
description: "Destroy all resources scoped to a task (cleanup safety gate §18). Destructive; requires approval.",
|
|
698
|
+
scope: "testing",
|
|
699
|
+
...APPROVAL_ONLY,
|
|
700
|
+
inputShape: {
|
|
701
|
+
resourceId: z.string().describe("Task-scoped resource id to destroy."),
|
|
702
|
+
reason: z.string().optional(),
|
|
703
|
+
},
|
|
704
|
+
outputShape: {
|
|
705
|
+
resourceId: z.string().optional(),
|
|
706
|
+
status: z.enum(["destroyed", "failed", "not_found"]).optional(),
|
|
707
|
+
destroyedAt: iso8601.optional(),
|
|
708
|
+
},
|
|
709
|
+
handler: async (args, { client, ctx }) => {
|
|
710
|
+
const id = asStr(args.resourceId, "resourceId");
|
|
711
|
+
return callBillable(client, ctx.approvalToken, `/api/v1/testing/environments/${encodeURIComponent(id)}`, args.reason ? { reason: args.reason } : undefined);
|
|
712
|
+
},
|
|
713
|
+
}),
|
|
714
|
+
];
|
|
715
|
+
// ===========================================================================
|
|
716
|
+
// Verification tools (6) — read-only attestation/proof/receipt inspection.
|
|
717
|
+
// ===========================================================================
|
|
718
|
+
const verificationTools = [
|
|
719
|
+
defineTool({
|
|
720
|
+
name: "capix_fetch_attestation",
|
|
721
|
+
description: "Fetch attestation evidence for a deployment (TEE / zkVM). Read-only.",
|
|
722
|
+
scope: "verification",
|
|
723
|
+
...READ_ONLY,
|
|
724
|
+
inputShape: {
|
|
725
|
+
deploymentId: deploymentIdShape,
|
|
726
|
+
},
|
|
727
|
+
outputShape: {
|
|
728
|
+
attestationId: z.string().optional(),
|
|
729
|
+
kind: z.enum(["tee", "zkvm"]).optional(),
|
|
730
|
+
resourceId: z.string().optional(),
|
|
731
|
+
evidence: z.string().optional(),
|
|
732
|
+
measurement: z.string().optional(),
|
|
733
|
+
fetchedAt: iso8601.optional(),
|
|
734
|
+
},
|
|
735
|
+
handler: async (args, { client }) => client.get(`/api/v1/verification/deployments/${encodeURIComponent(asStr(args.deploymentId, "deploymentId"))}/attestation`),
|
|
736
|
+
}),
|
|
737
|
+
defineTool({
|
|
738
|
+
name: "capix_verify_attestation",
|
|
739
|
+
description: "Verify an attestation against the expected reference measurement. Read-only.",
|
|
740
|
+
scope: "verification",
|
|
741
|
+
...READ_ONLY,
|
|
742
|
+
inputShape: {
|
|
743
|
+
attestationId: z.string(),
|
|
744
|
+
expectedMeasurement: z.string().optional().describe("Optional pinned reference measurement."),
|
|
745
|
+
},
|
|
746
|
+
outputShape: {
|
|
747
|
+
subjectId: z.string().optional(),
|
|
748
|
+
kind: z.enum(["tee", "zkvm", "measurement", "receipt"]).optional(),
|
|
749
|
+
verified: z.boolean().optional(),
|
|
750
|
+
reason: z.string().optional(),
|
|
751
|
+
verifier: z.string().optional(),
|
|
752
|
+
verifiedAt: iso8601.optional(),
|
|
753
|
+
},
|
|
754
|
+
handler: async (args, { client }) => client.post(`/api/v1/verification/attestations/${encodeURIComponent(asStr(args.attestationId, "attestationId"))}/verify`, { expectedMeasurement: args.expectedMeasurement }),
|
|
755
|
+
}),
|
|
756
|
+
defineTool({
|
|
757
|
+
name: "capix_fetch_proof",
|
|
758
|
+
description: "Fetch a zkVM proof artifact for a workload. Read-only.",
|
|
759
|
+
scope: "verification",
|
|
760
|
+
...READ_ONLY,
|
|
761
|
+
inputShape: {
|
|
762
|
+
workloadId: z.string(),
|
|
763
|
+
},
|
|
764
|
+
outputShape: {
|
|
765
|
+
proofId: z.string().optional(),
|
|
766
|
+
workloadId: z.string().optional(),
|
|
767
|
+
proofSystem: z.string().optional(),
|
|
768
|
+
artifactRef: z.string().optional(),
|
|
769
|
+
publicInputs: z.string().optional(),
|
|
770
|
+
fetchedAt: iso8601.optional(),
|
|
771
|
+
},
|
|
772
|
+
handler: async (args, { client }) => client.get(`/api/v1/verification/workloads/${encodeURIComponent(asStr(args.workloadId, "workloadId"))}/proof`),
|
|
773
|
+
}),
|
|
774
|
+
defineTool({
|
|
775
|
+
name: "capix_verify_proof",
|
|
776
|
+
description: "Verify a zkVM proof artifact against its public inputs. Read-only.",
|
|
777
|
+
scope: "verification",
|
|
778
|
+
...READ_ONLY,
|
|
779
|
+
inputShape: {
|
|
780
|
+
proofId: z.string(),
|
|
781
|
+
},
|
|
782
|
+
outputShape: {
|
|
783
|
+
subjectId: z.string().optional(),
|
|
784
|
+
kind: z.enum(["tee", "zkvm", "measurement", "receipt"]).optional(),
|
|
785
|
+
verified: z.boolean().optional(),
|
|
786
|
+
reason: z.string().optional(),
|
|
787
|
+
verifier: z.string().optional(),
|
|
788
|
+
verifiedAt: iso8601.optional(),
|
|
789
|
+
},
|
|
790
|
+
handler: async (args, { client }) => client.post(`/api/v1/verification/proofs/${encodeURIComponent(asStr(args.proofId, "proofId"))}/verify`),
|
|
791
|
+
}),
|
|
792
|
+
defineTool({
|
|
793
|
+
name: "capix_inspect_measurement",
|
|
794
|
+
description: "Inspect the recorded measurement of a workload (used to pin expected TEE state). Read-only.",
|
|
795
|
+
scope: "verification",
|
|
796
|
+
...READ_ONLY,
|
|
797
|
+
inputShape: {
|
|
798
|
+
workloadId: z.string(),
|
|
799
|
+
},
|
|
800
|
+
outputShape: {
|
|
801
|
+
workloadId: z.string().optional(),
|
|
802
|
+
measurement: z.string().optional(),
|
|
803
|
+
measurementAlgorithm: z.string().optional(),
|
|
804
|
+
imageDigest: z.string().optional(),
|
|
805
|
+
recordedAt: iso8601.optional(),
|
|
806
|
+
},
|
|
807
|
+
handler: async (args, { client }) => client.get(`/api/v1/verification/workloads/${encodeURIComponent(asStr(args.workloadId, "workloadId"))}/measurement`),
|
|
808
|
+
}),
|
|
809
|
+
defineTool({
|
|
810
|
+
name: "capix_inspect_receipt",
|
|
811
|
+
description: "Inspect a settled work receipt (cost breakdown, settlement, approval status). Read-only.",
|
|
812
|
+
scope: "verification",
|
|
813
|
+
...READ_ONLY,
|
|
814
|
+
inputShape: {
|
|
815
|
+
receiptId: z.string(),
|
|
816
|
+
},
|
|
817
|
+
outputShape: {
|
|
818
|
+
receiptId: z.string().optional(),
|
|
819
|
+
approvalStatus: z.string().optional(),
|
|
820
|
+
cost: z.record(z.unknown()).optional(),
|
|
821
|
+
settlement: z.record(z.unknown()).optional(),
|
|
822
|
+
postedAt: iso8601.optional(),
|
|
823
|
+
},
|
|
824
|
+
handler: async (args, { client }) => client.get(`/api/v1/verification/receipts/${encodeURIComponent(asStr(args.receiptId, "receiptId"))}`),
|
|
825
|
+
}),
|
|
826
|
+
];
|
|
827
|
+
// ===========================================================================
|
|
828
|
+
// Website tools (17) — static-site + preview hosting.
|
|
829
|
+
// ===========================================================================
|
|
830
|
+
const repoOptShape = {
|
|
831
|
+
repoUrl: z.string().describe("Git repository URL."),
|
|
832
|
+
branch: z.string().default("main"),
|
|
833
|
+
subPath: z.string().optional().describe("Optional monorepo subpath."),
|
|
834
|
+
framework: z.string().optional().describe("Optional pinned framework."),
|
|
835
|
+
};
|
|
836
|
+
const websiteTools = [
|
|
837
|
+
defineTool({
|
|
838
|
+
name: "capix_website_project_string_check",
|
|
839
|
+
description: "Check a repository string for framework/dep compatibility with Capix hosting. Read-only.",
|
|
840
|
+
scope: "website",
|
|
841
|
+
...READ_ONLY,
|
|
842
|
+
inputShape: {
|
|
843
|
+
repoUrl: z.string(),
|
|
844
|
+
},
|
|
845
|
+
outputShape: {
|
|
846
|
+
ok: z.boolean().optional(),
|
|
847
|
+
framework: z.string().optional(),
|
|
848
|
+
notes: z.string().optional(),
|
|
849
|
+
},
|
|
850
|
+
handler: async (args, { client }) => client.post("/api/v1/website/check-project-string", { repoUrl: asStr(args.repoUrl, "repoUrl") }),
|
|
851
|
+
}),
|
|
852
|
+
defineTool({
|
|
853
|
+
name: "capix_website_create",
|
|
854
|
+
description: "Create a Capix website project from a repo. Billable; requires approval.",
|
|
855
|
+
scope: "website",
|
|
856
|
+
...BILLABLE,
|
|
857
|
+
inputShape: repoOptShape,
|
|
858
|
+
outputShape: siteResultShape,
|
|
859
|
+
handler: async (args, { client, ctx }) => callBillable(client, ctx.approvalToken, "/api/v1/website/sites", args),
|
|
860
|
+
}),
|
|
861
|
+
defineTool({
|
|
862
|
+
name: "capix_website_detect",
|
|
863
|
+
description: "Detect the framework/build settings of a repo without provisioning. Read-only.",
|
|
864
|
+
scope: "website",
|
|
865
|
+
...READ_ONLY,
|
|
866
|
+
inputShape: {
|
|
867
|
+
repoUrl: z.string(),
|
|
868
|
+
branch: z.string().optional(),
|
|
869
|
+
},
|
|
870
|
+
outputShape: {
|
|
871
|
+
framework: z.string().optional(),
|
|
872
|
+
buildCommand: z.string().optional(),
|
|
873
|
+
outputDir: z.string().optional(),
|
|
874
|
+
nodeVersion: z.string().optional(),
|
|
875
|
+
detectedAt: iso8601.optional(),
|
|
876
|
+
},
|
|
877
|
+
handler: async (args, { client }) => client.post("/api/v1/website/detect", {
|
|
878
|
+
repoUrl: asStr(args.repoUrl, "repoUrl"),
|
|
879
|
+
branch: args.branch,
|
|
880
|
+
}),
|
|
881
|
+
}),
|
|
882
|
+
defineTool({
|
|
883
|
+
name: "capix_website_plan",
|
|
884
|
+
description: "Plan a website deployment (build + hosting plan). Read-only.",
|
|
885
|
+
scope: "website",
|
|
886
|
+
...READ_ONLY,
|
|
887
|
+
inputShape: {
|
|
888
|
+
siteId: siteIdShape.optional(),
|
|
889
|
+
repoUrl: z.string().optional(),
|
|
890
|
+
branch: z.string().optional(),
|
|
891
|
+
subPath: z.string().optional(),
|
|
892
|
+
framework: z.string().optional(),
|
|
893
|
+
},
|
|
894
|
+
outputShape: {
|
|
895
|
+
feasible: z.boolean().optional(),
|
|
896
|
+
plan: z.record(z.unknown()).optional(),
|
|
897
|
+
notes: z.string().optional(),
|
|
898
|
+
},
|
|
899
|
+
handler: async (args, { client }) => client.post("/api/v1/website/plan", args),
|
|
900
|
+
}),
|
|
901
|
+
defineTool({
|
|
902
|
+
name: "capix_website_quote",
|
|
903
|
+
description: "Get a canonical quote for a website deploy. Read-only.",
|
|
904
|
+
scope: "website",
|
|
905
|
+
...READ_ONLY,
|
|
906
|
+
inputShape: {
|
|
907
|
+
repoUrl: z.string().optional(),
|
|
908
|
+
branch: z.string().optional(),
|
|
909
|
+
durationHours: z.number().optional(),
|
|
910
|
+
},
|
|
911
|
+
outputShape: {
|
|
912
|
+
quoteId: z.string().optional(),
|
|
913
|
+
price: moneyShape.optional(),
|
|
914
|
+
feasible: z.boolean().optional(),
|
|
915
|
+
expiresAt: iso8601.optional(),
|
|
916
|
+
},
|
|
917
|
+
handler: async (args, { client }) => client.post("/api/v1/website/quote", args),
|
|
918
|
+
}),
|
|
919
|
+
defineTool({
|
|
920
|
+
name: "capix_website_deploy",
|
|
921
|
+
description: "Deploy a website build to production. Billable; requires approval.",
|
|
922
|
+
scope: "website",
|
|
923
|
+
...BILLABLE,
|
|
924
|
+
inputShape: {
|
|
925
|
+
siteId: siteIdShape,
|
|
926
|
+
branch: z.string().optional(),
|
|
927
|
+
commit: z.string().optional(),
|
|
928
|
+
quoteId: quoteIdShape.optional(),
|
|
929
|
+
},
|
|
930
|
+
outputShape: siteResultShape,
|
|
931
|
+
handler: async (args, { client, ctx }) => callBillable(client, ctx.approvalToken, `/api/v1/website/sites/${encodeURIComponent(asStr(args.siteId, "siteId"))}/deploy`, { branch: args.branch, commit: args.commit, quoteId: args.quoteId }),
|
|
932
|
+
}),
|
|
933
|
+
defineTool({
|
|
934
|
+
name: "capix_website_preview",
|
|
935
|
+
description: "Create a preview deployment for a branch. Billable; requires approval.",
|
|
936
|
+
scope: "website",
|
|
937
|
+
...BILLABLE,
|
|
938
|
+
inputShape: {
|
|
939
|
+
siteId: siteIdShape,
|
|
940
|
+
branch: z.string(),
|
|
941
|
+
},
|
|
942
|
+
outputShape: siteResultShape,
|
|
943
|
+
handler: async (args, { client, ctx }) => callBillable(client, ctx.approvalToken, `/api/v1/website/sites/${encodeURIComponent(asStr(args.siteId, "siteId"))}/preview`, { branch: args.branch }),
|
|
944
|
+
}),
|
|
945
|
+
defineTool({
|
|
946
|
+
name: "capix_website_promote",
|
|
947
|
+
description: "Promote a preview deployment to production. Billable; requires approval.",
|
|
948
|
+
scope: "website",
|
|
949
|
+
...BILLABLE,
|
|
950
|
+
inputShape: {
|
|
951
|
+
siteId: siteIdShape,
|
|
952
|
+
},
|
|
953
|
+
outputShape: siteResultShape,
|
|
954
|
+
handler: async (args, { client, ctx }) => callBillable(client, ctx.approvalToken, `/api/v1/website/sites/${encodeURIComponent(asStr(args.siteId, "siteId"))}/promote`),
|
|
955
|
+
}),
|
|
956
|
+
defineTool({
|
|
957
|
+
name: "capix_website_rollback",
|
|
958
|
+
description: "Roll a website back to its previous production deployment. Billable; requires approval.",
|
|
959
|
+
scope: "website",
|
|
960
|
+
...BILLABLE,
|
|
961
|
+
inputShape: {
|
|
962
|
+
siteId: siteIdShape,
|
|
963
|
+
targetDeploymentId: z.string().optional(),
|
|
964
|
+
},
|
|
965
|
+
outputShape: siteResultShape,
|
|
966
|
+
handler: async (args, { client, ctx }) => callBillable(client, ctx.approvalToken, `/api/v1/website/sites/${encodeURIComponent(asStr(args.siteId, "siteId"))}/rollback`, { targetDeploymentId: args.targetDeploymentId }),
|
|
967
|
+
}),
|
|
968
|
+
defineTool({
|
|
969
|
+
name: "capix_website_get",
|
|
970
|
+
description: "Get a website project descriptor. Read-only.",
|
|
971
|
+
scope: "website",
|
|
972
|
+
...READ_ONLY,
|
|
973
|
+
inputShape: {
|
|
974
|
+
siteId: siteIdShape,
|
|
975
|
+
},
|
|
976
|
+
outputShape: {
|
|
977
|
+
siteId: siteIdShape.optional(),
|
|
978
|
+
name: z.string().optional(),
|
|
979
|
+
url: z.string().optional(),
|
|
980
|
+
framework: z.string().optional(),
|
|
981
|
+
status: z.string().optional(),
|
|
982
|
+
createdAt: iso8601.optional(),
|
|
983
|
+
},
|
|
984
|
+
handler: async (args, { client }) => client.get(`/api/v1/website/sites/${encodeURIComponent(asStr(args.siteId, "siteId"))}`),
|
|
985
|
+
}),
|
|
986
|
+
defineTool({
|
|
987
|
+
name: "capix_website_deployments",
|
|
988
|
+
description: "List deployments for a website. Read-only.",
|
|
989
|
+
scope: "website",
|
|
990
|
+
...READ_ONLY,
|
|
991
|
+
inputShape: {
|
|
992
|
+
siteId: siteIdShape,
|
|
993
|
+
limit: z.number().int().min(1).max(200).default(50),
|
|
994
|
+
},
|
|
995
|
+
outputShape: listResultShape,
|
|
996
|
+
handler: async (args, { client }) => client.get(`/api/v1/website/sites/${encodeURIComponent(asStr(args.siteId, "siteId"))}/deployments`, { limit: args.limit }),
|
|
997
|
+
}),
|
|
998
|
+
defineTool({
|
|
999
|
+
name: "capix_website_logs",
|
|
1000
|
+
description: "Inspect build/runtime logs for a website. Read-only.",
|
|
1001
|
+
scope: "website",
|
|
1002
|
+
...READ_ONLY,
|
|
1003
|
+
inputShape: {
|
|
1004
|
+
siteId: siteIdShape,
|
|
1005
|
+
deploymentId: z.string().optional(),
|
|
1006
|
+
limit: z.number().int().min(1).max(1000).default(200),
|
|
1007
|
+
},
|
|
1008
|
+
outputShape: {
|
|
1009
|
+
lines: z.array(z.record(z.unknown())).optional(),
|
|
1010
|
+
truncated: z.boolean().optional(),
|
|
1011
|
+
},
|
|
1012
|
+
handler: async (args, { client }) => client.get(`/api/v1/website/sites/${encodeURIComponent(asStr(args.siteId, "siteId"))}/logs`, { deploymentId: args.deploymentId, limit: args.limit }),
|
|
1013
|
+
}),
|
|
1014
|
+
defineTool({
|
|
1015
|
+
name: "capix_website_metrics",
|
|
1016
|
+
description: "Inspect request/bandwidth metrics for a website. Read-only.",
|
|
1017
|
+
scope: "website",
|
|
1018
|
+
...READ_ONLY,
|
|
1019
|
+
inputShape: {
|
|
1020
|
+
siteId: siteIdShape,
|
|
1021
|
+
windowMinutes: z.number().int().min(1).max(10080).default(60),
|
|
1022
|
+
},
|
|
1023
|
+
outputShape: {
|
|
1024
|
+
metrics: z.array(z.record(z.unknown())).optional(),
|
|
1025
|
+
},
|
|
1026
|
+
handler: async (args, { client }) => client.get(`/api/v1/website/sites/${encodeURIComponent(asStr(args.siteId, "siteId"))}/metrics`, { windowMinutes: args.windowMinutes }),
|
|
1027
|
+
}),
|
|
1028
|
+
defineTool({
|
|
1029
|
+
name: "capix_website_domain_add",
|
|
1030
|
+
description: "Attach a custom domain to a website. Billable; requires approval.",
|
|
1031
|
+
scope: "website",
|
|
1032
|
+
...BILLABLE,
|
|
1033
|
+
inputShape: {
|
|
1034
|
+
siteId: siteIdShape,
|
|
1035
|
+
domain: z.string(),
|
|
1036
|
+
},
|
|
1037
|
+
outputShape: siteResultShape,
|
|
1038
|
+
handler: async (args, { client, ctx }) => callBillable(client, ctx.approvalToken, `/api/v1/website/sites/${encodeURIComponent(asStr(args.siteId, "siteId"))}/domains`, { domain: asStr(args.domain, "domain") }),
|
|
1039
|
+
}),
|
|
1040
|
+
defineTool({
|
|
1041
|
+
name: "capix_website_domain_verify",
|
|
1042
|
+
description: "Verify DNS ownership for a pending custom domain. Read-only.",
|
|
1043
|
+
scope: "website",
|
|
1044
|
+
...READ_ONLY,
|
|
1045
|
+
inputShape: {
|
|
1046
|
+
siteId: siteIdShape,
|
|
1047
|
+
domain: z.string(),
|
|
1048
|
+
},
|
|
1049
|
+
outputShape: {
|
|
1050
|
+
verified: z.boolean().optional(),
|
|
1051
|
+
records: z.array(z.record(z.unknown())).optional(),
|
|
1052
|
+
reason: z.string().optional(),
|
|
1053
|
+
},
|
|
1054
|
+
handler: async (args, { client }) => client.post(`/api/v1/website/sites/${encodeURIComponent(asStr(args.siteId, "siteId"))}/domains/verify`, { domain: asStr(args.domain, "domain") }),
|
|
1055
|
+
}),
|
|
1056
|
+
defineTool({
|
|
1057
|
+
name: "capix_website_domain_remove",
|
|
1058
|
+
description: "Detach a custom domain from a website. Billable; requires approval.",
|
|
1059
|
+
scope: "website",
|
|
1060
|
+
...BILLABLE,
|
|
1061
|
+
inputShape: {
|
|
1062
|
+
siteId: siteIdShape,
|
|
1063
|
+
domain: z.string(),
|
|
1064
|
+
},
|
|
1065
|
+
outputShape: siteResultShape,
|
|
1066
|
+
handler: async (args, { client, ctx }) => {
|
|
1067
|
+
const res = await callBillable(client, ctx.approvalToken, `/api/v1/website/sites/${encodeURIComponent(asStr(args.siteId, "siteId"))}/domains/${encodeURIComponent(asStr(args.domain, "domain"))}`);
|
|
1068
|
+
return res;
|
|
1069
|
+
},
|
|
1070
|
+
}),
|
|
1071
|
+
defineTool({
|
|
1072
|
+
name: "capix_website_destroy",
|
|
1073
|
+
description: "Destroy a website project and all its deployments. Billable; requires approval.",
|
|
1074
|
+
scope: "website",
|
|
1075
|
+
...BILLABLE,
|
|
1076
|
+
inputShape: {
|
|
1077
|
+
siteId: siteIdShape,
|
|
1078
|
+
reason: z.string().optional(),
|
|
1079
|
+
},
|
|
1080
|
+
outputShape: siteResultShape,
|
|
1081
|
+
handler: async (args, { client, ctx }) => callBillable(client, ctx.approvalToken, `/api/v1/website/sites/${encodeURIComponent(asStr(args.siteId, "siteId"))}/destroy`, args.reason ? { reason: args.reason } : undefined),
|
|
1082
|
+
}),
|
|
1083
|
+
];
|
|
1084
|
+
// ===========================================================================
|
|
1085
|
+
// Aggregate export
|
|
1086
|
+
// ===========================================================================
|
|
1087
|
+
export const TOOLS = [
|
|
1088
|
+
...discoveryTools,
|
|
1089
|
+
...planningTools,
|
|
1090
|
+
...lifecycleTools,
|
|
1091
|
+
...networkingTools,
|
|
1092
|
+
...testingTools,
|
|
1093
|
+
...verificationTools,
|
|
1094
|
+
...websiteTools,
|
|
1095
|
+
];
|
|
1096
|
+
export const TOOL_NAMES = TOOLS.map((t) => t.name);
|
|
1097
|
+
export const TOOL_COUNT = TOOLS.length;
|
|
1098
|
+
/** Map of tool name → definition, used by the server for O(1) lookup. */
|
|
1099
|
+
export const TOOL_MAP = new Map(TOOLS.map((t) => [t.name, t]));
|
|
1100
|
+
export { discoveryTools, planningTools, lifecycleTools, networkingTools, testingTools, verificationTools, websiteTools };
|
|
1101
|
+
//# sourceMappingURL=tools.js.map
|