Skip to main content
Strand AI runs a hosted Model Context Protocol server so any MCP-aware agent can drive the Strand AI platform. An agent browses owned or public samples, uploads an H&E whole-slide image, estimates or submits a Lattice virtual-staining run, tracks it, and downloads the predicted marker channels. Every action is authorized against your Strand AI organization; only submitted runs reserve its credits. It is a hosted, OAuth-authenticated service over Streamable HTTP. There is nothing to install and no API key to manage. You connect the server URL and authorize with your Strand AI account. Slide bytes and results never pass through the model or the server.

Connect

Add a custom connector with the server URL https://mcp.strandai.com/mcp over the Streamable HTTP transport, then authorize with Strand AI and pick an organization. See Claude for the step-by-step, authorization, and data-handling details. Slide upload depends on the client’s network because the client sends bytes directly to storage. Claude Code and the SDKs work without additional setup. Claude.ai requires one network setting. ChatGPT cannot upload because its sandbox has no outbound network access; upload with the browser or another client before running markers from ChatGPT.

Tools

Research use only (RUO). Not for use in clinical or diagnostic procedures.

Browsing and reading samples

list_samples accepts scope: mine | public | all (default mine), limit (default 48, maximum 100), an optional cursor, and an optional exact tag filter. mine contains active, non-trashed samples owned by your organization. public contains the curated public cohort. all puts owned samples first and removes owned-public overlap in favor of the owned item. Results use items and next_cursor. Every item has an ownership discriminator and canonical id. Public IDs are privacy-safe. The API trims and lowercases a tag and requires its normalized length to be from 1 to 50 characters. Every sample result also carries a canonical absolute app_url. Agents should link users to that value rather than building a URL from a sample ID. get_sample accepts that canonical ID for either branch. Owned detail includes jobs and job_count, covering current and historical runs. Public detail is limited to curated public fields and carries no owned job history or internal sample, organization, creator, or storage identifiers. Sample reads are credit-free. Owned detail also includes segmentation: lifecycle status, retryability, latest job, latest materialized layer, artifact availability, and the explicit zero-credit cost.

Cell segmentation

segment_sample starts segmentation when none exists and retries failed runs. The operation is state-idempotent and credit-free. It reuses active or completed work, and failed runs have a 60-second retry cooldown. Only owned, ready, non-archived samples can be changed. Public samples are read-only. Poll with get_sample; its latest layer reports whether the uint32 label-mask OME-Zarr and per-cell feature tables are available. download_results(..., include_segmentation: true) attaches the segmentation manifest. Cell morphology/geometry and each marker-expression Parquet table join on instance_id. These are true cell observations. Python AnnData created from ordinary prediction results remains a pixel-grid matrix and is not a segmentation result.

Updating a sample

patch_sample requires a sample ID and at least one of name, tags, or mpp. tags replaces the complete desired set. A null or empty name reverts to the uploaded filename. mpp is isotropic microns per pixel and takes precedence over embedded slide calibration.

Estimating and submitting a run

submit_run defaults to creating a job and reserving credits. Set dry_run: true to return patch and credit estimates without creating a job or reserving credits. A newly uploaded slide can take about 90 seconds to resolve its dimensions, scale, and tissue-tile count. During that interval a dry run returns status: not_ready, a reason, and retry_after_seconds: 15; retry the dry run after that interval.

Result formats

download_results requires format: ome-zarr | ome-zarr-zip | ome-tiff. Native ome-zarr returns stored data without conversion. OME-Zarr ZIP and OME-TIFF are cached asynchronous exports. Repeat the same invocation to poll or retry a failed export. H&E is off by default for every format. Setting include_he: true selects a separately cached H&E-inclusive OME-TIFF, and for OME-Zarr and OME-Zarr ZIP it returns the processed, registered H&E as its own artifacts.he link. include_segmentation adds the latest mask plus the per-cell geometry, morphology, and marker-expression manifest. Pixel-grid marker arrays are not cell expressions. Responses report the selected contents, status, expiration, retryability, and whether the prediction artifact was converted.

Waiting for a run

wait_for_job provides a status snapshot after waiting for at most 240 seconds. Long-running jobs may still be active when it returns. Terminal jobs return completed, partial_failed, failed, or cancelled as ordinary status results. If the timeout elapses first, the job keeps running and the tool returns a refreshed latest status. Call it again to continue waiting. The server-side wait reduces model polling and returns before Claude’s connector deadline.

Uploading a slide

Slides must be de-identified before upload. See Security and data handling. upload_slide does not take a file. The bytes are not sent through the model or the server. It returns a presigned, resumable upload session bound to your organization’s storage: an upload_id and an upload_url. Your agent then:
  1. Sends the slide bytes directly to upload_url with an HTTP PUT. One request works for a typical slide. Larger files can be sent as sequential chunks (each a multiple of 256 KiB except the last). The tool result provides structured transfer metadata for content ranges, ordering, alignment, and success statuses; network metadata identifies the required egress host and browser fallback.
  2. Uses submit_run with dry_run: true as the readiness check. GCS automatically starts ingest preprocessing when it commits the final PUT. Automated de-identification is off by default and runs during ingest only when enabled for your organization. While ingest is running, the dry run returns a structured not_ready result with a retry interval. No finalize tool or REST request is required.
Because the agent performs the PUT itself, upload_slide suits agents that can execute HTTP requests and reach storage.googleapis.com. Agents in a sandboxed client usually need a one-time setting to allow that traffic: on claude.ai web and desktop, add storage.googleapis.com under your organization’s Settings, Capabilities, Allow network egress before the first upload, then start a new chat so the sandbox picks the change up. See Claude for the per-client setup. For a multi-GB whole-slide image, or to skip the egress step entirely, upload in your browser at app.strandai.com/samples/upload. The browser uploader runs on your machine and does not require an egress setting. It runs independently from MCP upload sessions. Discover its resulting owned sample with list_samples or get_sample. For scripted or bulk uploads, the Python SDK and REST API stream slides for you end to end.

Example prompts

Upload this H&E slide to Strand AI, estimate a CD3e, CD8, and Ki67 run without reserving credits, show me the estimate, and ask before submitting it.
Read sample SAMPLE_ID and summarize its job history. If job JOB_ID is still running, wait for its latest status, then export completed results as an OME-TIFF.

See also

  • Claude: connect, authorize, and data handling.
  • ChatGPT: connection prerequisites and upload limitations.
  • Python SDK: the client library for programmatic uploads and pipelines.
  • REST API overview: the underlying HTTP surface.
  • Pricing: how credits map to slides × markers.