May 31, 2026

Chalie learns to call other people's tools

Chalie ships an outbound MCP client, a probe-verified vision capability, and a clean-context web search delegate in one long day.

Today was about extending Chalie’s reach — connecting it to tools it doesn’t own and senses it doesn’t natively have. Each piece follows the same discipline: don’t let the model see more surface area than it can be trusted with, and don’t let a new integration degrade what already works.

The outbound MCP client is the headline. Chalie could already act as an MCP server for other agents to call into; now it’s a client too, reaching any remote MCP server and pulling its tools into the same discovery and dispatch path as everything built-in. A new client service handles registration, sync, dispatch, and a periodic heartbeat to keep remote tool indexes fresh, with search spanning both the built-in ability catalog and the remote catalog in one pass. The first cut leaked complexity: the model saw a placeholder instead of a tool’s real parameters and brute-forced arguments, visible as bloat in the activity trail during testing. A same-day follow-up fixed it at the root — the model now gets the tool’s actual schema, remote-tool policy checks were folded into the same enforcement path everything else uses, and scoring was capped so a strong remote match can’t unfairly bump built-in abilities out of the results. Later passes added an edit UI for existing connections, idempotent registration so adding the same host twice updates the existing entry instead of duplicating it, and a tidier label now that the panel covers both directions.

Vision shipped as a provider capability, not a tool — a deliberate distinction. Rather than a “look at this image” tool the model has to remember to call, Chalie now probes each configured provider on save: a test image with known shapes and text, scored against an exact-match rubric, and only providers that clear the bar get marked vision-capable. That flows automatically through the send path — image-free conversations convert exactly as before, byte for byte. With no vision provider configured, the document pipeline still falls back to OCR. The probe’s test suite got a hard look too: nine tests asserted that hand-fed constants scored the way the code that generated them said they should — tautological, blind to a model quietly ignoring the image. Those got cut for tests that guard something real: parsing an occasionally messy model reply.

Web search got rebuilt around the idea shaping the rest of Chalie’s tool story: acknowledge instantly, then run the actual work somewhere it can’t pollute the main conversation. web_search now hands off to a clean-context delegate that runs its own search-and-read loop and reports back a synthesis with sources as a quiet follow-up turn. The underlying search primitive became system-only — invisible to the policy manager, uncallable by anything except that delegate. Compaction got the same treatment on the housekeeping side, now running as an internal, audit-logged step instead of an invisible side effect.

The rest of the day was compounding hygiene: filename handling for uploads consolidated onto one shared helper; a tool-call ID collision that could leave a stuck spinner in the activity trail got a root-fix; the news pipeline swapped hand-rolled feed parsing for a proper library, shedding code while gaining tolerance for malformed feeds; and a relevance tie-break bug that silently favored older results got caught with a regression test.

None of today’s pieces are flashy alone, but they point the same direction: every new surface — a remote tool, an image, a search — gets a narrow, audited path in rather than an open door. That’s the shape I want Chalie’s capability set to keep as these integrations compose.

  • Outbound MCP client: connect to any remote MCP server, dual-catalog find_tools, real schema-aware dispatch, idempotent registration, edit UI

  • Vision as a probe-verified provider capability (not a tool) — image-free conversion path stays byte-identical, OCR fallback when no vision provider exists

  • Web search rebuilt as a clean-context delegate with instant ack; the search primitive itself becomes uncallable by the model directly

  • Compaction now runs as an audited internal step with its own trail entry

  • Filename sanitization consolidated onto one shared helper; tool-call ID collisions and a relevance-ranking tie-break bug fixed with regression tests