Skip to content

About

Lineage MCP is a Model Context Protocol server that provides file operations with automatic change detection and instruction file discovery for LLM agents.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

26 Commits

Folders and files

Repository files navigation

🧬 Lineage MCP

A Model Context Protocol (MCP) server that provides file operations with automatic change detection and instruction file discovery for LLM agents.

Python 3.10+ MCP License: MIT Author

I've published a post talking about why I made this tool. Take a look if you're interested.

What is Lineage MCP?

Lineage MCP is a file operation server for LLM coding agents that solves two critical problems:

  1. Change Blindness - Standard file tools don't tell agents when files have been modified externally. Lineage tracks file modifications and reports exactly which lines changed since a file was last read.

  2. Context Loss - Large projects use instruction files (AGENTS.md, CLAUDE.md, etc.) to provide localized context, but agents don't know to look for them. Lineage automatically discovers and includes these files from all parent directories.

Features

Feature Description
File Operations List, search, read, modify, and delete files
Batch Modify Apply multiple create/overwrite/append/replace operations in a single call
Change Detection Line-level diff detection for externally modified files
Instruction Discovery Auto-finds AGENTS.md, CLAUDE.md, etc. in parent directories
Security Path traversal protection keeps operations within the workspace
Image Reading Returns images to the LLM as visible content (png, jpg, gif, webp)
Partial Reads Read specific line ranges for large files (offset/limit)
Line Numbers Optional line number formatting for precise code references
Session Cooldown Prevents redundant cache clears during initial AI tool bursts

Quick Start

Prerequisites

  • Python 3.10 or higher
  • pip (Python package manager) or uv

Installation

Using pip

# Clone the repository
git clone https://github.com/imattpeters/lineage-mcp.git
cd lineage-mcp

# Install dependencies
pip install -r requirements.txt

Using uv (faster alternative)

# Clone the repository
git clone https://github.com/imattpeters/lineage-mcp.git
cd lineage-mcp

# Install dependencies with uv
uv pip install -r requirements.txt

uv is a fast Python package manager written in Rust. It's fully compatible with requirements.txt and offers significantly faster dependency installation.

MCP Client Configuration

Python (standard)

{
  "mcpServers": {
    "lineage": {
      "command": "python",
      "args": ["/path/to/lineage-mcp/lineage.py", "/your/workspace"]
    }
  }
}

Python with uv

{
  "mcpServers": {
    "lineage": {
      "command": "uv",
      "args": [
        "run",
        "python",
        "/path/to/lineage-mcp/lineage.py",
        "/your/workspace"
      ]
    }
  }
}

Using uv run ensures dependencies are installed and the script runs in the correct environment.

Docker

{
  "mcpServers": {
    "lineage": {
      "command": "docker",
      "args": [
        "run",
        "-i",
        "--rm",
        "-v",
        "/your/workspace:/data",
        "lineage-mcp"
      ]
    }
  }
}

Docker arguments explained:

  • run - Start a new container
  • -i - Enable interactive mode (required for MCP's stdin-based communication)
  • --rm - Automatically remove the container when it exits (prevents clutter)
  • -v /your/workspace:/data - Mount your project directory to /data inside the container (the server uses /data as the base directory)
  • lineage-mcp - The Docker image name

Windows paths: Use forward slashes (C:/git/project) or escaped backslashes (C:\\git\\project).

Building the Docker image:

Before using Docker, build the image from the lineage-mcp directory:

docker build -t lineage-mcp .

OpenCode

OpenCode uses a plugin system for hooks. See Client Hooks below for setup instructions.

Tools Reference

Tool Description Parameters
list List directory contents path (optional)
search Search files by glob pattern pattern, path (optional)
read Read file with change tracking file_path, show_line_numbers, offset, limit, cursor
read_image Read an image as visible model content file_path, resize (optional, pass false to skip downscaling)
modify Modify one or more files operations, on_error (optional)
delete Delete file or empty directory file_path
clear Clear all session caches (none)

Usage Examples

Reading Files with Line Numbers

read("src/app.py", show_line_numbers=True)

# Output:
# 1→import os
# 2→from pathlib import Path
# 3→

Partial File Reads

Perfect for large generated files:

# Read lines 100-150 of a large file
read("types.gen.ts", offset=100, limit=50, show_line_numbers=True)

# Output:
# 101→export type User = {
# 102→  id: string;
# ...

File Search

# Find all Python files
search("**/*.py")

# Find config files in src/
search("*.config.*", path="src")

Reading Images

# Returns the image as visible content (image content block)
read_image("assets/screenshot.png")

# Skip the automatic downscaling to 1024px wide
read_image("assets/photo.jpg", resize=False)

Images wider than readImageMaxWidth (default 1024) are downscaled with the aspect ratio preserved, so a 4000px phone photo does not flood the model's context. Images within the limit are returned untouched. Supported types: png, jpg, jpeg, gif, webp.

File Modification

# Replace one exact string
modify([
    {
        "file_path": "config.py",
        "operation": "replace",
        "match_text": "old_value",
        "text": "new_value",
    }
])

# Replace all occurrences
modify([
    {
        "file_path": "config.py",
        "operation": "replace",
        "match_text": "DEBUG = True",
        "text": "DEBUG = False",
        "occurrence": "all",
    }
])

# Mix multiple operations in one call
modify(
    operations=[
        {"file_path": "src/app.py", "operation": "replace", "match_text": "v1", "text": "v2"},
        {"file_path": "src/config.py", "operation": "replace", "match_text": "DEBUG = True", "text": "DEBUG = False"},
        {"file_path": "CHANGELOG.md", "operation": "append", "text": "\n- Updated docs\n"},
    ],
    on_error="abort",
)

Change Detection

Lineage tracks every file you read and reports when external changes occur the next time any lineage tool is used by appending to the response:

[CHANGED_FILES]
- src/app.py (modified): lines 15-23 (5.2s ago)
- config/settings.json (modified): lines 1-EOF (12.8s ago)

How it works:

  • Files are tracked after being read
  • Line-level diffs are calculated on subsequent interactions and file changes are appended to the response
  • Only external changes are reported

This allows LLM agents to detect when humans or other processes modify files and respond accordingly.

Instruction File Discovery

When reading any file, Lineage walks up the directory tree and appends all instruction files to the response:

your-project/
├── AGENTS.md          ← Included automatically
├── src/
│   ├── CLAUDE.md      ← Included automatically
│   └── app/
│       └── handler.py ← File you're reading

The response includes:

--- content of file ---

[CLAUDE.md from src]
# Instructions for this module

[AGENTS.md from .]
# Project-wide instructions

Note: Instruction files at the workspace root (BASE_DIR) are excluded on the first session — they're already visible to most coding agents. After context compaction (when the session cache has been cleared at least twice), they are automatically included again since the LLM may have lost that context.

Configuration

Update the appsettings.json to customize instruction file names and priority:

{
  "instructionFileNames": [
    "AGENTS.md",
    "CLAUDE.md",
    "GEMINI.md",
    "QWEN.md",
    "AGENT.md",
    ".cursorrules"
  ]
}

Files are checked in priority order - first match per folder is used.

Image Reading

Images wider than the configured width are downscaled before reaching the model. read_image accepts resize=false to return the original bytes.

{
  "readImageMaxWidth": 1024
}

Allow Full Paths

By default, all file operations are restricted to the base directory. To allow access to any path on the system (e.g., for cross-project references), set allowFullPaths to true:

{
  "allowFullPaths": true
}

When enabled, absolute paths like /var/log/app.log or C:\other\project\file.txt are accepted. Relative paths still resolve against the base directory.

Session Management

LLM systems periodically "compact" or summarize conversation history to stay within context limits. When this happens, the detailed content from instruction files (AGENTS.md, CLAUDE.md, etc.) gets compressed or lost. The server's cache still thinks these files were "already provided" and won't re-send them.

Cache clearing is handled automatically:

  • System tray: Click "Clear Cache" in the tray menu
  • Client hooks: Automatically triggered on session start and during context compaction
  • Explicit clear() tool: Call directly when needed
clear()  # Instruction files will be re-provided on next read

When caches are cleared:

  • Server-side caches are cleared
  • Instruction files will be re-appended to responses
  • Change detection restarts from a clean slate

Cooldown

Cache clears within a 30-second window are silently ignored to prevent redundant clears during bursts of activity.

  • The cooldown is configurable via newSessionCooldownSeconds in appsettings.json
  • The explicit clear() tool always works regardless of cooldown
  • Set to 0 to disable the cooldown entirely

Client Hooks

Hook scripts automatically clear lineage-mcp caches on session start and before context compaction. The tray application must be running for hooks to work - it routes cache clear requests to the correct session using ancestor PID matching.

VS Code (Copilot Chat)

Create .github/hooks/clearcache.json in your project root:

{
  "hooks": {
    "SessionStart": [
      {
        "type": "command",
        "command": "python \"/path/to/lineage-mcp/hooks/clearcache.py\" \"Visual Studio Code\"",
        "timeout": 10
      }
    ],
    "PreCompact": [
      {
        "type": "command",
        "command": "python \"/path/to/lineage-mcp/hooks/clearcache.py\" \"Visual Studio Code\"",
        "timeout": 10
      }
    ]
  }
}

Note: Enable agent hooks in VS Code settings: "chat.hooks.enabled": true

OpenCode

Copy the pre-built plugin into your project's .opencode/plugins/ directory:

mkdir -p .opencode/plugins
cp /path/to/lineage-mcp/plugins/opencode/local/lineage-clearcache.ts .opencode/plugins/

Edit the CLEARCACHE_SCRIPT path in the copied file to point to your lineage-mcp installation:

const CLEARCACHE_SCRIPT = "/path/to/lineage-mcp/hooks/clearcache.py";

The plugin hooks into three events:

  • session.created - Clears stale caches when a new session starts
  • experimental.session.compacting - Clears caches before context compaction
  • session.compacted - Fallback clear after compaction completes

Add the plugin type dependency to .opencode/package.json:

{
  "dependencies": {
    "@opencode-ai/plugin": "latest"
  }
}

System Tray

Lineage MCP includes an optional system tray application (lineage-mcp-tray) that provides real-time visibility and control over running sessions.

cd lineage-mcp-tray
pip install -e .
python -m lineage_tray

The tray connects to all running MCP server instances via a named pipe (Windows) or Unix socket (macOS/Linux) and shows:

  • Active sessions grouped by workspace
  • Number of files tracked per session
  • Most recent tool call
  • Controls: Clear Cache, Interrupt, and Resume

Interrupt / Resume

Clicking Interrupt in the tray immediately halts the LLM's tool calls. The next tool invocation returns only the interrupt message and performs no operations. The LLM must stop and check with the user. Click Resume to restore normal operation.

The interrupt message is configurable via interruptMessage in appsettings.json.

Security

  • All paths are validated against the base directory
  • Path traversal (..) outside the workspace is blocked
  • Symlinks are resolved and validated
  • Only operations within the mounted workspace are allowed

Testing

# Using pip/standard Python
python -m pytest tests/ -v

# Using uv
uv run pytest tests/ -v

# Run specific test module
python -m pytest tests/test_read_file.py -v

# Run with coverage
python -m pytest tests/ --cov=. --cov-report=html

# Generate example responses
python tests/generate_examples.py

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

License

This project is licensed under the MIT License - see the LICENSE file for details.

Acknowledgments

Created by Matt Peters - Senior Software Architect.

Built with FastMCP from the Model Context Protocol team.

About

Lineage MCP is a Model Context Protocol server that provides file operations with automatic change detection and instruction file discovery for LLM agents.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages