Skip to content
162 changes: 162 additions & 0 deletions .coderabbit.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,162 @@
# yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

# mcp-ssh — CodeRabbit configuration
#
# Single Rust binary: an MCP server giving an AI agent remote shell + file
# access to ONE host, over authenticated MCP Streamable HTTP at /mcp.
# Authority: CLAUDE.md (Conventions + NEVER) is absolute. Cite the rule.

language: en-US
early_access: true
enable_free_tier: true

tone_instructions: "mcp-ssh: Rust 2024, tokio, axum, rmcp. CLAUDE.md NEVER rules are absolute — no password/token in logs/errors/responses, never run as root, never weaken auth, never add a 4th MCP tool (parametrize bash/job/file). Concrete diffs, skip nits."

reviews:
profile: assertive
request_changes_workflow: true
high_level_summary: true
high_level_summary_placeholder: "@coderabbitai summary"
auto_title_placeholder: "@coderabbitai"
poem: false
review_status: true
collapse_walkthrough: false
sequence_diagrams: true
estimate_code_review_effort: true
suggested_reviewers: true
auto_assign_reviewers: false
abort_on_close: true

auto_review:
enabled: true
auto_incremental_review: true
ignore_title_keywords:
- "WIP"
- "DRAFT"
- "DO NOT REVIEW"
drafts: false
base_branches:
- main

tools:
shellcheck: { enabled: true }
markdownlint: { enabled: true }
yamllint: { enabled: true }
actionlint: { enabled: true }
hadolint: { enabled: true }
gitleaks: { enabled: true }
github-checks: { enabled: true, timeout_ms: 900000 }
ruff: { enabled: false }
biome: { enabled: false }
eslint: { enabled: false }
rubocop: { enabled: false }

path_instructions:
- path: "**/*"
instructions: |
Review only changed files and code directly affected. Behaviour
changes must update docs/ in the same PR. Flag missing tests for new
public behaviour.

# Rust source — CLAUDE.md Conventions
- path: "src/**/*.rs"
instructions: |
Enforce CLAUDE.md Conventions:
- No unwrap/expect outside main.rs and #[cfg(test)]; panic in the
request path crashes every client.
- Errors typed with thiserror; anyhow only at the main.rs boundary.
- Async end-to-end. No std::sync::Mutex on the request path (use
tokio::sync), never held across .await. No block_on; spawn_blocking
for blocking I/O.
- Newtype over bare primitives with meaning (JobId, not String).
Make illegal states unrepresentable.
- tracing spans (request_id, tool), never println!.
- Files <=300 LOC, one responsibility. clippy -D warnings + rustfmt
clean is the floor.

# Auth + OAuth — security review required
- path: "src/auth.rs"
instructions: |
SECURITY REVIEW. HTTP Basic middleware. Never log/return the
password. Flag any path that bypasses or weakens auth.
- path: "src/oauth/**"
instructions: |
SECURITY REVIEW. OAuth 2.1: discovery, dynamic registration, PKCE on
authorize+token, bearer validation. No token material in logs/errors.

# Config — fail fast, secrets
- path: "src/config.rs"
instructions: |
Validated at boot — missing auth creds fail at startup, never at
request time. MCP_SSH_ALLOWED_HOSTS must be required. Secrets never
logged.

# Tools — constant 3-tool surface
- path: "src/tools/**"
instructions: |
Exactly 3 tools (bash/job/file) dispatching on action. NEW capability
= a new param/action, never a 4th tool. Thin adapters — no business
logic in the dispatch arm.

# Jobs — backgrounding, log pagination, process-group kill
- path: "src/jobs/**"
instructions: |
Output streams to a per-job log file; poll paginates (cursor/limit)
so chatty commands never flood agent context. Jobs spawn in their own
process group so kills reach descendants. Kill escalates TERM->KILL.
Reaper drops jobs >24h, killing any still-Running group first.

# Integration tests — real server over HTTP
- path: "tests/**/*.rs"
instructions: |
Boot the server and issue real MCP requests over HTTP. New behaviour
ships with the test that proves it.

# CI
- path: ".github/workflows/**"
instructions: |
Runner: blacksmith-2vcpu-ubuntu-2404. Pin actions to major versions.
Required jobs: fmt, clippy (-D warnings), test.

# Dockerfile
- path: "Dockerfile"
instructions: |
Multi-stage build. Non-root user — never run as root. No build
secrets baked in.

- path: "**/*.md"
instructions: |
Lead with the rule, tables over prose, file paths over descriptions,
no filler. Valid links, accurate code examples.

path_filters:
- "!target/**"
- "!**/target/**"
- "!**/*.log"
- "!.env*"
- "!**/.DS_Store"

chat:
auto_reply: true
art: false

knowledge_base:
opt_out: false

web_search:
enabled: true

code_guidelines:
enabled: true
filePatterns:
- "**/CLAUDE.md"
- "docs/**"

learnings:
scope: auto

issues:
scope: auto

pull_requests:
scope: auto
6 changes: 4 additions & 2 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,8 @@ Keep this accurate — it's the navigation aid.
| `src/config.rs` | env + TOML file config; fails fast if auth creds missing |
| `src/auth.rs` | HTTP Basic auth middleware |
| `src/oauth/` | minimal OAuth 2.1 server: discovery metadata, dynamic client registration, authorize + token with PKCE, bearer validation |
| `src/jobs.rs` | job engine: run a command, return inline if fast (<2s) else a job id (or immediately when `bg`); output streams to a per-job log file, polled paginated; hourly reaper drops jobs >24h old |
| `src/jobs/mod.rs` | job engine: run a command, return inline if fast (<2s) else a job id (or immediately when `bg`); output streams to a per-job log file, polled paginated |
| `src/jobs/reaper.rs` | hourly reaper drops jobs >24h old (killing any still-`Running` group first); process-group kill helpers (TERM→KILL escalation), shared with `job(action="kill")` |
| `src/tools/mod.rs` | MCP tool surface (`#[tool_router]`/`#[tool]` from rmcp): 3 tools (`bash`/`job`/`file`) dispatching on `action`. Thin adapters over jobs + files |
| `src/tools/files.rs` | file operations (`tokio::fs`; `ls`/`find`/`grep` shelled out) |

Expand Down Expand Up @@ -125,7 +126,8 @@ Non-negotiable: SOLID, SRP, tested code. The bar: idiomatic, boring, readable Ru
| Config / env / required creds | `src/config.rs` |
| HTTP Basic auth | `src/auth.rs` |
| OAuth 2.1 (discovery, registration, PKCE, bearer) | `src/oauth/` |
| Running commands, backgrounding, job logs | `src/jobs.rs` |
| Running commands, backgrounding, job logs | `src/jobs/mod.rs` |
| Reaper eviction + process-group kill helpers | `src/jobs/reaper.rs` |
| Tool definitions / MCP surface | `src/tools/mod.rs` |
| File operations | `src/tools/files.rs` |

Expand Down
Loading
Loading