Download tools/mcp_server/server.py from Tatopenn/dense-Evolution: direct link, hf CLI and curl.
- Browser
- Download file 4.39 kB
-
https://huggingface.co/Tatopenn/dense-Evolution/resolve/main/tools/mcp_server/server.py
- Command line
-
hf download hf://Tatopenn/dense-Evolution/tools/mcp_server/server.py
-
curl -L -o server.py https://huggingface.co/Tatopenn/dense-Evolution/resolve/main/tools/mcp_server/server.py
4.39 kB
| #!/usr/bin/env python3 | |
| """ | |
| MCP server for Dense-Evolution's Composer API (dense_evolution_mcp). | |
| This is a thin adapter, not a reimplementation: every tool here calls the | |
| same local FastAPI kernel the published Composer web page talks to | |
| (local_site/app/server.py, started with `dense-evolution serve`, listening | |
| on http://127.0.0.1:8800 by default). All computation -- circuit | |
| simulation, VQE, molecular Hamiltonians, QM/MM forces, ZNE mitigation -- | |
| happens inside dense_evolution/dashboard_core exactly as it does for the | |
| web UI; this file only exposes those same endpoints as MCP tools so an | |
| agent can drive them directly instead of a browser. | |
| Requires the kernel to be running separately: | |
| pip install dense-evolution[composer] | |
| dense-evolution serve | |
| (or `python -m local_site.app.server` from the repo root) | |
| Override the kernel URL with the DENSE_EVOLUTION_KERNEL_URL env var if it's | |
| not on the default host/port. | |
| Images (circuit diagrams, histograms, Q-sphere, Bloch vectors) come back | |
| from the kernel as base64 PNGs meant for a browser <img> tag -- inlining | |
| that into a tool's text response would flood an agent's context with a | |
| wall of base64 for a picture it can't even see inline. Instead this | |
| adapter decodes and writes each one to DENSE_EVOLUTION_MCP_IMAGE_DIR | |
| (default ~/.dense_evolution_mcp/images) and returns the file path, which | |
| Claude Code (or any agent with file access) can open directly. Large | |
| numeric arrays (statevector, probabilities) are similarly truncated to | |
| their most significant entries rather than dumped in full -- the kernel's | |
| own response can be tens of thousands of floats for a 20+ qubit circuit. | |
| Structure (prog.txt Sezione 3, now complete): settings live in config.py, | |
| the HTTP client + error handling in client.py, the Pydantic input schemas | |
| in models.py (Phase 1); image saving/truncation/molecule-catalog caching | |
| in utils/ and molecules.py (Phase 2); the 21 tools themselves, split by | |
| topic, in tools/ (Phase 3, this file). This file's only job is to create | |
| the MCPServer instance, import each tools/*.py module so its `@mcp.tool` | |
| decorators register against it, re-export every tool function (so | |
| `from mcp_server.server import dense_evolution_health` keeps working for | |
| existing callers, including this repo's own test suite), and provide the | |
| `main()` console-script entry point. | |
| `mcp` is created here BEFORE the `from .tools....` imports below, and | |
| every tools/*.py module does `from ..server import mcp` -- Python resolves | |
| this correctly despite looking circular: by the time those imports run, | |
| `mcp_server.server` is already in `sys.modules` (registered before this | |
| file's body starts executing) with `mcp` already assigned, so each | |
| submodule's `from ..server import mcp` finds it immediately. Reordering | |
| the `mcp = MCPServer(...)` line to after the tool imports would break this. | |
| """ | |
| from mcp.server import MCPServer | |
| mcp = MCPServer("dense_evolution_mcp") | |
| from .tools.system_tools import ( # noqa: E402 | |
| dense_evolution_health, dense_evolution_list_gates, dense_evolution_list_molecules, | |
| dense_evolution_list_noise_models, dense_evolution_list_presets, dense_evolution_system_limits, | |
| ) | |
| from .tools.circuit_tools import dense_evolution_build_circuit, dense_evolution_run_circuit # noqa: E402 | |
| from .tools.chemistry_tools import ( # noqa: E402 | |
| dense_evolution_custom_molecule_energy, dense_evolution_energy_scan, dense_evolution_md_trajectory, | |
| dense_evolution_mix_molecules, dense_evolution_molecule_energy, dense_evolution_qmmm_forces, | |
| dense_evolution_run_vqe, | |
| ) | |
| from .tools.mitigation_tools import ( # noqa: E402 | |
| dense_evolution_mitigate_density_matrix, dense_evolution_mitigate_zne, dense_evolution_vector_healing, | |
| ) | |
| from .tools.wormhole_tools import ( # noqa: E402 | |
| dense_evolution_wormhole_scan, dense_evolution_wormhole_select_instance, dense_evolution_wormhole_teleportation, | |
| ) | |
| def main(): | |
| """Console-script entry point (`dense-evolution mcp`, see | |
| dense_evolution/cli.py) -- identical to running this file directly. | |
| stdio transport: this process is meant to be launched by an MCP | |
| client (Claude Code, Claude Desktop, ...) as a subprocess, not run | |
| standalone in a terminal.""" | |
| mcp.run() # pragma: no cover -- blocks on the real stdio transport loop | |
| if __name__ == "__main__": | |
| main() | |