Back to the catalog

io.github.3xpr1ment/repiscope

Read-only MCP server: your agent sees all your sibling repos but structurally cannot touch them

Open source Open in the app JSON README (API)

About

Read-only MCP server: your agent sees all your sibling repos but structurally cannot touch them

Details

Kind
MCP servers
Topic
No topic detected
Publisher
3xpr1ment
Origin
official
Category
ferramentas
Transport
local
Version
0.2.2
Last push
2026-07-09T05:47:08Z
Repository state
ativo
Language
Python
License
MIT
Added
2026-08-29 03:01:38
Updated
2026-08-29 03:01:38
Origin id
io.github.3xpr1ment/repiscope

README

# Repiscope

**A periscope for your repos — see everything, touch nothing.**

Repiscope is a read-only MCP server that gives your coding agent (Claude Code,
Cursor, or any MCP client) awareness of the *sibling repositories* next to the
one it's working in — without ever letting it modify them.

## Why

I built a personal assistant to help me decide where my time goes: for that
it needs to know the real state of every project — what changed, what
stalled, what the next step is. So it has to *see* all my repos. But telling
an agent "don't touch anything" is a request, not a guarantee. Repiscope
makes it a **guarantee**: the server exposes zero write tools, so the agent
structurally *cannot* modify your repos. And the same periscope helps any
coding agent working in project A that needs to know how a part of
project B works.

Sandboxes make this worse, not better: mine (rightly) stops the agent from
even *reading* outside the repo it started in without asking. Widening the
sandbox would grant write access too. Repiscope is the third way — the
agent gets structured, read-only sight of every sibling repo through one
MCP server, and the sandbox stays tight.

## See it in action

You're working in `project-a` and need to pull data from another project's
API. Instead of you digging through that codebase, the agent asks Repiscope
directly:

```
You:    Use Repiscope to find out what kind of data I can retrieve
        from billing-api through its API.

Agent:  (calls list_projects → sees "billing-api")
        (calls project_overview "billing-api" → spots src/routes/)
        (calls search "route" project="billing-api")
        (calls read_file "billing-api" "src/routes/invoices.py")

        billing-api exposes three endpoints: /invoices (list, filterable
        by customer and date), /invoices/{id} (full invoice with line
        items), and /customers/{id}/balance (current balance). All
        responses are JSON; auth is a bearer token.
```

The agent explored a repo it has **no ability to write to**. No copy-paste,
no "please don't edit anything," no risk.

## Tools

| Tool | Input | Returns |
|------|-------|---------|
| `list_projects()` | — | every sibling repo + one-line description |
| `project_overview(project)` | repo name | full overview: purpose, stack, structure, recent commits |
| `search(query, project?)` | text, optional repo | files & lines matching the query |
| `read_file(project, path)` | repo + file path | full file contents (size-capped) |
| `store_summary(project, summary)` | repo + your text | caches an agent-written summary (see below) |

## How it stays fresh

Overviews are cached as markdown and refreshed lazily: on each call Repiscope
compares the repo's current git commit hash against the one recorded when the
overview was built. Same hash → serve the cache. Different → rebuild just that
repo's overview. No cron, no daemons.

## Borrowed intelligence

Repiscope has no LLM of its own — no API key, no model calls, zero cost. But
it talks to LLMs all day, so it borrows them: when an overview has no fresh
agent-written summary, it ends with a note asking the *calling* agent to
write one and hand it back via `store_summary`. The summary then opens every
future overview of that project — written by one agent, read by all the
next — until the repo's next commit marks it outdated and the cycle repeats.

## Security by architecture

Repiscope is built so that the safe behaviour is not a promise — it's the
only behaviour possible:

- **Zero repo-write tools.** The server exposes no tool that can create,
  edit or delete anything inside your repositories. The one tool that
  accepts data, `store_summary`, can only write to Repiscope's own cache in
  `~/.cache/repiscope`. An agent cannot misuse a capability that doesn't
  exist.
- **Secrets are invisible.** A single filter (`privacy.py`) is enforced by
  every tool: private keys, certificates (`.pem`, `.pfx`, `.p12`, …),
  `.env*` files, keystores, and anything named like a credential never
  appear in overviews, trees, search results or file reads.
  *Honest limit:* the filter hides sensitive **files** — it does not scrub
  mentions of e.g. a password pasted inside an ordinary text file.
- **Symlinks can't smuggle.** A cloned repo is untrusted content — it may
  contain a symlink like `notes.txt → ~/.ssh/id_rsa`. Anything whose real
  location falls outside the project is invisible to every tool, the secret
  filter also checks a link's real target, and path traversal (`../`) is
  refused.
- **You define the perimeter.** Repiscope only sees the folder you
  explicitly pass (`--root`), and `--exclude` makes chosen repos fully
  invisible — they can't even be resolved by name.
- **It leaves no trace.** Overview caches live in `~/.cache/repiscope`,
  never inside your repositories.

Every claim above is enforced by the test suite in `tests/` — clone the
repo and run `pytest` to check them yourself.

## Quick start

```bash
pip install repiscope
claude mcp add repiscope --scope user -- repiscope --root ~/your/projects/folder
```

That's it — point `--root` at the folder *containing* your repos (not a repo
itself). Optionally hide repos with `--exclude repo-a --exclude repo-b`.
Works with any MCP client; for Claude Desktop there's also a one-click
`.mcpb` bundle (build it with `mcpb/build.sh`).

From source instead:

```bash
git clone https://github.com/3xpr1ment/repiscope.git
cd repiscope
python -m venv .venv && .venv/bin/pip install -e .[dev]
.venv/bin/pytest   # the security claims, as executable proof
```

## Limitations

Honesty section — what Repiscope deliberately does *not* do:

- **The secret filter works at file level.** Sensitive *files* are
  invisible, but a password pasted inside an ordinary `notes.md` will not
  be scrubbed. The perimeter is yours: only point `--root` at folders you
  are comfortable showing to your agent — whatever the tools can see, your
  LLM provider will see too.
- **Search is deliberately dumb.** Case-insensitive substring match, capped
  results, no index, no regex. The calling LLM supplies the intelligence at
  both ends; for heavy code search, use a real code-search tool.
- **Overviews are mechanical.** Without an agent-written summary they are
  README excerpts, language stats and git logs — useful, not insightful.
  The insight arrives once your agents start leaving summaries behind.
- **Read-only cuts both ways.** There is no refresh tool to call: caches
  refresh lazily on the next commit, and stale summaries are served marked
  as stale until an agent writes a new one.
- **Python ≥ 3.11**, developed and tested on macOS; Linux should behave
  identically, Windows symlink semantics are untested.

## Status

v0.2.2 — working and dogfooded daily. Four read-only tools plus borrowed-LLM
summaries, lazy cache refresh, sensitive-file filtering, and a test suite
proving the security claims (path traversal, symlink escapes, secret
filtering — see `tests/`). API may still change.

## How this was built

To be completely clear about authorship: I am not an engineer. Every
architecture decision in Repiscope is mine — what it does, what it refuses
to do, where the security gates live — but the coding itself is done by
Claude (Anthropic's Fable model). My rule for the collaboration: nothing
goes in that I don't understand. The commit history carries the
co-authorship openly, commit by commit.

## License

[MIT](LICENSE)

---

mcp-name: io.github.3xpr1ment/repiscope

More