{
  "markdown": "<p align=\"center\">\n  <img src=\"assets/codecanvas-banner.png\" alt=\"CodeCanvas MCP — Trace the truth\" width=\"100%\">\n</p>\n\n# CodeCanvas MCP\n\n[![PyPI](https://img.shields.io/pypi/v/codecanvas-mcp)](https://pypi.org/project/codecanvas-mcp/)\n[![Python](https://img.shields.io/pypi/pyversions/codecanvas-mcp)](https://pypi.org/project/codecanvas-mcp/)\n[![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)\n\nUnderstand an unfamiliar Python system before spending thousands of tokens\nreading it file by file.\n\nCodeCanvas is a local static-analysis\n[Model Context Protocol](https://modelcontextprotocol.io/) server for Python. It\nturns project-wide call paths and control flow into compact, citation-ready\nanswers about branches, callers, callees, side effects, and change impact.\n\nThe benchmark now spans pinned revisions of **Google ADK, LangGraph, and\nFastAPI**. On an Apple M4 Pro, measured cold analysis ranged from **4.38s to\n61.62s**, and median warm `find_symbols` latency ranged from **48.264ms to\n293.778ms** across those repositories. In a controlled 54-session agent suite,\nboth conditions kept the same built-in code-search tools; the treatment added\nonly `logic_flow`. That single addition used a median **22.95% fewer total\ntokens** across three paired repetitions, demonstrating meaningful incremental\nvalue on top of ordinary code exploration. Uncached tokens increased by 0.78%,\nand the answers are not yet blind-graded. See the [methodology, full tables, and\nlimitations](benchmarks/README.md).\n\nUse it to answer questions such as:\n\n- Who calls this function, directly or transitively?\n- What can this function reach, and where do side effects happen?\n- Under which guards can this return or exception occur?\n- Does this source really reach that target in the requested mode?\n- Which API routes, scripts, or public exports are affected by a diff?\n\nCodeCanvas is Python-only and requires Python 3.10 or newer.\n\n## See the difference\n\nAsk one question:\n\n```text\nUse logic_flow on UserService.update_user. Show its branches, outcomes,\ndownstream effects, and evidence quality.\n```\n\nExcerpt from the actual response on the\n[included FastAPI sample](sample-fastapi/app/services/user_service.py):\n\n```json\n{\n  \"function\": \"app.services.user_service.UserService.update_user\",\n  \"source\": \"app/services/user_service.py:13\",\n  \"flow\": [\n    \"15  user = await self.user_repo.find_by_id(...)\",\n    \"16  if user is None:\",\n    \"17      → return None\",\n    \"18  → return await self.user_repo.update(user_id, user)\"\n  ],\n  \"outcomes\": [\n    {\"at\": 17, \"detail\": \"None\", \"guards\": [\"user is None\"]},\n    {\"at\": 18, \"detail\": \"await self.user_repo.update(user_id, user)\", \"guards\": []}\n  ],\n  \"downstream\": [\n    {\n      \"function\": \"app.repositories.user_repo.UserRepository.find_by_id\",\n      \"location\": \"app/repositories/user_repo.py:13\",\n      \"effects\": [\"db\"]\n    },\n    {\n      \"function\": \"app.repositories.user_repo.UserRepository.update\",\n      \"location\": \"app/repositories/user_repo.py:18\",\n      \"effects\": [\"db\"]\n    }\n  ],\n  \"evidence_grade\": \"inferred\",\n  \"safe_to_summarize\": false,\n  \"response_guidance\": \"Do not turn inferred call edges into unconditional claims.\"\n}\n```\n\nThat single response exposes the early return, success path, downstream database\nwork, exact source locations, and how cautiously the agent may summarize the\nresult.\n\n## Quick start\n\nInstall [uv](https://docs.astral.sh/uv/) if `uvx` is not already available.\nThe repository includes one shared plugin package with native manifests for\nboth Claude Code and Codex. Install it from the CodeCanvas marketplace:\n\n```bash\n# Claude Code\nclaude plugin marketplace add donggyun112/codecanvas\nclaude plugin install codecanvas@codecanvas\n\n# Codex\ncodex plugin marketplace add donggyun112/codecanvas\ncodex plugin add codecanvas@codecanvas\n```\n\nBoth plugins start `uvx codecanvas-mcp` and expose the complete tool catalog.\nSee the [plugin package](plugins/codecanvas/README.md) for local-checkout testing\nand validation commands.\n\nIf your client does not support plugins, register the server directly. For\nClaude Code:\n\n```bash\nclaude mcp add codecanvas -- uvx codecanvas-mcp\n```\n\nThat command exposes the complete tool catalog. Keep the full catalog enabled\nwhen your MCP client supports on-demand tool discovery or tool search: the\nclient can load the relevant schemas only when they are needed, so the other\nCodeCanvas tools remain available without paying their schema cost on every\nmodel request.\n\n```toml\n[mcp_servers.codecanvas]\ncommand = \"uvx\"\nargs = [\"codecanvas-mcp\"]\n```\n\nIf your client eagerly injects every enabled tool schema into every model\nrequest, use this compatibility profile instead:\n\n```toml\n[mcp_servers.codecanvas]\ncommand = \"uvx\"\nargs = [\"codecanvas-mcp\"]\nenabled_tools = [\"logic_flow\", \"who_calls\", \"call_tree\"]\n```\n\nThe three-tool allow-list is a fallback for eager-schema clients, not a\nrecommendation to discard the rest of CodeCanvas. For another MCP client, use\nthe equivalent stdio configuration:\n\n```json\n{\n  \"mcpServers\": {\n    \"codecanvas\": {\n      \"command\": \"uvx\",\n      \"args\": [\"codecanvas-mcp\"]\n    }\n  }\n}\n```\n\nPass an absolute `project_path` on the first tool call. CodeCanvas remembers the\nlast explicitly selected project for the rest of the server session.\n\nWith the complete catalog enabled, `project_status` reports candidate analysis\nroots for nested Python projects. Compact-profile users should pass the intended\nnested root explicitly.\n\n## Teach your agent when to use it\n\nAdding tools does not guarantee that an agent will choose them at the right\ntime. Put a short instruction like this in `AGENTS.md`, `CLAUDE.md`, or the\nequivalent file used by your coding agent:\n\n```markdown\n## Code analysis\n\nUse CodeCanvas before text search when you need to know:\n\n- how a Python function branches, returns, and produces side effects;\n- who calls it directly or transitively;\n- what it reaches downstream through project-internal calls.\n\nPass `project_path` once, then reuse the active project. Treat\n`safe_to_summarize: false`, inferred edges, ambiguity, and truncation as\nqualifications rather than unconditional facts.\n\nStart with `logic_flow`. Use `who_calls` for upstream impact and `call_tree`\nfor a deeper downstream trace.\n```\n\nThen ask your agent naturally:\n\n```text\nUse logic_flow first to understand checkout without repeated source searches.\nWhat calls UserService.update_user, up to three hops?\nWhat does checkout reach downstream, including HTTP or database effects?\n```\n\nWith the complete catalog enabled, CodeCanvas can also answer:\n\n```text\nList the entrypoints in this project.\nUnder exactly what conditions can authenticate raise?\nVerify that dry-run publish reaches _call_api.\nAnalyze the impact of the current diff.\n```\n\n## Why not just grep or an LSP?\n\nCodeCanvas complements both. It is for behavioral questions that otherwise\nrequire repeated searches and manual reconstruction.\n\n| Need | grep | LSP | CodeCanvas |\n|---|---|---|---|\n| Exact text | Best fit | Not its job | Keep using grep |\n| Definitions and direct references | Manual | Best fit | Resolves symbols inside structural results |\n| Transitive callers and callees | Repeated manual hops | References are not a call path | Bounded upstream and downstream graphs |\n| Branch guards and outcomes | Read and reconstruct source | Usually not modeled | Structured flow and guarded returns/raises |\n| Side effects and change impact | Infer manually | Usually not modeled | Effects attributed through call paths and entrypoints |\n| Uncertainty | No confidence model | Resolution-dependent | Evidence grade, ambiguity, truncation, and guidance |\n\n## What makes the answers trustworthy\n\nStatic analysis is not runtime truth, so CodeCanvas makes uncertainty visible\ninstead of hiding it.\n\nEvery successful MCP response identifies the selected `analysis_root` and\nincludes metadata that helps an agent decide how strongly it may state the\nresult:\n\n- `evidence_grade` describes the strength of the resolved evidence.\n- `inferred_edge_count` and `ambiguous_calls` expose uncertain call edges.\n- `truncated` says whether the bounded response omitted results.\n- `safe_to_summarize` says whether the result supports an unconditional claim.\n- `response_guidance` explains how to qualify a result when it does not.\n\n`verify_claim` goes further by combining candidate call paths with branch and\nreturn/raise guards. It returns `true`, `false`, or `uncertain`; unsupported\nqualifiers and inferred-only paths cannot silently become a definite `true`.\n\n## Tools\n\n### Discover and understand\n\n| Tool | Use it for |\n|---|---|\n| `project_status` | Inspect the active root, Python file count, cache, worker interpreter, and nested project candidates |\n| `list_entrypoints` | Find FastAPI routes, scripts, function entrypoints, and distributed library exports |\n| `find_symbols` | Locate functions, methods, and classes with exact-first name, semantic, or hybrid search |\n| `logic_flow` | Get one compact, citation-ready view of a function's branches, outcomes, downstream calls, and effects |\n| `what_does` | Triage a function from its signature, docstring, calls, effects, exceptions, and direct risk |\n| `function_flow` | Inspect a structured branch tree with subjects, conditions, scopes, and nesting |\n| `reaching_conditions` | Get the enclosing guards for each return or raise, plus complexity and unreachable code |\n\n### Follow behavior and assess change\n\n| Tool | Use it for |\n|---|---|\n| `who_calls` | Walk direct or transitive callers upstream |\n| `call_tree` | Walk project-internal callees downstream and attribute direct/transitive effects |\n| `verify_claim` | Conservatively check a qualified `source reaches target` claim against paths and guards |\n| `analyze_impact` | Map an inline diff or git ref to changed functions and affected entrypoints/public surfaces |\n\n### Reproduce state-shaped bugs\n\n| Tool | Use it for |\n|---|---|\n| `validate_state_schema` | Compare a function's state reads, writes, and mapping returns with a caller-provided schema |\n| `simulate_state_transition` | Execute focused generated or explicit state cases with invariants and dependency overrides |\n\nLarge result sets are capped. Use each tool's `filter`, `kind`, `path`, `depth`,\nor pagination arguments to narrow the answer before treating it as complete.\n\n## How it works\n\n1. **Select a project.** CodeCanvas resolves and remembers an explicit Python\n   project root. Ambiguous nested roots must be selected rather than guessed.\n2. **Build structural indexes.** Python AST analysis builds a project-wide call\n   graph and per-function control-flow data. Extractors add FastAPI routes and\n   `Depends()` chains, scripts, generic function entrypoints, and package\n   exports.\n3. **Reuse compatible analysis.** The call graph and entrypoints are cached in\n   `<project>/.codecanvas/`; an in-process builder is reused during the MCP\n   session.\n4. **Project compact answers.** Each MCP tool queries the shared analysis and\n   returns bounded results with origin, evidence, ambiguity, and truncation\n   metadata.\n\nThe default analysis limit is 5,000 Python files. Tune large-project behavior\nwith:\n\n| Variable | Default | Description |\n|---|---:|---|\n| `CODECANVAS_MAX_FILES` | `5000` | Maximum Python files to analyze |\n| `CODECANVAS_BATCH_SIZE` | `50` | Files processed before yielding |\n| `CODECANVAS_THROTTLE_MS` | `10` | Delay between batches in milliseconds |\n\n## Safety and limitations\n\n- CodeCanvas analyzes Python source; it does not model every possible dynamic\n  import, monkey patch, reflection path, or runtime value.\n- Inferred and ambiguous edges are reported as qualifications, not promoted to\n  definite evidence.\n- Static-analysis tools read project files and write the local `.codecanvas/`\n  cache. No remote CodeCanvas service is required.\n- `simulate_state_transition` is different: it imports and executes trusted\n  project code in a separate process. It is isolation for focused repros, not a\n  security sandbox. Project code may still access the filesystem, network, or\n  subprocesses and may have import-time side effects.\n- The simulator prefers `<project>/.venv` or `venv`, then the same directories\n  in the parent project. Use `python_executable` to choose explicitly and check\n  the returned `worker` metadata when imports fail.\n\n## Evidence\n\nThe measured local latency suite covers three pinned projects with 148–1,650\nPython files and 4,468–16,960 indexed functions. It reports cold analysis,\nfirst and warm search latency, and eight-worker throughput; the raw result is\ncommitted with the benchmark artifacts.\n\nThe model-backed evaluation covers frozen tasks and hidden rubrics for Google\nADK, LangGraph, and FastAPI. It compares built-in code exploration plus\n`logic_flow` against the same built-in exploration alone. Across 54 isolated\nsessions, three paired repetitions produced a suite-wide median of 22.95% fewer\nserver-reported total tokens. All 27 treatment sessions completed the required\ntool call, providing direct evidence that one CodeCanvas tool adds meaningful\nvalue without replacing the agent's existing search tools. Uncached input plus\noutput increased by a median 0.78%, and the answers are not yet blind-graded,\nso this is not yet an efficiency-at-equal-quality or billing-cost claim.\n\nSee the [full methodology, result tables, reproduction commands, and audit\nartifacts](benchmarks/README.md).\n\n## Development\n\n```bash\ngit clone https://github.com/donggyun112/codecanvas.git\ncd codecanvas/core\nuv sync --extra dev\ncd ..\ncore/.venv/bin/python -m pytest\n```\n\nThe package source lives under `core/`. The root test configuration runs both\nthe product tests in `tests/` and the package-level tests in `core/tests/`.\n\nIssues and focused reproduction cases are welcome:\n<https://github.com/donggyun112/codecanvas/issues>.\n\n## License\n\nCodeCanvas MCP is open-source software licensed under the [MIT License](LICENSE).\n",
  "bytes": 13953,
  "sha": "f208bcb622a6873be3e65323fc710c0ac94406771c768f5beb1acc881d52d799",
  "repo_slug": "donggyun112/codecanvas",
  "fonte": "repo",
  "truncated": false,
  "api": "https://agentalog.com/api/listings/mcp_io_github_donggyun112_codecanvas_5be3940b/readme"
}