feat(agent-toolkit): agents subgraph tools expansion#343
Conversation
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Implements the get_agent_catalog READ tool that fetches the account-wide catalog of available trigger types or skills for monday platform agents via the dev API version. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…d test assertion Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Implements list/add/remove actions for agent triggers, using the dev API versionOverride. All 10 tests pass. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…rigger actions Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Implements the manage_agent_skills tool supporting add/remove actions, with full test coverage for happy paths, request shape verification, and error propagation. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…null response tests Use explicit if/else branching in executeInternal and add tests verifying the ?? false fallback when the API returns null for add_skill_to_agent or remove_skill_from_agent. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Implements the update_agent WRITE tool that patches an existing monday platform agent's profile or execution plan, including only the provided fields in the mutation input. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Throw explicit error when update_agent returns no data instead of falling back to {}
- Strengthen agent_model describe string to match create_agent's STRONGLY DISCOURAGED wording
- Add profile.name assertion to happy-path test to confirm response forwarding
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Adds manage_agent_state tool supporting activate, deactivate, and run actions for monday platform agents. Includes 11 unit tests covering happy paths, error propagation, versionOverride, default inactive_reason, and null fallbacks. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ety, and test coverage Restructure try/catch blocks so return statements are outside the try, add explicit null check for run_agent response, and add test coverage for null run_agent case. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Implements list/add/update/remove actions for managing a monday platform agent's access to boards and docs, following the restructured try/catch pattern from manage-agent-state-tool. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…agent_knowledge test coverage Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…safety checks Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…s list note Move return statements inside try blocks (using const) for all branches in manage-agent-state-tool.ts and manage-agent-knowledge-tool.ts, eliminating non-null assertions. Add a note to manage_agent_skills description that there is no list action because the platform does not yet expose that query. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ills tool Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- create_agent: guide calling manage_agent_state(activate) after creation instead of redirecting to the monday.com UI - manage_agent_state: narrow inactive_reason to DEACTIVATED_BY_USER only (remove internal ACCOUNT_LEVEL_BLOCKING); describe when to pass it vs omit - manage_agent_knowledge: document that files in the list response cannot be managed via this tool and redirect to the platform UI - manage_agent_skills: clarify create→add flow — use the id returned by action:create directly, no catalog lookup needed - update-agent-tool.test: add missing null-response test for update_agent returning no data - manage-agent-state-tool.test: update test to reflect removed ACCOUNT_LEVEL_BLOCKING enum value Co-authored-by: Cursor <cursoragent@cursor.com>
RanEldann
left a comment
There was a problem hiding this comment.
Strong addition overall — the 6 new tools follow established patterns in the toolkit, tests cover happy paths plus most error/null/validation cases, and the GraphQL operations are correctly wired. Auth model is fine: JWT-scoped, every mutation goes through authorizeAgentAction('edit', agentId), no security concerns from the toolkit perspective.
Three blocking issues
- Prettier will fail CI —
create-agent-tool.ts:166-171has an 8-space indent in a 6-space block. Looks like an editor mishap during the latest edits. .optional()+ manualthrowinstead ofz.discriminatedUnionacross all fourmanage_*tools. The repo already uses discriminated unions in 4 places (update-doc-tool.schema.ts,create-doc-tool.ts). The current pattern means LLMs see all action-conditional fields asoptionalin the JSON schema and only learn requirements via runtime errors.field_values: z.record(z.unknown())inmanage_agent_triggersprovides no schema guidance to the LLM. The description tells it to callget_agent_catalogand followfield_schemas, but the JSON schema is fully untyped — three different shape conventions hide behind one record.
Theme: description ↔ code drift
Several tool descriptions claim or imply behaviors the code doesn't deliver:
inactive_reason's "omit if ambiguous" is meaningless because the code defaults to the same value either way (it's also a 1-value enum, so the field is pure noise)update_agent's "profile or execution plan" overpromises —avatar_url,background_color,goal,user_promptaren't inUpdateAgentInputagent_model's "degrades the agent's performance" is wrong — invalid values are rejected by the server, not degradedmanage_agent_triggersdoesn't mention that the catalog excludes 3rd-party (OAuth) triggers — LLMs will look up Slack/Salesforce and be confused they're missingmanage_agent_knowledge's "call list first" is overstated — only needed forupdate/remove, notadd
Theme: cross-tool inconsistency
update_agentreturns{ content: agent }while siblings return{ content: { message, agent } }— LLM has to learn per-tool shapesagent_id(new tools) vsid(existingupdate/get/delete-agent) — same concept, two namescountfield on most list responses but missing from knowledgelist
Nits
- Missing CHANGELOG.md entry for 5.11.0 (the
agent-toolkit/CLAUDE.mdmandates this — though to be fair, CHANGELOG was already stale at 5.7.1) update-agent-tool.test.tshas 3expect()s in a singleit()— violates the "one assert per test" rule used elsewhererethrowWithContextstrings are verbose and inconsistent — 4 of them have double-"agent" ("list agent knowledge for monday platform agent", etc.). The"monday platform agent"suffix is wasted tokens in every error- Domain validation errors (e.g.
throw new Error('create_agent_skill returned no data')) get double-wrapped to"Failed to X: <inner>"because the throw is inside thetryblock trigger_uuidreturned bymanage_agent_state action:runhas no companion query yet — the description should say "store for future correlation; no run-status query exists yet"manage_agent_knowledge listreturns afilesarray the tool can't act on; the description has to apologize. Either drop from the GraphQL selection or split into a separate read tool
Recommendations
- Fix Prettier first (item 1) — that's CI.
- Convert the four
manage_*schemas toz.discriminatedUnion('action', [...]). This single change fixes findings 2, 4, 8, 13, plus removes the manual cross-field throws. - Fix the description honesty issues (medium-severity but cheap) — they directly affect tool-call success rate in production.
- Align
update_agent's return shape and renameid→agent_idfor consistency. - Optional but recommended: type
agent_modelasz.nativeEnum(AgentModel)so wrong values fail at zod time with a clear list of valid options, instead of producing a confusing GraphQL error.
Nice work overall — happy to clarify or drop any of the smaller items.
- Fix Prettier indent in create-agent-tool.ts (CI blocker)
- update_agent: rename id→agent_id for consistency with new tools,
use z.nativeEnum(AgentModel), fix description to list only updatable
fields, add empty-input guard, fix return shape to { message, agent }
- manage_agent_state: remove inactive_reason (1-value enum always
defaulted), hardcode DeactivatedByUser, clarify trigger_uuid has no
companion run-status query
- manage_agent_knowledge: scope "call list first" to update/remove,
add count field to list response
- manage_agent_triggers: narrow field_values to typed union, add OAuth
exclusion note, clarify add returns no node_id
- get_agent_catalog: add .min(1) to block_reference_ids
- Update tests: split 3-expect test, agent_id naming, new return shape,
simplified inactive_reason coverage
- Add CHANGELOG.md entry for 5.11.0
Co-authored-by: Cursor <cursoragent@cursor.com>
…_skills create_agent_skill (account-catalog CRUD) and manage_agent_skills (attach/detach on a specific agent) operate on different domain entities, so they now live in separate tools. manage_agent_skills action enum shrinks to [add, remove]; all create logic and the createAgentSkill GraphQL mutation move to the new create_agent_skill tool. Co-authored-by: Cursor <cursoragent@cursor.com>
RanEldann
left a comment
There was a problem hiding this comment.
Nadav 👑 you're a king. Genuinely impressive turnaround — almost every finding addressed, several solved structurally (extracting create_agent_skill, dropping inactive_reason entirely), and descriptions are now honest about what each tool actually does. This is a major enhancement — agents can now manage the full agent lifecycle end-to-end with schemas they can actually act on. Approving 🎉
One thought on the discriminated-union pushback before we move on — I think the blocker is smaller than it looked, and the LLM ergonomics win is real:
The actual constraint is just Input extends ZodRawShape in BaseMondayApiTool plus 3–4 z.object(inputSchema) sites in toolkit.ts. ~15 lines, fully backwards-compatible:
// base-monday-api-tool.ts
export type ToolInputSchema = ZodRawShape | ZodTypeAny | undefined;
export abstract class BaseMondayApiTool<
Input extends ToolInputSchema,
Output extends Record<string, unknown> = never,
>// toolkit.ts — small helper
function buildZodSchema(input: any): ZodTypeAny | undefined {
if (!input) return undefined;
if (typeof input.safeParse === 'function') return input; // already a Zod schema
return z.object(input); // ZodRawShape — existing tools
}
// then replace the 4 z.object(inputSchema) sites with buildZodSchema(inputSchema)Then each manage_* schema becomes z.discriminatedUnion('action', [...]) with one z.object per variant. zodToJsonSchema produces oneOf with per-action required arrays — the LLM sees "for action=add, resource_id + scope_type + permission_type are required" in the schema itself instead of parsing it out of prose.
LLMs miss conditional prose ("Required for action:X") reasonably often. Discriminated oneOf cuts misuse-on-first-try meaningfully on real workloads. Bonus: drops the manual if (!input.x) throw blocks and TypeScript narrows the input type per case branch in executeInternal.
Fully backwards-compatible — every existing ZodRawShape tool keeps working unchanged. Not blocking, just smaller than the "follow-up" reply implied. Up to you whether to do it here or a separate PR 🙂
Great work 🚀
- Fix CHANGELOG entry to list actual tool names (manage_agent, manage_agent_capabilities, manage_agent_knowledge, agent_catalog) instead of stale names from an earlier design iteration - Refactor ManageAgentKnowledgeTool.executeInternal from if/else chain to switch with dedicated private handler methods, consistent with all other tools in the PR - Document readOnlyMode limitation in AgentCatalogTool description - Clarify zero-field create behavior and strengthen delete warning in ManageAgentTool description - Clarify list-skills gap note in ManageAgentCapabilitiesTool to distinguish catalog browsing from per-agent skill listing Co-authored-by: Cursor <cursoragent@cursor.com>
RanEldann
left a comment
There was a problem hiding this comment.
Did another focused pass on the restructure (consolidation from 9 → 4 tools), specifically on tool grouping and per-tool API legibility. Three concerns surfaced that I didn't catch in the May 14 approval — plus a security regression that re-opens something we'd already mitigated. Walking back the approval; details below.
Headline: tool count is the wrong optimization target; per-tool clarity is the right one. Several of the bundles are bundling unrelated things — and the bundling causes real costs (mixed destructiveHint, mixed READ/WRITE classification, all-optional schemas the LLM can't introspect).
High
🔴 inactive_reason re-exposes ACCOUNT_LEVEL_BLOCKING to LLMs (security regression). Prior version Zod-restricted to DEACTIVATED_BY_USER / hardcoded the value. The platform-side resolver runs blockApp() for the entire account on ACCOUNT_LEVEL_BLOCKING without an admin gate (verified in microservices/monday-agents/.../update-agent-state.ts:73; REST has the MANAGE_ACCOUNT_AGENTS gate, GraphQL doesn't). A user with edit on one agent can now ask the LLM to "block this for the account" and the call goes through. Inline comment below.
Medium — structural (the actual focus of this round)
These are the consolidation choices that look efficient (1 tool replaces N) but cost more than they save in LLM-correctness:
agent_catalogisWRITEbecausecreate_skillis bundled withlist_triggers/list_skills. Description self-acknowledges: "In deployments with readOnlyMode enabled, catalog browsing is therefore unavailable." Read-only LLM sessions can't even discover trigger types / skill IDs they need before any add operation. The split was correct in commit68dffd0; merging back was a regression.manage_agentmixes 3 unrelated categories (CRUD: create/get/update/delete; state: activate/deactivate; execution: run). 13 mostly-optional fields under 7 actions.deletepoisons the whole tool withdestructiveHint: true. Splitting into 3 (manage_agentfor CRUD,set_agent_state,run_agent) buys per-tool honesty in annotations, ~5-field tools instead of 13, no false-positive destructive warnings on non-destructive actions.manage_agent_capabilitiesmixes triggers + skills (orthogonal concepts) and ends up with an asymmetric capability surface —list_triggersexists per-agent,list_skillsper-agent doesn't (it's inagent_catalog, account-wide). LLM has to remember the gap. The original split intomanage_agent_triggers+manage_agent_skillswas structurally cleaner.
Medium — regressions vs my May 14 approval
agent_model: z.string()+as AgentModelcast — wasz.nativeEnum(AgentModel)after the prior fix. Invalid values now bypass Zod and fail at the GraphQL server with confusing errors. The "STRONGLY DISCOURAGED" prose is back unnecessarily.idvsagent_idinconsistency — now between sibling tools.manage_agentusesid;manage_agent_capabilitiesandmanage_agent_knowledgeuseagent_id. Same concept, two names within the new toolkit.destructiveHint: trueon a 7-action tool — per-tool not per-action; MCP clients warn on everyget/update/activate/run.
Medium — API ergonomics
createaction has two sub-modes (AI:prompt+agent_model; manual: 7 profile fields). Same action name, different inputs, runtime guard "Do not mix both." — that warning exists because the API invites mixing.getaction is two operations: withidreturns one agent; withoutidlists owned. Different output shapes behind one action name.- Discriminated-union concern is now bigger.
manage_agenthas 13 conditional fields under 7 actions — the JSON schema still gives no per-actionrequired. The base-class blocker is real, but the ~15-line fix sketched in my May 14 approval comment becomes higher-leverage as the consolidation grows.
Minor
- Cross-tool
list_triggerscollision — exists in bothmanage_agent_capabilities(per-agent attached) andagent_catalog(account-wide available). Disambiguation by tool name only. agent_catalogname implies browse-only but the tool also creates skills.- Cross-tool workflow chains (
agent_cataloglookup →manage_agent_capabilitiesadd) are described in prose only, not in schema.
What I'd actually change
If I were doing this myself, in order:
- Fix
inactive_reason(security) — must. - Split
manage_agent→manage_agent(CRUD) +set_agent_state+run_agent. ThedestructiveHint, sub-modecreate, and two-opgetissues all dissolve. - Split
agent_catalogback intoagent_catalog(READ) +create_agent_skill(WRITE). RestoresreadOnlyModeand the name fits. - Split
manage_agent_capabilitiesback intomanage_agent_triggers+manage_agent_skills. Removes the asymmetry. - Restore
z.nativeEnum(AgentModel)andagent_idnaming. - Discriminated-union refactor is still worth a separate PR — concrete sketch in the prior approval thread.
End state: ~7 tools, each with a tight coherent API. The original 9-tool layout was structurally close to this — the consolidation overshot. The 6-tool plan above hits a similar reduction goal without the bundling costs.
Keep manage_agent_knowledge exactly as-is — it's the model the others should follow.
Appreciate the iterations on this PR — the description quality and test coverage are great, this is just structural feedback. Happy to chat through any of it.
| plan: z.string().trim().min(1).optional().describe('Used with action:"update". New step-by-step execution plan in markdown.'), | ||
| // deactivate | ||
| inactive_reason: z | ||
| .enum(['DEACTIVATED_BY_USER', 'ACCOUNT_LEVEL_BLOCKING']) |
There was a problem hiding this comment.
🔴 [High — security regression] Re-introducing ACCOUNT_LEVEL_BLOCKING to the LLM-callable enum re-opens the platform's GraphQL authz hole. Verified in the prior security pass: microservices/monday-agents/src/agents/services/agent-management-service/update-agent-state.ts:73 calls PlatformApiManagementHttpClient.blockApp(...) with no admin gate when inactiveReason === ACCOUNT_LEVEL_BLOCKING. The REST middleware (permission-middleware.ts:119–150) gates this with MANAGE_ACCOUNT_AGENTS; the GraphQL path doesn't. The previous version of this PR mitigated by Zod-restricting to DEACTIVATED_BY_USER only, then later removed the field entirely.
Fix: re-restrict to 'DEACTIVATED_BY_USER' only, or drop the field (the server defaults work). Either is fine — the Zod gate is the only defense in this layer until the platform team adds the GraphQL admin check.
| .describe( | ||
| 'Used with action:"create" (AI mode). Plain-language description of what the agent should do. Platform uses this to generate profile, goal, and plan via AI. Be specific about domain and tasks.', | ||
| ), | ||
| agent_model: z |
There was a problem hiding this comment.
[Medium — type-safety regression] This was z.nativeEnum(AgentModel) after the May 14 fix — invalid values failed at Zod with a clear list of valid options. Now z.string().trim().min(1).optional() + as AgentModel cast at line 273 means any string passes Zod and fails at the GraphQL server with a confusing error.
Fix: restore z.nativeEnum(AgentModel).optional(); drop the cast at line 273; the giant "STRONGLY DISCOURAGED" paragraph can shrink to one line since invalid options now fail at parse time.
| .describe( | ||
| '"create" — create a new agent (AI mode: pass "prompt" / manual mode: pass name/role/etc). "get" — fetch agents by id or list owned agents. "update" — modify mutable fields on an existing agent. "delete" — permanently delete an agent (irreversible). "activate" — transition agent to ACTIVE. "deactivate" — transition agent to INACTIVE. "run" — manually enqueue an agent run (fire-and-forget).', | ||
| ), | ||
| id: z |
There was a problem hiding this comment.
[Medium — naming inconsistency] This tool uses id; manage_agent_capabilities and manage_agent_knowledge (sibling new tools) use agent_id. Same concept, two names within the new toolkit.
Fix: rename to agent_id here for consistency with the other 3 new tools, and remap to id only at the GraphQL variables boundary.
|
|
||
| export const manageAgentToolSchema = { | ||
| action: z | ||
| .enum(['create', 'get', 'update', 'delete', 'activate', 'deactivate', 'run']) |
There was a problem hiding this comment.
[Medium — grouping] 7 actions across 3 unrelated categories: CRUD (create/get/update/delete), state (activate/deactivate), execution (run). Symptoms of the mismatch:
deleteforcesdestructiveHint: trueon the whole tool — everyget/update/activate/runtriggers MCP destructive warnings.runis a fire-and-forget side effect that doesn't share inputs/outputs with the others.getis two operations (fetch one withid, list owned withoutid).createhas two sub-modes (AI / manual) — different validation, different mutations, runtime guard "Do not mix both."- 13 mostly-optional fields with "Used with action:X" prose. JSON schema gives no per-action
required.
Suggested split:
manage_agent→create | get | update | delete(CRUD;destructiveHint: trueis honest)set_agent_state→activate | deactivate(idempotent state transitions)run_agent→ standalone tool (fire-and-forget)
Net: 3 tools instead of 1, but each ~5 fields and coherent. Items 4, 7, 8, 13 from the review all dissolve in this split.
| annotations = createMondayApiAnnotations({ | ||
| title: 'Manage monday Platform Agent', | ||
| readOnlyHint: false, | ||
| destructiveHint: true, |
There was a problem hiding this comment.
[Medium — annotation regression] destructiveHint: true is per-tool, not per-action. With 7 actions in one tool, this means MCP clients that surface destructive warnings will warn on every get, update, activate, run call — even though only delete is actually destructive. False-positive friction.
Fixed by splitting delete to its own tool (or to manage_agent only), making the annotation honest.
| } | ||
| } | ||
|
|
||
| private async handleCreate(input: ToolInputType<typeof manageAgentToolSchema>): Promise<ToolOutputType<never>> { |
There was a problem hiding this comment.
[Medium — sub-modes footgun] create has two sub-modes:
- AI mode:
prompt(+ optionalagent_model) - Manual mode: 7 profile fields (
name,role,role_description,avatar_url,gender,background_color,user_prompt)
Same action name, completely different inputs, different mutations called (createAgentMutation vs createBlankAgentMutation), and a runtime guard at lines 175–177: "Do not mix both." The guard exists because the API invites mixing.
Fix options:
- Split into two actions:
create_with_promptandcreate_blank(clearest) - Or two tools (
create_agent+create_blank_agent) - Or — if keeping merged — at minimum mark the field groups in the schema description so the LLM sees the boundary
| } | ||
|
|
||
| private async handleGet(input: ToolInputType<typeof manageAgentToolSchema>): Promise<ToolOutputType<never>> { | ||
| if (input.id !== undefined) { |
There was a problem hiding this comment.
[Medium — overloaded action] get does two things: with id returns a single agent ({ message, agent }); without id lists owned agents ({ message, count, agents: [] }). Different output shapes behind one action name.
Not a deal-breaker but worth surfacing in the action enum: split into get | list so the LLM sees two distinct ops with predictable return shapes.
|
|
||
| export class AgentCatalogTool extends BaseMondayApiTool<typeof agentCatalogToolSchema> { | ||
| name = 'agent_catalog'; | ||
| type = ToolType.WRITE; |
There was a problem hiding this comment.
[Medium — readOnlyMode trap] ToolType.WRITE because of create_skill. The description acknowledges the cost:
"list_triggers and list_skills are read-only operations, but this tool is classified as WRITE because it also creates skills. In deployments with readOnlyMode enabled, catalog browsing is therefore unavailable."
That's a self-acknowledged regression. Read-only LLM sessions can't discover trigger types or skill IDs — meaning they can't even prepare an add_trigger/add_skill call.
This was correctly split in commit 68dffd0: agent_catalog (READ) + create_agent_skill (WRITE). Re-merging was the regression. Suggest reverting to that split — name fits each tool, readOnlyMode works.
| }; | ||
|
|
||
| export class AgentCatalogTool extends BaseMondayApiTool<typeof agentCatalogToolSchema> { | ||
| name = 'agent_catalog'; |
There was a problem hiding this comment.
[Minor — naming] "Catalog" implies a collection you browse, but this tool also authors entries (create_skill). After splitting WRITE off (per the prior comment), the name fits cleanly: agent_catalog becomes browse-only, and the authoring goes to create_agent_skill.
|
|
||
| export const manageAgentCapabilitiesToolSchema = { | ||
| action: z | ||
| .enum(['list_triggers', 'add_trigger', 'remove_trigger', 'add_skill', 'remove_skill']) |
There was a problem hiding this comment.
[Medium — orthogonal concepts in one tool] Triggers (when an agent runs) and skills (what it can do) are unrelated mechanisms that happen to both attach to an agent. Mixing them creates an asymmetric capability surface:
list_triggers ← exists (per-agent)
add_trigger ← exists
remove_trigger ← exists
[list_skills] ← MISSING per-agent (lives in agent_catalog, account-wide)
add_skill ← exists
remove_skill ← exists
The LLM has to know:
- "list triggers attached to this agent" →
manage_agent_capabilities - "list skills attached to this agent" → not supported by platform
- "list skills available to attach" →
agent_catalog(different tool)
The description has to apologize: "There is no action to list which skills are currently attached to a specific agent."
Suggest reverting to the prior structure: manage_agent_triggers (list/add/remove) + manage_agent_skills (add/remove until the platform exposes per-agent listing). The original split was structurally cleaner.
monday item
https://monday.monday.com/boards/10045819454/pulses/10045820228
Summary
@mondaydotcomorg/agent-toolkitcovering the full agents subgraph surfaceget_agent_catalog— discovers available trigger types and skills account-wide (READ)manage_agent_triggers— list, add, and remove triggers on an agent (WRITE)manage_agent_skills— create custom skills, attach and detach skills from an agent (WRITE)update_agent— update an agent's name, role, description, or execution plan (WRITE)manage_agent_state— activate, deactivate, or manually run an agent (WRITE)manage_agent_knowledge— list, grant, update, and revoke an agent's access to boards and docs (WRITE)5.11.0Design decisions
get_agent_catalogbefore adding triggers or skillsmanage_agent_triggersandmanage_agent_knowledgeinclude alistaction to support the lookup-before-mutate pattern (getnode_id/ inspect current state before remove/update)versionOverride: 'dev'— the agents subgraph is still on the dev API versionmanage_agent_skillsconsolidates skill creation (create_agent_skillmutation) alongside attach/detach in one tool since they're all skill management operationsshared/Test plan
npm testpasses (1013 tests across 55 suites)npm run buildcompiles cleanly🤖 Generated with Claude Code