Skip to navigation

Connect an AI agent

Let Claude, Cursor or VS Code digitise shades through the MorphiaOne MCP server, or give a coding agent the digitisation skill.

Two ways in, both on the public API, so scopes, rate limits, credits and test mode apply as they do to any key:

You useConnect withWhat it does
An MCP client that can send a bearer header (Claude Code, Cursor, VS Code)The MCP serverEleven task-shaped tools that answer compact views
An agent that runs shell commandsThe skillDrives the morphiaone CLI with its --compact views

Use a test-mode key while trying it: jobs run end to end, return fixture results and charge nothing. Start with digitisation.read and digitisation.write: the agent proposes candidates, and a person reviews and stages them in the Platform.

Only grant digitisation.review if the agent may make review decisions. Grant catalogue.read and catalogue.write together for import_shades, which creates or revises known colours. stage_candidate needs catalogue.write; find_variant needs catalogue.read. measure_regions requires both digitisation.write and digitisation.read, including with wait: false: its tool contract covers queuing and polling. Scopes do not imply each other.

MCP server

Streamable HTTP at /mcp. Send your API key as a bearer token; without one the server answers 401. It keeps no key and no state between calls.

Sign in instead of pasting a key

A client that connects through OAuth, such as a Claude.ai or Claude Desktop custom connector, signs you in with your MorphiaOne Platform account instead. The server publishes where to sign in at /.well-known/oauth-protected-resource, and its 401 names that document, so the client finds it alone: add the connector by its URL and sign in when asked.

The agent then acts as you, within your role in the account:

  • A viewer’s agent reads; a developer’s drafts; an owner’s or admin’s may also review.
  • Approving and publishing a catalogue stay in the console, for a person, whatever the role.
  • If your account requires a person to review, the agent’s decisions are refused as a key’s are; it gives you the candidate’s review link instead.
  • Removing you from the account stops the agent’s next call.

From your own code, pass the token where you would pass a key: access_token= in Python, accessToken in TypeScript (one or the other, never both).

Sign-in is being rolled out. Until the hosted endpoint offers it, use an API key.

The hosted MCP endpoint is not public yet. Until it is, ask for its URL when you request access, and use it where the snippets say MCP_URL.

Create .mcp.json with literal environment references:

{
"mcpServers": {
"morphiaone": {
"type": "http",
"url": "${MCP_URL}",
"headers": { "Authorization": "Bearer ${MORPHIAONE_API_KEY}" }
}
}
}

Set MCP_URL and MORPHIAONE_API_KEY in the environment that launches Claude Code. The client expands these references when connecting. Do not expand the key in a shell command or save its value in the configuration. In a real client session, check /mcp to confirm the connection before starting a job. See Claude Code’s environment-variable configuration.

Local server

morphiaone-mcp runs the same tools over stdio on your machine. It reads the key from MORPHIAONE_API_KEY and can upload a local photo by path. It needs no hosted URL and no OAuth, so Claude Desktop can use it too. Until the package is published, install it from a checkout: pip install -e sdk/python -e mcp-server.

The CLI writes the entry for you, keeping your other servers and backing up the file it changes:

morphiaone mcp install --client claude-code # or cursor, claude-desktop; --print to preview

It runs morphiaone-mcp from your PATH if it finds it, otherwise uvx morphiaone-mcp. These are the entries it writes:

.mcp.json:

{
"mcpServers": {
"morphiaone": {
"type": "stdio",
"command": "morphiaone-mcp",
"env": { "MORPHIAONE_API_KEY": "${MORPHIAONE_API_KEY}" }
}
}
}

MORPHIAONE_BASE_URL defaults to https://api.morphiaone.ai.

Tools

ToolKindDoes
start_uploadwriteStarts a single-use link the person sends one photo through, with no API key
get_uploadreadReads an upload link: pending, stored with its asset_id, or expired
retain_evidencewriteKeeps a photo as evidence: a local file (path, local server only), an uploaded asset (asset_id) or a public https link (url)
measure_regionswriteMeasures up to four regions of an image and waits for the result, sending progress notifications while it waits
make_candidatewriteFreezes one measured region for review
edit_candidatewriteCorrects a field, deriving a new pending candidate
review_candidatedestructiveAccepts or rejects a candidate, bound to its digest
stage_candidatedestructiveStages an accepted candidate as a catalogue draft
import_shadesdestructiveCreates or revises variants from known colours, row by row
list_review_queue, get_assessment, get_candidate, find_variantreadBrowse

retain_evidence takes exactly one of path, asset_id or url. Only a local server reads path, and only a .jpg, .png or .webp file whose bytes are that image; anything else is refused before it leaves your machine. A deployment that fetches no links answers a url with 400 INVALID_REQUEST and remote_input_disabled.

With a hosted server the agent never holds the photo, so it asks the person for it: start_upload answers an upload_url to send them. They open it to choose the photo, or run curl -T photo.jpg "<upload_url>"; it needs no API key, works once and expires after 15 minutes. The agent reads get_upload until it is stored, then passes its asset_id to retain_evidence. The link is shown only when the session starts, so start a new one rather than retrying. The account’s key network allowlist does not apply to the person’s send: the link itself is the permission. You can also upload the photo yourself with the SDK or morphiaone digitisation retain --file and hand the agent its evidence or asset id.

tools/list shows only tools for which your key has every required scope. A key with both read scopes sees four read tools. If the key cannot be checked, discovery fails instead of advertising unrestricted tools. Each tool call checks scopes again, so a client cannot bypass this check by calling a hidden tool and scope changes take effect on the next call. The gateway still authorizes each API operation. GET /v1/api-key (client.whoami(), morphiaone whoami) answers the key’s scopes.

Each tool answers the fields a reviewer needs and the digest the next call takes. Pass raw: true for the full response with its audit digests. Writes derive their Idempotency-Key from their arguments, so an agent’s retry replays the first answer, including a failed assessment. To measure the same regions again on purpose, pass attempt: 1 (then 2, and so on) to measure_regions.

The server tells the agent to show the user each measured colour and to accept only on an explicit yes. That is guidance to the agent, not proof that a person approved.

Every decision records who made it: a candidate’s reviewed_by and a stage’s reviewed_by and staged_by are {"type": "user"} for a member in the Platform or {"type": "api_key"} for a key. When the review must be a person’s, an owner or admin turns on Settings → Review policy in the Platform. Then the server enforces it for every key of the account, whatever its scopes:

  • accept and reject answer 403 HUMAN_REVIEW_REQUIRED.
  • stage answers the same unless a member accepted the candidate.
  • The candidate’s review_url opens it in the Platform. The agent gives that link to the user and waits; once a member accepts, the agent may stage it.

Each key decision and each refusal is a row in the account’s audit log. A key without digitisation.review and catalogue.write is still the narrowest grant: it can retain, measure and propose candidates and nothing more. The policy does not cover generic import_shades, which copies a known hex into a draft with catalogue.write and no candidate; do not grant that scope to an agent whose colours a person must approve. Staging is not publishing: a staged draft renders nothing until someone approves and publishes it in the Platform.

Skill

For agents that run shell commands (Claude Code, Claude Agent SDK), the morphiaone-digitisation skill ships in the SDK repository under sdk/skills/morphiaone-digitisation/. Copy that folder into .claude/skills/ (one project) or ~/.claude/skills/ (every project). It drives pip install morphiaone and reads the key only from MORPHIAONE_API_KEY.

The agent commands (whoami, --compact) need the current SDK; upgrade an older install.

Qualify locally before hosting

Claude Code and Cursor can connect to the local Streamable HTTP service; a public hostname is not required for a real-client test. Use a test-mode key, retain a local photo with morphiaone digitisation retain --file, and give its evidence id to the agent. Verify measurement, candidate creation, human Platform review and staging. Check retries, missing scopes and revocation with separate test keys. Record client and package versions and request ids, never credential values.

Public hosting needs a separate authentication review: the current static API-key adapter forwards the caller’s key to the public API. It is not an OAuth deployment. OAuth must validate tokens issued for the MCP endpoint and use separately authorized upstream credentials. Keep URL fetching disabled until its deployment gates pass; local-file retention works without arbitrary URL fetching.

Building your own agent on the SDK? Name it with app_info="my-agent/1.0" (appInfo in TypeScript): it goes first in the User-Agent the SDK sends.

The order of calls

Both follow Digitise and import shades: retain, measure, make a candidate, review, stage.