Skip to content

[Bug]: Pi sessions declare every t3-code tool on every turn #16651

Description

@drewbitt

Before submitting

  • I searched existing issues and did not find a duplicate.
  • I included enough detail to reproduce or investigate the problem.

Area

apps/server

Steps to reproduce

  1. Start a Pi thread, or delegate a task to Pi.
  2. Send a short prompt.
  3. In the Pi session file, count the first system message's toolsAdded entries named mcp__t3-code__* and check the first assistant usage.

Expected behavior

T3 tools a session rarely uses aren't declared on every turn. Pi 0.99+ supports this for extension tools: registerTool takes exposure (codemode, deferred), and inactive tools also leave out their promptSnippet and promptGuidelines (extensions.md, Tool exposure).

Actual behavior

piT3McpExtensionSource.ts registers every tools/list result with pi.registerTool() and no exposure, so all of them default to direct. Each one sends its full schema plus a snippet line and a guideline line.

From one Pi session on Opus:

part chars
72 t3-code schemas 78.1k
prompt snippets 23.6k
"Use mcp__t3-code__X ..." guidelines 9.3k
orchestration instructions 5.5k

That's about 116k of the 287k-char prefix, roughly 46k tokens at the 2.5 chars per token this session measured (first turn: 114.5k input tokens). Every delegated Pi child pays it again. Children get the same list as the orchestrator, because McpHttpServer.ts registers toolkits statically and session capabilities only gate calls.

main (517188b) registers tools the same way and defines 79. #16466 and #16528 add more through the same path.

Impact

Minor bug or occasional failure

Version or commit

0.0.46-nightly.20261006.2735, also checked main @ 517188b

Environment

macOS 26.7.1, T3 Code Nightly desktop, pi 1.0.4, anthropic/claude-opus-5-5 and claude-sonnet-5-5

Workaround

Untested: a second Pi provider instance for children, with --exclude-tools 'mcp__t3-code__*' in its launch arguments.

Possible fix, for Pi 0.99 or newer (MINIMUM_PI_VERSION is still 0.80.5):

pi.registerTool({
  name: registeredName,
  exposure: DIRECT_TOOLS.has(name) ? "direct" : "codemode",
  namespace: { name: "mcp__t3-code", description: "T3 Code orchestration" },
  // ...
});

DIRECT_TOOLS would be a short list such as delegate_task and task_status. Alternatively, Pi 1.0 ships a built-in MCP client, so the extension could call pi.registerMcpServer("t3-code", { url, headers, exposure: "codemode" }) instead of running its own client. The comment saying "Pi core has no MCP client" is out of date.

Activity

  1. juliusmarminge commented on Oct 7, 2026

    @juliusmarminge
    Member

    Note

    Grok responding on behalf of Julius.

    Confirmed on main @ 517188b — this is a real prefix-bloat bug in the Pi T3 MCP extension bridge.

    What main does

    In piT3McpExtensionSource.ts, after tools/list the extension loops every tool and calls pi.registerTool({...}) with name/label/description/promptSnippet/promptGuidelines/parameters/execute — and no exposure. With Pi’s default of direct, every schema + snippet + guideline line lands in the active tool prefix on every turn (and again on every delegated Pi child).

    The file header still says “Pi core has no MCP client,” which looks outdated relative to Pi 1.0’s built-in MCP support (registerMcpServer), while T3’s gate is still:

    // apps/server/src/provider/PiProvider.ts
    export const MINIMUM_PI_VERSION = "0.80.5";

    Tool surface (cheap static count)

    McpHttpServer registers toolkits onto /mcp statically (layer merge); session capabilities gate calls, not listing. Across the toolkit tools.ts files on main there are 80 Tool.make tools (79 string names + html_render). That matches the reporter’s “~79 on main / ~72 in one live session” ballpark; we did not re-measure live prefix chars/tokens.

    Related (not duplicates)

    Fix direction (no open fix PR found)

    Agree with the reporter’s sketch:

    1. Prefer exposure: "codemode" (or "deferred") for most tools, with a short DIRECT_TOOLS allowlist (delegate_task / task_status / … — exact set is a product call), or
    2. On Pi ≥1.0, switch the extension to pi.registerMcpServer(..., { exposure: "codemode" }) and drop the hand-rolled client once MINIMUM_PI_VERSION can move.

    Either way the bug is the missing non-direct exposure default, not “whether T3 should have MCP tools.”

    Verdict: valid eng bug — ready to track / fix. Exact DIRECT_TOOLS membership can land in the fix PR.

  2. added
    bugSomething is broken or behaving incorrectly.
    via-triageFiled through npx t3 triage
    on Oct 7, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething is broken or behaving incorrectly.via-triageFiled through npx t3 triage

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions