opensrc-mcp
Supports cloning and managing source code from Git-based repositories for querying and context-efficient batch operations.
Provides capabilities to fetch and query source code directly from GitHub repositories by owner, repo, and specific Git refs.
Facilitates fetching, reading, and searching through source code for JavaScript and TypeScript packages and their dependencies.
Allows fetching, searching, and querying source code from the npm registry, enabling context-efficient analysis of Node.js dependencies.
Enables fetching and searching Python package source code from the Python Package Index (PyPI) for server-side querying and analysis.
Allows for the retrieval and exploration of Python dependency source code through PyPI and pip-compatible sources.
Supports fetching and searching source code for Rust crates from the crates.io registry.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@opensrc-mcp fetch the zod package and search for where parse is defined"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
opensrc-mcp
A codemode MCP server for fetching and querying dependency source code.
Why?
Traditional MCP exposes tools directly to LLMs. This server uses the codemode pattern: agents write JavaScript that executes server-side, and only results return. Benefits:
Context efficient - Large source trees stay server-side
Batch operations - One call to search/read multiple files
LLMs are better at code - More training data for JS than tool-calling
Related MCP server: Satori
Installation
npm install -g opensrc-mcp
# or
npx opensrc-mcpOpenCode Configuration
Add to your OpenCode config (~/.config/opencode/config.json or project opencode.json):
{
"mcp": {
"opensrc": {
"type": "local",
"command": "npx",
"args": ["-y", "opensrc-mcp"]
}
}
}Tool
execute
Single tool exposing all operations. Agents write JS that runs server-side; only results return.
// Available in sandbox:
declare const opensrc: {
// Read operations
list(): Source[];
has(name: string, version?: string): boolean;
get(name: string): Source | undefined;
files(sourceName: string, glob?: string): Promise<FileEntry[]>;
tree(sourceName: string, options?: { depth?: number }): Promise<TreeNode>;
grep(pattern: string, options?: {
sources?: string[];
include?: string;
maxResults?: number;
}): Promise<GrepResult[]>;
astGrep(sourceName: string, pattern: string, options?: {
glob?: string;
lang?: string | string[];
limit?: number;
}): Promise<AstGrepMatch[]>;
read(sourceName: string, filePath: string): Promise<string>;
readMany(sourceName: string, paths: string[]): Promise<Record<string, string>>;
resolve(spec: string): Promise<ParsedSpec>;
// Mutation operations
fetch(specs: string | string[], options?: { modify?: boolean }): Promise<FetchedSource[]>;
remove(names: string[]): Promise<RemoveResult>;
clean(options?: {
packages?: boolean;
repos?: boolean;
npm?: boolean;
pypi?: boolean;
crates?: boolean;
}): Promise<RemoveResult>;
};
declare const sources: Source[]; // All fetched sources
declare const cwd: string; // Project directoryExamples:
// List all fetched sources
async () => opensrc.list()
// Fetch npm package (auto-detects version from lockfile)
async () => opensrc.fetch("zod")
// Fetch multiple packages
async () => opensrc.fetch(["zod", "drizzle-orm", "hono"])
// Fetch GitHub repo at specific ref
async () => opensrc.fetch("vercel/ai@v3.0.0")
// Fetch from other registries
async () => opensrc.fetch("pypi:requests")
async () => opensrc.fetch("crates:serde")
// Get directory tree
async () => opensrc.tree("zod", { depth: 2 })
// Find TypeScript files
async () => opensrc.files("zod", "**/*.ts")
// Text search
async () => opensrc.grep("parse", { sources: ["zod"], include: "*.ts" })
// AST search (structural pattern matching)
async () => opensrc.astGrep("zod", "function $NAME($$$ARGS)", { glob: "**/*.ts" })
// Read a specific file
async () => opensrc.read("zod", "src/index.ts")
// Read multiple files (supports globs)
async () => opensrc.readMany("zod", ["src/index.ts", "packages/*/package.json"])
// Remove a source
async () => opensrc.remove(["zod"])
// Clean all npm packages
async () => opensrc.clean({ npm: true })Package Formats
Format | Example | Description |
|
| npm (auto-detects version) |
|
| npm specific version |
|
| explicit npm |
|
| Python/PyPI |
|
| alias for pypi |
|
| Rust/crates.io |
|
| alias for crates |
|
| GitHub repo |
|
| GitHub at ref |
|
| explicit GitHub |
Storage
Sources are stored globally at ~/.local/share/opensrc/ (XDG compliant):
~/.local/share/opensrc/
├── sources.json # Index of fetched sources
├── packages/ # npm/pypi/crates packages
│ └── zod/
│ ├── src/
│ ├── package.json
│ └── ...
└── repos/ # GitHub repos
└── github.com/
└── vercel/
└── ai/Override with $OPENSRC_DIR or $XDG_DATA_HOME.
How It Works
Agent calls
executetool with JS code:async () => opensrc.fetch("zod")Code runs in sandboxed
vmcontext with injectedopensrcAPIServer fetches package via opensrc (handles registry lookup, git clone)
Only the result returns to agent context
┌─────────────────────────────────────────────────────────────┐
│ Agent Context │
├─────────────────────────────────────────────────────────────┤
│ Tool call: execute({ code: "async () => opensrc.fetch..." })│
│ ↓ │
│ Result: { success: true, source: { name: "zod", ... } } │
└─────────────────────────────────────────────────────────────┘
↕
┌─────────────────────────────────────────────────────────────┐
│ opensrc-mcp Server │
├─────────────────────────────────────────────────────────────┤
│ Sandbox executes code with injected opensrc API │
│ Full source tree stays here, never sent to agent │
└─────────────────────────────────────────────────────────────┘License
MIT
Available Tools
1 toolexecuteB
Query and mutate fetched source code. Data stays server-side.
Types:
interface Source { type: "npm" | "pypi" | "crates" | "repo"; name: string; version?: string; ref?: string; path: string; fetchedAt: string; repository: string; }
interface FileEntry { path: string; size: number; isDirectory: boolean; }
interface TreeNode { name: string; type: "file" | "dir"; children?: TreeNode[]; }
interface GrepResult { source: string; file: string; line: number; content: string; }
interface AstGrepMatch { file: string; line: number; column: number; text: string; metavars: Record<string, string>; // captured $VAR values }
interface ParsedSpec { type: "npm" | "pypi" | "crates" | "repo"; name: string; version?: string; ref?: string; repoUrl?: string; }
interface FetchedSource { source: Source; alreadyExists: boolean; }
interface RemoveResult { success: boolean; removed: string[]; }
declare const sources: Source[]; declare const cwd: string;
declare const opensrc: { // Read operations list(): Source[]; has(name: string, version?: string): boolean; get(name: string): Source | undefined; files(sourceName: string, glob?: string): Promise<FileEntry[]>; tree(sourceName: string, options?: { depth?: number }): Promise; grep(pattern: string, options?: { sources?: string[]; include?: string; maxResults?: number; }): Promise<GrepResult[]>; astGrep(sourceName: string, pattern: string, options?: { glob?: string; lang?: string | string[]; limit?: number; }): Promise<AstGrepMatch[]>; read(sourceName: string, filePath: string): Promise; readMany(sourceName: string, paths: string[]): Promise<Record<string, string>>; resolve(spec: string): Promise;
// Mutation operations fetch(specs: string | string[], options?: { modify?: boolean; }): Promise<FetchedSource[]>; remove(names: string[]): Promise; clean(options?: { packages?: boolean; repos?: boolean; npm?: boolean; pypi?: boolean; crates?: boolean; }): Promise; };
Fetch spec formats (input to opensrc.fetch):
zod -> npm package (latest or lockfile version)
zod@3.22.0 -> npm specific version
pypi:requests -> Python/PyPI package
crates:serde -> Rust/crates.io package
vercel/ai -> GitHub repo (default branch)
vercel/ai@v3.0.0 -> GitHub repo at tag/branch/commit
Source names (returned in FetchedSource.source.name, used for read/grep):
npm packages: "zod", "drizzle-orm", "@tanstack/react-query"
pypi packages: "requests", "numpy"
crates: "serde", "tokio"
GitHub repos: "github.com/vercel/ai", "github.com/anthropics/sdk"
IMPORTANT: After fetching, always use source.name for subsequent API calls.
Examples:
// List all fetched sources async () => { return opensrc.list().map(s => ({ name: s.name, type: s.type, version: s.version || s.ref })); }
// Fetch and explore structure with tree() async () => { const [{ source }] = await opensrc.fetch("zod"); return await opensrc.tree(source.name, { depth: 2 }); }
// Fetch a GitHub repo and read key files async () => { const [{ source }] = await opensrc.fetch("vercel/ai"); const files = await opensrc.readMany(source.name, [ "package.json", "README.md", "src/index.ts" ]); return { sourceName: source.name, files: Object.keys(files) }; }
// readMany with globs async () => { return await opensrc.readMany("zod", ["packages/*/package.json"]); }
// Fetch multiple packages async () => { const results = await opensrc.fetch(["zod", "drizzle-orm", "hono"]); return results.map(r => r.source.name); }
// Text search with grep async () => { const results = await opensrc.grep("export function parse", { sources: ["zod"], include: "*.ts" }); if (matches.length === 0) return "No matches"; const { source, file, line } = matches[0]; const content = await opensrc.read(source, file); return content.split("\n").slice(line - 1, line + 29).join("\n"); }
// Search across all sources
async () => {
const results = await opensrc.grep("throw new Error", { include: "*.ts", maxResults: 20 });
return results.map(r => ${r.source}:${r.file}:${r.line});
}
// AST search with astGrep (use $VAR for single node, $$$VAR for multiple) // Patterns: "function $NAME($$$)" | "const $X = $Y" | "useState($INIT)" | "$OBJ.$METHOD($$$)" async () => { const matches = await opensrc.astGrep("zod", "function $NAME($$$ARGS)", { glob: "**/*.ts", limit: 10 }); return matches.map(m => ({ file: m.file, name: m.metavars.NAME, line: m.line })); }
// Find entry points async () => { const files = await opensrc.files("github.com/vercel/ai", "**/{index,main}.{ts,js}"); if (files.length > 0) return await opensrc.read("github.com/vercel/ai", files[0].path); return "No entry point found"; }
// Batch read with error handling async () => { const files = await opensrc.readMany("zod", ["src/index.ts", "src/types.ts", "nonexistent.ts"]); // Failed reads have "[Error: ...]" as value return Object.keys(files).filter(p => !files[p].startsWith("[Error:")); }
// Remove sources async () => { return await opensrc.remove(["zod", "github.com/vercel/ai"]); }
Inputs: code (required).
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 1 tool
With only one tool, there is no possibility of confusion between tools. The single tool encompasses a well-defined API, and its purpose is clearly described in the description.
The server has a single tool named 'execute', which is consistent in itself. While the name is generic, there are no other tools to compare against, so no naming inconsistencies exist.
The domain covers fetching, searching, reading, and managing source code from multiple ecosystems, which is a broad scope. Exposing all of this through a single monolithic tool is overly condensed; separate tools for distinct operations (e.g., fetch, read, grep) would be more appropriate for agent discoverability.
The tool covers listing, fetching, reading, searching (grep and astGrep), and removal of sources, which is comprehensive for exploration. However, it lacks explicit update/edit capabilities for source files and no direct way to modify code, leaving a minor gap in mutation workflows.
Maintenance
Related MCP Connectors
An MCP server that gives your AI access to the source code and docs of all public github repos
Shared memory MCP server for Claude Code, Codex, Gemini CLI and Cursor. Cited, editable.
Capability registry for the agentic economy. Semantic search over verified MCP server listings.
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceMCP server that gives AI agents deep code understanding across multiple git repositories, combining git lifecycle management, Zoekt-based trigram code search, and cross-repo dependency analysis.MIT
- AlicenseNot gradedqualityBmaintenanceAgent-safe code retrieval MCP server that indexes repositories and provides semantic search, file navigation, call graph analysis, and bounded file reading tools for coding agents.7,358,368 npm3AGPL 3.0
- AlicenseNot gradedqualityCmaintenanceA local MCP server that indexes TypeScript/JavaScript projects and returns budget-aware, dependency-optimized context packs for AI coding assistants.1MIT
- AlicenseNot gradedqualityDmaintenanceA local MCP server that parses codebases into semantic chunks, indexes them in SQLite with vector embeddings, and exposes MCP tools for LLM agents to query.MIT