mcp-current-repo
by Wolfe-Jam
README.md
# mcp-current-repo
> **⚠️ Superseded.** [SEP-2577](https://github.com/modelcontextprotocol/modelcontextprotocol/pull/2577) deprecated MCP Roots — the mechanism this repo uses to carry project identity — citing vague semantics and overlap with tool parameters and server configuration. The successor is **[mcp-project-context](https://github.com/Wolfe-Jam/mcp-project-context)**, which carries the same identity through tool-parameter injection instead (the surface the SEP itself named as the alternative). Kept here as a record of the Roots-based approach and why it didn't hold up.
**Give an MCP server "current-project" focus** — so it stops doing the *"list every repo and guess"* dance — **without giving it filesystem access.**
The host already knows what project you're in. The protocol can carry that. The server never needs to touch your disk.
A working proof of the path **@SamMorrowDrums suggested** on
[github/github-mcp-server#1683](https://github.com/github/github-mcp-server/issues/1683):
> "I have often considered allowing for a repo-specific version… I think the host application would need to do it with a roots-like MCP protocol support. We don't have local folder access so unlike GH we cannot access files to determine current repo directly."
## The problem (#1683 / #1308)
Ask a GitHub-connected agent to "show *this* project's issues" and it wanders: `list_repositories` → enumerate every repo → guess the current one → maybe ask you. Slow, scattered, and it burns context the model needs for the actual task.
## The fix
```
current repo HOST (MCP client) SERVER
(derived by the ──▶ puts it in a root ──roots/list──▶ reads the root,
host) (protocol) auto-scopes the tool
— never reads a file
```
The **host** has the project context; it passes the repo identity over **MCP roots**; the **server** auto-scopes every tool. No exploration phase, no filesystem access on the server.
## Before / after (actual output of `npm run demo`)
```
BEFORE — plain workspace root, no project context
· no owner/repo in the call → requesting roots/list from the host…
· host returned 1 root(s): workspace
⛔ No project scope available.
A real agent now does the 'search-first-then-locate' dance:
→ list_repositories (enumerate every repo) → guess the current one → maybe ask the user.
AFTER — host carries the current repo via the root name
· no owner/repo in the call → requesting roots/list from the host…
· host returned 1 root(s): faf:repo=github.com/octocat/Hello-World
✅ Scoped to octocat/Hello-World (no fs, no exploration)
No exploration phase. The server read NO files.
```
## The finding worth knowing (a 20-min spike)
The MCP TypeScript SDK currently **hard-enforces `file://` on root URIs**:
```js
// @modelcontextprotocol/sdk — types.js
RootSchema = z.object({
uri: z.string().startsWith('file://'), // "This *must* start with file:// for now."
...
})
```
So you **cannot** pass `https://github.com/owner/repo` as a root URI today — it's rejected. This demo therefore carries the repo identity in the root **`name`**. That points at a small, concrete ask for the spec/SDK: **relax the roots URI constraint** (a typed `repo://` / project-context root), so identity doesn't have to ride in a free-text `name`.
## What a server would add (minimal)
1. On a tool call without `owner`/`repo`, call `roots/list` (the SDK already supports this).
2. Read the project root the host provides.
3. Use it as the default scope. Done — no exploration, no fs access.
## Where the current repo comes from
The host has to derive the repo somehow. This demo reads a **`project.faf`** — a typed, portable context file you own ([IANA-registered](https://www.iana.org/assignments/media-types/application/vnd.faf+yaml) as `application/vnd.faf+yaml`) — which already carries the project's identity in one field. It's a clean source because the file *is* the scope and travels with the repo.
But the mechanism is **source-agnostic**: derive the repo from `.git`, an env var, an IDE workspace setting — whatever the host knows. The roots path is the same; `project.faf` is just one tidy way to feed it.
## Run it
```bash
npm install
npm run demo
```
MIT. A stub for discussion, not a fork.
This server cannot be deployed
Maintenance
ActivityStale
ResponsivenessNo issues