Biomni Lab
Run biomedical research and bioinformatics.
MCP server URL
https://biomni-lab.gumstack.com/mcp
Works with
Tools 12
Send Message
Send a user message to a task and start the agent. Use this tool for queries like: * "ask the agent to summarize the trends in this dataset" * "tell the agent to also pull recent ClinVar submissions for BRCA1" * "follow up on the running task: add a literature search on the target gene" If the user is starting fresh (no task yet), use ``start_new_task`` instead — it creates the task and sends the first message together. To stream the agent's output, call ``wait_for_next_update`` a few times (at most ~3); if the task is still running, let the user know it may take a while and point them to ``biomni_url`` instead of polling indefinitely. Side effect: triggers AI agent execution. May take seconds to minutes depending on the request, consumes the customer's Biomni compute credits, and may launch sub-tasks (web search, HPC jobs, ClinVar queries). Prefer surfacing the cost/duration to the user before calling for expensive prompts. The send returns as soon as the agent starts; the reply is followed with ``wait_for_next_update``. The server resolves the project from the task, so ``project_id`` is optional and only used to build the ``biomni_url`` deep link in the response. Args: task_id: Target task id — get one from ``start_new_task``. Values look like ``tsk_…``; treat them as opaque ids. project_id: Optional project id — used to build the returned ``biomni_url`` deep link if the adapter response doesn't already carry one. Omit if you don't need a clickable link; the API call itself does not need it. message: User message text. file_ids: Optional list of input file ids to attach. Returns a trimmed dict: ``task`` (id / status / biomni_url), ``task_id`` (this conversation — reuse it for more send_message / list_result_files / wait_for_next_update), ``message_id`` (the agent's reply you just triggered), overall ``status``, and a short ``latest`` progress preview. To stream the reply, pass ``task_id`` to ``wait_for_next_update(task_id=...)`` a few times (at most ~3); if it's still running, tell the user it may take a while and point them to ``biomni_url`` rather than polling indefinitely.
Upload File
Upload a small TEXT file to a project's drive (CSV / TSV / JSON / code / VCF). Use this tool for queries like: * "save this CSV of experimental results to project X" * "add this script to the project drive for the agent to use" * "upload these variants as variants.vcf to the BRCA1 project" **Text only, inline.** The ``content`` is passed as a UTF-8 string in the tool-call argument, so **binary files (BAM, FASTQ, .vcf.gz, spreadsheets, images) cannot go through this tool** — they would be corrupted by string encoding. There is also a hard 25 MB cap on the inline content; larger files raise an error. For binary or large files, upload through the Biomni web UI instead — open the returned project web URL (``biomni_project_url`` / ``biomni_url``) and drag the file into the project drive there. (There is no separate presigned-URL / by-path upload tool over MCP; this is the only upload tool.) **Making the agent see the file:** after upload you get a ``file_id``. The agent does NOT pick the file up automatically — you MUST pass that ``file_id`` in the ``file_ids`` argument of ``start_new_task`` (or ``send_message``). Full programmatic flow: ``list_projects`` / ``create_project`` → ``upload_file`` → ``start_new_task(file_ids=[...])`` → ``wait_for_next_update``. Args: project_id: target project (use list_projects to find). filename: name the file will appear under in the drive (e.g. ``variants.vcf``). content: file content as a UTF-8 string. Multi-line is fine. mime_type: optional MIME type (default ``text/plain``). Common values: ``text/csv``, ``application/json``, ``text/tab-separated-values``, ``application/x-vcard`` (loose convention for VCF). Returns: a small dict with ``file_id``, ``filename``, and ``project_id``. Pass the ``file_id`` in the ``file_ids`` argument of ``start_new_task`` or ``send_message`` so the agent treats the file as an explicit input for that task.
List Tasks
List tasks in a project (or threads for ideal variant). Use this tool for queries like: * "what tasks do I have in the BRCA1 project?" * "show me my recent Biomni work" * "list tasks so I can pick one to continue" V0/V1: GET /tasks?project_id=… (flat URL shape). Args: project_id: The project to list tasks from. Required. (Accepted but ignored when BIOMNI_VARIANT=ideal, which uses a flat namespace.) limit: Max tasks to return.
List Files
List the input files already uploaded to a project. Use this tool for queries like: * "what files are in the BRCA1 project?" * "the PowerPoints I added to the project — start a task for each" * "list the project files so I can attach one to a task" Returns the files a user added through the Biomni web app's project files panel (or earlier via ``upload_file``) — the same files the agent can read during any task in that project. This is how you discover the ``file_id`` of an already-uploaded file: files are NOT attached to a task automatically, so pass the returned ``file_id`` values in the ``file_ids`` argument of ``start_new_task`` or ``send_message`` to attach them. Only input files are listed here. Result files the agent produced are listed by ``list_result_files(task_id)`` instead. Args: project_id: The project whose files to list. Required. limit: Max files to return (1–100, default 50). before_id: Return the page before this file ID. after_id: Return the page after this file ID. Returns a dict with ``files`` — each entry has ``file_id`` (pass to ``file_ids``), ``filename``, ``mime_type``, and ``size_bytes`` — plus ``biomni_url`` (the project files page) and ``has_more``.
Start New Task
Start a new conversation in a project: auto-create a task and send the first message in one call. Use this tool for queries like: * "analyze the CSV I uploaded and report the key findings" (no existing task) * "review these files in the project and flag anything unusual" * "ask Biomni to classify this VCF in the BRCA1 project" The single entry point for starting work — it creates the task and sends the first message together. **Attaching uploaded files (IMPORTANT):** if the user uploaded files first with ``upload_file``, you MUST pass the returned ``file_id`` values in the ``file_ids`` argument here. Files are NOT auto-attached — if you omit ``file_ids``, the agent will not see the uploaded files at all. Side effect: triggers AI agent execution. May take seconds to minutes, consumes the customer's Biomni compute credits. Use this only when the user has clearly asked to start work; for status/lookup use list_tasks or the waiting tools instead. Creates the task with ``POST /tasks``, then sends the first message to it. The call returns as soon as the agent starts; the reply is followed with ``wait_for_next_update``. Not available on the ideal variant. Args: project_id: The project to start the conversation in. Required. message: User message text. file_ids: Optional list of input file ids to attach. Pass the ``file_id`` values returned by ``upload_file`` here so the agent can see those files — they are not attached automatically. auto_mode: Run the task in Auto mode (default False). In Auto mode the agent never pauses to ask the user mid-run: the interaction gates it would normally block on — clarifying questions, plan approval, and Skill-load confirmations — resolve automatically so the task goes from start to finish unattended. Set True when the user wants a hands-off / autonomous run, or is not available to answer follow-ups (e.g. "just run it", "do the whole thing", overnight/batch work). Leave False (default) for interactive sessions where the user is present and wants to be asked before the agent makes assumptions. Auto mode only skips these user-input gates — it does not change auth, billing, or safety. task_name: Optional human-readable name for the new task. When set, it is used verbatim as the task title and bypasses the automatic naming from the first message. Omit to let Biomni auto-generate a title from ``message``. model: Optional model tier for the new task — ``'standard'``, ``'fast'``, or ``'max'`` (Max mode, the highest-capability model). Omit to use the account default (standard). Pass ``'max'`` only when the user asked for the strongest model / Max mode. Returns a trimmed dict with TWO distinct handles (don't conflate them): ``task_id`` — this conversation (a Biomni Task); reuse it for ``send_message`` (follow up), ``list_result_files``, and ``wait_for_next_update``. ``message_id`` — the agent's reply for this turn. Plus ``task`` (id / status / biomni_url), overall ``status``, and a short ``latest`` preview. Internal trace is stripped. After this returns, show the link and stream the reply with ``wait_for_next_update(task_id=...)`` a few times (at most ~3), not an open-ended loop. If it finishes within those, show the result; if it's still running, tell the user it may take a while and they can watch live in Biomni (``biomni_url``) or ask you to check progress later.
Create Project
Create a new project. Use this tool for queries like: * "make a new Biomni project called 'BRCA cohort 2026'" * "start a new project for the TP53 study" Only create a project when the user explicitly asks for a *new* one; otherwise call ``list_projects`` first to see if a suitable one exists. A project is a persistent container with its own file drive — tasks and uploaded files live under it. Each project belongs to a workspace (the backend calls a workspace an "org" — they are the SAME thing); the new project lands in the caller's current workspace automatically (you don't pass a workspace/org id). Users pick a project, not a workspace. Args: name: Human-readable project name. Required. description: Optional free-text description. metadata: Optional arbitrary key-value pairs (dict) stored alongside the project for your own use (e.g. external system IDs). Returns the created project object including its ``project_id``.
List Projects
List the caller's projects in their active workspace. Use this tool for queries like: * "what Biomni projects do I have?" * "find my project about BRCA1" * "which project should I add this to?" (discover by name) * "show me my most-recently-used projects with active tasks" (set include_activity=True) Always call this *before* asking the user to pick a project, instead of asking them to type the project_id from memory. Scope: this lists projects in the ACTIVE workspace only. If a project the user expects isn't here, it's in another workspace — call ``list_workspaces`` to see them and ``switch_workspace`` to change the active one, then list again. (Workspace switching takes effect over a signed-in/OAuth connection; a static API-key connection is bound to a single workspace.) Each project also includes ``updated_at`` (an RFC 3339 UTC datetime) when available — sort by it client-side to put "most recent" on top. Args: limit: Maximum number of projects to return (default 50). include_activity: If True, fetch per-project task counts in parallel and add ``running_tasks_count`` + ``total_tasks_count`` fields. Costs N extra list_tasks calls (one per project), so defaults to False. Use when the user explicitly asks about activity / in-flight work. Returns a paged list object with a ``data`` array of project objects.
List Workspaces
List the workspaces you belong to and show which one is active. Use this tool for queries like: * "what workspaces / teams do I have on Biomni?" * "which workspace am I in right now?" * "I can't find my project — is it in another workspace?" A workspace is the same thing as an "org". Projects, tasks and files are scoped to the *active* workspace, so ``list_projects`` only shows the active workspace's projects. If the user is looking for a project that isn't listed, call this to see their other workspaces, then ``switch_workspace`` into the right one. Returns a list of ``{id, name, type, is_active}`` plus ``active_workspace_id``.
Switch Workspace
Switch your active workspace so later calls act in it. Use this tool for queries like: * "switch to my Datasum Team workspace" * "work in the <team> workspace instead" * (after list_workspaces shows the project is elsewhere) move into it After switching, ``list_projects`` / ``create_project`` / tasks all act in the new workspace. Get workspace ids from ``list_workspaces``. A workspace is the same thing as an "org". Note: switching changes your account's active workspace (the same setting the web app uses). It takes effect when you're connected via sign-in (OAuth); a static API-key connection is bound to a single workspace and cannot switch. Args: workspace_id: the workspace (org) id to switch to — from list_workspaces. Returns ``{active_workspace_id, switched}``.
List Result Files
List the names and count of files an agent task produced. Refreshes stored result-file metadata from existing task outputs before listing them; this can create or update metadata records. Use this tool for queries like: * "what output files did this task produce?" * "the agent said the result is at /mnt/results/X.md — does that file exist?" * "how many result files are there?" The agent writes outputs to its sandbox (e.g. /mnt/results/report.md). This tool reports which files exist (name + size + mime_type), but does NOT return direct download links — to download a file, the user opens the Biomni web app. Tell the user the file names and steer them to the web app for the actual download. Note: a terminal ``wait_for_next_update`` result already auto-attaches a ``result_files`` array (names only) — call this tool only when you need to (re)list files outside that flow. Args: task_id: the task (session) whose outputs to list. Returns: { "data": [ {result_id, name, size_bytes, mime_type} ], "total": N }
Request Review
Run a Scientific Review of a completed task. Use this tool for queries like: * "review this analysis for scientific accuracy" * "double-check the agent's work for mistakes or hallucinations" * "is this result sound? flag any unsupported claims or limitations" Same as the "Review" button in the Biomni web app: a reviewer agent re-reads the finished task and checks it for scientific accuracy, correct use of the data/materials, unsupported claims (hallucinations), and stated limitations. Only worth running on a task the agent has already **completed** — a review of an idle or still-running task has nothing to look at yet. The review runs as a **background job** (an agent loop's worth of LLM turns + lookups), so this returns immediately with ``status: "running"`` — it does NOT return the review itself. When it finishes, the review is shown on the task's page in the Biomni web app; point the user to the returned ``biomni_url`` to read it there. (Unlike a normal reply, the review lands as its own conversation turn rather than the agent's latest assistant message, so ``wait_for_next_update`` is not the way to fetch it — the web link is.) Re-running: calling this while a review is already running is a no-op; calling it again after one finished starts a fresh review that replaces the previous one. Args: task_id: the task (session) to review — the conversation handle from ``start_new_task`` / ``send_message``. Returns ``{task_id, status, biomni_url}``.
Wait For Next Update
Long-poll for the next batch of progress on the agent's current reply. On a terminal reply, refreshes stored result-file metadata before attaching file names; this can create or update metadata records. **This is the only waiting tool.** Call it a few times to stream agent output to the user with incremental UI updates — but keep it bounded: **at most ~3 calls per turn**. If the task is still running after that, don't keep polling — tell the user it may take a while and point them to the task's Biomni link, or call this again later when they ask for an update. (`wait_until_complete`-style infinite loops are intentionally not the default — long runs belong on the web.) Use this tool for queries like: * "show me what the agent produced since I last checked" * "any updates on the running task?" * "give me the next bit of progress" How it works: server-side long-poll that returns the moment new content blocks arrive (sub-second latency to event) or the message reaches a terminal status (completed / failed / cancelled). Because **each call is its own tool result**, it surfaces as a separate visible message in Claude Desktop / Code / Cursor — ideal for keeping the user informed on long tasks without burning context on empty polls. Each call returns ONLY new blocks (sliced from ``since_block_index``), so token cost stays bounded regardless of total message length. Pass the ``task_id`` (the conversation handle from ``start_new_task`` / ``send_message``). Internally the server resolves it to the task's latest assistant reply and streams that. On each call, resolution picks the current turn — so after a ``send_message`` follow-up, you automatically stream the new reply. Block indices are per-reply and a follow-up starts again at 0, so ``since_block_index`` from an earlier turn is treated as 0 rather than reading past the new reply's end. Typical bounded pattern (at most ~3 updates, then hand off):: cursor = 0 for _ in range(3): res = wait_for_next_update(task_id, since_block_index=cursor) # ↑ each call surfaces as one visible tool result in the UI if res["status"] != "streaming": break # terminal — show the result cursor = res["cursor"] else: # still running — don't loop forever; tell the user it may take a # while and point them to res["biomni_url"], or check back later. ... The server blocks up to ``max_wait_seconds`` (capped to 30) waiting for new content; it returns immediately if new blocks arrive or status is terminal. Args: task_id: the ``task_id`` returned by ``start_new_task`` / ``send_message`` — the conversation to stream. The server resolves it to the latest assistant reply automatically. since_block_index: index of the first block to return. Pass 0 (default) on the first call; on subsequent calls pass ``res["cursor"]`` from the previous response to receive only newly-added blocks. max_wait_seconds: how long the server should hold the connection open waiting for new blocks. Default 15. Clamped to [0, 30]. Returns: JSON object with fields: ``blocks`` (new content blocks since ``since_block_index``), ``cursor`` (next value to pass as ``since_block_index``), ``status`` (current status), ``has_more`` (True if more blocks may still arrive), ``total_blocks`` (full count of blocks on the message), ``returned_from`` (echoes ``since_block_index``).