Jean docs
API & MCP

MCP

This is the manual. Every tool it describes runs in your browser, free, no account.

Open the workbench

Point an AI assistant at the workbench's tools and let it run them.

SettingValue
Server URLhttps://<host>/mcp
TransportStreamable HTTP (not SSE, and not a local command)
AuthenticationA personal key, carried in the address (/mcp?key=…) or as Authorization: Bearer …. Get it at /connect with Google or an invitation code. No OAuth. Listing the tools needs no key
Method the client speaksPOST, with Accept: application/json, text/event-stream
Narrowed servershttps://<host>/mcp/<scope>
Search-first serverhttps://<host>/mcp/discover
Account neededNone
Anything to fill in besides the URLNothing

What it does

The Model Context Protocol is how an AI assistant is given tools it can actually run. Pointing a client at /mcp hands the model the workbench's whole catalogue: it can compute a melting temperature, find restriction sites, design primers, digest a plasmid or check an assembly, and read the real result back, instead of estimating an answer from memory.

The tools it gets are the tools the workbench has. There is no separate, simplified set for models, and no tool that exists only here: the same declarations generate the panels, the workflow builder, the HTTP endpoints and this.

Why an engine, and not a model's memory

A model with a terminal can run code, but it still answers a scientific question from what it remembers unless something it calls is correct by construction. That is the difference this server makes: the model does the reasoning, the engine does the science.

Every tool that computes is checked against the reference implementation of its field, on that implementation's own data, before it ships. Its result says how it was reached: the method and the inputs it used. The tools that look things up instead (sequence databases, literature) say which authority answered. So an assistant can tell you why a number is what it is, and you can check it without trusting the assistant.

The cheapest way to see it is a case where a plausible answer is wrong. Ask for EcoRI sites on the circular sequence AATTCTTAGGATCCG: the only site spans the point where the circle closes, so an answer that reads the sequence as a straight line finds none. The tool finds it, and with circular: false it correctly finds nothing. Ask for an enzyme that does not exist and it refuses by name, rather than returning an empty list that reads as "no sites".

Connecting

Most clients take a URL. Give them:

https://<host>/mcp

/api/mcp is the same server and keeps working, so a client already configured with it needs no change. /mcp is simply the address to hand someone new.

The lab is invitation only, and the key is how a client gets in. Open https://<host>/connect, sign in with Google or enter the invitation code the page shows, and make a key. The page hands you the address with the key already in it, https://<host>/mcp?key=bi_…, which is the one thing a client needs: no header, no OAuth step. A client that sets headers can send the key as Authorization: Bearer bi_… instead. Listing the tools works without a key; running one without a key answers with a short message that names the connect page. Use is free; the lab counts accounts and calls, never what was sent. The server is stateless, so a client can reconnect freely.

Each tool arrives with its full input schema, so the model sees every parameter, its bounds and units, and the published options a parameter selects between with what each one is. That is what lets a model choose the SantaLucia 2004 table over Breslauer 1986 deliberately, rather than guessing at a parameter name.

Filling in a connector dialog, field by field

Most dialogs ask for more fields than this server needs. Every one of them but the URL is left empty:

Field the dialog asks forWhat to put
Name / labelAnything. Jean engine
Server URL / endpointThe address from /connect: https://<host>/mcp?key=bi_…, with the key in it
Transport / typeStreamable HTTP. Pick http if the choice is http or sse; this server has no SSE endpoint
Authentication / auth typeNone: the key is already in the address
API key · token · client ID · client secretLeave empty, or paste the key into a Bearer-token field if the dialog has one and you used the address without ?key=
Custom headersNone
Scope / audience / OAuth URLsLeave empty. This server publishes no OAuth metadata, on purpose
Command · args · environmentLeave empty. This is a remote server, not a local process

For a client that is configured by file rather than by dialog, the whole entry is two lines:

{
  "mcpServers": {
    "jane": {
      "type": "http",
      "url": "https://<host>/mcp"
    }
  }
}

Some clients spell the same two lines "transport": "http", and some take the URL alone. Nothing else belongs in the entry: no headers, no env, no command.

If your client can only run a local command and cannot take a URL, it needs a stdio-to-HTTP bridge of its own; this server offers no local process to launch, and configuring one as though it did is the most common way a working endpoint ends up looking broken.

Checking the address before you fill anything in

Open the URL in a browser, or run:

curl -s https://<host>/mcp

A working endpoint answers with the JSON card below. "authentication": "none" is the server stating, in its own words, that there is nothing to authenticate:

curl -sS https://<host>/mcp \
  -H 'content-type: application/json' \
  -H 'accept: application/json, text/event-stream' \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'

That is the exact request a client makes. If it returns a tool listing, the address is right and any remaining trouble is in the client's settings, not the server.

What the failures look like, and which is which:

What you getWhat it means
The JSON card, "authentication": "none"The endpoint is live. Fill the dialog in as above
405 with a body saying there is no event streamAlso fine — that is the answer to a request for a stream this server does not offer, and it is not a sign-in demand
A not found, or a bare 404That deployment does not carry the API. No connector setting fixes this
The workbench's own interface, as HTMLThe address reached the app instead of the API. Check for a typo in /mcp
A sign-in screenSomething in front of the deployment is asking, not this server

Connecting from Claude

In Claude, open Settings → Connectors → Add custom connector, and give it your deployment's address with /mcp on the end:

https://<your-domain>/mcp

Use the address the connect page gave you, with ?key= in it. There is no OAuth step: if the connector asks for authentication, leave it empty, because the key travels in the address.

If the setup step cannot detect the server, configure it manually as no-auth — the endpoint is fine. A client checking the address may report something like "set up as not requiring sign-in, but the server asked for sign-in when checked (status 405)". That 405 is not a sign-in demand. The Model Context Protocol lets a server decline to open a server-initiated event stream, and declining is answered with 405; this server has nothing to push, so a client that asks for that stream gets exactly that, while the POST a client actually speaks over answers normally. The refusal now says so in its own body, and the addresses a client checks for sign-in requirements (/.well-known/oauth-protected-resource and /.well-known/oauth-authorization-server) answer that nothing here authenticates. Continue past the detection step and finish the connector by hand.

The quickest way to check the address before you connect: open it in a browser. A working endpoint answers a plain visit with a short JSON card describing itself — the transport, the fact that it wants no authentication, the narrowed addresses below, and the exact request that lists the tools:

{
  "server": "jane-engine",
  "protocol": "Model Context Protocol",
  "transport": "streamable-http",
  "endpoint": "https://<your-domain>/mcp",
  "authentication": "none",
  "scienceTools": "how many science tools it serves",
  "call": { "method": "POST", "body": { "jsonrpc": "2.0", "id": 1, "method": "tools/list" } }
}

If instead you get the app's own interface, a not found, or a sign-in screen, the address is wrong or that deployment does not carry the API yet — which is a different problem from authentication, and no connector setting fixes it.

The card is for people and for probes; it is not part of the protocol. A real client opening the event stream still gets the 405 the specification asks for, because it says so in its request.

A first task to check it works. Once connected, ask Claude:

Using the melting temperature tool, what is the Tm of the primer GTAAAACGACGGCCAGT under the unified 2004 nearest-neighbour model, and again with 5% DMSO using the Cullen and Bick coefficient? Show me the per-step derivation.

You should get 57.883 °C and 55.383 °C, with a DMSO step of −2.5 °C attributed to Cullen and Bick (1976). If those are the numbers, the connector is wired to the real engine and not to the model's recollection.

A second one, to see a refusal work:

Find the BamHI sites in ATGGGATCCAAA, and then try again with an enzyme called NotAnEnzyme.

The first returns one site; the second is refused by name rather than answered with an empty list.

Connecting from ChatGPT

ChatGPT adds a custom server as a plugin, following OpenAI's own steps:

  1. Open chatgpt.com/plugins and press +, then Add custom MCP server.
  2. Give it a name and a short description (what it computes, so the model knows when to call it).
  3. Enter the same address as above, with /mcp on the end, or a narrowed one such as /mcp/cloning.
  4. For authentication choose none, and use the address with ?key= from the connect page.
  5. Confirm with I understand and want to continue, then Create as a plugin.

Whether custom servers can be added at all depends on your ChatGPT plan and, in a workspace, on what its administrator allows. The same two first tasks above check the connection: the Tm answer and its DMSO step should match to the last digit.

Narrowing the catalogue, and why you probably should

A model shown a hundred plausible tools picks a plausible one. Handing over the entire catalogue costs both accuracy and prompt space, so the same server is offered pre-narrowed:

https://<host>/mcp/cloning

Two kinds of scope are available, and they answer different questions.

By capability, which is what a tool is:

ScopeWhat it holds
analyzeReading a result: proteins and mass spectra, trees, qPCR, populations, differential expression, antibodies
sequencingReads and traces: FASTQ, mapping, Sanger traces and editing outcomes, alignments, copy number, variant calls
cloningBuilding a construct: cut sites, digests, Gibson, Golden Gate, ligation, recombination, mutagenesis primers
designDesigning a reagent or experiment: guides, probes, RBS and circuits, codon optimisation, barcodes, power, submissions
recordFinding and exporting records: archive search and fetch, annotation, maps, construction history
amplifyPrimers and PCR: primer design and checks, LAMP, degenerate and bisulfite primers, PCR products
workspaceThe open project: its record, selection, library, experiments and a description of what it holds

By deliverable, which is what a job needs. These are derived by following the connections between tools out from the job, so a task spanning three capabilities comes back whole:

ScopeWhat the job delivers
knockoutGuides, off-targets, a repair template, screening primers, the protocol and the order form
expressionSeveral coding sequences for one protein, each a different published strategy, scored

Narrowing is opt-in. An unscoped client still gets every tool, and no scope is applied by default. On the unscoped server each tool's description is its opening sentences; the describe_tools tool returns the full text (models, options, what the tool refuses) for the tools you name. A narrowed server lists every description whole.

Search first, for a client that cannot afford the listing at all. https://<host>/mcp/discover lists no science tools directly. Its find_tools takes the task in words and returns the closest tools with their full descriptions and input schemas, and call_tool runs one by name, answering exactly as the direct call would. The trade: every call goes through one tool, so a host that asks before running a tool asks every time, because call_tool can reach tools that write or query a remote service.

An unknown scope is refused, never quietly widened. Asking for a scope that does not exist returns an error rather than the full catalogue, because a client that believes it narrowed and did not is worse off than one told it was wrong.

What a model gets back

The same JSON the HTTP API returns, as structured tool output. That matters more for a model than for a person: a result that carries its model name, its per-step derivation and its citations lets an assistant tell you how a number was reached, and a refusal that names its reason lets it correct itself instead of inventing a plausible number.

Figures arrive as pictures. A tool that draws (a plasmid map, a gel, a phylogenetic tree, an alignment block, a Sanger chromatogram) returns its figure twice: as a lossless SVG and as a PNG, so a client that does not render SVG still shows the PNG. The same goes for plots: a hydropathy or membrane profile, a GC window, a FoldIndex disorder profile, a melt curve and its HRM trace, a predicted amplification curve, a lineages-through-time curve, per-base Sanger quality, and the heatmaps of a distance matrix, a primer cross-dimer ΔG grid and a codon-usage chart. The model is shown the picture once; the SVG is for you.

And in a client that supports MCP Apps, the result opens as a view inside the chat. At the extension's launch those were Claude, ChatGPT, VS Code Insiders and Goose. The figure comes first, then a sortable table for every list of rows (cut sites, primers, guides, hits), then the readouts. A figure can be shown at actual size and downloaded as SVG. The view shows the same result the model reads, and a client without MCP Apps simply gets the text.

A molecule can be named rather than pasted. _subject takes an archive accession, a bundled sample or a file, exactly as the HTTP API does (see Naming a record instead of pasting it on the HTTP page), so an assistant can say "the pEGFP-N1 sample" or "U55762" and the record arrives with its annotations and topology.

Limits worth knowing

  • It computes, it does not remember. These tools hold no project and no history. A model can melt an oligo or digest a sequence you give it; it cannot open your saved work.
  • Sequences you send leave your machine. The workbench computes locally in your browser; this is a server. For unpublished constructs, prefer the editor.
  • Free, and shared. A personal key from /connect, and finite capacity: one address may make 120 calls a minute, and the next is refused with how long to wait. One tool call may run for 60 seconds before it is stopped with the reason.
  • A very large answer comes back in windows. An answer over 16 MiB (the same size a request may be) returns the first part of its largest list or text, and says so before the data: for example "probes is items 0–48,000 of 412,000". read_answer_window returns any other part, given the same tool and arguments, the field and the range. Counts and summaries in the answer are always of the whole result, never of the part shown.

On this page