# RTK Integration Methods for Claude Code and Cursor AI Agents

> Learn RTK integration methods for Claude Code and Cursor AI agents. RTK intercepts tool-use events, rewrites commands, and provides expected JSON responses.

- Repository: [rtk-ai/rtk](https://github.com/rtk-ai/rtk)
- Tags: how-to-guide
- Published: 2026-04-24

---

**RTK integrates with Claude Code and Cursor through shell-based hooks that intercept agent tool-use events, validate the environment, and rewrite commands via `rtk rewrite` before returning JSON responses the agents expect.**

RTK (Rust Token Killer) provides agent-specific integration methods that transparently rewrite raw CLI commands into token-efficient `rtk` equivalents. These integrations hook into Claude Code and Cursor's pre-execution events, ensuring AI coding assistants operate with significantly reduced token usage without blocking native functionality.

## How RTK Hooks Into AI Agents

The integration relies on thin shell-script wrappers located in [`hooks/claude/rtk-rewrite.sh`](https://github.com/rtk-ai/rtk/blob/main/hooks/claude/rtk-rewrite.sh) and [`hooks/cursor/rtk-rewrite.sh`](https://github.com/rtk-ai/rtk/blob/main/hooks/cursor/rtk-rewrite.sh). These scripts serve as delegators between the AI agent and the Rust binary's rewrite logic, converting standard shell commands into optimized `rtk` invocations before the agent executes them.

### The Four-Step Hook Process

Every integration follows the same execution flow:

1. **Receive the agent's JSON payload** containing the command the assistant intends to execute.
2. **Validate the environment** by checking for `jq` installation and `rtk` version ≥ 0.23.0 with cached version checks.
3. **Call `rtk rewrite <command>`** to obtain a possible rewritten command and exit status encoding permission handling.
4. **Return a JSON response** in the exact shape the specific agent expects.

If the rewrite fails or the command is unsupported, the hook returns an empty or allow response, letting the agent fall back to the raw command without blocking execution.

## Claude Code Integration Method

Claude Code integration utilizes a shell-based **PreToolUse** event hook that intercepts commands before the LLM executes them.

### PreToolUse Hook Mechanism

When Claude Code prepares to run a tool, it sends a JSON payload to the hook script at [`hooks/claude/rtk-rewrite.sh`](https://github.com/rtk-ai/rtk/blob/main/hooks/claude/rtk-rewrite.sh):

```json
{
  "tool_input": { "command": "git status" }
}

```

The script parses this input, invokes `rtk rewrite "git status"`, and constructs a response in Claude Code's expected format using the `hookSpecificOutput` field.

### Permission Handling and Exit Codes

The `rtk rewrite` command returns specific exit codes that the hook translates into permission decisions (implemented in lines 58-79 of [`hooks/claude/rtk-rewrite.sh`](https://github.com/rtk-ai/rtk/blob/main/hooks/claude/rtk-rewrite.sh)):

- **Exit 0**: Auto-allow the rewritten command
- **Exit 1**: No rewrite available; proceed with original command
- **Exit 2**: Deny execution using Claude Code's native deny mechanism
- **Exit 3**: Ask the user for permission before proceeding

The hook returns a JSON object containing `hookSpecificOutput` with `permissionDecision`, `permissionDecisionReason`, and `updatedInput` fields.

## Cursor Integration Method

Cursor operates similarly but uses slightly different event naming and JSON response structures.

### preToolUse Hook Structure

Cursor triggers a shell-based **preToolUse** event (lowercase) that expects JSON with `tool_input.command`. The integration script at [`hooks/cursor/rtk-rewrite.sh`](https://github.com/rtk-ai/rtk/blob/main/hooks/cursor/rtk-rewrite.sh) processes this payload identically to the Claude Code version but formats the response for Cursor's consumption.

### Cursor-Specific JSON Response Format

Unlike Claude Code's nested `hookSpecificOutput` structure, Cursor expects a flat JSON object containing `permission` and `updated_input` fields:

```json
{
  "permission": "allow",
  "updated_input": { "command": "rtk cargo test" }
}

```

The permission handling logic mirrors Claude Code (lines 58-78 in [`hooks/cursor/rtk-rewrite.sh`](https://github.com/rtk-ai/rtk/blob/main/hooks/cursor/rtk-rewrite.sh)): exit codes 0 and 3 map to `allow`, exit 1 returns empty JSON for no rewrite, and exit 2 lets Cursor's native deny mechanism run.

## Core Rewrite Logic in Rust

All command classification and rewrite decisions are performed by the Rust module **[`src/discover/registry.rs`](https://github.com/rtk-ai/rtk/blob/main/src/discover/registry.rs)**, ensuring consistent behavior across all supported agents.

### Command Classification

The `classify_command` function matches raw commands against regex-based rule sets in the registry. When a match occurs, it yields `Classification::Supported` with the appropriate `rtk` command substitution.

### Rewrite Orchestration

The `rewrite_command` function orchestrates compound-command handling, environment-prefix stripping, and redirect awareness. This central logic guarantees that Claude Code, Cursor, and other agents use identical rewrite rules regardless of their specific hook implementations.

## Installation and Setup

Install the appropriate hook for your AI agent using the `rtk init` command:

```bash

# Install Claude Code hook globally

rtk init --global

```

```bash

# Install Cursor hook globally  

rtk init --global --cursor

```

Both commands copy the appropriate [`rtk-rewrite.sh`](https://github.com/rtk-ai/rtk/blob/main/rtk-rewrite.sh) into the agent's hook directory and, for Claude Code, patch [`settings.json`](https://github.com/rtk-ai/rtk/blob/main/settings.json) to enable the `PreToolUse` event.

## Summary

- **Shell-based hooks** in [`hooks/claude/rtk-rewrite.sh`](https://github.com/rtk-ai/rtk/blob/main/hooks/claude/rtk-rewrite.sh) and [`hooks/cursor/rtk-rewrite.sh`](https://github.com/rtk-ai/rtk/blob/main/hooks/cursor/rtk-rewrite.sh) serve as thin delegators between AI agents and the Rust binary.
- **Exit code semantics** (0=auto-allow, 1=no rewrite, 2=deny, 3=ask) enable granular permission control compatible with both agents' native mechanisms.
- **Agent-specific JSON formats** require Claude Code responses to use `hookSpecificOutput` while Cursor uses `permission` and `updated_input` fields.
- **Central classification logic** in [`src/discover/registry.rs`](https://github.com/rtk-ai/rtk/blob/main/src/discover/registry.rs) ensures consistent command rewriting across all supported AI agents.
- **Graceful degradation** ensures that unsupported commands fall back to the original input without blocking execution.

## Frequently Asked Questions

### How does RTK handle unsupported commands?

When `rtk rewrite` encounters an unsupported command, it returns exit code 1. The hook script detects this and returns an empty or pass-through JSON response, allowing Claude Code or Cursor to execute the original raw command without modification. This ensures RTK never blocks execution of commands outside its registry.

### What exit code does RTK return when auto-allowing rewrites?

Exit code 0 from `rtk rewrite` indicates a successful rewrite that should be auto-allowed. Both the Claude Code hook ([`hooks/claude/rtk-rewrite.sh`](https://github.com/rtk-ai/rtk/blob/main/hooks/claude/rtk-rewrite.sh)) and Cursor hook ([`hooks/cursor/rtk-rewrite.sh`](https://github.com/rtk-ai/rtk/blob/main/hooks/cursor/rtk-rewrite.sh)) map this exit code to their respective "allow" permission states, enabling the agent to execute the rewritten `rtk` command immediately.

### Where is the central command classification logic located?

The central classification and rewrite logic resides in **[`src/discover/registry.rs`](https://github.com/rtk-ai/rtk/blob/main/src/discover/registry.rs)**, specifically within the `classify_command` and `rewrite_command` functions. This module uses regex-based rules to match incoming commands and generate appropriate `rtk` substitutions, ensuring all AI agent integrations share identical rewrite behavior.

### Can RTK block command execution if needed?

Yes, RTK can block commands through exit code 2 (deny) or exit code 3 (ask). Exit code 2 triggers the agent's native deny mechanism, while exit code 3 prompts the agent to request user confirmation before proceeding. These permissions are handled in the shell hooks (lines 58-79 for Claude Code, lines 58-78 for Cursor) and provide fine-grained control over potentially destructive operations.