diff --git a/apps/marketing/src/assets/logos/opencode.svg b/apps/marketing/src/assets/logos/opencode.svg new file mode 100644 index 000000000..16327e94a --- /dev/null +++ b/apps/marketing/src/assets/logos/opencode.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/apps/marketing/src/pages/research/mcp-tool-visibility.astro b/apps/marketing/src/pages/research/mcp-tool-visibility.astro new file mode 100644 index 000000000..76cd0168d --- /dev/null +++ b/apps/marketing/src/pages/research/mcp-tool-visibility.astro @@ -0,0 +1,709 @@ +--- +import Layout from "../../layouts/Layout.astro"; +import claudeLogo from "../../assets/logos/claude.svg?url"; +import codexLogo from "../../assets/logos/codex.svg?url"; +import cursorLogo from "../../assets/logos/cursor.svg?url"; +import opencodeLogo from "../../assets/logos/opencode.svg?url"; + +const GH = "https://github.com/UsefulSoftwareCo/executor"; +const title = "How agents actually see your MCP tools"; +const description = + "The same MCP server, connected to five coding agents, with the model-bound traffic measured. Each harness shows the model something different: full definitions, bare names, or nothing at all."; + +// Δ prompt tokens for the 31 per-integration search tools, provider-reported. +const costs = [ + { name: "Claude Code", icon: claudeLogo, detail: "2.1.247 · inline", delta: 3464, plain: "36,013", search: "39,477" }, + { name: "opencode (beta)", icon: opencodeLogo, detail: "default · inline", delta: 3400, plain: "22,118", search: "25,518" }, + { name: "opencode", icon: opencodeLogo, detail: "1.18.15 · inline", delta: 3399, plain: "17,458", search: "20,857" }, + { name: "opencode (beta)", icon: opencodeLogo, detail: "code mode · TS signatures", delta: 1280, plain: "16,126", search: "17,406" }, + { name: "Cursor CLI", icon: cursorLogo, detail: "2026.07.23 · names only", delta: 170, plain: "16,140", search: "16,310" }, + { name: "Codex CLI", icon: codexLogo, detail: "0.147.0 · code mode", delta: 0, plain: "15,776", search: "15,776" }, +]; +const max = Math.max(...costs.map((c) => c.delta)); +--- + + +
+
+
+
+
+ +
+ + + {/* ─── HEADER ─── */} +
+
+ Research · August 2026 +

+ {title} +

+

+ One Executor workspace — 31 integrations — connected to each harness twice: plain, and + with ?search_tools=true, which adds one minimal + search_<integration> tool per integration. The + difference between the two captured sessions is what 31 tool definitions cost, and + where they end up. +

+
+
+ + {/* ─── CONTEXT VIEWER ─── */} +
+
+ The model's context window, per harness +

Same server, four context windows

+

+ Everything below is verbatim from the captured request each harness sent to its model. + For these runs the server also returned an MCP instructions + field carrying a tracer string, to pin down where server instructions surface. +

+ +
+
+ + + + +
+ +
+ v2.1.247 + + + + + +3,464 tokens for the 31 tools +
+ + {/* Claude Code */} +
+
+ system · 27,294 chars +
{`You are a Claude agent, built on Anthropic's Claude Agent SDK.
+
+You are an interactive agent that helps users with software engineering tasks. Use the instructions below and the tools available to you to assist the user.
+⋮ (no MCP content anywhere in the system prompt)`}
+
+
+ tools · 50 entries — 12 built-in + 38 from your server, verbatim +
{`{
+  "name": "mcp__executor__search_mcp_linear_app",
+  "description": "Search this integration's tools; empty query lists all. Run results with execute.",
+  "input_schema": {
+    "type": "object",
+    "properties": { "query": { "type": "string" } },
+    "$schema": "http://json-schema.org/draft-07/schema#"
+  }
+}
+⋮ × 38, resent every turn`}
+
+
+ messages[0] · your server's instructions, injected into the first user turn +
{`
+# MCP Server Instructions
+
+The following MCP servers have provided instructions for how to use their tools and resources:
+
+## executor
+Executor exposes every connected integration through search and execute. INSTRUCTIONS-MARKER-9F3 Prefer the search tools for discovery.
+`}
+
+
+ server instructions → first message + tool descriptions → tools array + tool arguments → tools array, full JSON Schema +
+
prompt 36,013 → 39,477 tokens · Δ +3,464
+
+ + {/* opencode, code mode off */} + + + {/* opencode, code mode on */} + + + {/* Cursor */} + + + {/* Codex */} + +
+
+
+ + {/* ─── COST ─── */} +
+
+ Measured, not estimated +

What 31 tool definitions cost, by harness

+

+ Δ prompt tokens between the plain and ?search_tools=true sessions, + as reported by the provider's usage accounting (input + cache write + cache read). Same + workspace, same prompt; only the endpoint query differs. +

+
+ { + costs.map((c) => ( +
+
+ + + {c.name} + {c.detail} + +
+
+
+
+
{c.delta === 0 ? "0" : `+${c.delta.toLocaleString()}`}
+
+ )) + } +
+

+ Cursor's model traffic terminates at its backend, so its pair comes from Cursor's own + per-request usage meter rather than a captured prompt. JSON tool definitions tokenize at + roughly 2.4 characters per token — schema punctuation is token-dense. +

+
+
+ + {/* ─── TAKEAWAYS ─── */} +
+
+ If you ship an MCP server +

Design for the weakest channel

+
+
+ 01 +

The name is the only universal channel

+

+ Every harness that shows tools at all shows the name. Descriptions reach only the + inliners; schemas effectively reach only the inliners. If information must arrive, + put it in the name. +

+
+
+ 02 +

Schema tricks don't travel

+

+ An enum of options inside a parameter looks clever and costs less — and is invisible + in Cursor and Codex, the two harnesses where you'd need it most. +

+
+
+ 03 +

Keep definitions small anyway

+

+ Where tools are inlined, every byte is paid on every turn, multiplied by tool count. + One shared description sentence and a single parameter cut this surface by more than half. +

+
+
+ 04 +

Measure with provider usage, not estimates

+

+ Client-side token meters and character counts both mislead. Run the same session + twice and diff what the provider bills — that number is the truth. +

+
+
+
+
+ + {/* ─── BOTTOM CTA ─── */} +
+
+

+ Connect any agent to everything. +

+ +
+
+ + {/* ─── FOOTER ─── */} + +
+
+
+ + + +