← Back to Blog

Debug Your OpenClaw Agent Like a Pro: MCP and Browser Tool Inspection

Debug Your OpenClaw Agent Like a Pro: MCP and Browser Tool Inspection

Debug Your OpenClaw Agent Like a Pro: MCP and Browser Tool Inspection

Last March, Chrome's DevTools team published a guide on using the Model Context Protocol to inspect tool calls directly in the browser. It hit the top of Hacker News and stayed there. Developers were surprised not by the technique — intercepting structured function calls is old news — but by what it revealed: their agents were calling tools they didn't know were registered, with arguments they hadn't audited.

If you're running OpenClaw agents in anything close to production, that should get your attention. OpenClaw MCP browser debugging isn't just a developer convenience; it's how you verify the agent is doing what your config says it should.

This guide walks you through how OpenClaw's tool permission model maps to MCP concepts, how to inspect live tool calls, and how to sandbox tools so a bug in one capability can't cascade into something worse.


Is OpenClaw MCP-Compatible?

Short answer: yes, with caveats.

OpenClaw supports MCP (Model Context Protocol) as a tool-integration layer. You can declare MCP servers in your workspace config and OpenClaw will negotiate tool availability at session start. The agent receives a tool manifest — a JSON list of callable functions with their schemas — and routes calls accordingly.

The caveat is that OpenClaw's internal permission model runs on top of MCP, not inside it. MCP itself has no access-control layer; it's a transport and discovery protocol. OpenClaw adds tool sandboxing, allowlists, and call logging on its own side. So "MCP-compatible" means the agent can talk to any compliant MCP server, but what it's allowed to call depends entirely on your OpenClaw config.


How OpenClaw Maps Tool Permissions to MCP Concepts

MCP defines three primitive resource types: tools, prompts, and resources. OpenClaw only exposes tools to the agent at runtime (prompts and resources are resolved at config load). This matters because it narrows the attack surface — a misbehaving agent can't rewrite its own system prompt via an MCP resource call.

Inside your AGENTS.md or tool config block, you declare which tools are available:

tools:
  allowed:
    - name: browser_navigate
      server: mcp-browser
      max_calls_per_session: 10
    - name: read_file
      server: mcp-filesystem
      path_allowlist:
        - /workspace/data
    - name: run_shell
      server: mcp-shell
      enabled: false

Each entry maps to an MCP tool exposed by the named server. The enabled: false on run_shell tells OpenClaw not to pass that tool to the model in the manifest — the model never sees it exists. That's different from allowing it but auditing it; the tool is invisible at negotiation time.

For a deeper look at how file-based configs give you this kind of explicit control, see Why File-Based Agent Configs Beat Black-Box AI Builders.


Setting Up the MCP Browser Server

Chrome's DevTools MCP server (@chrome-devtools/mcp-server) exposes browser automation as MCP tools: navigate, click, screenshot, evaluate, and a few others. You connect it to OpenClaw as an external MCP server.

Install and run the server:

npm install -g @chrome-devtools/mcp-server
chrome-devtools-mcp --port 9222 --allow-origins http://localhost:3000

Then register it in your OpenClaw workspace:

mcp_servers:
  - id: mcp-browser
    transport: stdio
    command: chrome-devtools-mcp
    args: ["--port", "9222"]
    env:
      CHROME_EXECUTABLE: /usr/bin/google-chrome

Once connected, OpenClaw will pull the tool manifest at session start. You can log that manifest to verify exactly which tools the agent has access to before you run anything.


Inspecting What Your Agent Actually Calls

This is where most debugging sessions fall apart: developers assume the agent is calling what the config says, and they're wrong.

OpenClaw logs every MCP tool call to ~/.openclaw/logs/tool_calls.jsonl by default. Each line is a structured record:

{
  "ts": "2026-06-14T10:23:11Z",
  "session": "sess_a1b2c3",
  "tool": "browser_navigate",
  "server": "mcp-browser",
  "args": { "url": "https://example.com/admin" },
  "result_status": "ok",
  "latency_ms": 312
}

To tail live tool calls during a session:

tail -f ~/.openclaw/logs/tool_calls.jsonl | jq .

If an argument value looks unexpected — a URL you didn't intend, a file path outside your allowlist — you'll catch it here before it propagates.

For DevTools-specific inspection, Chrome exposes its debugger on localhost:9222/json. You can open that in a browser tab and watch WebSocket traffic between OpenClaw and the MCP server in real time. The payload is just JSON-RPC, so it's readable without any tooling.


Reading the Tool Manifest Before You Run

One technique that saves time: dump the tool manifest at session start before the agent sends any messages.

OpenClaw exposes a --list-tools flag for this:

openclaw run --config ./workspace/AGENTS.md --list-tools

Output:

Available tools (mcp-browser):
  browser_navigate   Navigate to a URL
  browser_click      Click an element by selector
  browser_screenshot Capture a screenshot
  browser_evaluate   Execute JavaScript in the page context

Blocked tools (policy):
  run_shell          Disabled in config
  write_file         Not in allowlist

This gives you a pre-flight check. If a tool shows up here that you didn't intend to expose, fix the config before the agent runs — not after.

Common Mistakes

  • Forgetting to scope path allowlists. If you allow read_file without a path_allowlist, the agent can read any file the process has permission to access. Always scope it.
  • Assuming enabled: false is the same as not declaring a tool. If the MCP server advertises the tool and you don't explicitly block it, some older OpenClaw versions will pass it through. Declare an explicit block.
  • Not watching tool_calls.jsonl during your first few sessions. The manifest tells you what can be called. The log tells you what was called. Both matter.

Sandboxing Browser Tools Safely

Browser tools are the highest-risk capability you can give an agent. A browser_evaluate call is arbitrary JavaScript execution in whatever page context the browser is in. If your agent is authenticated to an internal tool and hits a prompt-injected page, that's a real attack vector.

Three things to do before you expose browser tools to an agent:

1. Run Chrome in a dedicated profile with no saved sessions.

google-chrome --user-data-dir=/tmp/agent-chrome-profile --no-first-run

This prevents the agent from accidentally accessing any authenticated sessions you use personally.

2. Restrict browser_navigate to an origin allowlist.

- name: browser_navigate
  server: mcp-browser
  url_allowlist:
    - "https://staging.yourapp.com"
    - "https://api.yourapp.com"

3. Disable browser_evaluate unless you have a specific need. JavaScript execution in-page is almost never necessary for a scraping or monitoring agent. Remove it from the manifest entirely.

For a broader checklist on locking down agent capabilities before they touch anything important, see the OpenClaw Security Checklist.


Tracing Multi-Step Tool Chains

Single tool calls are easy to inspect. The hard part is tracing a multi-step chain where the output of one call feeds the input of the next.

OpenClaw groups tool calls by session ID and step index in the log. You can filter a complete session trace:

jq 'select(.session == "sess_a1b2c3")' ~/.openclaw/logs/tool_calls.jsonl

If you want a human-readable trace, pipe through a simple awk:

jq -r '[.ts, .tool, (.args | tostring)] | @tsv' \
  ~/.openclaw/logs/tool_calls.jsonl | column -t

This is especially useful when debugging agents that navigate, extract data, then write output somewhere — you want to verify the data that flowed through each step, not just the final result.


Connecting MCP Inspection to Your CI Pipeline

If you're running OpenClaw agents on a schedule or as part of a deployment pipeline, ad-hoc log inspection doesn't scale. Add a log assertion step after each agent run.

A minimal shell check:

# Fail if the agent called any tool outside the expected set
UNEXPECTED=$(jq -r '.tool' ~/.openclaw/logs/tool_calls.jsonl \
  | grep -vE '^(browser_navigate|browser_screenshot|read_file)$')

if [ -n "$UNEXPECTED" ]; then
  echo "Unexpected tool calls detected: $UNEXPECTED"
  exit 1
fi

Plug this into your CI step after the agent run. If the agent starts calling something it shouldn't — because a new MCP server version exposed a new tool, or because a prompt injection worked — your pipeline fails and you know before it hits production.

For agents running in a devops context with deploy monitoring, see Turn Your Logs Into Alerts: Build a DevOps Watchdog Agent With OpenClaw — the same log-watching pattern applies.

Security Guardrails

  • Never expose browser_evaluate to an agent that touches external URLs. Prompt injection via a malicious page is a realistic attack, not a theoretical one.
  • Rotate your Chrome profile between agent sessions. Accumulated cookies and auth state from previous sessions can be read or misused by a later session.
  • Set max_calls_per_session on every tool. An agent stuck in a loop or manipulated by a bad prompt can exhaust rate limits, run up costs, or hammer internal services. A hard cap limits the blast radius.
  • Keep MCP server processes isolated from your main user account. Run them under a dedicated service user with minimal filesystem permissions.

When Debugging Points to a Config Problem, Not a Runtime Bug

About half the time, what looks like a runtime bug is actually a config ambiguity. The agent calls a tool you didn't expect because the tool description in the MCP manifest matched the agent's goal better than you planned.

MCP tool descriptions are part of the manifest the model reads. If a tool is described vaguely — "access data" instead of "read a specific CSV file from /workspace/data" — the model will use it in ways you didn't intend.

You can't edit MCP server tool descriptions directly (they're defined by the server), but you can write a wrapper config that limits which tools are exposed and adds a description_override in OpenClaw's tool block:

- name: read_file
  server: mcp-filesystem
  description_override: "Read a single CSV or JSON file from /workspace/data only."
  path_allowlist:
    - /workspace/data

The model sees your description, not the server's. That alone can eliminate 30% of unexpected tool calls in a misconfigured agent.

If you're rebuilding an agent config from scratch after finding problems like these, the post Fixing the 7 Most Common OpenClaw Setup Mistakes Before They Cost You Hours covers the usual culprits in order of frequency.


Debugging an OpenClaw agent through MCP isn't complicated once you know where to look — tool manifests, tool_calls.jsonl, and the DevTools WebSocket feed cover most of what you need. The harder discipline is building the habit of checking before you trust.

If your current agent config doesn't have explicit tool blocks, path allowlists, or per-session call caps, start there. A five-minute config review now is cheaper than tracing an unexpected tool call through production logs later.

Get Your Tool Permissions Configured Before Your Agent Runs

If you want an OpenClaw workspace config with MCP tool blocks, allowlists, and call caps already wired in, the wizard builds one for your specific use case in a few minutes.

Build My Agent Config

Share