orca-copilot-mcp
# Orca Copilot
A chat panel docked inside OrcaSlicer. It reads the presets you have selected,
measures what is on the plate, checks each slice for the things that cost
prints, and suggests setting changes you apply with one click — in plain
language, naming settings the way the slicer does. The same tools are also an
MCP server any Claude Code session can use with OrcaSlicer closed.
## What you need
- **macOS, so far.** It finds the slicer's directories by the slicer's own
rules on Windows and Linux too, and looks for the Claude CLI where each
platform's installers put it, but only macOS has actually been run.
- **An OrcaSlicer build with the plugin host API.** No tagged release has it
yet. The nightly builds carry the plugin system itself but not the host calls
the panel, the plate measuring and the live setting edits are made of; those
are on the `feat/preset-write-api` branch, waiting to go upstream. Until they
do, a build of that branch is the only OrcaSlicer this runs in.
- **[Claude Code](https://claude.com/claude-code), installed and logged in** with
a Claude subscription. If `claude` works in a terminal, the copilot works. There
is nothing else to set up: it starts its own session under your login and
reads none of your Claude Code settings (see below). API keys are not enough
on their own — the CLI takes them from an environment variable, and a slicer
launched from the Dock has no environment to take one from.
## Install
1. Get `orca_copilot-<version>-py3-none-any.whl` from the
[Releases page](https://github.com/peterbedorjr/orca-copilot/releases), or
build it from a checkout with `uv build --wheel`.
2. In OrcaSlicer, open **File → Plugins**, press **Install local plugin**, and
pick the wheel. OrcaSlicer installs the one dependency (the `mcp` package)
into its own bundled Python; your system Python is never involved.
3. Press **Activate**. If the Copilot panel does not appear beside the plater,
restart OrcaSlicer.
The panel docks itself when OrcaSlicer starts. If you close it, **Open Copilot
Chat** in the Plugins dialog brings it back.
Developers can skip the dialog: `scripts/install_plugin.sh` builds the wheel
and drops it straight into the plugin directory.
## Using it
Ask in the panel the way you would ask someone at the next desk:
> Why is the first layer not sticking?
>
> Will this print without supports?
>
> Set this profile up for a strong functional part.
It reads the process, filament and printer presets you have selected, measures
the model on the plate you are looking at, and looks things up in the OrcaSlicer
wiki before naming a number. When you have an object selected, "this" means
that object.
**Changes are yours to apply.** A suggestion arrives as a card with an Apply
button. Nothing in the slicer changes until you press it, and what you applied
is modified-but-unsaved, exactly as if you had typed it in — ask the copilot to
save or discard, or do it in the slicer.
**After each slice it checks your work.** It measures the sliced layers and says
only what is likely to cost you the print: overhangs your supports will not
cover, a first-layer island too small to hold, a part tall enough to topple. It
stays quiet when nothing stands out. The **Check my work** box at the top of the
panel turns this off; then it only answers what you ask.
With the wiki tooltips installed (see [Filling in the setting
popover](#filling-in-the-setting-popover)), hovering a setting's label opens its
wiki section in a popover, with an **Ask the copilot about this** link that puts
the question in the panel.
## What leaves your machine
Everything the copilot reads — your preset values, measurements of your model,
what you type — goes to Anthropic through Claude Code, under your own account,
the same as anything you type into Claude Code itself. Nothing goes anywhere
else. The plugin opens no network connections of its own and reports nothing
back to anyone; the only traffic on your machine is between the panel, the
slicer and the Claude CLI, on localhost.
## Cost
It runs on your Claude subscription. The model is pinned to Sonnet, so the
same question costs everyone the same and nobody's personal default turns the
copilot into an Opus session without them noticing. The check after each slice
is a full turn with several tool calls; if you slice a lot and would rather
spend that on questions, untick **Check my work**.
## Your Claude Code setup stays out
The copilot's session is started with `--setting-sources ""` and
`--strict-mcp-config`: none of your hooks, plugins, skills, output styles or
MCP servers load into it. A hook that rewrites answers into your house style
would otherwise be rewriting slicer advice, with nothing in the panel to say so.
Your login is untouched. The session runs in `copilot_session/` under the
OrcaSlicer data directory, not your home, so no `CLAUDE.md` of yours is read
either. One consequence: an `apiKeyHelper` in your settings is a setting, and is
not read.
## Using the tools from Claude Code
The same MCP server runs standalone, with OrcaSlicer closed:
```bash
claude mcp add orca -- uv --directory /path/to/orca-copilot run orca-copilot-mcp
```
Then ask, in any session:
> What process preset am I using, and what have I overridden in it?
>
> Clone the standard A2L profile and set the top shell to 7 layers.
The tools are `get_current_presets`, `list_presets`, `get_preset`,
`set_preset_values` and `clone_preset` over the presets themselves;
`describe_setting` and `find_settings` over what each setting means;
`search_wiki` and `read_wiki` over the OrcaSlicer wiki; and `describe_plate` and
`get_plate_thumbnail` over the last saved project.
**Standalone, changes land in the preset file, not in a running OrcaSlicer.**
The slicer loads presets at startup and holds them in memory, so restart it to
see an edit — and don't re-save that preset from the slicer UI before
restarting, or it will write the in-memory values back over the file. Every
write is backed up first (20 revisions per preset, under `copilot_backups/` in
the OrcaSlicer data directory).
System presets are read-only by design. Clone one and edit the clone.
## Development
```bash
uv run pytest # 418 tests, no OrcaSlicer required
```
Tests read real preset files from the installed OrcaSlicer and copy them into
a temp directory, so they exercise the actual profile shapes rather than
invented fixtures. They never write to your real configuration. The panel tests
run the page's own script under node against a small DOM shim, so they are the
slow ones.
After upgrading OrcaSlicer, regenerate the settings schema:
```bash
uv run python scripts/generate_schema.py
```
This unions the 680 keys OrcaSlicer's own `--export-settings` reports with the
271 more that only appear in shipped vendor profiles; validation rejects
anything outside that set, so a stale schema means real settings get refused.
It then annotates those keys with the label, category, tooltip, unit, range and
legal enum values parsed out of `PrintConfig.cpp`, which is what `describe_setting`
and `find_settings` serve to the model. That needs a local OrcaSlicer checkout,
expected beside this one at `../OrcaSlicer` or wherever `ORCA_SRC` points (the
wiki likewise: `../OrcaSlicer.wiki` or `ORCA_WIKI`). Pass `--reuse-defaults` to refresh only
that metadata, which skips starting the slicer to re-dump defaults that have not
changed.
## Filling in the setting popover
Hovering a setting label in the Print, Filament or Printer tabs opens a webview
popover that OrcaSlicer has always had and never filled: it looks for
`resources/tooltip/<label>.md` and the only file shipped is a placeholder reading
"TODO: We are creating these contents, please wait ...". The OrcaSlicer wiki is
that content.
```bash
git clone https://github.com/SoftFever/OrcaSlicer.wiki.git ../OrcaSlicer.wiki
scripts/install_tooltips.sh ../OrcaSlicer.wiki
```
That writes ~1050 files into
`~/Library/Application Support/OrcaSlicer/resources/tooltip/common/`, which
`MarkdownTip::LoadTip` reads before the app bundle, so nothing in OrcaSlicer is
modified. Refresh the content later with `git pull` in the wiki checkout and run
the script again; it never fetches anything itself.
566 of the 951 settings get a section. The strongest signal is not in the wiki at
all: `Tab.cpp` already names a wiki page and usually a `#section` anchor for each
settings row — the target of the "?" link beside it — which covers 510 of them
exactly. The rest come from the `[Variables]` line a wiki section carries, a
heading matching the setting's label, and finally any inline mention of the key.
**Upstream builds compile the popover away.** `MarkdownTip::ShowTip` opens with
`#ifdef NDEBUG return false; #endif`, so every Release build of upstream
OrcaSlicer returns before showing anything. The `feat/preset-write-api` branch
drops those lines, which is why it shows there.
## Giving the model the wiki
The same generator writes `src/orca_copilot/data/wiki.json`, which is what
`search_wiki` and `read_wiki` serve:
```bash
uv run python scripts/generate_tooltips.py ../OrcaSlicer.wiki
```
486 KB, 102 pages, and the section that explains each of 572 settings. It is
committed and loaded out of the installed wheel, like `settings_schema.json`, so
the tools work from a Claude Code session with OrcaSlicer closed and no tooltips
installed. **Nothing is fetched, at generation time or at runtime**: refreshing
the content is a `git pull` in your own wiki checkout followed by a re-run of the
script.
The corpus is wider than the popover's. A hover has a setting to show a section
for; "how do I calibrate pressure advance" has not, and two in five of these pages
explain no setting at all — the calibration procedures, the troubleshooting, the
print-preparation guides. Left out are the release notes, the plugin API reference
and the localization glossary, which mention every term in 3D printing and explain
none of them.
Images are stripped and links flattened to their own text, exactly as for the
popover: an image the model cannot fetch is a wasted token, and a URL in a tool
result is something it may quote at the user.
TDQS
Scored across 14 tools
Most tools are clearly separated by resource and action: preset retrieval/editing, wiki search/read, settings find/describe, and plate describe/render. The only possible confusion is between get_preset and get_current_presets, and between search_wiki and read_wiki, though their descriptions do disambiguate them.
The majority follow a consistent snake_case verb_noun pattern (list_presets, get_preset, set_preset_values, describe_setting, read_wiki). remember, forget, and preflight deviate from that pattern, making the naming mostly but not perfectly consistent.
Fourteen tools is within the ideal 3-15 range and each tool covers a distinct facet: memory, presets, settings lookup, plate inspection, and wiki reference. The size feels appropriate for an OrcaSlicer copilot rather than padded or insufficient.
The set has significant gaps: descriptions explicitly defer to absent tools such as get_selection, measure_slice, and suggest_settings, so agents will hit dead ends when trying to identify the current plate/object, measure geometry, or get recommended settings. There is also no tool to delete a cloned/edited preset, leaving the preset lifecycle incomplete.