Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
166 changes: 76 additions & 90 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,52 @@

**A security-hardened MCP server that gives AI coding agents safe, deterministic access to local repositories.**

[![CI](https://github.com/bgorzelic/ghostlink/actions/workflows/ci-typescript.yml/badge.svg)](https://github.com/bgorzelic/ghostlink/actions/workflows/ci-typescript.yml)
[![npm](https://img.shields.io/npm/v/%40bgorzelic%2Fghostlink?style=flat&logo=npm&logoColor=white&label=npm)](https://www.npmjs.com/package/@bgorzelic/ghostlink)
[![TypeScript](https://img.shields.io/badge/TypeScript-strict-3178C6?style=flat&logo=typescript&logoColor=white)](tsconfig.json)
[![Node](https://img.shields.io/badge/Node.js-%E2%89%A518-339933?style=flat&logo=nodedotjs&logoColor=white)](.nvmrc)
[![Tests](https://img.shields.io/badge/tests-108%20passing-brightgreen?style=flat&logo=vitest&logoColor=white)](tests/)
[![License: ISC](https://img.shields.io/badge/license-ISC-blue?style=flat)](LICENSE)

Add it to any MCP client that supports STDIO. For Claude Code, create `.mcp.json` in the target repo root:

```json
{
"mcpServers": {
"ghostlink": {
"command": "npx",
"args": ["-y", "@bgorzelic/ghostlink"],
"env": {
"GHOSTLINK_REPO_ROOT": "/path/to/target/repo"
}
}
}
}
```

Then run `claude` in that directory — six repo tools appear, all confined to `GHOSTLINK_REPO_ROOT`. Every tool call returns the same deterministic `ToolEnvelope`:

```json
{
"ok": true,
"data": { ... },
"provenance": { "tool": "repo.search", "timestamp": "2026-02-24T...", "duration_ms": 42 }
}
```

On error, `"error": { "code": "...", "message": "..." }` replaces `"data"`. Full tool schemas: [docs/TOOLS.md](docs/TOOLS.md).

## Tools

| Tool | Description |
|---|---|
| `repo.search` | Ripgrep-powered regex search with glob filtering, deterministic ordering, and output caps (max 200 results) |
| `repo.read_file` | File read with size caps (max 10MB), binary detection, and truncation flags |
| `repo.apply_patch` | Unified diff patching with dry-run mode, full sandbox validation, and atomic rollback on failure |
| `repo.run` | Curated command execution (test, lint, typecheck, build, smoke) -- no arbitrary shell, allowlisted args only |
| `git.status` | Normalized git status with branch info, ahead/behind tracking, and sorted file entries |
| `git.diff` | Staged or unstaged diff with path filtering, sandbox validation, and output caps (max 2MB) |

## What is GhostLink?

GhostLink is a local-first [Model Context Protocol](https://modelcontextprotocol.io) server that exposes your codebase to AI coding agents through a small set of policy-gated tools. It solves a specific problem: AI agents need to search, read, patch, and verify code, but giving them raw shell access is a liability. GhostLink provides a sandboxed capability plane where every tool call is confined to a single repository root, every output follows a deterministic JSON shape, and every invocation is audit-logged.
Expand All @@ -17,28 +63,20 @@ GhostLink is a local-first [Model Context Protocol](https://modelcontextprotocol
| Multi-server composition | One GhostLink instance per repo, composable with other MCP servers in the same client session |
| Production-ready Phase 2 base | Transport abstraction, schema versioning, and auth hook seams are preserved in the architecture today |

## Tools

| Tool | Description |
|---|---|
| `repo.search` | Ripgrep-powered regex search with glob filtering, deterministic ordering, and output caps (max 200 results) |
| `repo.read_file` | File read with size caps (max 10MB), binary detection, and truncation flags |
| `repo.apply_patch` | Unified diff patching with dry-run mode, full sandbox validation, and atomic rollback on failure |
| `repo.run` | Curated command execution (test, lint, typecheck, build, smoke) -- no arbitrary shell, allowlisted args only |
| `git.status` | Normalized git status with branch info, ahead/behind tracking, and sorted file entries |
| `git.diff` | Staged or unstaged diff with path filtering, sandbox validation, and output caps (max 2MB) |
## Architecture

Every tool returns a `ToolEnvelope`:
GhostLink is a three-layer stack designed for extensibility without core changes:

```json
{
"ok": true,
"data": { ... },
"provenance": { "tool": "repo.search", "timestamp": "2026-02-24T...", "duration_ms": 42 }
}
```mermaid
flowchart TD
T["Transport -- src/index.ts<br/>STDIO now, HTTP/SSE in Phase 2"]
S["Server factory -- src/server.ts<br/>Transport-agnostic tool registration via MCP SDK + Zod schemas"]
TL["Tools -- src/core/tools/*<br/>Six tools, each returning ToolEnvelope&lt;T&gt;"]
P["Policy -- src/core/policy/*<br/>Sandbox enforcement, audit logging, output caps"]
T --> S --> TL --> P
```

On error, `"error": { "code": "...", "message": "..." }` replaces `"data"`. Full tool schemas: [docs/TOOLS.md](docs/TOOLS.md).
The `createServer()` factory knows nothing about transport. Adding HTTP/SSE in Phase 2 means writing a new transport binding and auth middleware -- the server factory and all tool implementations remain unchanged. Phase 3 (agent runtime) adds memory resources and orchestration as consumers of GhostLink, not modifications to it.

## Quick Start

Expand All @@ -48,7 +86,15 @@ On error, `"error": { "code": "...", "message": "..." }` replaces `"data"`. Full
- ripgrep (`brew install ripgrep`)
- A git repository to expose

### Install and Build
### Install

From npm:

```bash
npm install @bgorzelic/ghostlink
```

Or from source:

```bash
git clone https://github.com/bgorzelic/ghostlink.git
Expand All @@ -68,59 +114,9 @@ echo '{"jsonrpc":"2.0","id":1,"method":"tools/list"}' | \

This returns all 6 tools and their schemas.

### npm Package

```bash
npm install @bgorzelic/ghostlink
```

## Client Configuration

GhostLink works with any MCP client that supports STDIO transport.

### Claude Code

Create `.mcp.json` in the target repo root:

```json
{
"mcpServers": {
"ghostlink": {
"command": "node",
"args": ["/absolute/path/to/ghostlink/dist/index.js"],
"env": {
"GHOSTLINK_REPO_ROOT": "/path/to/target/repo"
}
}
}
}
```

Then run `claude` in that directory. GhostLink tools appear as available MCP tools.

### Claude Desktop

Add to `~/Library/Application Support/Claude/claude_desktop_config.json`:

```json
{
"mcpServers": {
"ghostlink": {
"command": "node",
"args": ["/absolute/path/to/ghostlink/dist/index.js"],
"env": {
"GHOSTLINK_REPO_ROOT": "/path/to/target/repo"
}
}
}
}
```

Restart Claude Desktop. GhostLink tools appear in the tool picker.

### Cursor, Windsurf, Cline, and Other MCP Clients

Add to your client's MCP server configuration:
GhostLink works with any MCP client that supports STDIO transport. The `npx` snippet at the top of this page works everywhere; a source checkout uses `node` with the built entry point instead:

```json
{
Expand All @@ -134,11 +130,13 @@ Add to your client's MCP server configuration:
}
```

Consult your client's documentation for the exact config file location. The transport is always STDIO.
| Client | Where the config goes |
|---|---|
| Claude Code | `.mcp.json` in the target repo root (`mcpServers` key), then run `claude` there |
| Claude Desktop | `~/Library/Application Support/Claude/claude_desktop_config.json` (`mcpServers` key), then restart |
| Cursor, Windsurf, Cline, others | Your client's MCP server configuration -- consult its documentation for the file location |

## Prompt Templates

[docs/PROMPTS.md](docs/PROMPTS.md) contains ready-to-use prompts for high-autonomy agent operation, including orchestrator prompts, sub-agent role definitions (Protocol Engineer, Toolsmith, Security Reviewer, Test Engineer, Docs Engineer), and multi-instance coordination patterns.
The transport is always STDIO. Ready-to-use `.mcp.json` and CLAUDE.md templates for target projects live in [templates/](templates/).

## Security Model

Expand Down Expand Up @@ -168,6 +166,10 @@ Set via environment variable:
GHOSTLINK_LOG=file GHOSTLINK_REPO_ROOT=/path/to/repo node dist/index.js
```

## Prompt Templates

[docs/PROMPTS.md](docs/PROMPTS.md) contains ready-to-use prompts for high-autonomy agent operation, including orchestrator prompts, sub-agent role definitions (Protocol Engineer, Toolsmith, Security Reviewer, Test Engineer, Docs Engineer), and multi-instance coordination patterns.

## Development

```bash
Expand Down Expand Up @@ -199,22 +201,6 @@ npm test && npm run lint && npm run typecheck && npm run build
| [docs/ENGINEERING_REPORT_v0.1.0.md](docs/ENGINEERING_REPORT_v0.1.0.md) | v0.1.0 ship report with milestone history and decision log |
| [templates/](templates/) | Ready-to-use CLAUDE.md and .mcp.json templates for target projects |

## Architecture

GhostLink is a three-layer stack designed for extensibility without core changes:

```
Transport (src/index.ts) STDIO now, HTTP/SSE in Phase 2
|
Server Factory (src/server.ts) Transport-agnostic tool registration via MCP SDK + Zod schemas
|
Tools (src/core/tools/*) Six tools, each returning ToolEnvelope<T> through shared policy
|
Policy (src/core/policy/*) Sandbox enforcement, audit logging, output caps
```

The `createServer()` factory knows nothing about transport. Adding HTTP/SSE in Phase 2 means writing a new transport binding and auth middleware -- the server factory and all tool implementations remain unchanged. Phase 3 (agent runtime) adds memory resources and orchestration as consumers of GhostLink, not modifications to it.

## Roadmap

### Phase 1 -- Local STDIO [Shipped, v0.1.0]
Expand Down
Loading