Cross Repo Ops MCP
# Cross Repo Ops MCP
A repo-neutral MCP (Model Context Protocol) capability layer for controlled local repository operations.
## What It Does
Cross Repo Ops MCP provides a security-hardened stdio JSON-RPC server that exposes bounded, policy-controlled operations on local git repositories:
- **Read**: tree listing, ripgrep search, bounded file reads, git status/diff
- **Write**: context-checked patches with create/modify support (writable repos only)
- **Tasks**: approved named task execution (allowlist-only, no arbitrary shell)
- **Git**: branch list/create/switch, commit (explicit files only), push (origin only, pushable repos only)
## Architecture
Cross Repo Ops MCP is a repo-neutral capability layer for controlled local repository operations. It is designed to sit beside an XcodeIDEapp project, borrowing ideas from IDE dashboard scaffolding patterns, but remains generic and does not depend on any specific IDE or project structure.
```
Cross Repo Ops MCP = controlled local repository actions (read, patch, git, tasks)
```
The server is policy-driven: repos, capabilities, excluded paths, and approved tasks are all declared in a JSON config. No project-specific logic is hardcoded in the core.
### Modules
| Module | Responsibility |
|--------|---------------|
| `policy.py` | Centralized repository capability policy (allowlist, writable/pushable flags, excluded paths, task allowlist, limits, timeouts) |
| `guard.py` | Single authoritative path-validation boundary (traversal, symlink, absolute-path, containment checks) |
| `repo.py` | Tree listing, ripgrep search, bounded file read, git status/diff |
| `patch.py` | Context-checked patch application with create/modify support |
| `git.py` | Branch, commit, and push operations with safety guards |
| `tasks.py` | Named task allowlist resolution and execution |
| `server.py` | stdio JSON-RPC MCP server |
| `errors.py` | Error types |
## Security Model
- **Repository allowlist**: Only repos explicitly listed in the policy are accessible.
- **Capability flags**: `writable` and `pushable` are per-repo, default `false`.
- **Path containment**: All paths are resolved and checked against the repo root. Traversal (`..`), absolute paths, and symlinks are rejected.
- **Sensitive file exclusion**: `.env`, `*.pem`, API keys, tokens, credentials, and binary files are blocked from read and write.
- **Patch safety**: `old_text` must match exactly; multiple matches require `context` to disambiguate. `create=true` refuses to overwrite existing files.
- **Task allowlist**: Tasks are resolved by name from a server-side allowlist, not from user input. No arbitrary shell commands.
- **Git safety**: Bulk staging (`git add -A`) is rejected. Commits are limited to explicitly listed files. Sensitive files cannot be committed. Branch names are validated against injection. Push is limited to `origin` for pushable repos only.
- **Output limits**: All operations have configurable output caps (read chars, search results, tree entries, diff chars, task output).
## Installation
```bash
# No external dependencies required — Python 3.10+ standard library only.
cd cross-repo-ops
pip install -e . # optional, for package install
```
## Usage
### Run the MCP server
```bash
python3 -m cross_repo_ops
```
The server listens on stdin/stdout for JSON-RPC 2.0 messages.
### Custom policy
```bash
CROSS_REPO_OPS_CONFIG=/path/to/policy.json python3 -m cross_repo_ops
```
### Policy file format
```json
{
"repos": {
"myrepo": {
"root": "/path/to/repo",
"writable": true,
"pushable": false
}
},
"tasks": {
"myrepo": {
"build": {
"command": ["xcodebuild", "-scheme", "MyApp", "build"],
"cwd": "{root}",
"timeout": 180
},
"test": {
"command": ["xcodebuild", "test", "-scheme", "MyApp"],
"cwd": "{root}",
"timeout": 300
}
}
}
}
```
## MCP Tools
| Tool | Description |
|------|-------------|
| `repo_tree` | List files/directories with safety exclusions |
| `repo_search` | Ripgrep search with bounded output |
| `repo_read` | Read a bounded slice of a non-sensitive text file |
| `git_status` | Inspect git status |
| `git_diff` | View unstaged/staged/commit diffs |
| `apply_patch` | Apply a context-checked patch (writable repos only) |
| `run_task` | Run an approved named task (allowlist only) |
| `git_branch` | List/create/switch branches (writable repos for create/switch) |
| `git_commit` | Stage and commit explicit files (writable repos only) |
| `git_push` | Push to origin (pushable repos only) |
## Testing
```bash
python3 -m unittest tests.test_security tests.test_adversarial -v
```
32 tests covering:
- Allowed and blocked reads
- Path traversal, absolute path, and symlink escape rejection
- Sensitive file read/write/commit blocking
- Writable vs read-only repo enforcement
- Patch with correct/stale context
- Patch targeting excluded files
- Named task allowlist (success, unknown name, shell injection attempt)
- Task timeout and output truncation
- Git status/diff
- Branch name injection safeguards
- Commit safeguards (empty message, sensitive files, bulk staging, pre-staged files)
- Push rejection for non-pushable repos
- Server missing-argument handling
## License
MIT
TDQS
Scored across 10 tools
Each tool maps cleanly to a distinct action: repo_* covers content browsing/search, git_* covers repository state operations, and apply_patch/run_task cover modifications. Adjacent tools like git_status and git_diff are clearly separated by purpose. No two tools appear to do the same thing.
Most tools follow a clear domain-prefix pattern: repo_* for content operations and git_* for VCS operations. The exceptions are apply_patch and run_task, which use bare verb_noun names but remain readable and consistent with the overall snake_case style.
Ten tools is an ideal size for this scope; each tool covers a distinct operation without redundancy. The set feels intentionally scoped rather than padded.
The read/search → patch → branch → commit → push workflow provides a complete edit-and-publish lifecycle. Minor gaps include no repository enumeration, no git pull/fetch, and no way to list approved run_task tasks, but these do not block the primary workflow.