Skip to content

fix: make the safety hooks and MCP servers work in Codex - #5

Merged
viragtripathi merged 1 commit into
mainfrom
fix/mcp-config-and-hooks
Oct 9, 2026
Merged

viragtripathi merged 1 commit into
mainfrom
fix/mcp-config-and-hooks

Conversation

@viragtripathi

Copy link
Copy Markdown
Contributor

What

The safety hooks never ran in Codex. There were four separate causes, each fixed here:

  • Not discovered. Codex looks for plugin hooks in hooks/hooks.json, and the file sat at the plugin root. It now lives in plugins/cockroachdb/hooks/hooks.json.
  • Matcher never matched. Codex replaces every character outside [A-Za-z0-9_] in MCP tool names, so the Toolbox SQL tool is mcp__cockroachdb_toolbox__cockroachdb_execute_sql. The hyphenated matcher never matched it.
  • Script not found. Codex runs hook commands in the session's working directory, so python3 ./scripts/... couldn't find the script. Python's exit 2 would also have blocked every matched call once the first two causes were fixed. Commands now reference "${PLUGIN_ROOT}/scripts/...", which Codex substitutes, and end with ; exit 0 so a missing or crashing script fails open.
  • Output ignored. Codex rejects unknown top-level keys in hook output and then ignores the whole output, so the scripts' Copilot CLI fields turned a deny into a no-op. The scripts take a --codex flag that emits only the keys Codex accepts. Without the flag, their output is unchanged, so the copilot plugin can keep sharing them.

The lint hook now sees Codex file edits. check-sql-files.py reads the edited paths from apply_patch input, which is how Codex edits files.

MCP and docs.

  • The localhost cockroachdb-toolbox-http server is gone; it failed unless Toolbox was already serving HTTP on port 5000.
  • The README no longer says COCKROACHDB_CLUSTER_ID is required, and documents turning off a backend through config.toml.
  • The nonexistent codex plugin trust command is replaced with /hooks.
  • The secure-cluster troubleshooting is fixed: it told users to export SSL variables that Codex never forwarded.
  • The README adds Toolbox over HTTP and the first-party CockroachDB MCP Server as alternative backends.
  • The execute-sql description no longer promises DDL and DML, since Toolbox runs read-only.

Testing

  • python3 -m unittest -v tests/test_plugin_package.py: all pass. New cases check:
    • the hooks location;
    • that the SQL matcher equals the Codex name derived from .mcp.json and tools.yaml;
    • the ${PLUGIN_ROOT} commands and ; exit 0;
    • that the --codex output uses only keys Codex accepts;
    • the apply_patch path parsing;
    • that every remote server uses https.
  • Live in Codex CLI 0.162.0, with the plugin installed from a local marketplace into a separate CODEX_HOME and run against a local CockroachDB v25.4 cluster with Toolbox 1.12.0 (codex exec --dangerously-bypass-hook-trust):
    • Asking Codex to run TRUNCATE through the Toolbox tool: "Tool call blocked by PreToolUse hook: TRUNCATE is blocked by CockroachDB plugin safety hook... Tool: mcp__cockroachdb_toolbox__cockroachdb_execute_sql".
    • Asking Codex to create a .sql file that uses SERIAL: Codex wrote it with apply_patch, and the lint reached the model ("CockroachDB lint: SERIAL/BIGSERIAL detected...").
  • The copilot plugin's hook regression suite passes with the shared scripts.

Not tested: the interactive /hooks trust flow (the live runs used the bypass flag) and Windows.

Related to cockroachdb/claude-plugin#27.

The safety hooks never ran in Codex, for four separate reasons:

- Codex looks for plugin hooks in hooks/hooks.json, and the file sat at
  the plugin root, so it was never loaded. It now lives in
  plugins/cockroachdb/hooks/hooks.json.
- Codex replaces every character outside [A-Za-z0-9_] in MCP tool
  names, so the Toolbox SQL tool is
  mcp__cockroachdb_toolbox__cockroachdb_execute_sql. The hyphenated
  matcher never matched it.
- Codex runs hook commands in the session's working directory, so
  python3 ./scripts/... couldn't find the script, and Python's exit 2
  would have blocked every matched call. Commands now reference
  "${PLUGIN_ROOT}/scripts/...", which Codex substitutes, and end with
  "; exit 0" so a missing or crashing script fails open.
- Codex rejects unknown top-level keys in hook output and then ignores
  the whole output, so the scripts' Copilot CLI fields made a deny a
  no-op. The scripts take a --codex flag that emits only the keys Codex
  accepts; without it their output is unchanged.

check-sql-files.py also reads the edited paths out of apply_patch input,
which is how Codex edits files, so the lint now runs after Codex edits.

The localhost cockroachdb-toolbox-http server is gone: it failed unless
Toolbox was already serving HTTP on port 5000. The README no longer
says the cluster ID is required, documents turning off a backend
through config.toml, replaces the nonexistent codex plugin trust
command with /hooks, fixes the secure-cluster troubleshooting (Codex
never forwarded the SSL variables it described), and adds Toolbox
over HTTP and the first-party CockroachDB MCP Server as alternative
backends. The execute-sql description no longer promises DDL and DML,
since Toolbox runs read-only.

Related to cockroachdb/claude-plugin#27
@viragtripathi
viragtripathi merged commit 836f445 into main Oct 9, 2026
1 check passed
@viragtripathi
viragtripathi deleted the fix/mcp-config-and-hooks branch October 9, 2026 07:35
@github-actions github-actions Bot mentioned this pull request Oct 9, 2026
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.

1 participant