Where tools run
A mental model for hosted vs. self-hosted (MCP) vs. inline tools — and what really happens, machine by machine, when a smith calls a tool from a web app, a chat surface like Telegram, or email.
The one idea. A tool is just a function — call it
execute(). The only interesting questions are who calls that function and over what wire. Everything below is a variation on that. Ingram Cloud always runs the model; the model only ever asks for a tool. What turns that ask into a real action is something — sometimes Ingram Cloud, sometimes your own server — invokingexecute().
Three layers people accidentally merge
"Who runs the tool?" feels like one question. It's three, and they don't share an answer:
- Runs the model — decides a tool should be called. This is always Ingram Cloud; the LLM lives there. Your code never runs inference.
- Runs
execute()— runs the tool's actual code. This is the variable. For a hosted tool it's Ingram Cloud; for your tool it's always your server. - Does the side-effect — the real-world action (the SMTP send, the API
write). Usually a third party (an email/SMTP provider, a SaaS API) that
execute()calls.
The word "hosted" only describes layer 2. And there are exactly two kinds of tool:
- Hosted by Ingram Cloud — e.g.
web_search,web_fetch. Ingram Cloud implements and runs them end-to-end. You write no code; your server never hears about the call. - Your tools (self-hosted, via MCP) — e.g.
send_email, calendar/contacts actions. The code is yours and always runs on your server. The only question is how the request reaches yourexecute()— over your/mcpendpoint, or inline in your own loop.
Explore it live
Pick an entry point (row) and a tool kind (column), then step through the
trace. Watch the ★ — that's the exact moment execute() runs, and on whose
machine. The summary table and the MCP-vs-inline panel below the explorer load
straight into it.
execute() here? Your `/mcp` endpoint — Ingram Cloud reached your server over HTTP to invoke the tool. IC is the trigger; your endpoint is the caller.execute() runsThe whole model on one page — click any row to load it above.
| Entry point + tool | Runs the model | Runs execute() | Side-effect |
|---|---|---|---|
| Web → send_email (MCP) | Ingram Cloud | your /mcp (HTTP from IC) | External service |
| Web → send_email (inline) | Ingram Cloud | your agent loop (in-process) | External service |
| Web → web_search (hosted) | Ingram Cloud | Ingram Cloud | Ingram Cloud |
| Telegram → send_email (MCP) | Ingram Cloud | your /mcp (HTTP from IC) | External service |
| Telegram → web_search (hosted) | Ingram Cloud | Ingram Cloud | Ingram Cloud |
| Email channel → reply (your key) | Ingram Cloud | — (no tool of yours) | Email provider, sent by IC |
MCP vs. inline — when to choose which
Reach for MCP (IC calls your /mcp)
- The tool must work on a channel or schedule — inline doesn't exist there.
- It's shared across many entry points, or needs approval / human-in-the-loop gating.
- You want Ingram Cloud to drive the whole run; you just expose an endpoint.
- Cost: you host an HTTP endpoint IC can reach; identity arrives as headers.
Reach for inline (you drive the loop)
- The run already starts in your own server process (a web app you host).
- The tool lives in-process — you want zero extra hops and no shared secret.
- You want full control of the agent loop and don't need IC to gate.
- Limit: only where your code drives the loop — never on channels.
Rule of thumb: if a channel or a schedule can trigger it, it has to be MCP. If your own server is always the one driving the run, inline is the shortest path.
Three things to remember
- For your tools, your server always runs
execute()and originates the side-effect — never Ingram Cloud. "Hosted vs. self-hosted" only decides whose machine the tool code lives on. The external service (an email/SMTP provider, a SaaS API) is what performs the real action, in every case. - "What calls
execute()" has exactly two answers: your/mcpendpoint (when Ingram Cloud reaches you over HTTP — the MCP path), or your own agent loop in-process (the inline path). Same function, different caller. - Deployments only have the first answer. Ingram Cloud drives deployment runs, so
the inline path doesn't exist there — a self-hosted tool must go through
/mcp. Anything you want available on deployments has to be reachable as an MCP tool, full stop.
The one exception: an email deployment. Because Ingram Cloud owns the deployment address and holds the email-provider key you configured for it, IC originates that outbound call on your behalf. It's the single place the external call comes from IC rather than from your server — see the Email deployment scenario in the explorer.
Identities on MCP calls travel as headers — the run's smith (X-IC-Smith-Id)
and your stable end-user id (X-IC-Smith-External-Id) — which is how your /mcp
endpoint knows who it's acting for. See Tools & approvals for the
full auth model.