@cat-factory/mcp-server 0.30.0 → 0.32.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/dist/server.d.ts CHANGED
@@ -2,7 +2,7 @@ import { Server } from '@modelcontextprotocol/sdk/server/index.js';
2
2
  import { type CatFactoryMcpOptions } from './config.ts';
3
3
  import { type CatFactoryTool } from './tools.generated.ts';
4
4
  /** The npm version, stamped into the SDK's `User-Agent` so a deployment can attribute calls. */
5
- export declare const MCP_SERVER_VERSION = "0.30.0";
5
+ export declare const MCP_SERVER_VERSION = "0.32.0";
6
6
  /** The name this server reports to a host. */
7
7
  export declare const MCP_SERVER_NAME = "cat-factory";
8
8
  export interface CatFactoryMcpServer {
package/dist/server.js CHANGED
@@ -19,7 +19,7 @@ import { CAT_FACTORY_TOOLS } from './tools.generated.js';
19
19
  // has been round-tripped through a second type system, and every gap in that conversion becomes a
20
20
  // tool that misdescribes its own input.
21
21
  /** The npm version, stamped into the SDK's `User-Agent` so a deployment can attribute calls. */
22
- export const MCP_SERVER_VERSION = '0.30.0';
22
+ export const MCP_SERVER_VERSION = '0.32.0';
23
23
  /** The name this server reports to a host. */
24
24
  export const MCP_SERVER_NAME = 'cat-factory';
25
25
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"tools.generated.d.ts","sourceRoot":"","sources":["../src/tools.generated.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAA;AAExD,6CAA6C;AAC7C,MAAM,WAAW,cAAc;IAC7B,mEAAmE;IACnE,IAAI,EAAE,MAAM,CAAA;IACZ,gDAAgD;IAChD,KAAK,EAAE,MAAM,CAAA;IACb,iFAAiF;IACjF,KAAK,EAAE,MAAM,CAAA;IACb,sFAAsF;IACtF,WAAW,EAAE,MAAM,CAAA;IACnB,8FAA8F;IAC9F,QAAQ,EAAE,OAAO,CAAA;IACjB;;;;OAIG;IACH,KAAK,CAAC,EAAE;QAAE,WAAW,EAAE,OAAO,CAAC;QAAC,UAAU,EAAE,OAAO,CAAA;KAAE,CAAA;IACrD,WAAW,EAAE,MAAM,CAAA;IACnB,WAAW,EAAE;QACX,IAAI,EAAE,QAAQ,CAAA;QACd,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;QACnC,QAAQ,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;QAC5B,oBAAoB,EAAE,KAAK,CAAA;KAC5B,CAAA;IACD;;;;;;;;OAQG;IACH,YAAY,CAAC,EAAE;QACb,IAAI,EAAE,QAAQ,CAAA;QACd,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;KACpC,CAAA;IACD,kDAAkD;IAClD,MAAM,EAAE,CAAC,MAAM,EAAE,gBAAgB,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,OAAO,CAAC,OAAO,CAAC,CAAA;CACtF;AAED;;;;;;GAMG;AACH,MAAM,WAAW,0BAA0B;IACzC,WAAW,EAAE,MAAM,CAAA;IACnB,sCAAsC;IACtC,KAAK,EAAE,MAAM,CAAA;IACb,qEAAqE;IACrE,OAAO,EAAE,MAAM,CAAA;IACf,MAAM,EAAE,MAAM,CAAA;CACf;AAuHD,wFAAwF;AACxF,eAAO,MAAM,iBAAiB,EAAE,SAAS,cAAc,EA8pCtD,CAAA;AAED,wEAAwE;AACxE,eAAO,MAAM,8BAA8B,EAAE,SAAS,0BAA0B,EAmB/E,CAAA;AAED,kEAAkE;AAClE,eAAO,MAAM,uBAAuB,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAqBpE,CAAA"}
1
+ {"version":3,"file":"tools.generated.d.ts","sourceRoot":"","sources":["../src/tools.generated.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAA;AAExD,6CAA6C;AAC7C,MAAM,WAAW,cAAc;IAC7B,mEAAmE;IACnE,IAAI,EAAE,MAAM,CAAA;IACZ,gDAAgD;IAChD,KAAK,EAAE,MAAM,CAAA;IACb,iFAAiF;IACjF,KAAK,EAAE,MAAM,CAAA;IACb,sFAAsF;IACtF,WAAW,EAAE,MAAM,CAAA;IACnB,8FAA8F;IAC9F,QAAQ,EAAE,OAAO,CAAA;IACjB;;;;OAIG;IACH,KAAK,CAAC,EAAE;QAAE,WAAW,EAAE,OAAO,CAAC;QAAC,UAAU,EAAE,OAAO,CAAA;KAAE,CAAA;IACrD,WAAW,EAAE,MAAM,CAAA;IACnB,WAAW,EAAE;QACX,IAAI,EAAE,QAAQ,CAAA;QACd,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;QACnC,QAAQ,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;QAC5B,oBAAoB,EAAE,KAAK,CAAA;KAC5B,CAAA;IACD;;;;;;;;OAQG;IACH,YAAY,CAAC,EAAE;QACb,IAAI,EAAE,QAAQ,CAAA;QACd,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;KACpC,CAAA;IACD,kDAAkD;IAClD,MAAM,EAAE,CAAC,MAAM,EAAE,gBAAgB,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,OAAO,CAAC,OAAO,CAAC,CAAA;CACtF;AAED;;;;;;GAMG;AACH,MAAM,WAAW,0BAA0B;IACzC,WAAW,EAAE,MAAM,CAAA;IACnB,sCAAsC;IACtC,KAAK,EAAE,MAAM,CAAA;IACb,qEAAqE;IACrE,OAAO,EAAE,MAAM,CAAA;IACf,MAAM,EAAE,MAAM,CAAA;CACf;AA0HD,wFAAwF;AACxF,eAAO,MAAM,iBAAiB,EAAE,SAAS,cAAc,EA+rCtD,CAAA;AAED,wEAAwE;AACxE,eAAO,MAAM,8BAA8B,EAAE,SAAS,0BAA0B,EAmB/E,CAAA;AAED,kEAAkE;AAClE,eAAO,MAAM,uBAAuB,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAsBpE,CAAA"}
@@ -48,6 +48,9 @@ const QUERY_JOBS_LIST = [
48
48
  { name: 'status', required: false },
49
49
  { name: 'since', required: false },
50
50
  ];
51
+ const QUERY_REPOS_LIST_AVAILABLE = [
52
+ { name: 'q', required: false },
53
+ ];
51
54
  const QUERY_TASKS_LIST_BY_SERVICE = [
52
55
  { name: 'limit', required: false },
53
56
  { name: 'cursor', required: false },
@@ -232,17 +235,39 @@ export const CAT_FACTORY_TOOLS = [
232
235
  outputSchema: { "type": "object", "properties": { "createdAt": { "type": "number" }, "error": { "anyOf": [{ "type": "string" }, { "type": "null" }] }, "failureDetail": { "anyOf": [{ "type": "string" }, { "type": "null" }] }, "failureHint": { "anyOf": [{ "type": "string" }, { "type": "null" }] }, "failureKind": { "anyOf": [{ "type": "string", "description": "One of: preflight, dispatch, environment, evicted, timeout, agent, job_failed, rejected, companion_rejected, stalled, cancelled, unknown. A newer deployment may report a member not in this list." }, { "type": "null" }] }, "jobId": { "type": "string" }, "progress": { "anyOf": [{ "type": "object", "properties": { "completed": { "type": "number" }, "inProgress": { "type": "number" }, "items": { "type": "array", "items": { "type": "object", "properties": { "label": { "type": "string" }, "status": { "type": "string", "description": "One of: pending, in_progress, completed. A newer deployment may report a member not in this list." } } } }, "total": { "type": "number" } } }, { "type": "null" }] }, "repoName": { "type": "string" }, "repoOwner": { "anyOf": [{ "type": "string" }, { "type": "null" }] }, "repoUrl": { "anyOf": [{ "type": "string" }, { "type": "null" }] }, "serviceId": { "anyOf": [{ "type": "string" }, { "type": "null" }] }, "status": { "type": "string", "description": "One of: pending, running, succeeded, failed. A newer deployment may report a member not in this list." }, "updatedAt": { "type": "number" } } },
233
236
  invoke: (client, args) => client.repos.getBootstrap(str(args, 'jobId')),
234
237
  },
238
+ {
239
+ name: 'repos_link',
240
+ title: 'Adopt an existing repository into this workspace',
241
+ group: 'repos',
242
+ operationId: 'linkPublicRepo',
243
+ readOnly: false,
244
+ description: 'Adopt an existing repository into this workspace\n\nLink a repository the connection can reach, by `owner` and `name`, so a service can be created against it. The act that had no headless counterpart: nothing links a repository for you (the provider webhook for an added repository does not project one, and a resync refreshes what is already linked), so a repository created by any means stayed invisible to the repos list and unusable by service creation until a person opened the app. Takes a NAME rather than the numeric `repoId` its sibling reads report, because a caller setting a workspace up from configuration knows the name and cannot know a provider id for a repository no public read lists; the response carries the `repoId` for the service-creation call that follows. Idempotent: a repository this workspace already links returns its row rather than refusing, so a setup script re-running itself needs no special case. A repository the connection cannot reach is a 404 with `details.reason: repo_not_reachable`, which covers both "it does not exist" and "your credential is not granted it": a provider answers those identically, and inventing a split would be a guess.\n\nCalls `POST /api/v1/repos/link` (operation `linkPublicRepo`).',
245
+ inputSchema: { "type": "object", "properties": { "body": { "type": "object", "properties": { "name": { "type": "string", "minLength": 1, "maxLength": 100 }, "owner": { "type": "string", "minLength": 1, "maxLength": 255 } }, "required": ["name", "owner"], "description": "The request body." } }, "additionalProperties": false, "required": ["body"] },
246
+ outputSchema: { "type": "object", "properties": { "defaultBranch": { "type": "string" }, "linkedElsewhere": { "type": "boolean" }, "monorepo": { "type": "boolean" }, "name": { "type": "string" }, "owner": { "type": "string" }, "private": { "type": "boolean" }, "provider": { "type": "string" }, "repoId": { "type": "number" }, "serviceId": { "anyOf": [{ "type": "string" }, { "type": "null" }] } } },
247
+ invoke: (client, args) => client.repos.link(args.body),
248
+ },
235
249
  {
236
250
  name: 'repos_list',
237
251
  title: 'List the repositories a service can be created against',
238
252
  group: 'repos',
239
253
  operationId: 'listPublicRepos',
240
254
  readOnly: true,
241
- description: 'List the repositories a service can be created against\n\nList the repositories the key’s workspace has connected, each with the service that already backs it (null when nothing does, and always null for a monorepo, which can back several). The discovery half of service creation: the create takes a repoId, and this is where one comes from.\n\nCalls `GET /api/v1/repos` (operation `listPublicRepos`).',
255
+ description: 'List the repositories a service can be created against\n\nList the repositories the key’s workspace has LINKED, each with the service that already backs it (null when nothing does, and always null for a monorepo, which can back several). The discovery half of service creation: the create takes a repoId, and this is where one comes from. A repository the connection can reach but nobody has adopted yet is NOT here; list those with the available-repos endpoint and adopt one with the link endpoint.\n\nCalls `GET /api/v1/repos` (operation `listPublicRepos`).',
242
256
  inputSchema: { "type": "object", "properties": {}, "additionalProperties": false },
243
257
  outputSchema: { "type": "object", "properties": { "repos": { "type": "array", "items": { "type": "object", "properties": { "defaultBranch": { "type": "string" }, "linkedElsewhere": { "type": "boolean" }, "monorepo": { "type": "boolean" }, "name": { "type": "string" }, "owner": { "type": "string" }, "private": { "type": "boolean" }, "provider": { "type": "string" }, "repoId": { "type": "number" }, "serviceId": { "anyOf": [{ "type": "string" }, { "type": "null" }] } } } } } },
244
258
  invoke: (client, args) => client.repos.list(),
245
259
  },
260
+ {
261
+ name: 'repos_list_available',
262
+ title: 'List the repositories this workspace could adopt',
263
+ group: 'repos',
264
+ operationId: 'listPublicAvailableRepos',
265
+ readOnly: true,
266
+ description: 'List the repositories this workspace could adopt\n\nThe repositories the workspace’s source-control connection can REACH, whether or not this workspace links them, with `linked` as the join onto the repos list. It exists because those two populations differ and the difference is invisible otherwise: linking is explicit per workspace, so a repository that exists and is perfectly reachable is absent from the repos list in exactly the way one that was never created is, and those need opposite fixes. Pass `q` as an exact `owner/name` for an authoritative point-read, as a substring to search, or omit it to browse what is accessible. Each call reaches the provider, so it is a setup-time read rather than one to poll.\n\nCalls `GET /api/v1/repos/available` (operation `listPublicAvailableRepos`).',
267
+ inputSchema: { "type": "object", "properties": { "q": { "type": "string" } }, "additionalProperties": false },
268
+ outputSchema: { "type": "object", "properties": { "repos": { "type": "array", "items": { "type": "object", "properties": { "defaultBranch": { "type": "string" }, "linked": { "type": "boolean" }, "linkedElsewhere": { "type": "boolean" }, "monorepo": { "type": "boolean" }, "name": { "type": "string" }, "owner": { "type": "string" }, "personal": { "type": "boolean" }, "private": { "type": "boolean" }, "provider": { "type": "string", "description": "One of: github, gitlab. A newer deployment may report a member not in this list." }, "repoId": { "type": "number" }, "serviceId": { "anyOf": [{ "type": "string" }, { "type": "null" }] } } } }, "truncated": { "type": "boolean" } } },
269
+ invoke: (client, args) => client.repos.listAvailable(pick(args, QUERY_REPOS_LIST_AVAILABLE)),
270
+ },
246
271
  {
247
272
  name: 'tasks_add_dependency',
248
273
  title: 'Declare that a task waits for another',
@@ -251,7 +276,7 @@ export const CAT_FACTORY_TOOLS = [
251
276
  readOnly: false,
252
277
  description: 'Declare that a task waits for another\n\nRecord that this task cannot start until `dependsOnTaskId` is done. Both ends must be tasks in this workspace, and an edge that would close a cycle is refused. Idempotent: an edge that already exists is returned as-is rather than toggled off, so a provisioning integration re-running its own setup converges. Pair it with `autoStartDependents` on the BLOCKER (the task patch) to have the chain run itself.\n\nCalls `POST /api/v1/tasks/{taskId}/dependencies` (operation `addPublicTaskDependency`).',
253
278
  inputSchema: { "type": "object", "properties": { "taskId": { "type": "string", "description": "Path parameter `taskId`." }, "body": { "type": "object", "properties": { "dependsOnTaskId": { "type": "string", "minLength": 1, "maxLength": 120 } }, "required": ["dependsOnTaskId"], "description": "The request body." } }, "additionalProperties": false, "required": ["taskId", "body"] },
254
- outputSchema: { "type": "object", "properties": { "autoStartDependents": { "type": "boolean" }, "dependsOn": { "type": "array", "items": { "type": "string" } }, "description": { "type": "string" }, "progress": { "type": "number" }, "pullRequestUrl": { "anyOf": [{ "type": "string" }, { "type": "null" }] }, "runId": { "anyOf": [{ "type": "string" }, { "type": "null" }] }, "serviceId": { "type": "string" }, "status": { "type": "string", "description": "One of: planned, ready, in_progress, blocked, pr_ready, done. A newer deployment may report a member not in this list." }, "taskId": { "type": "string" }, "taskType": { "type": "string", "description": "Usually one of: feature, bug, document, spike, review, ralph, recurring. Other values are accepted where the deployment defines them." }, "title": { "type": "string" } } },
279
+ outputSchema: { "type": "object", "properties": { "autoStartDependents": { "type": "boolean" }, "dependsOn": { "type": "array", "items": { "type": "string" } }, "description": { "type": "string" }, "modelPresetId": { "anyOf": [{ "type": "string" }, { "type": "null" }] }, "progress": { "type": "number" }, "pullRequestUrl": { "anyOf": [{ "type": "string" }, { "type": "null" }] }, "riskPolicyId": { "anyOf": [{ "type": "string" }, { "type": "null" }] }, "runId": { "anyOf": [{ "type": "string" }, { "type": "null" }] }, "serviceId": { "type": "string" }, "status": { "type": "string", "description": "One of: planned, ready, in_progress, blocked, pr_ready, done. A newer deployment may report a member not in this list." }, "taskId": { "type": "string" }, "taskType": { "type": "string", "description": "Usually one of: feature, bug, document, spike, review, ralph, recurring. Other values are accepted where the deployment defines them." }, "title": { "type": "string" } } },
255
280
  invoke: (client, args) => client.tasks.addDependency(str(args, 'taskId'), args.body),
256
281
  },
257
282
  {
@@ -272,8 +297,8 @@ export const CAT_FACTORY_TOOLS = [
272
297
  operationId: 'createPublicTask',
273
298
  readOnly: false,
274
299
  description: 'Create a task under a service\n\nCreate a task inside a service frame the key’s workspace owns. The task starts in the `planned` state; start it with the start endpoint. Optionally file it FROM a tracker ticket, and/or attach the requirements documents it is to be built against (named in a connected document source, or uploaded inline): the only way to get spec-sized input onto a repository-touching run.\n\nCalls `POST /api/v1/services/{serviceId}/tasks` (operation `createPublicTask`).',
275
- inputSchema: { "type": "object", "properties": { "serviceId": { "type": "string", "description": "Path parameter `serviceId`." }, "body": { "type": "object", "properties": { "description": { "type": "string", "maxLength": 2000 }, "documents": { "type": "array", "items": { "anyOf": [{ "type": "object", "properties": { "kind": { "const": "source" }, "ref": { "type": "string", "minLength": 1, "maxLength": 500 }, "source": { "type": "string", "enum": ["confluence", "notion", "github", "figma", "zeplin", "linear"] } }, "required": ["kind", "ref", "source"] }, { "type": "object", "properties": { "content": { "type": "string", "minLength": 1, "maxLength": 100000 }, "kind": { "const": "upload" }, "title": { "type": "string", "minLength": 1, "maxLength": 200 } }, "required": ["content", "kind", "title"] }], "description": "Discriminated by `kind` (source | upload)." } }, "fields": { "type": "object", "additionalProperties": { "anyOf": [{ "type": "string" }, { "type": "array", "items": { "type": "string" } }, { "type": "boolean" }, { "type": "number" }] } }, "taskType": { "type": "string", "description": "Usually one of: feature, bug, document, spike, review, ralph. Other values are accepted where the deployment defines them." }, "ticket": { "type": "object", "properties": { "ref": { "type": "string", "minLength": 1, "maxLength": 500 }, "source": { "type": "string", "description": "Usually one of: jira, github, linear, gitlab. Other values are accepted where the deployment defines them." } }, "required": ["ref", "source"] }, "title": { "type": "string", "minLength": 1, "maxLength": 200 } }, "required": ["title"], "description": "The request body." } }, "additionalProperties": false, "required": ["serviceId", "body"] },
276
- outputSchema: { "type": "object", "properties": { "autoStartDependents": { "type": "boolean" }, "dependsOn": { "type": "array", "items": { "type": "string" } }, "description": { "type": "string" }, "progress": { "type": "number" }, "pullRequestUrl": { "anyOf": [{ "type": "string" }, { "type": "null" }] }, "runId": { "anyOf": [{ "type": "string" }, { "type": "null" }] }, "serviceId": { "type": "string" }, "status": { "type": "string", "description": "One of: planned, ready, in_progress, blocked, pr_ready, done. A newer deployment may report a member not in this list." }, "taskId": { "type": "string" }, "taskType": { "type": "string", "description": "Usually one of: feature, bug, document, spike, review, ralph, recurring. Other values are accepted where the deployment defines them." }, "title": { "type": "string" } } },
300
+ inputSchema: { "type": "object", "properties": { "serviceId": { "type": "string", "description": "Path parameter `serviceId`." }, "body": { "type": "object", "properties": { "description": { "type": "string", "maxLength": 2000 }, "documents": { "type": "array", "items": { "anyOf": [{ "type": "object", "properties": { "kind": { "const": "source" }, "ref": { "type": "string", "minLength": 1, "maxLength": 500 }, "source": { "type": "string", "enum": ["confluence", "notion", "github", "figma", "zeplin", "linear"] } }, "required": ["kind", "ref", "source"] }, { "type": "object", "properties": { "content": { "type": "string", "minLength": 1, "maxLength": 100000 }, "kind": { "const": "upload" }, "title": { "type": "string", "minLength": 1, "maxLength": 200 } }, "required": ["content", "kind", "title"] }], "description": "Discriminated by `kind` (source | upload)." } }, "fields": { "type": "object", "additionalProperties": { "anyOf": [{ "type": "string" }, { "type": "array", "items": { "type": "string" } }, { "type": "boolean" }, { "type": "number" }] } }, "modelPresetId": { "type": "string", "minLength": 1, "maxLength": 120 }, "riskPolicyId": { "type": "string", "minLength": 1, "maxLength": 120 }, "taskType": { "type": "string", "description": "Usually one of: feature, bug, document, spike, review, ralph. Other values are accepted where the deployment defines them." }, "ticket": { "type": "object", "properties": { "ref": { "type": "string", "minLength": 1, "maxLength": 500 }, "source": { "type": "string", "description": "Usually one of: jira, github, linear, gitlab. Other values are accepted where the deployment defines them." } }, "required": ["ref", "source"] }, "title": { "type": "string", "minLength": 1, "maxLength": 200 } }, "required": ["title"], "description": "The request body." } }, "additionalProperties": false, "required": ["serviceId", "body"] },
301
+ outputSchema: { "type": "object", "properties": { "autoStartDependents": { "type": "boolean" }, "dependsOn": { "type": "array", "items": { "type": "string" } }, "description": { "type": "string" }, "modelPresetId": { "anyOf": [{ "type": "string" }, { "type": "null" }] }, "progress": { "type": "number" }, "pullRequestUrl": { "anyOf": [{ "type": "string" }, { "type": "null" }] }, "riskPolicyId": { "anyOf": [{ "type": "string" }, { "type": "null" }] }, "runId": { "anyOf": [{ "type": "string" }, { "type": "null" }] }, "serviceId": { "type": "string" }, "status": { "type": "string", "description": "One of: planned, ready, in_progress, blocked, pr_ready, done. A newer deployment may report a member not in this list." }, "taskId": { "type": "string" }, "taskType": { "type": "string", "description": "Usually one of: feature, bug, document, spike, review, ralph, recurring. Other values are accepted where the deployment defines them." }, "title": { "type": "string" } } },
277
302
  invoke: (client, args) => client.tasks.create(str(args, 'serviceId'), args.body),
278
303
  },
279
304
  {
@@ -305,7 +330,7 @@ export const CAT_FACTORY_TOOLS = [
305
330
  readOnly: true,
306
331
  description: 'Get a task\'s status\n\nRead a task’s current lifecycle status, run progress, run id, and PR URL (once one exists).\n\nCalls `GET /api/v1/tasks/{taskId}` (operation `getPublicTask`).',
307
332
  inputSchema: { "type": "object", "properties": { "taskId": { "type": "string", "description": "Path parameter `taskId`." } }, "additionalProperties": false, "required": ["taskId"] },
308
- outputSchema: { "type": "object", "properties": { "autoStartDependents": { "type": "boolean" }, "dependsOn": { "type": "array", "items": { "type": "string" } }, "description": { "type": "string" }, "progress": { "type": "number" }, "pullRequestUrl": { "anyOf": [{ "type": "string" }, { "type": "null" }] }, "runId": { "anyOf": [{ "type": "string" }, { "type": "null" }] }, "serviceId": { "type": "string" }, "status": { "type": "string", "description": "One of: planned, ready, in_progress, blocked, pr_ready, done. A newer deployment may report a member not in this list." }, "taskId": { "type": "string" }, "taskType": { "type": "string", "description": "Usually one of: feature, bug, document, spike, review, ralph, recurring. Other values are accepted where the deployment defines them." }, "title": { "type": "string" } } },
333
+ outputSchema: { "type": "object", "properties": { "autoStartDependents": { "type": "boolean" }, "dependsOn": { "type": "array", "items": { "type": "string" } }, "description": { "type": "string" }, "modelPresetId": { "anyOf": [{ "type": "string" }, { "type": "null" }] }, "progress": { "type": "number" }, "pullRequestUrl": { "anyOf": [{ "type": "string" }, { "type": "null" }] }, "riskPolicyId": { "anyOf": [{ "type": "string" }, { "type": "null" }] }, "runId": { "anyOf": [{ "type": "string" }, { "type": "null" }] }, "serviceId": { "type": "string" }, "status": { "type": "string", "description": "One of: planned, ready, in_progress, blocked, pr_ready, done. A newer deployment may report a member not in this list." }, "taskId": { "type": "string" }, "taskType": { "type": "string", "description": "Usually one of: feature, bug, document, spike, review, ralph, recurring. Other values are accepted where the deployment defines them." }, "title": { "type": "string" } } },
309
334
  invoke: (client, args) => client.tasks.get(str(args, 'taskId')),
310
335
  },
311
336
  {
@@ -327,7 +352,7 @@ export const CAT_FACTORY_TOOLS = [
327
352
  readOnly: true,
328
353
  description: 'List a service\'s tasks\n\nList every task under a service (the whole subtree — tasks directly under the frame and under its modules).\n\nCalls `GET /api/v1/services/{serviceId}/tasks` (operation `listPublicServiceTasks`).',
329
354
  inputSchema: { "type": "object", "properties": { "serviceId": { "type": "string", "description": "Path parameter `serviceId`." }, "limit": { "type": "integer" }, "cursor": { "type": "string" }, "status": { "type": "string", "enum": ["planned", "ready", "in_progress", "blocked", "pr_ready", "done"] } }, "additionalProperties": false, "required": ["serviceId"] },
330
- outputSchema: { "type": "object", "properties": { "nextCursor": { "anyOf": [{ "type": "string" }, { "type": "null" }] }, "tasks": { "type": "array", "items": { "type": "object", "properties": { "autoStartDependents": { "type": "boolean" }, "dependsOn": { "type": "array", "items": { "type": "string" } }, "description": { "type": "string" }, "progress": { "type": "number" }, "pullRequestUrl": { "anyOf": [{ "type": "string" }, { "type": "null" }] }, "runId": { "anyOf": [{ "type": "string" }, { "type": "null" }] }, "serviceId": { "type": "string" }, "status": { "type": "string", "description": "One of: planned, ready, in_progress, blocked, pr_ready, done. A newer deployment may report a member not in this list." }, "taskId": { "type": "string" }, "taskType": { "type": "string", "description": "Usually one of: feature, bug, document, spike, review, ralph, recurring. Other values are accepted where the deployment defines them." }, "title": { "type": "string" } } } } } },
355
+ outputSchema: { "type": "object", "properties": { "nextCursor": { "anyOf": [{ "type": "string" }, { "type": "null" }] }, "tasks": { "type": "array", "items": { "type": "object", "properties": { "autoStartDependents": { "type": "boolean" }, "dependsOn": { "type": "array", "items": { "type": "string" } }, "description": { "type": "string" }, "modelPresetId": { "anyOf": [{ "type": "string" }, { "type": "null" }] }, "progress": { "type": "number" }, "pullRequestUrl": { "anyOf": [{ "type": "string" }, { "type": "null" }] }, "riskPolicyId": { "anyOf": [{ "type": "string" }, { "type": "null" }] }, "runId": { "anyOf": [{ "type": "string" }, { "type": "null" }] }, "serviceId": { "type": "string" }, "status": { "type": "string", "description": "One of: planned, ready, in_progress, blocked, pr_ready, done. A newer deployment may report a member not in this list." }, "taskId": { "type": "string" }, "taskType": { "type": "string", "description": "Usually one of: feature, bug, document, spike, review, ralph, recurring. Other values are accepted where the deployment defines them." }, "title": { "type": "string" } } } } } },
331
356
  invoke: (client, args) => client.tasks.listByService(str(args, 'serviceId'), pick(args, QUERY_TASKS_LIST_BY_SERVICE)),
332
357
  },
333
358
  {
@@ -349,7 +374,7 @@ export const CAT_FACTORY_TOOLS = [
349
374
  readOnly: false,
350
375
  description: 'Drop a dependency edge\n\nRemove the ordering between this task and `dependsOnTaskId`. Idempotent: an edge that is not there is a no-op.\n\nCalls `POST /api/v1/tasks/{taskId}/dependencies/remove` (operation `removePublicTaskDependency`).',
351
376
  inputSchema: { "type": "object", "properties": { "taskId": { "type": "string", "description": "Path parameter `taskId`." }, "body": { "type": "object", "properties": { "dependsOnTaskId": { "type": "string", "minLength": 1, "maxLength": 120 } }, "required": ["dependsOnTaskId"], "description": "The request body." } }, "additionalProperties": false, "required": ["taskId", "body"] },
352
- outputSchema: { "type": "object", "properties": { "autoStartDependents": { "type": "boolean" }, "dependsOn": { "type": "array", "items": { "type": "string" } }, "description": { "type": "string" }, "progress": { "type": "number" }, "pullRequestUrl": { "anyOf": [{ "type": "string" }, { "type": "null" }] }, "runId": { "anyOf": [{ "type": "string" }, { "type": "null" }] }, "serviceId": { "type": "string" }, "status": { "type": "string", "description": "One of: planned, ready, in_progress, blocked, pr_ready, done. A newer deployment may report a member not in this list." }, "taskId": { "type": "string" }, "taskType": { "type": "string", "description": "Usually one of: feature, bug, document, spike, review, ralph, recurring. Other values are accepted where the deployment defines them." }, "title": { "type": "string" } } },
377
+ outputSchema: { "type": "object", "properties": { "autoStartDependents": { "type": "boolean" }, "dependsOn": { "type": "array", "items": { "type": "string" } }, "description": { "type": "string" }, "modelPresetId": { "anyOf": [{ "type": "string" }, { "type": "null" }] }, "progress": { "type": "number" }, "pullRequestUrl": { "anyOf": [{ "type": "string" }, { "type": "null" }] }, "riskPolicyId": { "anyOf": [{ "type": "string" }, { "type": "null" }] }, "runId": { "anyOf": [{ "type": "string" }, { "type": "null" }] }, "serviceId": { "type": "string" }, "status": { "type": "string", "description": "One of: planned, ready, in_progress, blocked, pr_ready, done. A newer deployment may report a member not in this list." }, "taskId": { "type": "string" }, "taskType": { "type": "string", "description": "Usually one of: feature, bug, document, spike, review, ralph, recurring. Other values are accepted where the deployment defines them." }, "title": { "type": "string" } } },
353
378
  invoke: (client, args) => client.tasks.removeDependency(str(args, 'taskId'), args.body),
354
379
  },
355
380
  {
@@ -361,7 +386,7 @@ export const CAT_FACTORY_TOOLS = [
361
386
  hints: { "destructive": true, "idempotent": false },
362
387
  description: 'Retry a task\'s failed run\n\nRetry a task’s failed run. A task on an individual-usage model cannot be retried through the API (no headless personal-credential unlock).\n\nCalls `POST /api/v1/tasks/{taskId}/retry` (operation `retryPublicTask`).',
363
388
  inputSchema: { "type": "object", "properties": { "taskId": { "type": "string", "description": "Path parameter `taskId`." } }, "additionalProperties": false, "required": ["taskId"] },
364
- outputSchema: { "type": "object", "properties": { "autoStartDependents": { "type": "boolean" }, "dependsOn": { "type": "array", "items": { "type": "string" } }, "description": { "type": "string" }, "progress": { "type": "number" }, "pullRequestUrl": { "anyOf": [{ "type": "string" }, { "type": "null" }] }, "runId": { "anyOf": [{ "type": "string" }, { "type": "null" }] }, "serviceId": { "type": "string" }, "status": { "type": "string", "description": "One of: planned, ready, in_progress, blocked, pr_ready, done. A newer deployment may report a member not in this list." }, "taskId": { "type": "string" }, "taskType": { "type": "string", "description": "Usually one of: feature, bug, document, spike, review, ralph, recurring. Other values are accepted where the deployment defines them." }, "title": { "type": "string" } } },
389
+ outputSchema: { "type": "object", "properties": { "autoStartDependents": { "type": "boolean" }, "dependsOn": { "type": "array", "items": { "type": "string" } }, "description": { "type": "string" }, "modelPresetId": { "anyOf": [{ "type": "string" }, { "type": "null" }] }, "progress": { "type": "number" }, "pullRequestUrl": { "anyOf": [{ "type": "string" }, { "type": "null" }] }, "riskPolicyId": { "anyOf": [{ "type": "string" }, { "type": "null" }] }, "runId": { "anyOf": [{ "type": "string" }, { "type": "null" }] }, "serviceId": { "type": "string" }, "status": { "type": "string", "description": "One of: planned, ready, in_progress, blocked, pr_ready, done. A newer deployment may report a member not in this list." }, "taskId": { "type": "string" }, "taskType": { "type": "string", "description": "Usually one of: feature, bug, document, spike, review, ralph, recurring. Other values are accepted where the deployment defines them." }, "title": { "type": "string" } } },
365
390
  invoke: (client, args) => client.tasks.retry(str(args, 'taskId')),
366
391
  },
367
392
  {
@@ -373,7 +398,7 @@ export const CAT_FACTORY_TOOLS = [
373
398
  hints: { "destructive": true, "idempotent": false },
374
399
  description: 'Start (run) a task\n\nStart a task’s pipeline. Uses the request’s pipelineId, else the task’s pinned pipeline. A pipeline that can park on a human decision requires a `decide`-scope key. A task on an individual-usage model cannot be started through the API (no headless personal-credential unlock).\n\nCalls `POST /api/v1/tasks/{taskId}/start` (operation `startPublicTask`).',
375
400
  inputSchema: { "type": "object", "properties": { "taskId": { "type": "string", "description": "Path parameter `taskId`." }, "body": { "type": "object", "properties": { "pipelineId": { "type": "string", "minLength": 1, "maxLength": 120 } }, "description": "The request body." } }, "additionalProperties": false, "required": ["taskId"] },
376
- outputSchema: { "type": "object", "properties": { "autoStartDependents": { "type": "boolean" }, "dependsOn": { "type": "array", "items": { "type": "string" } }, "description": { "type": "string" }, "progress": { "type": "number" }, "pullRequestUrl": { "anyOf": [{ "type": "string" }, { "type": "null" }] }, "runId": { "anyOf": [{ "type": "string" }, { "type": "null" }] }, "serviceId": { "type": "string" }, "status": { "type": "string", "description": "One of: planned, ready, in_progress, blocked, pr_ready, done. A newer deployment may report a member not in this list." }, "taskId": { "type": "string" }, "taskType": { "type": "string", "description": "Usually one of: feature, bug, document, spike, review, ralph, recurring. Other values are accepted where the deployment defines them." }, "title": { "type": "string" } } },
401
+ outputSchema: { "type": "object", "properties": { "autoStartDependents": { "type": "boolean" }, "dependsOn": { "type": "array", "items": { "type": "string" } }, "description": { "type": "string" }, "modelPresetId": { "anyOf": [{ "type": "string" }, { "type": "null" }] }, "progress": { "type": "number" }, "pullRequestUrl": { "anyOf": [{ "type": "string" }, { "type": "null" }] }, "riskPolicyId": { "anyOf": [{ "type": "string" }, { "type": "null" }] }, "runId": { "anyOf": [{ "type": "string" }, { "type": "null" }] }, "serviceId": { "type": "string" }, "status": { "type": "string", "description": "One of: planned, ready, in_progress, blocked, pr_ready, done. A newer deployment may report a member not in this list." }, "taskId": { "type": "string" }, "taskType": { "type": "string", "description": "Usually one of: feature, bug, document, spike, review, ralph, recurring. Other values are accepted where the deployment defines them." }, "title": { "type": "string" } } },
377
402
  invoke: (client, args) => client.tasks.start(str(args, 'taskId'), args.body),
378
403
  },
379
404
  {
@@ -384,7 +409,7 @@ export const CAT_FACTORY_TOOLS = [
384
409
  readOnly: false,
385
410
  description: 'Stop a task\'s run\n\nStop a task’s in-flight run. Records a `cancelled` terminal state, leaving the run retryable.\n\nCalls `POST /api/v1/tasks/{taskId}/stop` (operation `stopPublicTask`).',
386
411
  inputSchema: { "type": "object", "properties": { "taskId": { "type": "string", "description": "Path parameter `taskId`." } }, "additionalProperties": false, "required": ["taskId"] },
387
- outputSchema: { "type": "object", "properties": { "autoStartDependents": { "type": "boolean" }, "dependsOn": { "type": "array", "items": { "type": "string" } }, "description": { "type": "string" }, "progress": { "type": "number" }, "pullRequestUrl": { "anyOf": [{ "type": "string" }, { "type": "null" }] }, "runId": { "anyOf": [{ "type": "string" }, { "type": "null" }] }, "serviceId": { "type": "string" }, "status": { "type": "string", "description": "One of: planned, ready, in_progress, blocked, pr_ready, done. A newer deployment may report a member not in this list." }, "taskId": { "type": "string" }, "taskType": { "type": "string", "description": "Usually one of: feature, bug, document, spike, review, ralph, recurring. Other values are accepted where the deployment defines them." }, "title": { "type": "string" } } },
412
+ outputSchema: { "type": "object", "properties": { "autoStartDependents": { "type": "boolean" }, "dependsOn": { "type": "array", "items": { "type": "string" } }, "description": { "type": "string" }, "modelPresetId": { "anyOf": [{ "type": "string" }, { "type": "null" }] }, "progress": { "type": "number" }, "pullRequestUrl": { "anyOf": [{ "type": "string" }, { "type": "null" }] }, "riskPolicyId": { "anyOf": [{ "type": "string" }, { "type": "null" }] }, "runId": { "anyOf": [{ "type": "string" }, { "type": "null" }] }, "serviceId": { "type": "string" }, "status": { "type": "string", "description": "One of: planned, ready, in_progress, blocked, pr_ready, done. A newer deployment may report a member not in this list." }, "taskId": { "type": "string" }, "taskType": { "type": "string", "description": "Usually one of: feature, bug, document, spike, review, ralph, recurring. Other values are accepted where the deployment defines them." }, "title": { "type": "string" } } },
388
413
  invoke: (client, args) => client.tasks.stop(str(args, 'taskId')),
389
414
  },
390
415
  {
@@ -394,8 +419,8 @@ export const CAT_FACTORY_TOOLS = [
394
419
  operationId: 'updatePublicTask',
395
420
  readOnly: false,
396
421
  description: 'Edit a task\'s inputs\n\nEdit a task’s human-authored inputs before it runs: its title, its description, and `fields`, the per-case values for its own task type (checked against the descriptors `GET /api/v1/task-types` serves). All are optional. `fields` is MERGED over what the task already carries — a key you send is written, a key you omit keeps its stored value — because this API does not serve the bag back. This is what makes an input the pre-dispatch gate refused repairable: supply the value it named, then recheck the parked run.\n\nCalls `PATCH /api/v1/tasks/{taskId}` (operation `updatePublicTask`).',
397
- inputSchema: { "type": "object", "properties": { "taskId": { "type": "string", "description": "Path parameter `taskId`." }, "body": { "type": "object", "properties": { "autoStartDependents": { "type": "boolean" }, "description": { "type": "string", "maxLength": 2000 }, "fields": { "type": "object", "additionalProperties": { "anyOf": [{ "type": "string" }, { "type": "array", "items": { "type": "string" } }, { "type": "boolean" }, { "type": "number" }] } }, "title": { "type": "string", "minLength": 1, "maxLength": 200 } }, "description": "The request body." } }, "additionalProperties": false, "required": ["taskId"] },
398
- outputSchema: { "type": "object", "properties": { "autoStartDependents": { "type": "boolean" }, "dependsOn": { "type": "array", "items": { "type": "string" } }, "description": { "type": "string" }, "progress": { "type": "number" }, "pullRequestUrl": { "anyOf": [{ "type": "string" }, { "type": "null" }] }, "runId": { "anyOf": [{ "type": "string" }, { "type": "null" }] }, "serviceId": { "type": "string" }, "status": { "type": "string", "description": "One of: planned, ready, in_progress, blocked, pr_ready, done. A newer deployment may report a member not in this list." }, "taskId": { "type": "string" }, "taskType": { "type": "string", "description": "Usually one of: feature, bug, document, spike, review, ralph, recurring. Other values are accepted where the deployment defines them." }, "title": { "type": "string" } } },
422
+ inputSchema: { "type": "object", "properties": { "taskId": { "type": "string", "description": "Path parameter `taskId`." }, "body": { "type": "object", "properties": { "autoStartDependents": { "type": "boolean" }, "description": { "type": "string", "maxLength": 2000 }, "fields": { "type": "object", "additionalProperties": { "anyOf": [{ "type": "string" }, { "type": "array", "items": { "type": "string" } }, { "type": "boolean" }, { "type": "number" }] } }, "modelPresetId": { "type": "string", "minLength": 1, "maxLength": 120 }, "riskPolicyId": { "type": "string", "minLength": 1, "maxLength": 120 }, "title": { "type": "string", "minLength": 1, "maxLength": 200 } }, "description": "The request body." } }, "additionalProperties": false, "required": ["taskId"] },
423
+ outputSchema: { "type": "object", "properties": { "autoStartDependents": { "type": "boolean" }, "dependsOn": { "type": "array", "items": { "type": "string" } }, "description": { "type": "string" }, "modelPresetId": { "anyOf": [{ "type": "string" }, { "type": "null" }] }, "progress": { "type": "number" }, "pullRequestUrl": { "anyOf": [{ "type": "string" }, { "type": "null" }] }, "riskPolicyId": { "anyOf": [{ "type": "string" }, { "type": "null" }] }, "runId": { "anyOf": [{ "type": "string" }, { "type": "null" }] }, "serviceId": { "type": "string" }, "status": { "type": "string", "description": "One of: planned, ready, in_progress, blocked, pr_ready, done. A newer deployment may report a member not in this list." }, "taskId": { "type": "string" }, "taskType": { "type": "string", "description": "Usually one of: feature, bug, document, spike, review, ralph, recurring. Other values are accepted where the deployment defines them." }, "title": { "type": "string" } } },
399
424
  invoke: (client, args) => client.tasks.update(str(args, 'taskId'), args.body),
400
425
  },
401
426
  {
@@ -461,7 +486,7 @@ export const CAT_FACTORY_TOOLS = [
461
486
  operationId: 'connectPublicEnvironment',
462
487
  readOnly: false,
463
488
  description: 'Connect the workspace to the cluster its environments deploy onto\n\nBind environment provisioning to a Kubernetes cluster: the apiserver, how its TLS is verified, the namespace template, and how an environment URL is derived once manifests are applied. The secret bundle authenticating the connection is write-only; the response reports which secret KEYS were stored and never their values. Idempotent, so re-connecting replaces rather than accumulating.\n\nCalls `POST /api/v1/environments/connections` (operation `connectPublicEnvironment`).',
464
- inputSchema: { "type": "object", "properties": { "body": { "type": "object", "properties": { "connection": { "anyOf": [{ "type": "object", "properties": { "engine": { "const": "kubernetes" }, "kubernetes": { "type": "object", "properties": { "annotations": { "type": "object", "additionalProperties": { "type": "string" } }, "apiServerUrl": { "type": "string", "maxLength": 500 }, "caCertPem": { "type": "string" }, "defaultTtlMs": { "type": "number", "minimum": 60000 }, "imageTemplate": { "type": "string", "maxLength": 500 }, "insecureSkipTlsVerify": { "type": "boolean" }, "label": { "type": "string", "minLength": 1, "maxLength": 120 }, "labels": { "type": "object", "additionalProperties": { "type": "string" } }, "namespaceTemplate": { "type": "string", "minLength": 1, "maxLength": 200 }, "url": { "anyOf": [{ "type": "object", "properties": { "hostTemplate": { "type": "string", "minLength": 1, "maxLength": 500 }, "scheme": { "type": "string", "enum": ["http", "https"] }, "source": { "const": "ingressTemplate" } }, "required": ["hostTemplate", "source"] }, { "type": "object", "properties": { "ingressName": { "type": "string", "minLength": 1 }, "scheme": { "type": "string", "enum": ["http", "https"] }, "source": { "const": "ingressStatus" } }, "required": ["source"] }, { "type": "object", "properties": { "port": { "type": "integer", "minimum": 1, "maximum": 65535 }, "scheme": { "type": "string", "enum": ["http", "https"] }, "serviceName": { "type": "string", "minLength": 1 }, "source": { "const": "serviceStatus" } }, "required": ["serviceName", "source"] }, { "type": "object", "properties": { "gatewayName": { "type": "string", "minLength": 1 }, "scheme": { "type": "string", "enum": ["http", "https"] }, "source": { "const": "gatewayStatus" } }, "required": ["source"] }, { "type": "object", "properties": { "httpRouteName": { "type": "string", "minLength": 1 }, "scheme": { "type": "string", "enum": ["http", "https"] }, "source": { "const": "httpRouteStatus" } }, "required": ["source"] }], "description": "Discriminated by `source` (ingressTemplate | ingressStatus | serviceStatus | gatewayStatus | httpRouteStatus)." } }, "required": ["apiServerUrl", "label", "url"] } }, "required": ["engine", "kubernetes"] }], "description": "Discriminated by `engine` (kubernetes)." }, "secrets": { "type": "object", "additionalProperties": { "type": "string" } } }, "required": ["connection", "secrets"], "description": "The request body." } }, "additionalProperties": false, "required": ["body"] },
489
+ inputSchema: { "type": "object", "properties": { "body": { "type": "object", "properties": { "connection": { "anyOf": [{ "type": "object", "properties": { "engine": { "const": "kubernetes" }, "kubernetes": { "type": "object", "properties": { "annotations": { "type": "object", "additionalProperties": { "type": "string" } }, "apiServerUrl": { "type": "string", "maxLength": 500 }, "caCertPem": { "type": "string" }, "defaultTtlMs": { "type": "number", "minimum": 60000 }, "imageTemplate": { "type": "string", "maxLength": 500 }, "insecureSkipTlsVerify": { "type": "boolean" }, "label": { "type": "string", "minLength": 1, "maxLength": 120 }, "labels": { "type": "object", "additionalProperties": { "type": "string" } }, "namespaceTemplate": { "type": "string", "minLength": 1, "maxLength": 200 }, "url": { "anyOf": [{ "type": "object", "properties": { "hostTemplate": { "type": "string", "minLength": 1, "maxLength": 500 }, "port": { "type": "integer", "minimum": 1, "maximum": 65535 }, "scheme": { "type": "string", "enum": ["http", "https"] }, "source": { "const": "ingressTemplate" } }, "required": ["hostTemplate", "source"] }, { "type": "object", "properties": { "ingressName": { "type": "string", "minLength": 1 }, "scheme": { "type": "string", "enum": ["http", "https"] }, "source": { "const": "ingressStatus" } }, "required": ["source"] }, { "type": "object", "properties": { "port": { "type": "integer", "minimum": 1, "maximum": 65535 }, "scheme": { "type": "string", "enum": ["http", "https"] }, "serviceName": { "type": "string", "minLength": 1 }, "source": { "const": "serviceStatus" } }, "required": ["serviceName", "source"] }, { "type": "object", "properties": { "gatewayName": { "type": "string", "minLength": 1 }, "scheme": { "type": "string", "enum": ["http", "https"] }, "source": { "const": "gatewayStatus" } }, "required": ["source"] }, { "type": "object", "properties": { "httpRouteName": { "type": "string", "minLength": 1 }, "scheme": { "type": "string", "enum": ["http", "https"] }, "source": { "const": "httpRouteStatus" } }, "required": ["source"] }], "description": "Discriminated by `source` (ingressTemplate | ingressStatus | serviceStatus | gatewayStatus | httpRouteStatus)." } }, "required": ["apiServerUrl", "label", "url"] } }, "required": ["engine", "kubernetes"] }], "description": "Discriminated by `engine` (kubernetes)." }, "secrets": { "type": "object", "additionalProperties": { "type": "string" } } }, "required": ["connection", "secrets"], "description": "The request body." } }, "additionalProperties": false, "required": ["body"] },
465
490
  outputSchema: { "type": "object", "properties": { "apiServerUrl": { "type": "string" }, "engine": { "type": "string" }, "label": { "type": "string" }, "provisionType": { "type": "string" }, "secretKeys": { "type": "array", "items": { "type": "string" } } } },
466
491
  invoke: (client, args) => client.environments.connect(args.body),
467
492
  },
@@ -472,7 +497,7 @@ export const CAT_FACTORY_TOOLS = [
472
497
  operationId: 'testPublicEnvironmentConnection',
473
498
  readOnly: false,
474
499
  description: 'Probe a candidate cluster connection without saving it\n\nReach the apiserver with the supplied credentials and report what came back, persisting nothing. Worth a call of its own because the alternative is discovering an unreachable cluster or an expired token on the deploy step of a run that has already paid for a design pass and an implementation. A cluster that refuses the credential is an ANSWER, so it is a 200 carrying `ok: false` rather than an error.\n\nCalls `POST /api/v1/environments/connections/test` (operation `testPublicEnvironmentConnection`).',
475
- inputSchema: { "type": "object", "properties": { "body": { "type": "object", "properties": { "connection": { "anyOf": [{ "type": "object", "properties": { "engine": { "const": "kubernetes" }, "kubernetes": { "type": "object", "properties": { "annotations": { "type": "object", "additionalProperties": { "type": "string" } }, "apiServerUrl": { "type": "string", "maxLength": 500 }, "caCertPem": { "type": "string" }, "defaultTtlMs": { "type": "number", "minimum": 60000 }, "imageTemplate": { "type": "string", "maxLength": 500 }, "insecureSkipTlsVerify": { "type": "boolean" }, "label": { "type": "string", "minLength": 1, "maxLength": 120 }, "labels": { "type": "object", "additionalProperties": { "type": "string" } }, "namespaceTemplate": { "type": "string", "minLength": 1, "maxLength": 200 }, "url": { "anyOf": [{ "type": "object", "properties": { "hostTemplate": { "type": "string", "minLength": 1, "maxLength": 500 }, "scheme": { "type": "string", "enum": ["http", "https"] }, "source": { "const": "ingressTemplate" } }, "required": ["hostTemplate", "source"] }, { "type": "object", "properties": { "ingressName": { "type": "string", "minLength": 1 }, "scheme": { "type": "string", "enum": ["http", "https"] }, "source": { "const": "ingressStatus" } }, "required": ["source"] }, { "type": "object", "properties": { "port": { "type": "integer", "minimum": 1, "maximum": 65535 }, "scheme": { "type": "string", "enum": ["http", "https"] }, "serviceName": { "type": "string", "minLength": 1 }, "source": { "const": "serviceStatus" } }, "required": ["serviceName", "source"] }, { "type": "object", "properties": { "gatewayName": { "type": "string", "minLength": 1 }, "scheme": { "type": "string", "enum": ["http", "https"] }, "source": { "const": "gatewayStatus" } }, "required": ["source"] }, { "type": "object", "properties": { "httpRouteName": { "type": "string", "minLength": 1 }, "scheme": { "type": "string", "enum": ["http", "https"] }, "source": { "const": "httpRouteStatus" } }, "required": ["source"] }], "description": "Discriminated by `source` (ingressTemplate | ingressStatus | serviceStatus | gatewayStatus | httpRouteStatus)." } }, "required": ["apiServerUrl", "label", "url"] } }, "required": ["engine", "kubernetes"] }], "description": "Discriminated by `engine` (kubernetes)." }, "secrets": { "type": "object", "additionalProperties": { "type": "string" } } }, "required": ["connection"], "description": "The request body." } }, "additionalProperties": false, "required": ["body"] },
500
+ inputSchema: { "type": "object", "properties": { "body": { "type": "object", "properties": { "connection": { "anyOf": [{ "type": "object", "properties": { "engine": { "const": "kubernetes" }, "kubernetes": { "type": "object", "properties": { "annotations": { "type": "object", "additionalProperties": { "type": "string" } }, "apiServerUrl": { "type": "string", "maxLength": 500 }, "caCertPem": { "type": "string" }, "defaultTtlMs": { "type": "number", "minimum": 60000 }, "imageTemplate": { "type": "string", "maxLength": 500 }, "insecureSkipTlsVerify": { "type": "boolean" }, "label": { "type": "string", "minLength": 1, "maxLength": 120 }, "labels": { "type": "object", "additionalProperties": { "type": "string" } }, "namespaceTemplate": { "type": "string", "minLength": 1, "maxLength": 200 }, "url": { "anyOf": [{ "type": "object", "properties": { "hostTemplate": { "type": "string", "minLength": 1, "maxLength": 500 }, "port": { "type": "integer", "minimum": 1, "maximum": 65535 }, "scheme": { "type": "string", "enum": ["http", "https"] }, "source": { "const": "ingressTemplate" } }, "required": ["hostTemplate", "source"] }, { "type": "object", "properties": { "ingressName": { "type": "string", "minLength": 1 }, "scheme": { "type": "string", "enum": ["http", "https"] }, "source": { "const": "ingressStatus" } }, "required": ["source"] }, { "type": "object", "properties": { "port": { "type": "integer", "minimum": 1, "maximum": 65535 }, "scheme": { "type": "string", "enum": ["http", "https"] }, "serviceName": { "type": "string", "minLength": 1 }, "source": { "const": "serviceStatus" } }, "required": ["serviceName", "source"] }, { "type": "object", "properties": { "gatewayName": { "type": "string", "minLength": 1 }, "scheme": { "type": "string", "enum": ["http", "https"] }, "source": { "const": "gatewayStatus" } }, "required": ["source"] }, { "type": "object", "properties": { "httpRouteName": { "type": "string", "minLength": 1 }, "scheme": { "type": "string", "enum": ["http", "https"] }, "source": { "const": "httpRouteStatus" } }, "required": ["source"] }], "description": "Discriminated by `source` (ingressTemplate | ingressStatus | serviceStatus | gatewayStatus | httpRouteStatus)." } }, "required": ["apiServerUrl", "label", "url"] } }, "required": ["engine", "kubernetes"] }], "description": "Discriminated by `engine` (kubernetes)." }, "secrets": { "type": "object", "additionalProperties": { "type": "string" } } }, "required": ["connection"], "description": "The request body." } }, "additionalProperties": false, "required": ["body"] },
476
501
  outputSchema: { "type": "object", "properties": { "message": { "anyOf": [{ "type": "string" }, { "type": "null" }] }, "ok": { "type": "boolean" } } },
477
502
  invoke: (client, args) => client.environments.testConnection(args.body),
478
503
  },
@@ -499,15 +524,26 @@ export const CAT_FACTORY_TOOLS = [
499
524
  invoke: (client, args) => client.vcs.getConnection(),
500
525
  },
501
526
  {
502
- name: 'merge_presets_list',
503
- title: 'List the workspace’s merge-threshold presets',
504
- group: 'merge_presets',
505
- operationId: 'listPublicMergePresets',
527
+ name: 'risk_policies_list',
528
+ title: 'List the workspace’s risk policies',
529
+ group: 'risk_policies',
530
+ operationId: 'listPublicRiskPolicies',
531
+ readOnly: true,
532
+ description: 'List the workspace’s risk policies\n\nThe policy library, including which row is the workspace default that a task pinning none resolves. `autoMergeEnabled` is the master switch that decides whether a run can land its pull request without a person; `dryRunRoles` names the roles whose runs the policy forces into dry-run mode, which is the difference between “this policy merges” and “this policy merges for everyone except one role”. A policy also caps CI-fixer attempts, requirement and tester iteration rounds and the release-health watch, which is why it is not called a merge preset; the id is what a task pins as `riskPolicyId`.\n\nCalls `GET /api/v1/risk-policies` (operation `listPublicRiskPolicies`).',
533
+ inputSchema: { "type": "object", "properties": {}, "additionalProperties": false },
534
+ outputSchema: { "type": "object", "properties": { "policies": { "type": "array", "items": { "type": "object", "properties": { "autoMergeEnabled": { "type": "boolean" }, "ciMaxAttempts": { "type": "number" }, "dryRunRoles": { "type": "array", "items": { "type": "string", "description": "One of: admin, member, viewer. A newer deployment may report a member not in this list." } }, "isDefault": { "type": "boolean" }, "name": { "type": "string" }, "policyId": { "type": "string" }, "submissionRestrictedRoles": { "type": "array", "items": { "type": "string", "description": "One of: admin, member, viewer. A newer deployment may report a member not in this list." } } } } } } },
535
+ invoke: (client, args) => client.riskPolicies.list(),
536
+ },
537
+ {
538
+ name: 'model_presets_list',
539
+ title: 'List the workspace’s model presets',
540
+ group: 'model_presets',
541
+ operationId: 'listPublicModelPresets',
506
542
  readOnly: true,
507
- description: 'List the workspace’s merge-threshold presets\n\nThe preset library, including which row is the workspace default that a task pinning none resolves. `autoMergeEnabled` is the master switch that decides whether a run can land its pull request without a person; `dryRunRoles` names the roles whose runs the preset forces into dry-run mode, which is the difference between “this preset merges” and “this preset merges for everyone except one role”.\n\nCalls `GET /api/v1/merge-presets` (operation `listPublicMergePresets`).',
543
+ description: 'List the workspace’s model presets\n\nThe preset library, including which row is the workspace default that a task pinning none resolves. `baseModelId` is the model every agent step runs on under the preset, and `overrides` names the agent kinds that run on something else, which is usually the one that matters: two presets often differ only in what the CODER gets. Whether a preset can actually be dispatched to is NOT repeated here, because the models endpoint already answers it while keeping unconfigured apart from refused-by-policy; join on `baseModelId`.\n\nCalls `GET /api/v1/model-presets` (operation `listPublicModelPresets`).',
508
544
  inputSchema: { "type": "object", "properties": {}, "additionalProperties": false },
509
- outputSchema: { "type": "object", "properties": { "presets": { "type": "array", "items": { "type": "object", "properties": { "autoMergeEnabled": { "type": "boolean" }, "ciMaxAttempts": { "type": "number" }, "dryRunRoles": { "type": "array", "items": { "type": "string", "description": "One of: admin, member, viewer. A newer deployment may report a member not in this list." } }, "isDefault": { "type": "boolean" }, "name": { "type": "string" }, "presetId": { "type": "string" }, "submissionRestrictedRoles": { "type": "array", "items": { "type": "string", "description": "One of: admin, member, viewer. A newer deployment may report a member not in this list." } } } } } } },
510
- invoke: (client, args) => client.mergePresets.list(),
545
+ outputSchema: { "type": "object", "properties": { "presets": { "type": "array", "items": { "type": "object", "properties": { "baseModelId": { "type": "string" }, "isDefault": { "type": "boolean" }, "name": { "type": "string" }, "overrides": { "type": "object", "additionalProperties": { "type": "string" } }, "presetId": { "type": "string" } } } } } },
546
+ invoke: (client, args) => client.modelPresets.list(),
511
547
  },
512
548
  {
513
549
  name: 'webhook_delete',
@@ -1318,7 +1354,7 @@ export const CAT_FACTORY_TOOL_GROUPS = {
1318
1354
  'jobs': 'Headless jobs (a public, inline pipeline run against a brief): start, poll or stream one.',
1319
1355
  'services': 'The workspace\'s board services, the frames tasks are created under: list them, create one (optionally backed by a repository), or patch one, including declaring where the manifests for its per-run environments are read from.',
1320
1356
  'spec': 'A service\'s in-repo specification: the structured requirement tree (modules → feature groups → requirements, with their acceptance criteria and domain rules), the Gherkin rendered from it, and the branch and commit the read describes. Read-only; the requirement ids are the join key onto a run\'s report and outcome.',
1321
- 'repos': 'The repositories this workspace can back a service with, and which service each already backs (the discovery half of service creation), plus creating a brand-new one: a bootstrap writes the repository with an agent and reports the board service it materialises.',
1357
+ 'repos': 'The repositories this workspace can back a service with, and which service each already backs (the discovery half of service creation); the ones its connection could reach but has not adopted yet, and adopting one by name; plus creating a brand-new one, where a bootstrap writes the repository with an agent and reports the board service it materialises.',
1322
1358
  'tasks': 'A board task\'s whole lifecycle: create, edit, start, stop, retry, watch, delete, plus the two relationships that outlive a create: the tasks it waits for, and the requirements documents it is built against.',
1323
1359
  'pipelines': 'The pipelines a task can be started with, and whether each is headless-startable.',
1324
1360
  'task_types': 'What a task can be created AS in this workspace (the built-in kinds plus the operations the deployment registered), and the fields each one accepts.',
@@ -1326,7 +1362,8 @@ export const CAT_FACTORY_TOOL_GROUPS = {
1326
1362
  'environments': 'The cluster this workspace provisions per-run environments onto: probe a candidate connection without saving it, or bind one. The credential is write-only, so a read reports which secret keys are stored and never their values.',
1327
1363
  'models': 'The models a run in this workspace could actually dispatch to, and why an unavailable one is unavailable: unconfigured, or refused by the account model-family policy. Those two need opposite fixes.',
1328
1364
  'vcs': 'The workspace\'s source-control connection: which account it talks to, how it authenticates, and whether it may create repositories and write workflow files. Both permissions are enforced by the provider at push time, so reading them beats discovering one missing halfway through an automated setup.',
1329
- 'merge_presets': 'The merge-threshold presets a task can resolve, including which is the workspace default: what decides whether a run can land its pull request without a person.',
1365
+ 'risk_policies': 'The risk policies a task can pin, including which is the workspace default: what decides whether a run can land its pull request without a person, and how many attempts its CI fixer, requirement rounds and release watch are given. Broader than merging, which is why it is not called a merge preset.',
1366
+ 'model_presets': 'The model presets a task can pin, including which is the workspace default: what decides which model each agent step runs on, and so what a run costs. Availability is not repeated here; join `baseModelId` against the models group, which keeps unconfigured and policy-refused apart.',
1330
1367
  'webhook': 'The workspace\'s outbound endpoints: register, inspect or remove the receivers that notifications, run-lifecycle events and health alerts are pushed to. The unnamed calls address the `default` endpoint; the named ones let an integration enroll its own receiver, with its own signing secret and filters, beside whatever else is registered.',
1331
1368
  'usage': 'The workspace\'s money, two ways: the billing period\'s metered budget position with the per-model breakdown behind it, and spend over a window sliced by the dimension a budget is kept against (a repository, a tracker ticket, one run).',
1332
1369
  'me': 'What the calling key is and what it may do — the self-check an integration runs at startup.',