# 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