Skip to content

fix: make the bundled MCP servers and SQL safety hooks work out of the box - #28

Merged
viragtripathi merged 4 commits into
mainfrom
fix/drop-localhost-toolbox-http
Oct 9, 2026
Merged

viragtripathi merged 4 commits into
mainfrom
fix/drop-localhost-toolbox-http

Conversation

@viragtripathi

@viragtripathi viragtripathi commented Oct 9, 2026 •

Copy link
Copy Markdown
Contributor

What

  • Removes the cockroachdb-toolbox-http server. It pointed at http://127.0.0.1:5000/mcp, so it failed at startup unless Toolbox was already running in HTTP mode. Its execute-sql tool also skipped the SQL safety hook, and Anthropic's plugin directory blocks non-https MCP server URLs.
  • Falls back to defaults when connection variables are unset (cockroachdb-toolbox on Windows: no toolbox install instructions, and unset env placeholders are passed literally #27). Claude Code passes an unset bare ${VAR} through as literal text, so Toolbox received strings like ${COCKROACHDB_PORT} and couldn't build its connection URL. The env block now uses ${VAR:-default} with the same defaults as tools.yaml. The optional mcp-cluster-id header defaults to empty, which the Cloud server treats as absent; before, an unset cluster ID made the server fail with HTTP 400.
  • Makes the SQL safety hooks run for plugin installs. Claude Code names plugin MCP tools mcp__plugin_cockroachdb_<server>__<tool>, and the matcher only listed the bare name, so validate-sql never fired. Separately, current Claude Code no longer substitutes ${CLAUDE_PLUGIN_ROOT} inside shell-form commands, and the bootstrap read it from inside single quotes, so both hooks failed open. The bootstrap now falls back to the exported CLAUDE_PLUGIN_ROOT, and the Windows long-path prefix, which evaluated to \?\ instead of \\?\, is fixed.
  • Docs. Toolbox runs in read-only mode, so the execute-sql tool description, the agent files, and the README no longer promise DDL and DML. The README now covers installing Toolbox on Windows, the running cluster the Toolbox server needs, turning off a server from /mcp, the optional cluster ID, the first-party CockroachDB MCP Server as an alternative backend, and the current /plugin install command. CONTRIBUTING and AGENTS no longer recommend bare ${VAR} references and document the scoped tool names hook matchers need.

Testing

Run on macOS with Claude Code 2.1.295, MCP Toolbox 1.12.0, and a local CockroachDB v25.4 cluster.

  • bash scripts/test-hooks.sh: all pass, including new cases that leave the placeholder unsubstituted and export CLAUDE_PLUGIN_ROOT, in both the sh and PowerShell forms. The previous bootstrap fails those cases.
  • claude plugin validate .: passes, with the same pre-existing warning about CLAUDE.md at the repo root.
  • End to end through claude -p --plugin-dir:
    • Asking Toolbox to run TRUNCATE is now blocked by the hook ("TRUNCATE is blocked by CockroachDB plugin safety hook"). With the previous matcher the hook never ran, and only Toolbox's read-only mode stopped the statement.
    • Writing a .sql file that uses SERIAL triggers the PostToolUse lint.
    • With every connection variable unset, Toolbox receives localhost, 26257, root, defaultdb, require, and an empty password.
  • claude mcp list with the cluster ID unset: the old header form fails with "HTTP 400: invalid cluster_id", and the new form shows "Needs authentication".
  • Toolbox rejects writes with CRDB_READONLY_VIOLATION in the shipped configuration and allows them with enableWriteMode: true.
  • CockroachDB MCP Server v0.1.0, built from source and run with the documented local development settings, registers read tools by default, adds write tools with CRDB_MCP_ENABLE_WRITE_QUERIES=true, and refuses a DELETE without WHERE.

Not tested: Windows (the long-path prefix fix was checked by evaluating the string), Claude Desktop, and Cowork.

Fixes #27.

The cockroachdb-toolbox-http entry in .mcp.json pointed at
http://127.0.0.1:5000/mcp, so it failed to connect at startup for anyone
not already running Toolbox in HTTP mode on that port. Its execute-sql
tool also bypassed the SQL safety hook, which only matches the stdio
server, and Anthropic's plugin directory validation blocks MCP server
URLs that aren't https.

The stdio cockroachdb-toolbox server provides the same tools. The README
already listed the HTTP backend as an optional alternative; it now shows
how to add it with claude mcp add, and the backends table says it isn't
shipped.
Claude Code passes an unset bare ${VAR} reference through as the literal
text ${VAR}. With COCKROACHDB_* unset, Toolbox received strings like
${COCKROACHDB_PORT} and failed to parse its connection URL, which also
defeated the defaults in tools.yaml. The Cloud server's mcp-cluster-id
header had the same problem and failed with HTTP 400.

The Toolbox env block now uses ${VAR:-default} with the same defaults as
tools.yaml. Toolbox uses an empty value as-is rather than falling back,
so every connection setting except the password gets a real default. The
cluster ID header defaults to empty, which the Cloud server treats as
absent, so the connection reaches every cluster the user's role allows.

Toolbox runs with readOnlyMode, so the execute-sql tool description, the
agent files, and the README no longer promise DDL and DML. The README
now covers installing Toolbox on Windows, the running cluster the
Toolbox server needs, turning off a server from /mcp, the optional
cluster ID, and the first-party CockroachDB MCP Server as an
alternative, and it uses the current /plugin install command.
CONTRIBUTING and AGENTS no longer recommend bare ${VAR} references and
document the scoped tool names that hook matchers need.

Fixes #27
The validate-sql hook never ran for anyone who installed the plugin.
Claude Code names tools from a plugin's own MCP servers
mcp__plugin_<plugin>_<server>__<tool>, and the matcher only listed the
bare mcp__cockroachdb-toolbox__cockroachdb-execute-sql name, which
Claude Code compares as an exact string. The matcher now lists both
names.

Both hooks also failed to find their scripts on current Claude Code.
The bootstrap read ${CLAUDE_PLUGIN_ROOT} from inside single quotes, but
Claude Code no longer substitutes the placeholder in shell-form
commands. It exports CLAUDE_PLUGIN_ROOT and leaves the shell to expand
it, which single quotes prevent, so Python looked for a literal
${CLAUDE_PLUGIN_ROOT}/scripts path and the hook failed open. The
bootstrap now uses the substituted path when a host provides one and
the exported variable otherwise, and exits quietly when neither leads
to the script.

The Windows long-path prefix also evaluated to \?\ instead of \\?\. It
is now built with chr(92) so no escaping layer can change it.

test-hooks.sh gains cases that leave the placeholder unsubstituted and
export CLAUDE_PLUGIN_ROOT, in both the sh and PowerShell forms. The old
bootstrap fails them.
@viragtripathi viragtripathi changed the title fix: stop shipping the localhost toolbox HTTP server fix: make the bundled MCP servers and SQL safety hooks work out of the box Oct 9, 2026
The documented bootstrap snippet still showed the version that reads ${CLAUDE_PLUGIN_ROOT} from inside single quotes. It now matches hooks/hooks.json, and AGENTS notes the environment-variable fallback as part of the load-bearing pattern.
@viragtripathi
viragtripathi merged commit 75853b7 into main Oct 9, 2026
1 check passed
@viragtripathi
viragtripathi deleted the fix/drop-localhost-toolbox-http branch October 9, 2026 07:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

cockroachdb-toolbox on Windows: no toolbox install instructions, and unset env placeholders are passed literally

1 participant