feat(composio): teach the model to reach for Composio - #330
Open
plombeer31 wants to merge 1 commit into
Open
Conversation
Mounting Composio's meta-tools is not enough on its own. In the catalog they read as four opaque mcp.composio.COMPOSIO_* entries with nothing to say that "email this to Ivan" is now possible, so the model answers "I can't send email" while holding a tool that sends email. Adds a four-line `### integrations` section to the stable prefix that names the flow: search first, never guess an app tool's name, execute what you found, and if the account is not connected yet put the sign-in link in a `reply` so the user can click it. That last point is why no new rendering code is needed. Tool results are not linkified in chat, but replies are -- they already get OSC 8 links and clickable chips -- so routing the connect URL through `reply` reuses the surface that exists instead of teaching the tool renderer about links. Derived, not flagged: the section keys off `mcp.composio.COMPOSIO_SEARCH_TOOLS` being present in the descriptor list, so it cannot drift out of sync with what actually mounted, and it needs no new plumbing through BuildPromptInput. The text is ours rather than Composio's `experimental.assistive_prompt` (which their session response offers, ready to drop in). Piping a remote-controlled string into the system prompt would let a third party silently re-steer the agent, and any edit on their side would invalidate the KV-cached prefix for every user at once. The list of already-connected apps is deliberately left out. It would be useful, but it changes the moment the operator authorises something -- mid-session -- and the stable prefix is the one part of the prompt that must not move. Placement is between `### capabilities` and `### instructions`, so persona, rules, skills and the whole tools catalog stay byte-identical whether or not Composio is configured; with no key the section is absent entirely and the prefix matches pre-integration builds. No approval work was needed after all: Composio annotates SEARCH_TOOLS and GET_TOOL_SCHEMAS `readOnlyHint: true` and the two mutating tools destructive, which is exactly what mcp-tool-adapter already gates on. Discovery flows unprompted and every write to a real account still hits the approval gate, with no per-tool ACL override and no change to the documented MCP invariants. Verified on a real runtime: with a key the section renders after a 4-tool Composio catalog; with no key it is absent.
plombeer31
force-pushed
the
feat/integrations-telegram
branch
from
September 4, 2026 21:56
de326ec to
3819f04
Compare
plombeer31
force-pushed
the
feat/composio-seamless
branch
from
September 4, 2026 21:56
891db54 to
a0510a8
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Mounting Composio's meta-tools isn't enough on its own. In the catalog they read as four opaque
mcp.composio.COMPOSIO_*entries with nothing to say that "email this to Ivan" is now possible — so the model answers "I can't send email" while holding a tool that sends email.This adds a four-line
### integrationssection to the stable prefix that names the flow: search first, never guess an app tool's name, execute what you found, and if the account isn't connected yet put the sign-in link in areply.Why that last line means no new rendering code
Tool results aren't linkified in chat, but replies are — they already get OSC 8 links and clickable
[link]chips. Routing the connect URL throughreplyreuses the surface that already exists, instead of teaching the tool renderer about links (a change to a much busier surface for a strictly worse result).Derived, not flagged
The section keys off
mcp.composio.COMPOSIO_SEARCH_TOOLSbeing present in the descriptor list rather than a newcomposioActiveboolean threaded throughBuildPromptInput. The descriptors already reflect exactly what mounted this boot, so the guidance cannot drift out of sync with the tools it describes — and replay gets it for free.Why our text, not Composio's
Composio's session response ships an
experimental.assistive_promptthat would drop straight in. I didn't use it:A short local paragraph costs a few dozen tokens and keeps both properties.
Also deliberately omitted: the list of already-connected apps. Genuinely useful, but it changes the moment the operator authorises something — mid-session — and the stable prefix is the one part of the prompt that must not move. The model can ask Composio directly.
KV-cache placement
Between
### capabilitiesand### instructions. Persona, rules, skills and the entire tools catalog stay byte-identical whether or not Composio is configured; with no key the section is absent and the prefix matches pre-integration builds. A test pins all three properties.The approval work turned out to be unnecessary
The plan flagged a risk: if Composio didn't tag its discovery tools
readOnlyHint, every search would need approval and the seamlessness would die. Reading the live endpoint settled it —readOnlyHintCOMPOSIO_SEARCH_TOOLStrueCOMPOSIO_GET_TOOL_SCHEMAStrueCOMPOSIO_MANAGE_CONNECTIONSfalse, destructiveCOMPOSIO_MULTI_EXECUTE_TOOLfalse, destructive— which is exactly what
mcp-tool-adapter.tsalready gates on. Discovery flows unprompted, every write to a real account still hits the approval gate, and no per-tool ACL override was needed — the documented MCP invariants are untouched.Testing
npm run lintandnpm testgreen (7220 tests). 9 new tests.Verified on a real runtime: with a key, a 4-tool Composio catalog and the section rendered after
### capabilities; with no key, no section at all.