annotate_cluster
Assign a cell-type label to a cluster in a MilliMap session, recording the annotation in the session snapshot.
Instructions
Set a cell-type annotation on a cluster in the running MilliMap session.
The label appears in MilliMap's annotation panel and is written back to the session snapshot — use this when you've figured out what a cluster is.
Args: cluster_id: Cluster identifier as shown in MilliMap (e.g. "Cluster 3", "1"). label: Cell-type name (e.g. "CD8+ T cell", "fibroblast", "doublet").
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| cluster_id | Yes | ||
| label | Yes |
Output Schema
| Name | Required | Description | Default |
|---|---|---|---|
| result | Yes |
Implementation Reference
- src/millimap_mcp/server.py:292-305 (handler)The MCP tool handler function 'annotate_cluster' that proxies the call to the running MilliMap desktop app via HTTP POST. It takes cluster_id and label parameters and returns the result formatted as JSON.
@mcp.tool() def annotate_cluster(cluster_id: str, label: str) -> str: """Set a cell-type annotation on a cluster in the running MilliMap session. The label appears in MilliMap's annotation panel and is written back to the session snapshot — use this when you've figured out what a cluster is. Args: cluster_id: Cluster identifier as shown in MilliMap (e.g. "Cluster 3", "1"). label: Cell-type name (e.g. "CD8+ T cell", "fibroblast", "doublet"). """ return _fmt_json(_post_tool("annotate_cluster", { "cluster_id": cluster_id, "label": label, })) - src/millimap_mcp/server.py:292-292 (registration)The @mcp.tool() decorator registers this function as an MCP tool named 'annotate_cluster' with the FastMCP server.
@mcp.tool() - src/millimap_mcp/server.py:33-58 (helper)The _post_tool helper function that sends the actual HTTP POST request to the MilliMap desktop app's tool endpoint. Used by annotate_cluster to proxy the tool call.
def _post_tool(name: str, args: dict, timeout: float = 600.0) -> dict: ctrl = _load_control() if not ctrl or not ctrl.get("port"): return { "ok": False, "error": ( f"MilliMap control endpoint not found at {CONTROL_PATH}. " "Make sure MilliMap is running with a dataset loaded." ), } host = ctrl.get("host", "127.0.0.1") port = int(ctrl["port"]) url = f"http://{host}:{port}/tool" data = json.dumps({"name": name, "args": args}).encode("utf-8") req = urllib.request.Request( url, data=data, headers={"Content-Type": "application/json"}, method="POST", ) try: with urllib.request.urlopen(req, timeout=timeout) as resp: return json.loads(resp.read().decode("utf-8")) except urllib.error.URLError as exc: return {"ok": False, "error": f"connection failed: {exc.reason}"} except Exception as exc: return {"ok": False, "error": f"HTTP call failed: {exc}"} - src/millimap_mcp/server.py:77-78 (helper)The _fmt_json helper used by annotate_cluster to format the response dictionary as a pretty-printed JSON string.
def _fmt_json(payload: Any) -> str: return json.dumps(payload, indent=2, default=str) - src/millimap_mcp/server.py:299-305 (schema)The input schema (parameters) for annotate_cluster defined in the docstring/function signature: cluster_id (string) and label (string).
Args: cluster_id: Cluster identifier as shown in MilliMap (e.g. "Cluster 3", "1"). label: Cell-type name (e.g. "CD8+ T cell", "fibroblast", "doublet"). """ return _fmt_json(_post_tool("annotate_cluster", { "cluster_id": cluster_id, "label": label, }))