The Problem: MCP Tool Definitions Eat Your Context

When you use MCP (Model Context Protocol) tools in Claude Code, the tool definitions themselves consume massive amounts of context before you even use them. Chrome DevTools MCP? 20,000 tokens just to load the tool definitions. Add a few more MCP servers and you’re starting every conversation with 50% of your context window already gone.

Then the output floods in: console logs, network traces, DOM snapshots, performance data. You end up with:

  • 20k tokens: Chrome DevTools tool definitions
  • 200 lines: console output from debugging
  • 50 lines: network request details
  • Your actual code question: buried and competing for the remaining context

This isn’t just messy - it’s cognitive overload. Claude is working with a bloated context window where most tokens are MCP overhead, not your actual task. And it gets worse: research shows language models perform significantly worse on information buried in the middle of long contexts (the “lost in the middle” problem). Your actual code question gets sandwiched between MCP definitions and debug output, exactly where Claude’s attention degrades.

The solution: isolate MCP tools in separate Claude instances. Keep your main conversation clean, spawn specialized agents when needed.

What is MCP?

Model Context Protocol lets Claude access external tools like browser automation, file systems, or APIs. Chrome DevTools MCP gives Claude full control over Chrome for debugging, testing, and inspecting web apps.

The Obvious Solution (That Doesn’t Work)

Claude Code supports custom slash commands. Perfect for this use case:

# .claude/commands/chrome.md
---
allowed-tools:
  - Bash(claude:*)
description: Launch Chrome DevTools agent for browser debugging
---

Execute command:

!`claude --mcp-config ~/.claude/.mcp.chrome.json \
  --strict-mcp-config \
  --allowed-tools "mcp__chrome-devtools" \
  -p "debug my app at http://localhost:3001"`

This should spawn a new Claude instance with Chrome MCP tools, run the task, and return results. Clean separation of concerns.

Except it fails every time:

Error: Bash command permission check failed: This command requires approval

The Real Problem: Known Bugs

Turns out this isn’t a configuration issue. Claude Code has multiple documented bugs with bash permissions in slash commands:

  • #4144: Bash Permissions Not Working in Slash Command
  • #3662: Custom slash commands can’t request permission for bash scripts
  • #462: Bash(*) pattern matching doesn’t work properly

Even using allowed-tools: Bash (no pattern) doesn’t help. The permission system for bash commands in slash commands is fundamentally broken as of October 2025.

When the tool breaks, bypass the tool. Don’t wait for the fix, build the workaround.

— The hard truth about tooling

The Workaround: Shell Functions

If slash commands can’t execute bash reliably, just skip them. Use a regular shell function instead:

# ~/.claude/chrome-helper.sh
#!/bin/bash

chrome-debug() {
  claude \
    --mcp-config ~/.claude/.mcp.chrome.json \
    --strict-mcp-config \
    --allowed-tools "Read Write(/tmp/**) WebSearch WebFetch mcp__chrome-devtools" \
    --print \
    -p "SYSTEM_INSTRUCTION: @~/.claude/chrome-prompt.md

USER_INPUT: $*"
}

Source it in your shell config:

# ~/.zshrc or ~/.bashrc
source ~/.claude/chrome-helper.sh

Now you can invoke it directly:

chrome-debug "debug my app at http://localhost:3001"
chrome-debug "take a screenshot of the homepage"
chrome-debug "check console errors"

This achieves everything the slash command was supposed to do:

  • Spawns a separate Claude instance with Chrome MCP
  • Keeps context isolated from your main conversation
  • Returns only the final results
  • No context bloat in your main window

Why This Matters Beyond Chrome

The pattern isn’t specific to Chrome DevTools. Every MCP server adds tool definition overhead before you even use it:

  • Database MCP: Tool definitions + query results consume context
  • API Testing MCP: HTTP method definitions + network logs bloat the window
  • File System MCP: File operation definitions + directory listings compete for tokens
  • Custom MCP servers: Your tool schemas load before any actual work happens

The real problem: tool definition weight. Loading 3-4 MCP servers can consume 50k+ tokens just from their schemas, leaving limited context for your actual coding task.

Context as a Resource

Treat Claude’s context window like RAM. MCP tool definitions are like running background processes - they consume resources even when idle. Specialized operations should run in separate instances.

The Setup

Here’s the complete setup for Chrome DevTools isolation:

1. Create the MCP config (~/.claude/.mcp.chrome.json):

{
  "mcpServers": {
    "chrome-devtools": {
      "command": "npx",
      "args": ["-y", "@executeautomation/chrome-devtools-mcp"]
    }
  }
}

2. Create the system prompt (~/.claude/chrome-prompt.md):

# Chrome DevTools Agent

You are a specialized agent with access to Chrome DevTools via MCP.
Your role is to debug web applications and report findings concisely.

## Instructions
- Be specific: provide line numbers, network timings, console errors
- Take screenshots for visual inspection
- Analyze performance traces for slow pages
- Report findings clearly without verbose explanations

3. Create the shell function (~/.claude/chrome-helper.sh):

#!/bin/bash

chrome-debug() {
  claude \
    --mcp-config ~/.claude/.mcp.chrome.json \
    --strict-mcp-config \
    --allowed-tools "Read Write(/tmp/**) WebSearch WebFetch mcp__chrome-devtools" \
    --print \
    -p "SYSTEM_INSTRUCTION: @~/.claude/chrome-prompt.md

USER_INPUT: $*"
}

4. Source it in your shell (~/.zshrc):

source ~/.claude/chrome-helper.sh

Reload your shell and test:

source ~/.zshrc
chrome-debug "what mcp tools do you have?"

Using the Shell Function

Once configured, you have two ways to invoke the isolated Chrome agent:

Option 1: Execute Directly with !

From within Claude Code, prefix the command with ! to run it in your shell:

!chrome-debug "take a screenshot of localhost:3001"
!chrome-debug "check for console errors"
!chrome-debug "inspect the DOM for #navbar"

The ! tells Claude Code to execute the command directly in your terminal, bypassing the tool system entirely.

Option 2: Instruct Claude to Use It

Tell Claude Code to invoke the function when you need testing or debugging:

Test my app at localhost:3001 using chrome-debug. Check for console errors
and take a screenshot of the homepage.

Claude will then execute:

!chrome-debug "navigate to localhost:3001, check console for errors,
and take screenshot of homepage"

Benefits of both approaches:

  • Chrome MCP context stays isolated
  • Main conversation remains clean
  • Results come back concisely
  • No 20k token overhead in your coding session
  • Permissions are explicitly constrained via --allowed-tools flag
Security: Permissions Without Bypass

Notice the --allowed-tools flag in the shell function? That constrains what the isolated agent can do (Read, Write to /tmp, WebSearch, WebFetch, and chrome-devtools MCP only). No need to use --dangerously-bypass-permissions - you define exactly what’s allowed upfront.

When to Use Which

Use ! prefix when you know exactly what you want. Instruct Claude when you want it to formulate the debugging task based on your problem description.

Lessons Learned

  • Tooling abstractions break: Slash commands seemed like the right solution, but they add complexity that fails in practice
  • Shell functions are more reliable: Direct bash invocation bypasses Claude Code’s permission bugs entirely
  • Context isolation is underrated: Specialized MCP agents should report results, not dump logs
  • Known bugs matter: Check GitHub issues before spending hours debugging configuration

This pattern works for any MCP tool where you want isolated context. The slash command system may get fixed eventually, but the shell function approach will always work.

Try It Yourself

The shell function pattern is simple to adapt:

  1. Create an MCP config JSON for your specialized tool
  2. Write a focused system prompt for the agent’s role
  3. Wrap it in a shell function that calls claude --mcp-config
  4. Source it in your shell config

You now have isolated, specialized Claude agents that keep your main context clean.

Limitations

This approach works best for self-contained tasks that can report back in one response. For interactive debugging sessions, you’ll still want to use MCP tools directly in your main conversation.