AI / MCP integration

drive Симолёт from an LLM — Claude runs the platform as a tool

The idea: subscription, not API

Симолёт exposes a native Model Context Protocol server. Add it to a Claude client you already pay for (Claude Desktop, Claude Code, or a claude.ai connector) and Claude launches simulations, polls status, reads logs and fetches artifacts — from the chat, on your Claude Max/Pro subscription, with no per-token API bill. Симолёт does the heavy compute (meshing, solving, rendering) on its own fleet.

Endpoint
POST https://sim-orch.sverk.io/mcp (synonym /v1/mcp)
Protocol
JSON-RPC 2.0 over HTTP (Streamable-HTTP MCP)
Auth
Authorization: Bearer slt_…
Server
A thin facade over the live REST router — every tool call passes the same RBAC scopes, tenancy and quotas as REST.

Connect — Claude Desktop

Settings → Connectors → Add custom connector, then:

Name simolyot · URL https://sim-orch.sverk.io/mcp · Bearer token slt_…

Claude runs initializetools/list and shows the 37 tools below. If your build takes a JSON config for remote servers:

{
  "mcpServers": {
    "simolyot": {
      "type": "url",
      "url": "https://sim-orch.sverk.io/mcp",
      "authorization_token": "slt_YOUR_TOKEN"
    }
  }
}

Connect — Claude Code (CLI)

claude mcp add --transport http simolyot https://sim-orch.sverk.io/mcp \
  --header "Authorization: Bearer slt_YOUR_TOKEN"

claude mcp list          # → simolyot should appear

Then just describe the task in chat — Claude picks and calls the tools.

Connect — Anthropic MCP connector (Messages API)

To drive it from your own automation, attach the server via the Messages API MCP connector (this path uses an Anthropic API key, separate from the subscription story):

import anthropic
client = anthropic.Anthropic()  # ANTHROPIC_API_KEY

resp = client.beta.messages.create(
    model="claude-opus-4-8",
    max_tokens=2048,
    betas=["mcp-client-2025-11-20"],
    mcp_servers=[{
        "type": "url",
        "name": "simolyot",
        "url": "https://sim-orch.sverk.io/mcp",
        "authorization_token": "slt_YOUR_TOKEN",
    }],
    messages=[{"role": "user", "content":
        "List the stacks, run hello-sim, wait for it, and summarize the logs."}],
)
print(resp.content)

How an LLM should use it

Call get_stack_guide first to learn how to author a run — it returns the run contract (how /work, /config/run.json and the ##metric protocol work), the stack’s config schema, and a working example to adapt. (list_stacks also carries each base’s docs and configurable fields.) Then reach for the smallest surface that fits:

  • One runsubmit_job → poll get_job until phase is succeeded/failed → read get_logs + list_artifacts. preflight_job validates limits/headroom first.
  • Layered configsubmit_run (four overlays platform<org<project<user, provenance-tracked); resolve_run/validate_run preview it. run.id == job.id, so the job tools still apply.
  • Multi-step DAGsubmit_pipeline (each stage a run gated on its needs) → poll get_pipeline. validate_pipeline checks it first.
  • Interactive podcreate_sessionget_session (launching→ready) → stop_session.
  • Share a live runmint_embed. Admin → orgs, get_policy/preview_policy, node grants.

Every tool dispatches back through the live REST router, so it inherits that route’s RBAC scope, tenancy and quota — the MCP facade adds no bypass.

Author & discover
get_stack_guideHow to AUTHOR a run for a stack: the run contract, config schema + a working example. Call this FIRST.
list_stacksDiscover the base simulators + their config surface.
get_nodesThe compute fleet: status, tier, capabilities, free resources.
entitlementsThe caller's org usage vs. quota — check before a batch.
Run a job
submit_jobLaunch a run on the fleet; returns a job_id immediately (async).
preflight_jobDry-run admission: how limits clamp + headroom, without enqueuing.
get_jobOne run's phase, node, timings, final metrics + artifacts. The primary poll.
list_jobsList the caller's runs; filter by phase / stack / project.
get_logsA run's historical logs + metric history (poll form; MCP has no streaming).
list_artifactsThe output files a finished run produced (name, size, download URL).
cancel_jobStop a queued or running job.
rerun_jobRe-submit a run's spec, producing a new job_id.
Layered RunSpec
submit_runLaunch a run from a layered config (platform<org<project<user); run.id == job.id.
resolve_runPreview the layer merge + per-key provenance, without launching.
validate_runCheck a layered RunSpec against the stack schema, without launching.
get_runOne run's detail + the resolved snapshot (effective config, provenance, layers).
list_runsThe caller's runs as run rows; filter by phase / stack / project.
DAG pipelines
submit_pipelineSubmit a multi-stage DAG; each stage a run gated on its needs. Returns a pipeline_run id.
validate_pipelineCheck the DAG topology + every stage's RunSpec, without launching.
get_pipelineThe full DAG: overall status + each stage's phase / job_id / metrics.
list_pipelinesThe caller's pipeline runs, newest first, with progress.
cancel_pipelineCancel a running pipeline (kills non-terminal stages).
Interactive sessions
create_sessionLaunch a long-lived multi-service pod a human drives; returns a session id.
get_sessionA session's phase, services, teleop channel + timings. The primary poll.
list_sessionsThe caller's interactive sessions, newest first.
stop_sessionTear the pod down and release its quota reservation.
Share & embed
mint_embedMint a read-only, time-boxed embed token + URL an external app iframes for a live run view.
Teams, policy & fleet sharing (admin)
list_orgsThe org seats the caller (a user session) is a member of.
create_orgCreate a team org with the caller as owner.
list_org_membersAn org's members + roles (owner/admin).
add_org_memberSeat a member with a role; a new user gets a one-time login token.
remove_org_memberRemove a membership (owner/admin; last owner protected).
get_policyAn org's resolved quota policy: platform seed + layers + effective caps.
preview_policyPreview the effective policy (and stack manifest) a subject would get.
list_node_grantsCross-org node grants issued + received by the caller's org.
create_node_grantGrant another org access to place jobs on your org's nodes.
revoke_node_grantRevoke a node-access grant (owner org only).

The raw wire (for engineers)

A 5-second connectivity check: initializetools/listtools/call list_stacks.

curl -sS https://sim-orch.sverk.io/mcp \
  -H "Authorization: Bearer slt_YOUR_TOKEN" -H "Content-Type: application/json" \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/call",
       "params":{"name":"list_stacks","arguments":{}}}'

A tools/call result is {"content":[{"type":"text","text":"…JSON…"}],"isError":false} — the text is the raw REST response body (the stack catalog, a job object, …). If you see serverInfo.name = “simolyot” and a stack list, MCP is live.

Same auth as everything else: mint a member-role slt_ token on Admin (or Settings). It gives runs:* + read scopes — enough to launch, poll, and read logs/artifacts from the chat.