capix-mcp 2.1.1 → 2.2.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/README.md +51 -72
- package/dist/prompts.d.ts +6 -1
- package/dist/prompts.d.ts.map +1 -1
- package/dist/prompts.js +41 -75
- package/dist/prompts.js.map +1 -1
- package/dist/route-families.d.ts +47 -0
- package/dist/route-families.d.ts.map +1 -0
- package/dist/route-families.js +96 -0
- package/dist/route-families.js.map +1 -0
- package/dist/server.d.ts +5 -5
- package/dist/server.js +8 -8
- package/dist/server.js.map +1 -1
- package/dist/tools/define-tool.d.ts +6 -0
- package/dist/tools/define-tool.d.ts.map +1 -1
- package/dist/tools/define-tool.js +1 -0
- package/dist/tools/define-tool.js.map +1 -1
- package/dist/tools/factory.d.ts +42 -0
- package/dist/tools/factory.d.ts.map +1 -0
- package/dist/tools/factory.js +363 -0
- package/dist/tools/factory.js.map +1 -0
- package/dist/tools/generate.d.ts +108 -0
- package/dist/tools/generate.d.ts.map +1 -0
- package/dist/tools/generate.js +149 -0
- package/dist/tools/generate.js.map +1 -0
- package/dist/tools/infra-context.d.ts +15 -11
- package/dist/tools/infra-context.d.ts.map +1 -1
- package/dist/tools/infra-context.js +43 -92
- package/dist/tools/infra-context.js.map +1 -1
- package/dist/tools/memes.d.ts +31 -0
- package/dist/tools/memes.d.ts.map +1 -0
- package/dist/tools/memes.js +175 -0
- package/dist/tools/memes.js.map +1 -0
- package/dist/tools.d.ts +47 -7
- package/dist/tools.d.ts.map +1 -1
- package/dist/tools.js +341 -891
- package/dist/tools.js.map +1 -1
- package/dist/types.d.ts +17 -2
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +0 -2
- package/dist/types.js.map +1 -1
- package/package.json +3 -3
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generate.d.ts","sourceRoot":"","sources":["../../src/tools/generate.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,KAAK,EAAE,OAAO,EAAY,SAAS,EAAE,MAAM,aAAa,CAAC;AAMhE,wDAAwD;AACxD,MAAM,MAAM,eAAe,GAAG,KAAK,GAAG,MAAM,GAAG,QAAQ,CAAC;AAExD;;;GAGG;AACH,MAAM,WAAW,iBAAiB,CAAC,CAAC,SAAS,CAAC,CAAC,WAAW;IACxD,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,SAAS,CAAC;IACjB,yEAAyE;IACzE,QAAQ,EAAE,OAAO,CAAC;IAClB,uEAAuE;IACvE,gBAAgB,EAAE,OAAO,CAAC;IAC1B,wDAAwD;IACxD,MAAM,EAAE,eAAe,CAAC;IACxB;;;;;OAKG;IACH,IAAI,EAAE,MAAM,CAAC;IACb;;;OAGG;IACH,KAAK,EAAE,CAAC,CAAC;IACT;;;;OAIG;IACH,KAAK,CAAC,EAAE,SAAS,CAAC,MAAM,CAAC,GAAG,MAAM,CAAC,EAAE,CAAC;IACtC;;;;;;OAMG;IACH,IAAI,CAAC,EAAE,SAAS,CAAC,MAAM,CAAC,GAAG,MAAM,CAAC,EAAE,CAAC;IACrC;;;;OAIG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,wEAAwE;IACxE,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,UAAU,CAAC,CAAC;IAC3C;;;;;;;OAOG;IACH,SAAS,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAC1E;AAMD,8DAA8D;AAC9D,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CAKnD;AAqBD;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,CAAC,SAAS,CAAC,CAAC,WAAW,EAAE,IAAI,EAAE,iBAAiB,CAAC,CAAC,CAAC,GAAG,OAAO,CAyGhG"}
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Capix MCP Server — declarative tool generator.
|
|
3
|
+
*
|
|
4
|
+
* The generation pattern adapted here — declare method + path + input schema
|
|
5
|
+
* ONCE in a tool spec, then derive both the MCP tool registration and the
|
|
6
|
+
* HTTP dispatch from that single declaration — follows the route-registry
|
|
7
|
+
* approach of OpenShip (https://github.com/oblien/openship),
|
|
8
|
+
* apps/api/src/modules/mcp/ (mcp-tools.ts / mcp-dispatch.ts).
|
|
9
|
+
* Copyright the OpenShip contributors, licensed under the Apache License 2.0.
|
|
10
|
+
* See the NOTICE file at the repository root. Only the pattern is adapted;
|
|
11
|
+
* this implementation is original and specific to the Capix control plane.
|
|
12
|
+
*
|
|
13
|
+
* Why this exists: hand-written tools drift when the control-plane API
|
|
14
|
+
* changes. A generated tool keeps the endpoint declaration (method, canonical
|
|
15
|
+
* `/api/v1/*` path, typed Zod input) co-located with the registration, so the
|
|
16
|
+
* MCP surface and the HTTP call can never disagree.
|
|
17
|
+
*
|
|
18
|
+
* The generator enforces the repo's existing control-plane conventions:
|
|
19
|
+
*
|
|
20
|
+
* - problem passthrough — the handler delegates to the shared CapixClient,
|
|
21
|
+
* which parses non-2xx responses as problem+json (RFC 9457, which
|
|
22
|
+
* obsoletes RFC 7807) and throws CapixApiError; the generator never
|
|
23
|
+
* catches or rewrites it, so problem details reach the server wrapper
|
|
24
|
+
* (server.ts errorResult) untouched.
|
|
25
|
+
* - idempotency — mutation specs (billable / requiresApproval POST or
|
|
26
|
+
* DELETE) route through the client's existing Idempotency-Key helper
|
|
27
|
+
* (client.post(..., { idempotent: true }) / client.delete), reusing the
|
|
28
|
+
* path+body-hash key derivation in client.ts rather than re-inventing it.
|
|
29
|
+
* - typed inputs — inputs are declared as a Zod raw shape, validated
|
|
30
|
+
* by the McpServer before dispatch, exactly like defineTool.
|
|
31
|
+
* - approval gate — billable / requiresApproval specs throw the same
|
|
32
|
+
* `approval_required` (402) error shape as callBillable in tools.ts when
|
|
33
|
+
* no approvalToken is bound.
|
|
34
|
+
* - payload truncation — an optional `transform` post-processes successful
|
|
35
|
+
* responses so oversized inline artifacts (SVG, base64) are reduced to a
|
|
36
|
+
* pointer (share URL / id) before they reach the agent's context.
|
|
37
|
+
*/
|
|
38
|
+
// ===========================================================================
|
|
39
|
+
// Generator
|
|
40
|
+
// ===========================================================================
|
|
41
|
+
/** Extract `:param` names from a canonical path, in order. */
|
|
42
|
+
export function pathParamsOf(path) {
|
|
43
|
+
return path
|
|
44
|
+
.split("/")
|
|
45
|
+
.filter((s) => s.startsWith(":"))
|
|
46
|
+
.map((s) => s.slice(1));
|
|
47
|
+
}
|
|
48
|
+
/** Throw the repo-standard approval error (same shape as callBillable). */
|
|
49
|
+
function approvalRequiredError() {
|
|
50
|
+
const err = new Error("approvalToken is required for this billable tool (§5)");
|
|
51
|
+
err.capixCode = "approval_required";
|
|
52
|
+
err.status = 402;
|
|
53
|
+
return err;
|
|
54
|
+
}
|
|
55
|
+
/** Throw the repo-standard invalid-argument error (same shape as asStr). */
|
|
56
|
+
function invalidArgumentError(field) {
|
|
57
|
+
const err = new Error(`${field} is required`);
|
|
58
|
+
err.capixCode = "invalid_argument";
|
|
59
|
+
err.status = 400;
|
|
60
|
+
return err;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Generate a ToolDef from a declarative spec. The returned definition is a
|
|
64
|
+
* plain ToolDef — indistinguishable from a defineTool declaration to the
|
|
65
|
+
* server, the registry, and the annotations layer.
|
|
66
|
+
*/
|
|
67
|
+
export function defineGeneratedTool(spec) {
|
|
68
|
+
const pathParams = pathParamsOf(spec.path);
|
|
69
|
+
// Declaration-time enforcement: every path param must be a declared input,
|
|
70
|
+
// so a spec can never reference a path segment the caller cannot supply.
|
|
71
|
+
for (const param of pathParams) {
|
|
72
|
+
if (!(param in spec.input)) {
|
|
73
|
+
throw new Error(`defineGeneratedTool(${spec.name}): path param :${param} is not declared in the input shape`);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
if (spec.method === "GET" && spec.body) {
|
|
77
|
+
throw new Error(`defineGeneratedTool(${spec.name}): GET tools cannot declare a request body`);
|
|
78
|
+
}
|
|
79
|
+
const pathParamSet = new Set(pathParams);
|
|
80
|
+
const nonPathKeys = Object.keys(spec.input).filter((k) => !pathParamSet.has(k));
|
|
81
|
+
const queryKeys = spec.query ?? (spec.method === "GET" ? nonPathKeys : []);
|
|
82
|
+
const bodyKeys = spec.body ?? (spec.method === "POST" ? nonPathKeys : []);
|
|
83
|
+
const idempotent = spec.idempotent ?? (spec.method !== "GET" && (spec.billable || spec.requiresApproval));
|
|
84
|
+
const needsApproval = spec.billable || spec.requiresApproval;
|
|
85
|
+
const handler = async (rawArgs, { client, ctx }) => {
|
|
86
|
+
// Approval gate — mirrors callBillable in tools.ts. The server wrapper
|
|
87
|
+
// also gates before dispatch; this keeps the invariant when a handler is
|
|
88
|
+
// invoked directly (tests, future transports).
|
|
89
|
+
if (needsApproval && !ctx.approvalToken)
|
|
90
|
+
throw approvalRequiredError();
|
|
91
|
+
// Fill path params (URL-encoded), failing closed on empty values.
|
|
92
|
+
let path = spec.path;
|
|
93
|
+
for (const param of pathParams) {
|
|
94
|
+
const value = rawArgs[param];
|
|
95
|
+
if (value === undefined || value === null || `${value}` === "") {
|
|
96
|
+
throw invalidArgumentError(param);
|
|
97
|
+
}
|
|
98
|
+
path = path.replace(`:${param}`, encodeURIComponent(String(value)));
|
|
99
|
+
}
|
|
100
|
+
// Success-path post-processing (e.g. payload truncation); problem
|
|
101
|
+
// passthrough is untouched because this never wraps a throw.
|
|
102
|
+
const finish = (result) => spec.transform ? spec.transform(result) : result;
|
|
103
|
+
if (spec.method === "GET") {
|
|
104
|
+
const params = {};
|
|
105
|
+
for (const key of queryKeys)
|
|
106
|
+
params[key] = rawArgs[key];
|
|
107
|
+
return finish(await client.get(path, queryKeys.length > 0 ? params : undefined));
|
|
108
|
+
}
|
|
109
|
+
if (spec.method === "DELETE") {
|
|
110
|
+
// client.delete always derives an Idempotency-Key from the path.
|
|
111
|
+
return finish(await client.delete(path));
|
|
112
|
+
}
|
|
113
|
+
// POST: assemble the body from the declared body keys, dropping undefined
|
|
114
|
+
// fields. When nothing has a value, send no body at all (hand-written
|
|
115
|
+
// convention).
|
|
116
|
+
let body;
|
|
117
|
+
if (bodyKeys.length > 0) {
|
|
118
|
+
const assembled = {};
|
|
119
|
+
for (const key of bodyKeys) {
|
|
120
|
+
if (rawArgs[key] !== undefined)
|
|
121
|
+
assembled[key] = rawArgs[key];
|
|
122
|
+
}
|
|
123
|
+
body = Object.keys(assembled).length > 0 ? assembled : undefined;
|
|
124
|
+
}
|
|
125
|
+
if (!idempotent && !needsApproval) {
|
|
126
|
+
// Read-only POST (quote/plan/validate): no idempotency key, no approval
|
|
127
|
+
// header — identical to the hand-written `client.post(path, args)`.
|
|
128
|
+
return finish(await client.post(path, body));
|
|
129
|
+
}
|
|
130
|
+
return finish(await client.post(path, body, {
|
|
131
|
+
...(idempotent ? { idempotent: true } : {}),
|
|
132
|
+
...(needsApproval ? { approvalToken: ctx.approvalToken } : {}),
|
|
133
|
+
}));
|
|
134
|
+
};
|
|
135
|
+
return {
|
|
136
|
+
name: spec.name,
|
|
137
|
+
description: spec.description,
|
|
138
|
+
scope: spec.scope,
|
|
139
|
+
billable: spec.billable,
|
|
140
|
+
requiresApproval: spec.requiresApproval,
|
|
141
|
+
routePath: spec.path,
|
|
142
|
+
inputShape: spec.input,
|
|
143
|
+
outputShape: spec.outputShape,
|
|
144
|
+
// Sound cast: same guarantee as defineTool — the McpServer validates args
|
|
145
|
+
// against inputShape before the handler runs.
|
|
146
|
+
handler: handler,
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
//# sourceMappingURL=generate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generate.js","sourceRoot":"","sources":["../../src/tools/generate.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,17 +1,21 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Capix MCP Server — infra-context tools (
|
|
2
|
+
* Capix MCP Server — infra-context tools (2).
|
|
3
3
|
*
|
|
4
|
-
* Read-only live views over the customer's Capix infrastructure footprint
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
* `/api/v1/*` routes through the shared Capix client.
|
|
4
|
+
* Read-only live views over the customer's Capix infrastructure footprint.
|
|
5
|
+
* Every tool is read-only — safe to auto-run after authentication — and
|
|
6
|
+
* delegates to a canonical `/api/v1/*` route that EXISTS in the control
|
|
7
|
+
* plane (verified 2026-07; see ../route-families.ts):
|
|
9
8
|
*
|
|
10
|
-
* capix_marketplace_browse live GPU
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
9
|
+
* capix_marketplace_browse GET /api/v1/marketplace/offers live GPU offers (public)
|
|
10
|
+
* capix_model_list GET /api/v1/models deployable model catalog
|
|
11
|
+
*
|
|
12
|
+
* Removed in the 2026-07 repair (no backing route in the control plane):
|
|
13
|
+
* capix_node_status — there is no /api/v1/nodes/status (only
|
|
14
|
+
* nodes/[id]/earnings and nodes/[id]/conformance)
|
|
15
|
+
* capix_earnings_check — there is no /api/v1/earnings aggregate route
|
|
16
|
+
* capix_deployment_list — duplicated capix_deployments once both were
|
|
17
|
+
* aligned to the real GET /api/v1/deployments
|
|
18
|
+
* contract (status/cursor/limit, no phase/include)
|
|
15
19
|
*
|
|
16
20
|
* This module shares `defineTool` with the aggregate registry in ../tools.ts
|
|
17
21
|
* via ./define-tool.js (a leaf module), so there is no import cycle. The
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"infra-context.d.ts","sourceRoot":"","sources":["../../src/tools/infra-context.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"infra-context.d.ts","sourceRoot":"","sources":["../../src/tools/infra-context.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAMH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAkB3C,eAAO,MAAM,iBAAiB,EAAE,OAAO,EAkDtC,CAAC;AAEF,eAAO,MAAM,wBAAwB,EAAE,MAAM,EAAyC,CAAC"}
|
|
@@ -1,17 +1,21 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Capix MCP Server — infra-context tools (
|
|
2
|
+
* Capix MCP Server — infra-context tools (2).
|
|
3
3
|
*
|
|
4
|
-
* Read-only live views over the customer's Capix infrastructure footprint
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
* `/api/v1/*` routes through the shared Capix client.
|
|
4
|
+
* Read-only live views over the customer's Capix infrastructure footprint.
|
|
5
|
+
* Every tool is read-only — safe to auto-run after authentication — and
|
|
6
|
+
* delegates to a canonical `/api/v1/*` route that EXISTS in the control
|
|
7
|
+
* plane (verified 2026-07; see ../route-families.ts):
|
|
9
8
|
*
|
|
10
|
-
* capix_marketplace_browse live GPU
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
9
|
+
* capix_marketplace_browse GET /api/v1/marketplace/offers live GPU offers (public)
|
|
10
|
+
* capix_model_list GET /api/v1/models deployable model catalog
|
|
11
|
+
*
|
|
12
|
+
* Removed in the 2026-07 repair (no backing route in the control plane):
|
|
13
|
+
* capix_node_status — there is no /api/v1/nodes/status (only
|
|
14
|
+
* nodes/[id]/earnings and nodes/[id]/conformance)
|
|
15
|
+
* capix_earnings_check — there is no /api/v1/earnings aggregate route
|
|
16
|
+
* capix_deployment_list — duplicated capix_deployments once both were
|
|
17
|
+
* aligned to the real GET /api/v1/deployments
|
|
18
|
+
* contract (status/cursor/limit, no phase/include)
|
|
15
19
|
*
|
|
16
20
|
* This module shares `defineTool` with the aggregate registry in ../tools.ts
|
|
17
21
|
* via ./define-tool.js (a leaf module), so there is no import cycle. The
|
|
@@ -20,119 +24,66 @@
|
|
|
20
24
|
*/
|
|
21
25
|
import { z } from "zod";
|
|
22
26
|
import { defineTool } from "./define-tool.js";
|
|
27
|
+
import { defineGeneratedTool } from "./generate.js";
|
|
23
28
|
import { READ_ONLY } from "../types.js";
|
|
24
29
|
// ===========================================================================
|
|
25
30
|
// Local Zod fragments (mirror tools.ts — keep in sync)
|
|
26
31
|
// ===========================================================================
|
|
27
32
|
const iso8601 = z.string().datetime().or(z.string());
|
|
28
|
-
const moneyShape = z.object({
|
|
29
|
-
amount: z.string().describe("Integer minor units (e.g. lamports, micro-USDC, cents)."),
|
|
30
|
-
asset: z.enum(["SOL", "USDC", "USD-credit"]),
|
|
31
|
-
scale: z.number().int(),
|
|
32
|
-
}).describe("Integer minor/native money amount serialized as a JSON string.");
|
|
33
|
-
const deploymentIdShape = z.string().describe("Canonical deployment id (dep_…).");
|
|
34
33
|
const listResultShape = {
|
|
35
34
|
entries: z.array(z.record(z.unknown())).optional().describe("Paginated item array."),
|
|
36
35
|
nextCursor: z.string().optional().describe("Opaque cursor for the next page; absent when exhausted."),
|
|
37
36
|
fetchedAt: iso8601.optional().describe("ISO8601 fetch timestamp."),
|
|
38
37
|
};
|
|
39
38
|
// ===========================================================================
|
|
40
|
-
// Infra-context tools (
|
|
39
|
+
// Infra-context tools (2) — read-only infra visibility for agents.
|
|
41
40
|
// ===========================================================================
|
|
42
41
|
export const infraContextTools = [
|
|
43
42
|
defineTool({
|
|
44
43
|
name: "capix_marketplace_browse",
|
|
45
|
-
description: "Browse live GPU marketplace offers (
|
|
44
|
+
description: "Browse live GPU marketplace offers (provider-anonymized: region, trust tier, capability, price/hr, health score). Read-only.",
|
|
46
45
|
scope: "infra-context",
|
|
47
46
|
...READ_ONLY,
|
|
47
|
+
routePath: "/api/v1/marketplace/offers",
|
|
48
48
|
inputShape: {
|
|
49
|
-
|
|
49
|
+
gpuModel: z.string().optional().describe("Optional GPU model filter (e.g. A100, H100)."),
|
|
50
50
|
region: z.string().optional().describe("Optional region filter."),
|
|
51
|
-
|
|
51
|
+
trustTier: z
|
|
52
|
+
.enum(["community", "verified", "sovereign"])
|
|
53
|
+
.optional()
|
|
54
|
+
.describe("Optional trust tier filter."),
|
|
55
|
+
capability: z
|
|
56
|
+
.enum(["cpu", "gpu", "gpu_high_mem", "secure_enclave", "quantum_sim"])
|
|
57
|
+
.optional()
|
|
58
|
+
.describe("Optional capability filter."),
|
|
59
|
+
limit: z.number().int().min(1).max(200).default(50).describe("Max offers to return (upstream bounds)."),
|
|
60
|
+
cursor: z.string().optional().describe("Opaque pagination cursor from a previous page."),
|
|
52
61
|
},
|
|
53
62
|
outputShape: listResultShape,
|
|
54
63
|
handler: async (args, { client }) => client.get("/api/v1/marketplace/offers", {
|
|
55
|
-
|
|
64
|
+
gpuModel: args.gpuModel,
|
|
56
65
|
region: args.region,
|
|
66
|
+
trustTier: args.trustTier,
|
|
67
|
+
capability: args.capability,
|
|
57
68
|
limit: args.limit,
|
|
69
|
+
cursor: args.cursor,
|
|
58
70
|
}),
|
|
59
71
|
}),
|
|
60
|
-
|
|
61
|
-
name: "capix_node_status",
|
|
62
|
-
description: "Show liveness and health for every node across the account's deployments. Read-only.",
|
|
63
|
-
scope: "infra-context",
|
|
64
|
-
...READ_ONLY,
|
|
65
|
-
inputShape: {
|
|
66
|
-
deploymentId: deploymentIdShape.optional().describe("Optional deployment filter."),
|
|
67
|
-
},
|
|
68
|
-
outputShape: {
|
|
69
|
-
...listResultShape,
|
|
70
|
-
summary: z
|
|
71
|
-
.object({
|
|
72
|
-
total: z.number().int().optional(),
|
|
73
|
-
online: z.number().int().optional(),
|
|
74
|
-
offline: z.number().int().optional(),
|
|
75
|
-
})
|
|
76
|
-
.optional()
|
|
77
|
-
.describe("Aggregate liveness counts across the returned nodes."),
|
|
78
|
-
},
|
|
79
|
-
handler: async (args, { client }) => client.get("/api/v1/nodes/status", {
|
|
80
|
-
deploymentId: args.deploymentId,
|
|
81
|
-
}),
|
|
82
|
-
}),
|
|
83
|
-
defineTool({
|
|
84
|
-
name: "capix_earnings_check",
|
|
85
|
-
description: "Check the earnings dashboard: wallet balance, total spend, active deployments and dev-token earnings. Read-only.",
|
|
86
|
-
scope: "infra-context",
|
|
87
|
-
...READ_ONLY,
|
|
88
|
-
inputShape: {},
|
|
89
|
-
outputShape: {
|
|
90
|
-
wallet: moneyShape.optional(),
|
|
91
|
-
totalSpent: moneyShape.optional(),
|
|
92
|
-
activeDeployments: z.number().int().optional(),
|
|
93
|
-
devTokenBalance: z.number().optional(),
|
|
94
|
-
devTokenTotalEarned: z.number().optional(),
|
|
95
|
-
asOf: iso8601.optional(),
|
|
96
|
-
},
|
|
97
|
-
handler: async (_args, { client }) => client.get("/api/v1/earnings"),
|
|
98
|
-
}),
|
|
99
|
-
defineTool({
|
|
72
|
+
defineGeneratedTool({
|
|
100
73
|
name: "capix_model_list",
|
|
101
|
-
description: "List deployable models
|
|
74
|
+
description: "List deployable models: the public Capix catalog plus the caller's ready private " +
|
|
75
|
+
"endpoints (id, label, category, context window, pricing, availability). Read-only.",
|
|
102
76
|
scope: "infra-context",
|
|
103
77
|
...READ_ONLY,
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
78
|
+
method: "GET",
|
|
79
|
+
path: "/api/v1/models",
|
|
80
|
+
input: {
|
|
81
|
+
projectId: z.string().optional().describe("Optional project id (the only query param the route accepts)."),
|
|
107
82
|
},
|
|
108
83
|
outputShape: {
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
},
|
|
112
|
-
handler: async (args, { client }) => client.get("/api/v1/models", {
|
|
113
|
-
category: args.category,
|
|
114
|
-
limit: args.limit,
|
|
115
|
-
}),
|
|
116
|
-
}),
|
|
117
|
-
defineTool({
|
|
118
|
-
name: "capix_deployment_list",
|
|
119
|
-
description: "List the deployment inventory with live status, health and hourly cost. Read-only.",
|
|
120
|
-
scope: "infra-context",
|
|
121
|
-
...READ_ONLY,
|
|
122
|
-
inputShape: {
|
|
123
|
-
limit: z.number().int().min(1).max(200).default(50).describe("Max deployments to return."),
|
|
124
|
-
phase: z.string().optional().describe("Optional DeploymentPhase filter."),
|
|
125
|
-
includeNodes: z
|
|
126
|
-
.boolean()
|
|
127
|
-
.default(false)
|
|
128
|
-
.describe("When true, embed per-node health for each deployment."),
|
|
84
|
+
models: z.array(z.record(z.unknown())).optional(),
|
|
85
|
+
projectId: z.string().optional(),
|
|
129
86
|
},
|
|
130
|
-
outputShape: listResultShape,
|
|
131
|
-
handler: async (args, { client }) => client.get("/api/v1/deployments", {
|
|
132
|
-
limit: args.limit,
|
|
133
|
-
phase: args.phase,
|
|
134
|
-
include: args.includeNodes ? "nodes,health" : undefined,
|
|
135
|
-
}),
|
|
136
87
|
}),
|
|
137
88
|
];
|
|
138
89
|
export const INFRA_CONTEXT_TOOL_NAMES = infraContextTools.map((t) => t.name);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"infra-context.js","sourceRoot":"","sources":["../../src/tools/infra-context.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"infra-context.js","sourceRoot":"","sources":["../../src/tools/infra-context.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Capix MCP Server — meme + image generation tools (3).
|
|
3
|
+
*
|
|
4
|
+
* Thin wrappers over the control-plane content routes (see
|
|
5
|
+
* app/api/v1/memes/route.ts and app/api/v1/images/route.ts in the protocol
|
|
6
|
+
* repo):
|
|
7
|
+
*
|
|
8
|
+
* capix_meme POST /api/v1/memes generate a meme (billable)
|
|
9
|
+
* capix_image_gen POST /api/v1/images text-to-image (billable)
|
|
10
|
+
* capix_meme_templates GET /api/v1/memes template/vibe catalog (read-only)
|
|
11
|
+
*
|
|
12
|
+
* All three are declared with `defineGeneratedTool` (./generate.ts), so the
|
|
13
|
+
* registration and the HTTP dispatch share one spec. The two POSTs are real
|
|
14
|
+
* money-moving mutations — they inherit the generator's defaults for billable
|
|
15
|
+
* specs: an Idempotency-Key derived from path+body and the bound
|
|
16
|
+
* approvalToken header, matching the routes' `Idempotency-Key` requirement.
|
|
17
|
+
*
|
|
18
|
+
* Payload truncation: both POST responses carry large inline artifacts
|
|
19
|
+
* (`svg` markup for memes, `base64` rasters for images). The `transform`
|
|
20
|
+
* hook replaces each artifact with a short omission pointer (share URL /
|
|
21
|
+
* id + the canonical GET /api/v1/memes/:id retrieval route) so the payload
|
|
22
|
+
* itself never floods the agent's context. Captions, prompt, and the
|
|
23
|
+
* `charge` object pass through untouched.
|
|
24
|
+
*
|
|
25
|
+
* This module shares `defineGeneratedTool` with the aggregate registry in
|
|
26
|
+
* ../tools.ts via ./generate.js (a leaf module), so there is no import cycle.
|
|
27
|
+
*/
|
|
28
|
+
import type { ToolDef } from "../types.js";
|
|
29
|
+
export declare const memeImageTools: ToolDef[];
|
|
30
|
+
export declare const MEME_IMAGE_TOOL_NAMES: string[];
|
|
31
|
+
//# sourceMappingURL=memes.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"memes.d.ts","sourceRoot":"","sources":["../../src/tools/memes.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAKH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAmE3C,eAAO,MAAM,cAAc,EAAE,OAAO,EAwFnC,CAAC;AAEF,eAAO,MAAM,qBAAqB,EAAE,MAAM,EAAsC,CAAC"}
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Capix MCP Server — meme + image generation tools (3).
|
|
3
|
+
*
|
|
4
|
+
* Thin wrappers over the control-plane content routes (see
|
|
5
|
+
* app/api/v1/memes/route.ts and app/api/v1/images/route.ts in the protocol
|
|
6
|
+
* repo):
|
|
7
|
+
*
|
|
8
|
+
* capix_meme POST /api/v1/memes generate a meme (billable)
|
|
9
|
+
* capix_image_gen POST /api/v1/images text-to-image (billable)
|
|
10
|
+
* capix_meme_templates GET /api/v1/memes template/vibe catalog (read-only)
|
|
11
|
+
*
|
|
12
|
+
* All three are declared with `defineGeneratedTool` (./generate.ts), so the
|
|
13
|
+
* registration and the HTTP dispatch share one spec. The two POSTs are real
|
|
14
|
+
* money-moving mutations — they inherit the generator's defaults for billable
|
|
15
|
+
* specs: an Idempotency-Key derived from path+body and the bound
|
|
16
|
+
* approvalToken header, matching the routes' `Idempotency-Key` requirement.
|
|
17
|
+
*
|
|
18
|
+
* Payload truncation: both POST responses carry large inline artifacts
|
|
19
|
+
* (`svg` markup for memes, `base64` rasters for images). The `transform`
|
|
20
|
+
* hook replaces each artifact with a short omission pointer (share URL /
|
|
21
|
+
* id + the canonical GET /api/v1/memes/:id retrieval route) so the payload
|
|
22
|
+
* itself never floods the agent's context. Captions, prompt, and the
|
|
23
|
+
* `charge` object pass through untouched.
|
|
24
|
+
*
|
|
25
|
+
* This module shares `defineGeneratedTool` with the aggregate registry in
|
|
26
|
+
* ../tools.ts via ./generate.js (a leaf module), so there is no import cycle.
|
|
27
|
+
*/
|
|
28
|
+
import { z } from "zod";
|
|
29
|
+
import { defineGeneratedTool } from "./generate.js";
|
|
30
|
+
import { BILLABLE, READ_ONLY } from "../types.js";
|
|
31
|
+
// ===========================================================================
|
|
32
|
+
// Local Zod fragments (mirror tools.ts — keep in sync)
|
|
33
|
+
// ===========================================================================
|
|
34
|
+
/**
|
|
35
|
+
* Charge envelope returned by the meme/image routes: either a settled
|
|
36
|
+
* balance charge (integer minor units as a string) or a free-tier grant.
|
|
37
|
+
*/
|
|
38
|
+
const chargeShape = z
|
|
39
|
+
.object({
|
|
40
|
+
kind: z.enum(["free", "balance"]).optional(),
|
|
41
|
+
amountMinor: z
|
|
42
|
+
.string()
|
|
43
|
+
.optional()
|
|
44
|
+
.describe("Integer minor units charged, serialized as a string."),
|
|
45
|
+
asset: z.string().optional(),
|
|
46
|
+
scale: z.number().int().optional(),
|
|
47
|
+
freeUsedToday: z.number().int().optional(),
|
|
48
|
+
freePerDay: z.number().int().optional(),
|
|
49
|
+
})
|
|
50
|
+
.describe("Settled charge for the generation (balance debit or free-tier grant).");
|
|
51
|
+
/** Caption voices accepted by POST /api/v1/memes (MEME_VIBES upstream). */
|
|
52
|
+
const MEME_VIBE_VALUES = ["degen", "pump", "bagholder", "unhinged", "dev", "spicy"];
|
|
53
|
+
// ===========================================================================
|
|
54
|
+
// Payload truncation (transform hooks)
|
|
55
|
+
// ===========================================================================
|
|
56
|
+
/** Replace an oversized inline payload with a short omission pointer. */
|
|
57
|
+
function omitPayload(payload, pointer) {
|
|
58
|
+
return `[omitted ${payload.length} chars — ${pointer}]`;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Swap the inline meme SVG for a pointer to the share page / canonical
|
|
62
|
+
* retrieval route. Everything else (captions, charge, ids) passes through.
|
|
63
|
+
*/
|
|
64
|
+
function truncateMemeResponse(res) {
|
|
65
|
+
if (typeof res.svg !== "string")
|
|
66
|
+
return res;
|
|
67
|
+
const memeId = typeof res.memeId === "string" ? res.memeId : "unknown";
|
|
68
|
+
const shareUrl = typeof res.shareUrl === "string" ? res.shareUrl : undefined;
|
|
69
|
+
const pointer = shareUrl
|
|
70
|
+
? `view at ${shareUrl} or fetch via GET /api/v1/memes/${memeId}`
|
|
71
|
+
: `fetch via GET /api/v1/memes/${memeId}`;
|
|
72
|
+
return { ...res, svg: omitPayload(res.svg, pointer) };
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Swap the inline base64 raster for a pointer to the image id. The image is
|
|
76
|
+
* persisted server-side and retrievable via GET /api/v1/memes/:id.
|
|
77
|
+
*/
|
|
78
|
+
function truncateImageResponse(res) {
|
|
79
|
+
if (typeof res.base64 !== "string")
|
|
80
|
+
return res;
|
|
81
|
+
const imageId = typeof res.imageId === "string" ? res.imageId : "unknown";
|
|
82
|
+
return {
|
|
83
|
+
...res,
|
|
84
|
+
base64: omitPayload(res.base64, `imageId ${imageId} — fetch via GET /api/v1/memes/${imageId}`),
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
// ===========================================================================
|
|
88
|
+
// Meme + image tools (3)
|
|
89
|
+
// ===========================================================================
|
|
90
|
+
export const memeImageTools = [
|
|
91
|
+
defineGeneratedTool({
|
|
92
|
+
name: "capix_meme",
|
|
93
|
+
description: "Generate a meme from a topic: template captions, or a fully AI-generated canvas image. " +
|
|
94
|
+
"The account gets a small free daily allowance, then a fixed balance charge; omitting " +
|
|
95
|
+
"templateId (or passing \"ai-canvas\") generates the image with AI at 2x the template " +
|
|
96
|
+
"price. Returns the meme id, captions, shareUrl, and the settled charge; the inline SVG " +
|
|
97
|
+
"is replaced with a pointer to the share URL. Billable; requires approval.",
|
|
98
|
+
scope: "lifecycle",
|
|
99
|
+
...BILLABLE,
|
|
100
|
+
method: "POST",
|
|
101
|
+
path: "/api/v1/memes",
|
|
102
|
+
input: {
|
|
103
|
+
topic: z.string().min(1).describe("What the meme is about."),
|
|
104
|
+
vibe: z
|
|
105
|
+
.enum(MEME_VIBE_VALUES)
|
|
106
|
+
.optional()
|
|
107
|
+
.describe("Caption voice (see capix_meme_templates for the live catalog)."),
|
|
108
|
+
templateId: z
|
|
109
|
+
.string()
|
|
110
|
+
.optional()
|
|
111
|
+
.describe("Template id from capix_meme_templates. Omit (or pass \"ai-canvas\") for a fully " +
|
|
112
|
+
"AI-generated image at 2x the template price."),
|
|
113
|
+
},
|
|
114
|
+
outputShape: {
|
|
115
|
+
memeId: z.string().optional(),
|
|
116
|
+
svg: z
|
|
117
|
+
.string()
|
|
118
|
+
.optional()
|
|
119
|
+
.describe("Omission pointer — the full SVG is at shareUrl / GET /api/v1/memes/:id."),
|
|
120
|
+
caption: z.string().optional(),
|
|
121
|
+
captions: z.record(z.string()).optional(),
|
|
122
|
+
templateId: z.string().optional(),
|
|
123
|
+
vibe: z.string().optional(),
|
|
124
|
+
mode: z.string().optional(),
|
|
125
|
+
shareUrl: z.string().optional(),
|
|
126
|
+
charge: chargeShape.optional(),
|
|
127
|
+
},
|
|
128
|
+
transform: truncateMemeResponse,
|
|
129
|
+
}),
|
|
130
|
+
defineGeneratedTool({
|
|
131
|
+
name: "capix_image_gen",
|
|
132
|
+
description: "Generate an image from a text prompt (fixed per-image balance charge, no free tier). " +
|
|
133
|
+
"Returns the image id, content type, and the settled charge; the base64 payload is " +
|
|
134
|
+
"replaced with a pointer to the retrievable image id. Billable; requires approval.",
|
|
135
|
+
scope: "lifecycle",
|
|
136
|
+
...BILLABLE,
|
|
137
|
+
method: "POST",
|
|
138
|
+
path: "/api/v1/images",
|
|
139
|
+
input: {
|
|
140
|
+
prompt: z
|
|
141
|
+
.string()
|
|
142
|
+
.min(2)
|
|
143
|
+
.max(1000)
|
|
144
|
+
.describe("Image prompt (2–1000 characters, per the control-plane limit)."),
|
|
145
|
+
},
|
|
146
|
+
outputShape: {
|
|
147
|
+
imageId: z.string().optional(),
|
|
148
|
+
base64: z
|
|
149
|
+
.string()
|
|
150
|
+
.optional()
|
|
151
|
+
.describe("Omission pointer — the full image is retrievable via GET /api/v1/memes/:id."),
|
|
152
|
+
contentType: z.string().optional(),
|
|
153
|
+
prompt: z.string().optional(),
|
|
154
|
+
charge: chargeShape.optional(),
|
|
155
|
+
},
|
|
156
|
+
transform: truncateImageResponse,
|
|
157
|
+
}),
|
|
158
|
+
defineGeneratedTool({
|
|
159
|
+
name: "capix_meme_templates",
|
|
160
|
+
description: "List the meme catalog: available templates (ids, slots, hints), caption vibes, and " +
|
|
161
|
+
"whether AI-canvas image generation is currently available. Free; read-only.",
|
|
162
|
+
scope: "discovery",
|
|
163
|
+
...READ_ONLY,
|
|
164
|
+
method: "GET",
|
|
165
|
+
path: "/api/v1/memes",
|
|
166
|
+
input: {},
|
|
167
|
+
outputShape: {
|
|
168
|
+
templates: z.array(z.record(z.unknown())).optional(),
|
|
169
|
+
vibes: z.array(z.string()).optional(),
|
|
170
|
+
aiCanvasAvailable: z.boolean().optional(),
|
|
171
|
+
},
|
|
172
|
+
}),
|
|
173
|
+
];
|
|
174
|
+
export const MEME_IMAGE_TOOL_NAMES = memeImageTools.map((t) => t.name);
|
|
175
|
+
//# sourceMappingURL=memes.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"memes.js","sourceRoot":"","sources":["../../src/tools/memes.ts"],"names":[],"mappings":"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"}
|