Content
# PERISCOPE — Read-only Fusion 360 MCP
**Let a local AI inspect the Autodesk Fusion design you have open — without letting it touch anything.**
PERISCOPE exposes the live Fusion session as structured, strictly read-only [MCP](https://modelcontextprotocol.io) tools: assembly tree, joints, rigid groups, assembly constraints, timeline health, parameters, current selection, viewport screenshots — plus **direct measurement** (`measure`, `get_geometry_context`) so answers come from evaluated geometry, not guesswork.
> *"List all joints, rigid groups, and constraints in my active design, and tell me which ones are in error or conflict."*
> *"Measure the minimum clearance between these two components."*
> *"What did I just select, and what drives its dimensions?"*
**Status: working, actively developed, Windows-verified.** macOS paths exist but are untested. Expect rough edges; the tools report their own limits honestly.
## Read-only means read-only
There is **no write path in this codebase**. No mutation tools, no "run Python in Fusion" escape hatch, no timeline rollback; the local bridge answers no HTTP method other than GET. This is a property of the code, enforced by a regression test that fails the build if a mutating call appears — not a runtime flag. It is safe to query mid-command, mid-design, without wondering what it might do.
## How it works
```
Any MCP client (Claude Desktop, Claude Code, others)
│ MCP over stdio
▼
periscope_mcp external Python process (official `mcp` SDK)
│ HTTP GET, 127.0.0.1:8735, bearer token
▼
Fusion add-in bridge inside Fusion's embedded Python, stdlib only
▼
the live Fusion session (all API calls on Fusion's main thread)
```
Two processes, because the Fusion API only exists inside Fusion's interpreter and is not thread-safe. The bridge binds loopback only and requires a locally generated bearer token on every request.
## Quick start
Requirements: Windows, Autodesk Fusion, Python 3.10+.
```bash
git clone https://github.com/VXNTedits/fusion360-mcp-periscope
cd fusion360-mcp-periscope
python install/install.py
```
Then in Fusion: **Shift+S → Add-Ins tab → Periscope → Run** (tick *Run on Startup*).
Verify from a shell:
```bash
python install/verify.py --probe
```
Register with Claude Desktop / Claude Code:
```bash
python install/register.py --show # preview
python install/register.py --all
```
Any other stdio-MCP client — point it at:
```json
{
"command": "<repo>/server/.venv/Scripts/python.exe",
"args": ["-m", "periscope_mcp"],
"env": { "PYTHONPATH": "<repo>/server" }
}
```
Note: the registered command points into your clone — don't move the folder after installing.
## The tools
Twelve, all annotated read-only. See [FEATURES.md](FEATURES.md) for details and [AGENTS.md](AGENTS.md) for AI-facing usage guidance.
`fusion_health` · `get_session_info` · `get_assembly_tree` · `get_joints` · `get_rigid_groups` · `get_constraints` · `get_timeline` · `get_parameters` · `measure` · `get_geometry_context` · `get_selection` · `capture_viewport`
## Design principles
- **Measured over inferred.** Distances and extents come from Fusion's `MeasureManager` and evaluated B-Rep bounds. Every value is classified `fusion_measured`, `fusion_reported`, or `derived` (with the formula shown). Parameters are labeled as nominal inputs, because a `1000 mm` extrusion parameter says nothing about what downstream features left behind.
- **Honest gaps.** "This design has none" and "the API cannot see this" are never the same answer. Coverage blocks, truncation notes, and inline error nodes make the difference explicit — a design with one broken feature stays inspectable, because the broken feature is usually what you're asking about.
- **Boring security.** Loopback-only bind (refuses to start otherwise), per-install token compared with `hmac.compare_digest`, browser `Origin` and DNS-rebinding `Host` checks, failing closed. Design data leaves the machine only as answers into your own AI conversation.
## Limits (current)
- Inspects **open** Design documents; does not browse cloud files, drawings, or version history.
- Constraint *relationship entities* (which faces an existing constraint mates) are not readable — the Fusion API only exposes them after a timeline roll, which is a write, which PERISCOPE refuses. Names, health, error text, offsets, and timeline order are fully reported.
- Very large assemblies get bounded, explicitly-labeled partial results rather than hangs.
- One request at a time inside Fusion (by design); a modal dialog or long compute yields a clean `fusion_busy`.
## Credits
The transport and threading patterns were informed by reading several MIT-licensed Fusion MCP projects, chiefly [ndoo/fusion360-mcp-bridge](https://github.com/ndoo/fusion360-mcp-bridge) and [frankhommers/autodesk-fusion-mcp](https://github.com/frankhommers/autodesk-fusion-mcp). Neither was forked: both are authoring tools with code-execution surfaces, and PERISCOPE's read-only diagnostics surface had no prior art to adapt.
## License
[MIT](LICENSE)