# chromaframe-mcp
Agent-oriented MCP stdio server for deterministic ChromaFrame SDK flows.
> [!IMPORTANT]
> **v1 capability scope**
>
> - **Transport:** stdio only
> - **Capabilities:** tools only
> - **Tools:** `chromaframe_readiness`, `chromaframe_rank_candidates`, `chromaframe_analyze_image`
> - **Prompts:** none
> - **Resources:** none
All tools are read-only and idempotent. `chromaframe_analyze_image` does not create overlays or write artifacts; it only reads a caller-supplied local image path and returns sanitized measurements.
## Quickstart: Docker recommended
Pull and run the GHCR image. It contains the compiled `chromaframe-mcp` binary, Python 3.12 helper runtime, pinned Python dependencies, and verified model assets:
```bash
docker pull ghcr.io/kdcokenny/chromaframe-mcp:main
docker run --rm -i ghcr.io/kdcokenny/chromaframe-mcp:main
```
The GHCR image is multi-platform for `linux/amd64` and `linux/arm64`; Docker selects the matching image automatically on supported hosts, including Apple Silicon Docker environments.
MCP uses stdio, so keep `-i` in client commands. For image analysis, bind-mount the host folder containing images read-only and pass the container path to `chromaframe_analyze_image`:
```bash
docker run --rm -i \
-v /absolute/path/to/images:/images:ro \
ghcr.io/kdcokenny/chromaframe-mcp:main
```
Normal Docker use does not require host-side model setup or runtime downloads. The image sets:
- `CHROMAFRAME_VISION_HELPER_PYTHON=/opt/chromaframe/venv/bin/python`
- `CHROMAFRAME_MEDIAPIPE_TASK_PATH=/opt/chromaframe/assets/mediapipe/face_landmarker.task`
- `CHROMAFRAME_FACE_PARSING_ONNX_PATH=/opt/chromaframe/assets/face-parser/resnet18.onnx`
- `CHROMAFRAME_VISION_ASSET_MANIFEST=/opt/chromaframe/assets/face-parser/resnet18.manifest.json`
The baked assets are external artifacts with separate licenses/provenance from ChromaFrame code, and they make the image larger than the Rust crates alone. Image analysis stays local inside the container; raw pixels are not sent to a network service by ChromaFrame.
## Advanced: local repository run
Run the server from repository root:
```bash
cargo run -p chromaframe-mcp
```
For local image analysis without Docker, configure the same mandatory local helper and model-asset environment used by `chromaframe-sdk`:
```bash
CHROMAFRAME_VISION_HELPER_PYTHON=/absolute/path/to/python \
CHROMAFRAME_MEDIAPIPE_TASK_PATH=/absolute/path/to/face_landmarker.task \
CHROMAFRAME_FACE_PARSING_ONNX_PATH=/absolute/path/to/resnet18.onnx \
CHROMAFRAME_VISION_ASSET_MANIFEST=/absolute/path/to/resnet18.manifest.json \
cargo run -p chromaframe-mcp
```
## Host setup examples
Docker host examples use `ghcr.io/kdcokenny/chromaframe-mcp:main`; release tags are also published as `ghcr.io/kdcokenny/chromaframe-mcp:mcp-vX.Y.Z`. Replace `/absolute/path/to/images` with a host image directory when analysis needs image files.
### Claude Code
```json
{
"mcpServers": {
"chromaframe": {
"type": "stdio",
"command": "docker",
"args": ["run", "--rm", "-i", "-v", "/absolute/path/to/images:/images:ro", "ghcr.io/kdcokenny/chromaframe-mcp:main"]
}
}
}
```
### Codex
```bash
codex mcp add chromaframe \
-- docker run --rm -i -v /absolute/path/to/images:/images:ro ghcr.io/kdcokenny/chromaframe-mcp:main
```
### OpenCode
```json
{
"mcp": {
"chromaframe": {
"type": "local",
"command": ["docker", "run", "--rm", "-i", "-v", "/absolute/path/to/images:/images:ro", "ghcr.io/kdcokenny/chromaframe-mcp:main"],
"enabled": true
}
}
}
```
## Tools
| `chromaframe_readiness` | Sanitized SDK/helper readiness, missing package/model categories, optional warnings. |
| `chromaframe_rank_candidates` | Deterministic candidate ranking from manual Lab measurements and a goal vector. |
| `chromaframe_analyze_image` | Decode a local image, run helper extraction, rank candidates, and return sanitized observations/evidence without writing overlays. |
Privacy constraints: never return raw pixels, EXIF, full private paths, helper stdout/stderr, model cache paths, or secrets. Reports describe measured color fit and uncertainty only; they do not make beauty, attractiveness, race, identity, age, or medical claims.
## Development
```bash
cargo fmt --all
cargo clippy --workspace --all-targets --all-features -- -D warnings
cargo test --workspace --all-features
```
## Publishing
MCP releases use `mcp-vX.Y.Z` tags. `chromaframe-mcp` must keep `chromaframe-sdk` pinned exactly as `version = "=X.Y.Z"` with the local `path = "../sdk"`, and that SDK version must already exist on crates.io before MCP publish automation proceeds. See [`../docs/releasing.md`](../docs/releasing.md).