Skip to main content
Glama

thinkrail — one plugin, three CLI coding agents

ThinkRail's spec graph and workflow family, packaged so Claude Code, Codex CLI and the Grok CLI all load it from one directory:

  • seven spec_* tools over an MCP stdio server — spec_grep, spec_get, spec_graph, spec_create, spec_update, spec_delete, spec_validate;

  • ten workflow skills — choosing-a-workflow and the family it routes;

  • the standing rule — specs are the ground truth, and every new piece of work enters the router.

It is a port: the spec-graph code and the workflow skill texts come from JetBrains ThinkRail (packages/spec-graph, packages/pi-thinkrail-workflow, Apache-2.0 / MIT — see NOTICE), through the DSH (dshthinkrailspec), PI-Desktop (pideskthinkrails) and omp (ompthinkrail) carriers. What changed here is the carrier, not the workflow: see architecture.md and the difference table below.

Install

The plugin is this directory. One command wires all three hosts (it is convergent — a second run leaves the same state):

node scripts/install.mjs            # add the plugin to claude, codex and grok; write the grok rule
node scripts/install.mjs --dry-run  # print what it would run
node scripts/install.mjs --uninstall

What it does per host, and why:

Host

Plugin

Tools

Rule

Claude Code

claude plugin marketplace add <dir> + claude plugin install thinkrail@thinkrail

.mcp.json (${CLAUDE_PLUGIN_ROOT})

hooks/hooks.json → SessionStart additionalContext

Codex CLI

codex plugin marketplace add <dir> + codex plugin add thinkrail@thinkrail

codex mcp add thinkrail -- node <dir>/mcp/server.mjs

the same SessionStart hook (Codex trusts hooks by hash: run /hooks once)

Grok CLI

grok plugin install <dir> --trust + grok plugin enable thinkrail

.mcp.json (${CLAUDE_PLUGIN_ROOT})

~/.grok/rules/thinkrail-workflow.md (Grok has no session-start context channel)

Manual equivalents, if you prefer to run them yourself:

claude plugin marketplace add "$PWD" && claude plugin install thinkrail@thinkrail
codex  plugin marketplace add "$PWD" && codex plugin add thinkrail@thinkrail
codex  mcp add thinkrail -- node "$PWD/mcp/server.mjs"
grok   plugin install "$PWD" --trust && grok plugin enable thinkrail

Restart the host (or reload plugins) so a new session picks everything up. In Claude Code, claude plugin details thinkrail prints the component inventory; Codex needs /hooks once to trust the hook; Grok's grok plugin details thinkrail and grok mcp doctor thinkrail show the same thing.

Edits to this directory reach the hosts differently: Claude Code loads the plugin in place and Grok links it, so both pick up a skill or tool change at the next session; Codex copies the plugin into ~/.codex/plugins/cache/, so re-run node scripts/install.mjs after editing.

The MCP server takes the workspace root from --root, then THINKRAIL_ROOT, then CLAUDE_PROJECT_DIR, then its own working directory (which every one of the three hosts sets to the session's project directory). A root that is missing or not a directory is reported as an error instead of as an empty project.

Related MCP server: MCP SDD Server

What loads

  • Tools. One MCP stdio server (mcp/server.mjs) exposes the seven tools with the family's names, parameters and wording. The host namespaces them: mcp__plugin_thinkrail_thinkrail__spec_get on Claude Code, mcp__thinkrail__spec_get on Codex, thinkrail__spec_get on Grok.

  • Skills. skills/<name>/SKILL.md — Claude Code registers them as thinkrail:<name> (invoke /thinkrail:spec-graph), Codex lists them as thinkrail:<name> (invoke $spec-graph), Grok lists them by name. Descriptions are kept under 150 characters because Grok cuts a longer catalog entry at ~150; everything else is the family's text, verbatim.

  • The rule. hooks/workflow-rule.mjs holds the text; hooks/session-start.mjs hands it to SessionStart as hookSpecificOutput.additionalContext, which is model-visible developer context on Claude Code and Codex. Grok records a SessionStart hook's output without injecting it, so the installer writes the same text to $GROK_HOME/rules/thinkrail-workflow.md, a rules directory Grok scans in every project.

Anatomy

.mcp.json                the MCP server, on the path all three hosts read by default
hooks/                   the standing rule (text) and its SessionStart hook
mcp/server.mjs           JSON-RPC 2.0 over stdio; root resolution; error folding
mcp/tools.mjs            the seven spec_* tools: names, parameters, wording, scaffold headings
core/                    the host-free spec model (parse, graph, query, validate, store) + vendored yaml
skills/<name>/SKILL.md   the ten workflow skills
.claude-plugin/          Claude Code plugin + marketplace manifests
.codex-plugin/           Codex plugin manifest
.agents/plugins/         Codex marketplace index
.grok-plugin/            Grok marketplace index
plugin.json              Grok's optional manifest
scripts/install.mjs      the per-host wiring above
tests/                   node --test: core model, MCP transport, repo/host contract

Deliberate carrier differences

Behavior is ported, the carrier is not. Against pideskthinkrails (and, through it, dshthinkrailspec):

PI-Desktop carrier

Here

Why

Plugin process with globalThis.pi and a manifest permission model

An MCP stdio server started by the host

A CLI host has no plugin runtime; MCP is the one tool protocol all three speak

pi.fs gateway with declared scopes (fs.read/fs.write/fs.delete)

node:fs in the server process

The plugin is the process; a gateway would add a contract with nothing behind it

Right-hand panel, view tabs, hint polling, two commands that point at it

— (dropped)

No UI to host them; the commands only told a user where to look

3-second short-term read cache for the panel

— (dropped)

Nothing human-paced reads here; a tool call always revalidates, so a generic write/edit cannot leave a stale graph

Two systemPromptOptions.sections rules through the agent extension

SessionStart hook (Claude, Codex) + $GROK_HOME/rules/ (Grok)

No plugin prompt API exists in a CLI host

Description budget 240 characters

150 characters

Grok truncates the catalog entry at ~150; the family's rule is to keep the whole trigger

spec_delete to the system trash via the host API

Trash on macOS (rename into ~/.Trash), unlink elsewhere

Keeps the safer semantics where this is developed

Scaffold headings in the repo's language (Chinese)

English (## Responsibility, ## Boundary, …)

Convention, not contract: no consumer parses body headings

Everything else is byte-parity: tool names, parameter schemas, acceptance criteria, model-visible text, frontmatter dialect (a file is a spec exactly when its frontmatter carries non-empty id and type), lossless frontmatter edits, index revalidation, walk order, and the ten skill bodies.

Verified against

Each host was exercised with the real CLI on this machine; claude = Claude Code 2.1.284, codex = Codex CLI 0.153.4, grok = Grok 1.0.44.

Claim

Evidence

Claude Code loads the plugin

claude plugin details thinkrail → Skills (10), Hooks (1), MCP servers (1)

…sees the skills and tools

session transcript: skill_listing with all ten thinkrail:<name> entries, mcp__plugin_thinkrail_* tool names, server Connected in claude mcp list

…gets the rule

transcript: SessionStart:startup hook_success whose stdout is the rule, then a hook_additional_context attachment carrying it

…launches the server with the session's root

probe server logged cwd=/private/tmp/tr-smoke, CLAUDE_PLUGIN_ROOT=<plugin>, CLAUDE_PROJECT_DIR=<project>, and answered roots/list with the project

Codex loads the plugin

codex plugin list → installed, enabled; r7 = …/plugins/cache/thinkrail/thinkrail/1.0.0/skills in the session's skill roots with all ten skills listed

Codex runs the rule hook

session rollout: the rule text as a developer message after hook: SessionStart Completed

Codex launches the server with the session's root

probe server logged cwd=/private/tmp/tr-smoke

Grok loads the plugin and its tools

grok plugin details → 1 skill dir, hooks, MCP servers; grok mcp doctor thinkrail → handshake OK, 7 tools discovered

Grok sees the skills

grok inspect --json → the plugin provides 10 skills, and all ten are in the catalog

Grok gets the rule

session prompt_context.json → agents_md_files contains ~/.grok/rules/thinkrail-workflow.md with the rule text

The tools work end to end

node --test tests/*.test.mjs (34 tests): MCP handshake, all seven tools over the transport, error wording, path escapes

Codex and Grok could not complete a model turn on this machine (no reachable credentials), so their per-host evidence stops at what the host records before the model call: plugin inventory, skill catalog, hook injection, MCP handshake and tool discovery. The rule text and the tool results themselves are verified live on Claude Code (which injected the rule and where the server answers), and over the MCP transport directly.

Known limits

  • Codex cannot use ${CLAUDE_PLUGIN_ROOT} in MCP arguments. Verified: the variable is absent from a plugin MCP server's environment and a literal ${…} argument never resolves. That is why Codex's server is registered by absolute path in ~/.codex/config.toml, where it takes precedence over the plugin's own entry and inherits the session's working directory. Re-run scripts/install.mjs if the repository moves.

  • Codex trusts hooks by hash. Until you run Codex's /hooks review, the SessionStart rule does not fire (the plugin's MCP tools still work).

  • Grok has no session-start context channel, and its SessionStart hook output is recorded but not injected — hence the rules file. Grok also gates a server whose command lives inside the folder you are working in behind folder trust (--trust), which only matters when you run Grok inside this repository.

  • Claude Code's plugin install of a local directory is live, not a frozen copy: the marketplace points at this directory and ${CLAUDE_PLUGIN_ROOT} resolves to it. Moving the directory means re-adding the marketplace.

  • Rule 14 (verify-by-use) stays suspended. No request has been observed flowing router → worker → handoff in a real model turn; the tests pin contract-level facts, and the smoke checks above pin loading, not routing.

  • The three hosts' skill catalogs are always-on context. Ten skills cost ~40 tokens each on Claude Code (claude plugin details prints the estimate); Codex shortens descriptions when its budget fills.

Docs

  • goal-and-requirements.md — what this port is for, in and out of scope, acceptance criteria.

  • architecture.md — drivers, decisions, invariants, out-of-scope.

  • SPEC.md, core/SPEC.md, mcp/SPEC.md — the plugin's own module specs.

  • NOTICE — attribution and the license each part keeps.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    D
    maintenance
    Enables spec-driven development workflows with AI assistants, providing tools for managing specification lifecycles, task dependencies, code navigation, testing, and automated reviews through a unified CLI and MCP interface.
    4
    MIT
  • A
    license
    Not graded
    quality
    A
    maintenance
    Autonomous spec-to-product coding-agent CLI. Its MCP server exposes 34 tools over stdio: project state and task-queue ops, memory retrieve/store, code search, quality and verification reports, repo hotspots/co-changes, and structured findings/learnings.
    13,524 npm
    1,088
    Business Source 1.1
  • A
    license
    C
    quality
    B
    maintenance
    Enables authoring, validating, inspecting, blackbox-inventorying, tracing, and capability-querying SPEC.md documents through MCP tools over stdio JSON-RPC. Each tool wraps the same command modules the CLI uses and returns identical JSON envelopes.
    9
    Apache 2.0