Skip to content

feat(integrations): give the agent each integration's full toolset - #410

Merged
agjs merged 1 commit into
mainfrom
feat/full-integration-toolsets
Sep 29, 2026
Merged

agjs merged 1 commit into
mainfrom
feat/full-integration-toolsets

Conversation

@agjs

@agjs agjs commented Sep 29, 2026

Copy link
Copy Markdown
Collaborator

Problem

The curated verbs were a cap, not a convenience. With a linear server connected, tsforge hid all 68 of Linear's MCP tools. The agent had only create + comment: it couldn't rename an issue, set status, priority or assignee, or touch projects, milestones or labels. Worse, it told users "the harness only supports create and comment". Twenty had no delete. Chatwoot had no label removal and nothing beyond its five ops.

Fix

  • Full toolsets by default for Linear, Notion, Sentry and Twenty. Every mcp__<server>__* tool is offered with the server's own input schemas, which also retires tsforge-side key guessing (the class of the earlier teamId bug). The curated verbs stay as shortcuts (linear_start, twenty_read, …). TSFORGE_<NAME>_RAW=0 opts back into shortcuts-only.
  • Read/write policy for raw calls. A raw integration call is classified by what it does:
    • get_/list_/search… tools are integration_read, allowed in plan mode.
    • Everything else is integration_write, gated by consent like the verbs.
    • An unknown verb is a write.
    • Twenty's execute_tool follows its inner tool: find_many_* reads, delete_one_* writes.
    • The unregistered-server block covers these kinds too.
  • Chatwoot chatwoot_api: any endpoint on the configured instance (contacts, starting conversations, canned responses, teams, custom attributes, deletes, reports). GET is a read and every other method a write. The path can't leave the instance (no scheme or host, no ..). Plus a new chatwoot_write unlabel op.
  • Guidance and tool text now tell the agent it has everything. The old text said "there is deliberately no status op" and "There is no delete", which the agent repeated to users. Docs are updated.

What Linear's own MCP lacks, and the docs say so: there's no issue delete (cancel it or mark it a duplicate instead), and initiatives only appear if the Linear plan includes them.

Verification

  • Live Linear: all 68 tools reach the model with Linear's schemas (save_issue, save_project, save_milestone, save_issue_label, …). list_projects, list_issue_labels and list_teams ran in plan mode through real policy and dispatch.
  • Live Chatwoot: chatwoot_api read canned responses, teams, custom attributes and contacts. It then created a test contact, deleted it, and confirmed the 404.
  • The classifier is tested against Linear's real 68 tool names, each one landing on the right side.
  • Mutation-checked: 8 deliberate breaks, all caught. These include the raw-default flag, the classification, the unregistered-server block, execute_tool inner routing, the read-name boundary (getaway isn't a read), chatwoot_api path safety and unlabel.
  • bun run ci:local: 6343 pass, 0 fail, and all PTY suites pass. Docs build is clean.

The curated verbs capped what the agent could do: with a `linear` server
connected, all 68 of Linear's MCP tools were hidden and the agent had only
create + comment — no editing an issue, no status, no projects, milestones or
labels. Twenty had no delete; Chatwoot no label removal or anything beyond
its five ops.

- Linear, Notion, Sentry, Twenty: the full `mcp__<server>__*` toolset is now
  offered by default, with the server's own input schemas (so no tsforge
  key-guessing either). The curated verbs stay as shortcuts. TSFORGE_<NAME>_RAW=0
  opts back into shortcuts-only.
- Policy: a raw integration call is classified by what it does — get_/list_/
  search… are integration_read (allowed while planning), anything else
  integration_write (consent-gated like the verbs); an unknown verb is a write.
  Twenty's execute_tool follows its inner tool (find_many_* reads,
  delete_one_* writes). The unregistered-server block now covers these kinds.
- Chatwoot: chatwoot_api reaches any endpoint on the configured instance
  (contacts, conversations, canned responses, teams, deletes…), GET a read and
  every other method a write; the path cannot leave the instance. New
  chatwoot_write unlabel.
- Guidance and tool descriptions tell the agent it has everything (the old
  text said "no status op" / "there is no delete", which it repeated to the
  user); docs updated.

Verified live: all 68 Linear tools reach the model with Linear's schemas and
reads run in plan mode through real policy + dispatch; chatwoot_api read the
account and created + deleted a test contact.
@cloudflare-workers-and-pages

Copy link
Copy Markdown

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Preview URL Updated (UTC)
✅ Deployment successful!
View logs
tsforge 2c5f022 Commit Preview URL

Branch Preview URL
Sep 29 2026, 01:34 PM

@agjs
agjs merged commit 10d3390 into main Sep 29, 2026
9 checks passed
@agjs
agjs deleted the feat/full-integration-toolsets branch September 29, 2026 13:43
@agjs agjs mentioned this pull request Sep 29, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant