Skip to main content
Glama
milliomics

millimap-mcp

Official
by milliomics

find_markers

Identifies marker genes for each cluster by running rank_genes_groups, updating the MilliMap snapshot with top markers for subsequent retrieval.

Instructions

Run rank_genes_groups in MilliMap to find marker genes per cluster.

After this completes, the MilliMap snapshot refreshes with the top markers per cluster — subsequent calls to get_cluster_markers or genes_for_cell_type will see them.

Args: groupby: obs column to group by. Default 'clusters'. method: 'wilcoxon' (default), 't-test', or 'logreg'.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
groupbyNoclusters
methodNowilcoxon

Output Schema

TableJSON Schema
NameRequiredDescriptionDefault
resultYes

Implementation Reference

  • The `find_markers` tool registered with `@mcp.tool()`. Delegates to the MilliMap desktop app by POSTing to its /tool endpoint with name='find_markers' and the groupby/method arguments.
    @mcp.tool()
    def find_markers(groupby: str = "clusters", method: str = "wilcoxon") -> str:
        """Run rank_genes_groups in MilliMap to find marker genes per cluster.
    
        After this completes, the MilliMap snapshot refreshes with the top
        markers per cluster — subsequent calls to get_cluster_markers or
        genes_for_cell_type will see them.
    
        Args:
            groupby: obs column to group by. Default 'clusters'.
            method: 'wilcoxon' (default), 't-test', or 'logreg'.
        """
        return _fmt_json(_post_tool("find_markers", {
            "groupby": groupby, "method": method,
        }))
  • Helper function that sends the tool request to the MilliMap desktop app's HTTP endpoint. Used by `find_markers` and all other write-path tools.
    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}"}
  • Helper that formats the response dict as a pretty-printed JSON string. Used by `find_markers` to return its result.
    def _fmt_json(payload: Any) -> str:
        return json.dumps(payload, indent=2, default=str)
  • The `@mcp.tool()` decorator registers `find_markers` as an MCP tool on the FastMCP server instance.
    @mcp.tool()
    def find_markers(groupby: str = "clusters", method: str = "wilcoxon") -> str:
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Without annotations, description carries full burden. It reveals a side effect (snapshot refresh) but omits details on idempotency, authorization, or state requirements.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Concise with a clear first sentence and structured Args, but the side-effect sentence could be integrated to reduce length slightly.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Coverage is adequate for a simple tool with output schema; adds side-effect context and param details. Missing prerequisites (e.g., needing clusters) are a minor gap.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 0%, so description compensates with clear 'Args' listing allowed values and defaults, though method lists only three options while schema allows any string.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states it finds marker genes per cluster using rank_genes_groups in MilliMap. The mention of subsequent calls to get_cluster_markers or genes_for_cell_type distinguishes it from those retrieval tools.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It implies usage by noting that after completion, other tools will see the results, but lacks explicit direction on when to use versus alternatives like run_clustering.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Install Server

Other Tools

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/milliomics/millimap-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server