rmor 0.1.0

Secure web fetch MCP server with prompt injection detection
# rmor

Secure web fetch MCP server for Claude Code CLI, written in Rust.

Claude Code's built-in `web_fetch` passes web content directly into the LLM context with no
sanitisation or injection detection. This is especially dangerous in YOLO mode — a malicious
page can inject instructions that hijack the agent mid-session.

rmor replaces `web_fetch` with a local MCP server that can go **interactive** when suspicious
content is detected, so the user decides before anything enters Claude's context.

> Current status: straight-through pass with request logging. Scanning and the interactive
> circuit breaker are not yet implemented — see [doc/todo.md]doc/todo.md.

## Requirements

- Rust toolchain (stable) — install via [rustup]https://rustup.rs

## Installation

### Build from source

```sh
git clone https://github.com/jimbarritt/rmor
cd rmor
cargo build --release
```

The binary lands at `target/release/rmor`. Copy it somewhere on your `$PATH` if you want:

```sh
cp target/release/rmor ~/.local/bin/rmor
```

## Running locally

rmor communicates over stdio using the MCP protocol. You don't run it directly — Claude Code
launches it as a subprocess.

### Register with Claude Code

Add rmor to your Claude Code MCP config. Edit `~/.claude/claude_desktop_config.json` (or
`~/.claude/settings.json` depending on your version):

```json
{
  "mcpServers": {
    "rmor": {
      "command": "/path/to/rmor",
      "args": []
    }
  }
}
```

Replace `/path/to/rmor` with the full path to the binary, e.g. `~/.local/bin/rmor` or
`/Users/you/Code/rmor/target/release/rmor`.

Restart Claude Code. The `web_fetch` tool provided by rmor will now be available in your
session.

### Log file

Every HTTP request is logged to `~/.rmor/rmor.log`. The directory is created automatically
on first run.

```sh
tail -f ~/.rmor/rmor.log
```

### Testing the server manually

You can exercise the MCP handshake directly over stdio:

```sh
printf '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"test","version":"0.1"}}}\n' \
  | ./target/debug/rmor 2>/dev/null
```

Expected output:

```json
{"jsonrpc":"2.0","id":1,"result":{"protocolVersion":"2024-11-05","capabilities":{"tools":{}},"serverInfo":{"name":"rmcp","version":"0.16.0"},"instructions":"Secure web fetch. Logs all requests to ~/.rmor/rmor.log."}}
```

## Development

```sh
cargo build          # debug build
cargo build --release
cargo test
```

Logs go to stderr during development if you set `RUST_LOG`:

```sh
RUST_LOG=debug cargo run
```

## License

MIT