Move SKILL.md + references/ scripts/ evals/ from skills/halcon/ up to the plugin root. Per Claude Code plugins-reference, a plugin with SKILL.md at its root and no skills/ subdir is auto-loaded as a single-skill plugin (v2.1.142+), so the invocation name = frontmatter name = halcon → clean /halcon. Bump plugin.json 2.0.0 → 2.0.1 so existing installs receive the update. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
5.6 KiB
Remote HALCON over MCP (halcon-remote)
A remote HALCON compute service exposed as an MCP server. Use it when there is no local HALCON (e.g. MacOS, a plain Linux box, a colleague's machine) — it runs HALCON 24.11 on a headless Linux server and is reachable over the public internet. Client needs only network + a bearer token; no HALCON, no minio creds, no VPN/tailnet.
- Endpoint:
https://halcon-mcp.totoro.studio/mcp(Streamable HTTP, Bearer auth) - Token: server-side
/opt/halcon-mcp/.env(HALCON_MCP_TOKEN); in configs reference${HALCON_MCP_TOKEN}, never hardcode. - Source/ops: repo
halcon-mcp-remote/; server192.168.1.13:/opt/halcon-mcp(systemdhalcon-mcp). Full deploy facts: repohalcon-tools.yaml→halcon_mcp_remote.
Register the server (client side)
# user scope (works across all projects)
claude mcp add --scope user --transport http halcon-remote \
https://halcon-mcp.totoro.studio/mcp --header "Authorization: Bearer $HALCON_MCP_TOKEN"
claude mcp list # expect: halcon-remote ... ✔ Connected
Or project .mcp.json: { "type":"http", "url":".../mcp", "headers":{"Authorization":"Bearer ${HALCON_MCP_TOKEN}"} }.
Tools (full names: mcp__halcon-remote__<tool>)
| Tool | Does | Key args |
|---|---|---|
halcon_get_env |
Self-check: version/hostid/arch | — |
halcon_create_upload |
Presigned PUT URL to upload one file (image or zip), no creds | filename, expires_minutes |
halcon_find_circles |
Subpixel find circles → list + preview | image or image_b64 |
halcon_measure_overlay |
Bullseye overlay: Top/Bottom center deviation (µm) | image or image_b64, apply_registration |
halcon_overlay_batch |
Batch overlay over a minio prefix → CSV | prefix, max_images |
halcon_find_circles_zip |
Batch find circles: image zip → 4 ring-mark centers (TL/TR/BL/BR) → CSV | zip_key, min/max_radius |
halcon_exec_hdev |
Run an HDevelop script via hrun → stdout (destructive) | script_text |
Image I/O — how images get in and results out
An image argument accepts one of:
file:/abs/path— a file on the server (testing only; e.g.file:/tmp/amm_test/2-zuoshang.bmp).<key>— a minio object key in the default buckethalcon(e.g.inbox/die.png).minio://<bucket>/<key>— explicit bucket.
Or pass image_b64 (inline base64, may include data: prefix) — best for a single small image, no upload step.
Results: numeric metrics come back inline (structuredContent). Heavy artifacts (preview jpg, CSV) are
uploaded to minio and returned as a key + presigned URL on the public host minio-home.totoro.studio
(openable from anywhere). Small files (preview/CSV) — just GET the URL.
Three usage patterns (pick by size)
1. Single small image → inline (simplest).
halcon_measure_overlay(image_b64="<base64 of the bullseye image>")
→ {status:"ok", overlay_dX_um, overlay_dY_um, top/bottom centers, n_circles}
2. Single/few images from an external client → presigned PUT (no creds).
k = halcon_create_upload(filename="die.bmp") # → {put_url, key}
curl -T die.bmp "<put_url>" # public PUT, no creds
halcon_measure_overlay(image=k.key)
3. Large batch (hundreds–thousands) → zip once, then process (recommended). Zip is the right move: one file = one upload = works with presigned PUT (external users too), vs mirroring many files (needs minio creds).
zip -0 -q -j batch.zip *.png # store mode (PNG already compressed)
k = halcon_create_upload(filename="batch.zip")
curl -T batch.zip "<k.put_url>" # one PUT
halcon_find_circles_zip(zip_key=k.key) # server unzips + batch + CSV
→ {total, ok, seconds, per_image_ms, csv_key, csv_url}
# then GET csv_url
CSV columns: file,status,n_found,TL_col,TL_row,TL_r,TR_...,BL_...,BR_... (4 ring-mark centers per image, ordered by position).
D2W overlay conventions (this project's domain)
- Axes: X = image right +, Y = image up +; pixel size 271.048 nm/px; overlay = Bottom − Top.
- Mark grouping: outer thick ring = Top Die Mark; inner dot + mid ring = Bottom Die Mark.
apply_registration=Trueadds the +13.5/+9.6 nm offset (0627-JC 2-point calibration; drop for other tools/batches).- Sanity values (die-2 four corners, raw dev µm): TL −0.778/+0.794 · TR −0.265/+0.391 · BL −0.171/+1.022 · BR +0.230/+0.435.
Performance (measured, single HALCON process, 16 threads)
- find_circles on 5312×4608 (24MP): ~92 ms/image (~11 img/s). 1920 images ≈ 176 s compute.
- 90 MB zip public PUT: ~20 s. End-to-end 1920 images ≈ 3.3 min.
- Circle-center repeatability across 1920 shots: std 0.01–0.04 px.
Gotchas
- Sync execution.
halcon_find_circles_zip/halcon_overlay_batchrun synchronously. ~1920 images (~3 min) is near the comfortable ceiling — set a long client timeout. For much larger jobs, chunk or use async (not yet built). - License
SESSIONS=1→ cannot multi-process; rely on HALCON's internal 16-thread parallelization (already fast). - Preview/CSV URLs use
minio-home.totoro.studio(public), not the internal192.168.1.2:9000— openable off-LAN. - Big batches: always zip (one PUT). Per-file
create_uploadfor N files is N round-trips — only for a handful. file:paths are server-side, not the client's filesystem — only for images already on192.168.1.13.- Tool errors return
isError+ an actionable message (e.g. "先用 halcon_create_upload 传图") — read it and self-correct.