Cordyceps Search
Traces frontend HTTP requests made with Axios and links them to backend endpoint definitions for cross-boundary API tracking.
Identifies and traces backend endpoints defined in Django, enabling cross-boundary API tracking from frontend HTTP calls.
Identifies and traces backend endpoints defined in FastAPI, enabling cross-boundary API tracking from frontend HTTP calls.
Identifies and traces backend endpoints defined in Flask, enabling cross-boundary API tracking from frontend HTTP calls.
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., "@Cordyceps SearchFind all callers of authenticate_user and assess the impact of renaming it."
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.
Cordyceps
Cordyceps is an MCP server that gives coding agents structural understanding of a codebase: what is where, which definition a name refers to, and what else depends on it.
Agents already have read, grep and glob. What they lack is the picture an IDE
builds in the background: the definition tree of every file, canonical identities for
symbols with the same name, and a call graph to answer "what breaks if I change this".
Cordyceps indexes the workspace with tree-sitter, stores the result in a Rust CSR
graph (engramedb), keeps it in sync with a file watcher, and exposes exactly three tools.
Tools
All tools answer in YAML. Every response carries meta.index_stale, meta.graph_built
and, when relevant, meta.warnings, so an agent can tell a trustworthy answer from a
partial one.
code_map(path=".", depth=1)
Outline of a directory or a file.
Directory: immediate sub-folders (with file/symbol counts), immediate files (line count, symbol counts by kind, top-level definition names).
depth(1–4) expands nested folders.File: the definition tree — classes with their methods, functions with nested definitions, routes, declarations — each with line range and signature, plus imports and exports. Anonymous inline callbacks are not listed (counted in
meta.inline_callbacks); functions defined inside them appear under the enclosing definition.
symbols:
- name: CodeStructure
kind: Class
lines: 54-505
members:
- name: map
kind: Function
lines: 76-89
signature: 'def map(self, path: str = ".", depth: int = 1) -> dict'lookup_symbol(symbol, path=None)
Where a symbol is defined and what it is directly connected to. symbol may be a bare
name (create_sale), a qualified name (SalesAPI.create_sale), <file>:<name>
(api.py:create_sale), a full node id, or a file path. path restricts matches to a folder.
status: resolved→symbol(id, kind, file, lines, signature, container, docstring, decorators, base classes) andrelationships(callers, callees, members, unresolved external calls; for files: imports, imported_by, defines).status: ambiguous→candidates. The server never picks one of several matches.status: not_found→ close-matchsuggestions.
impact(symbol, depth=2, direction="callers")
Blast radius. Follows executable edges only (calls and framework/HTTP links — never imports or containment), grouped by file with the hop distance of every entry.
meta: {direct: 2, total: 3, files: 2, truncated: false, more_beyond_depth: false}
affected:
src/structure/resolver.py:
- resolve_symbol [Function] L40-70 depth=1
src/structure/service.py:
- CodeStructure.lookup [Function] L92-112 depth=2Direct neighbours are the depth=1 entries of affected (no separate list).
With direction="callers", possible_callers adds by-name candidates the resolver
could not link (untyped receivers — verify the call site); with "callees",
unresolved_callees lists calls that could not be resolved. Anonymous inline
callbacks (items.map(x => ...)) are transparent everywhere: their calls count
as the enclosing definition's.
direction="callees" answers the opposite question ("what does this rely on").
meta.more_beyond_depth and meta.truncated say explicitly when the picture is incomplete.
Related MCP server: OmniWeave
Supported languages
Language | Extensions | Call resolution |
Python |
| Contextual: imports/aliases, lexical scope, |
JavaScript / JSX |
| Contextual: ESM/CommonJS imports and aliases, exports/re-exports, lexical scope, shadowing, |
TypeScript / TSX |
| Same as JavaScript, plus typed parameters/fields and direct |
JS/TS resolution is deliberately conservative: dynamic factory receivers, runtime monkey-patching, ambiguous modules/exports, and unconfigured package aliases remain unresolved instead of falling back to a same-name symbol elsewhere in the repository.
Web-framework linking (Django URLconf, Flask/FastAPI/Ninja decorators, Express routers,
frontend fetch/axios calls → backend routes) produces Route/Middleware nodes and
edges that make impact cross the frontend/backend boundary. These edges are heuristic
and are flagged as such.
Other files (.json, .md, .html, .css, .yml, .yaml, .toml, .txt, .sql) are
indexed as File nodes so they appear in code_map.
The language registry is config-driven (src/database/parser/languages/*.yaml), but a new
language still needs a grammar dependency, extraction rules tested against that language's
AST shapes, and fixtures for its symbol kinds. Trustworthy call resolution needs a
per-language resolver; unsupported dynamic receivers remain unresolved rather than guessed.
Excluded directories: node_modules, venv/.venv, __pycache__, target, dist,
build, migrations, .git, .idea, .vscode, coverage, .next, .nuxt, fixture
directories, and any dot-directory. Extend with CORDYCEPS_EXCLUDE=dir1,dir2.
Persistence (.engram_snapshot.bin + .cordyceps_index_meta.json) is written to the
workspace root by default. Set CORDYCEPS_INDEX_DIR=/some/cache/dir to keep the
workspace pristine (useful when the workspace is checkpointed, pushed, or watched for
external changes by the host). The directory is created on demand.
Architecture
main.py MCP entrypoint: 3 tools + serve()
src/structure/ the tools' logic (pure functions over the graph)
index_view.py request-scoped snapshot of the index + node-id rules
resolver.py name / qualified / <file>:<name> -> canonical id (or candidates)
records.py allow-listed projections; never leaks source bodies
service.py CodeStructure.map / lookup / impact
src/indexing/workspace.py WorkspaceIndex: scan, warm start, incremental sync, edge pipeline
src/database/ EngramClient over the Rust engine; cross-file resolution passes
javascript_resolver.py contextual JS/TS calls (imports, scope, classes, receiver types)
src/database/parser/ UniversalCodeParser (tree-sitter) + languages/*.yaml
src/watcher/ watchdog handler: parses a file and injects nodes/edgesEvery tool call first drains pending file-change events on the main thread (all Rust calls stay on one thread), then reads the graph.
Getting started
Requirements: Python ≥ 3.11 (< 3.14), uv.
git clone https://github.com/ghassenTn/cordyceps_mcp.git
cd cordyceps_mcp
uv sync --python 3.11
uv run python main.py /path/to/workspace # stdio MCP server
# or, after installation:
uv run cordyceps-mcp /path/to/workspaceengramedb is installed from PyPI. For engine development use a sibling checkout:
# layout: cordyceps_mcp/ ../engramedb/
# [tool.uv.sources] engramedb = { path = "../engramedb", editable = true }
cd ../engramedb && maturin develop --releaseOpenCode configuration
{
"$schema": "https://opencode.ai/config.json",
"mcp": {
"cordyceps": {
"type": "local",
"enabled": true,
"timeout": 120000,
"command": ["uv", "--directory", "/path/to/cordyceps_mcp", "run", "--python", "3.11",
"python", "main.py", "/path/to/your/workspace"]
}
},
"permission": {"cordyceps_*": "allow"}
}OpenCode prefixes MCP tools with the server name, hence the cordyceps_* permission.
The workspace path may also come from WORKSPACE_PATH; the current directory is the last
fallback. The index is persisted next to the workspace (.engram_snapshot.bin,
.cordyceps_index_meta.json) and reused on restart when no file changed.
Tests
uv run python -m pytest # full suite
uv run python -m pytest -m unit # parser, adapters, structural tools (in-memory fake graph), MCP boundary
uv run python -m pytest -m integration # real workspaces: parse -> index -> tools (test_indexing.py)This server cannot be deployed
Maintenance
Related MCP Connectors
Code intelligence for coding agents: semantic, AST, graph, and full-text search. 279+ languages.
Codebase graphs, caller impact analysis, and recorded project context for AI coding agents.
Code intelligence platform for AI agents. 20 tools for architecture, security & impact analysis.
Codebase intelligence for AI agents — dead code, blast radius, ownership.
Related MCP Servers
- AlicenseNot gradedqualityAmaintenanceSupercharges AI coding agents with a pre-indexed semantic code graph, enabling instant symbol relationships, impact analysis, and context retrieval across 20+ languages.70,850 npm71,313MIT
- AlicenseNot gradedqualityDmaintenanceA high-performance, polyglot code-analysis graph for coding agents that enables cross-language and cross-process code relationship queries in sub-millisecond time.MIT
- AlicenseNot gradedqualityBmaintenanceProvides semantic code search and code insights via a knowledge graph, enabling AI to understand, navigate, and modify complex projects with deep dependency and architecture analysis.MIT
- AlicenseNot gradedqualityBmaintenanceEnables LLM agents to efficiently understand and navigate a codebase by providing semantic search over symbols and a reference graph, replacing expensive grep/glob calls with structured tools like definition lookup, caller/callee queries, and change-impact analysis.2MIT