A codemode MCP server for fetching and querying dependency source code.
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:
npm install -g opensrc-mcp
# or
npx opensrc-mcp
Add to your OpenCode config (~/.config/opencode/config.json or project opencode.json):
{
"mcp": {
"opensrc": {
"type": "local",
"command": "npx",
"args": ["-y", "opensrc-mcp"]
}
}
}
searchQuery fetched sources without consuming context. Data stays server-side.
// Available in sandbox:
declare const opensrc: {
list(): Source[];
has(name: string, version?: string): boolean;
get(name: string): Source | undefined;
files(sourceName: string, glob?: string): Promise<FileEntry[]>;
grep(pattern: string, options?: {
sources?: string[];
include?: string;
maxResults?: number;
}): Promise<GrepResult[]>;
read(sourceName: string, filePath: string): Promise<string>;
resolve(spec: string): Promise<ParsedSpec>;
};
declare const sources: Source[]; // All fetched sources
declare const cwd: string; // Project directory
Examples:
// List all fetched sources
async () => opensrc.list()
// Check if zod is fetched
async () => opensrc.has("zod")
// Find TypeScript files in zod
async () => opensrc.files("zod", "**/*.ts")
// Search for "parse" in zod source
async () => opensrc.grep("parse", { sources: ["zod"], include: "*.ts" })
// Read a specific file
async () => opensrc.read("zod", "src/index.ts")
executeMutations: fetch packages, remove, clean.
declare const opensrc: {
fetch(specs: string | string[], options?: {
modify?: boolean;
}): Promise<FetchResult[]>;
remove(names: string[]): Promise<RemoveResult>;
clean(options?: {
packages?: boolean;
repos?: boolean;
npm?: boolean;
pypi?: boolean;
crates?: boolean;
}): Promise<RemoveResult>;
readMany(sourceName: string, paths: string[]): Promise<Record<string, string>>;
};
Examples:
// 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")
// Remove a source
async () => opensrc.remove(["zod"])
// Clean all npm packages
async () => opensrc.clean({ npm: true })
// Read multiple files at once
async () => opensrc.readMany("zod", ["src/index.ts", "src/types.ts"])
| Format | Example | Description |
|---|---|---|
<name> |
zod |
npm (auto-detects version) |
<name>@<version> |
zod@3.22.0 |
npm specific version |
npm:<name> |
npm:react |
explicit npm |
pypi:<name> |
pypi:requests |
Python/PyPI |
pip:<name> |
pip:flask |
alias for pypi |
crates:<name> |
crates:serde |
Rust/crates.io |
cargo:<name> |
cargo:tokio |
alias for crates |
owner/repo |
vercel/ai |
GitHub repo |
owner/repo@ref |
vercel/ai@v1.0.0 |
GitHub at ref |
github:owner/repo |
github:facebook/react |
explicit GitHub |
Sources are stored in opensrc/ in your project:
your-project/
├── opensrc/
│ ├── sources.json # Index of fetched sources
│ └── zod/ # Fetched source code
│ ├── src/
│ ├── package.json
│ └── ...
└── ...
execute tool with JS code: async () => opensrc.fetch("zod")vm context with injected opensrc API┌─────────────────────────────────────────────────────────────┐
│ 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 │
└─────────────────────────────────────────────────────────────┘
MIT
$ claude mcp add opensrc-mcp \
-- python -m otcore.mcp_server <graph>