MCP setup
EngineerLM speaks the Model Context Protocol, so an assistant can call
the 22 engineering tools directly instead of going through
HTTP by hand. Same registry, same dispatcher, same ownership checks and
the same elm- API keys as the REST API: a tools/call
is a persisted execution you can re-read afterwards.
The endpoint
| URL | https://engineerlm.com/mcp |
|---|---|
| Transport | Streamable HTTP (one endpoint, POST) |
| Auth |
Bearer API key -
Authorization: Bearer elm-...
|
| Not | OAuth. No dynamic client registration, no discovery document. A client that only supports OAuth discovery will not connect. |
| Sessions | None; the transport is sessionless |
| Protocol |
2026-07-28 for a current client;
the handshake-era revisions
2025-11-25, 2025-06-18, 2025-03-26, 2024-11-05
are still accepted
|
1. Create an API key
Keys are created at /keys/. Only a
digest is stored, so the secret is shown exactly once - copy it
immediately. A key needs engineering:read for every MCP
request and engineering:execute to call tools; a key with
full access has both.
Keys belong to an approved account. If yours is still waiting for approval, key creation is not open yet.
2. Add the server
Claude Code
claude mcp add --transport http engineerlm https://engineerlm.com/mcp \
--header "Authorization: Bearer elm-..."
Add --scope user to make it available in every project;
the default is this project only. Check it with
claude mcp list, which should report
Connected. The tools then appear to the model as
mcp__engineerlm__pipe_pressure_drop and
so on.
Any other Streamable HTTP client
Most clients take a JSON block of this shape, usually under
mcpServers. Where the file lives is per-client; check your
client's own documentation.
{
"mcpServers": {
"engineerlm": {
"type": "http",
"url": "https://engineerlm.com/mcp",
"headers": {
"Authorization": "Bearer elm-..."
}
}
}
}
The two things that matter to this server are the Streamable HTTP
transport - not stdio, not SSE - and a static
Authorization header.
3. What you get
- One MCP tool per registry entry, named by its canonical tool id. The
advertised
inputSchemais the tool's own pydantic model - the very one the dispatcher validates against - so the published contract cannot drift from what is enforced. - Resources under
elm://mirroring the REST read routes: the catalog, your studies, revisions, executions and artifacts. Every account-scoped read goes through the same owner-checked service, so a missing id, a malformed id and another account's id are one indistinguishable not-found. - Arguments the tool itself rejects are not a transport error: you get
a persisted execution with status
invalid_input, matching REST exactly. - Only synchronous execution is exposed over MCP. Durable mode, polling and cancellation stay on the REST side for now.
Client compatibility
Only what was actually driven end to end is listed as verified. Nothing else is claimed.
| Client | Result | Evidence |
|---|---|---|
| Official MCP Python SDK 2.2.0 (Streamable HTTP, 2026-07-28) | Lists tools, calls tools, lists and reads resources | mcp_server/tests.py, the whole suite |
| Official MCP Python SDK 2.2.0, handshake era (2025-11-25) | Connects and lists the full tool set | test_handshake_era_client_still_connects |
| Claude Code 2.1.236 | Connected, and the model ran pipe_pressure_drop to the reference-case value | Driven manually on 2026-09-09, recorded in the MCP guide |
Not tested, and therefore not claimed: Claude Desktop, any IDE MCP integration, the TypeScript SDK, ChatGPT and OpenAI connectors, Cursor, Windsurf, Zed, Continue. These may well work - the transport is the standard one and the handshake era is supported - but none has been driven against this adapter, so this page does not say they do.
Signing in with Google creates your account. Access to chat, the API and MCP is switched on once an administrator approves it, so you may wait a little before your first calculation. No card is asked for at any point.