Usage
Claude Code decides which tool to call from a skill's description and its supporting files.
Without one naming Rift's tools, an agent falls back to grepping the repository even when a
rift mcp server already indexes it. rift install claude writes that skill.
Install
Run this from a codebase Rift serves:
rift install claudeThe command writes SKILL.md and a references/tools.md sidecar under .claude/skills/rift/
in the current workspace. Claude Code reads SKILL.md's frontmatter to decide when to load the
skill, and loads the sidecar on demand for each tool's parameters.
Pass --user to write under the operator's home directory instead of the workspace, so every
project the operator opens with Claude Code picks up the skill:
rift install claude --userPass --remove to delete the generated skill from either scope:
rift install claude --remove
rift install claude --user --removeInstall as a plugin
Since v0.0.31The repository doubles as a Claude Code plugin marketplace, so the skill installs without the
rift CLI:
/plugin marketplace add volarized/rift
/plugin install rift@riftThe plugin ships the same generated skill plus an .mcp.json naming the rift mcp server, so
one install covers every project the operator opens. The plugin's server entry is additive and
scoped to the plugin: Claude Code leaves the operator's own .mcp.json and settings untouched,
and uninstalling the plugin removes the entry with it.
The rift executable is still what serves the tools. When it is missing, Claude Code skips the
plugin's server entry and the skill's own install section names the installer commands; the
quickstart carries the same commands.
The steering hook stays with rift install claude: the plugin carries the skill and the server
entry alone. A workspace already carrying a rift entry written by rift install claude runs a
second proxy beside the plugin's; both reach the same workspace server. Keep one: remove the
project entry or disable the plugin for that project.
What the skill teaches
The generated SKILL.md carries a decision table pointing the agent at the tool that answers
its situation:
searchanswers when the target is unknown.get_symbolreads one exact symbol identity returned by search.nodesanswers when the syntax structure at one position is needed.searchwith atraversalblock answers a symbol's neighbors, its impact (who breaks when it changes), or a path between two symbols.
The skill also points the agent at rift://map as the first
read in an unfamiliar repository, and at rift server logs
when a refusal alone doesn't say why.
Steering
Since v0.0.29A skill changes what an agent reaches for; habit still wins the first time it needs to search.
Claude Code agents call Grep and Glob from training, even in a workspace rift mcp already
indexes, and a session whose tool set lists neither runs grep, rg, or find through Bash.
rift steer catches that first call and redirects it.
rift install claude writes a PreToolUse hook alongside the skill:
{
"hooks": {
"PreToolUse": [
{
"hooks": [
{
"command": "rift steer",
"type": "command"
}
],
"matcher": "Grep|Glob|Bash"
}
]
}
}Claude Code runs rift steer before every Grep, Glob, and Bash call and pipes it the tool
call as JSON on stdin. In a workspace Rift has indexed and version control tracks, the first
search call of a session is denied: the reason names the search call
that answers the same question, get_symbol for an established symbol identity,
and rift://map for orientation.
The suggested call carries the agent's own search:
- a
Grepcall becomes apatternsearch with the same regex. Itspath,glob, andtypebecomepaths.include,-ia(?i)prefix, andhead_limitandoffsetthe page - a
Globcall becomes apatternsearch for\A, which matches once at the start of every file, withtarget: "file": the answer lists the indexed files its pattern selects - a
Bashcall running one plaingrep,rg, orfindcommand is read as theGreporGlobcall it equals. grep's basic and extended syntax is translated into the regex syntaxpatternreads, sogrep -rn "cfg(test)" src/from the workspace root suggests:
{ "pattern": "cfg\\(test\\)", "paths": { "include": ["src/**"] } }A call with a part search has no form for passes without a deny: context lines, multiline,
output_mode: "count", a pipeline or a list of commands, or a flag the steer does not map.
The same call passes if the agent retries it, and every later call in that session passes
without a prompt. rift steer marks the session with a file under .rift/steer/, so it denies
at most once per session.
Every other case passes without a prompt too: a workspace with no index yet, one with no version control, and a session that already saw its one redirect.
Set RIFT_STEER=0 in the environment Claude Code runs in to disable the hook entirely; every
call then passes.
On a workspace installed while the hook ran under Grep|Glob alone, rift install claude
rewrites the steering hook's matcher to Grep|Glob|Bash and reports that it wrote the hook. A
steering hook sharing its group with other hooks moves to a group of its own, so none of them
starts running on Bash.
rift install claude --remove strips the hook entry from .claude/settings.json, leaving every
other entry in the file untouched.
Regeneration
rift install claude reads the same tool router rift mcp serves, so the skill's tool names
can never drift from what this build actually serves. Rerun the command after every upgrade; it
overwrites the previous skill with the current one.