Sobmit Docs

Sobmit as an MCP server

Sobmit is not just an MCP client — it can be consumed as an MCP server. An external agent (Claude Desktop, Cursor, or any MCP 2026-07-28 client) can discover Sobmit as a protected resource, authenticate with OAuth 2.1, and then build, read and validate flows on your behalf.

Endpoint

The MCP server is served over a stateless JSON-RPC POST endpoint:

POST /api/mcp

It implements the MCP 2026-07-28 protocol (createMcpHandler from the official SDK v2), constructing a fresh server per request so tool definitions are always backed by the current authenticated user.

Discovery (RFC 9728)

An MCP client discovers the server through its protected-resource metadata, served at the well-known root:

GET /.well-known/oauth-protected-resource

This document is what the 401 WWW-Authenticate challenge points to via its resource_metadata field, so a standards-compliant client finds the authorization server and token endpoint without manual configuration.

Authentication — OAuth 2.1 authorization-code flow + PKCE

Access is granted with the standard OAuth 2.1 authorization-code flow with PKCE (RFC 7636). The flow:

  1. Authorization request — the client redirects the user to /oauth2/authorize with client_id, scope, redirect_uri and the PKCE code_challenge.
  2. Consent — if the user has not already consented, Sobmit shows a consent screen at /consent naming the requesting client and the scopes it asks for. The user approves or denies.
  3. Authorization code — on approval, the browser is redirected back to the client’s redirect_uri with a one-time code.
  4. Token exchange — the client exchanges the code (plus its PKCE code_verifier) for an access token at the token endpoint.
  5. Access — the client calls POST /api/mcp with the bearer access token. requireMcpAuth verifies the token (issuer, audience, expiry) against the authorization server’s JWKS and maps it to the authenticated user.

The signing key is published at:

GET /jwks

Access tokens are audience-bound to the /api/mcp resource and scoped to the specific user who consented — a client can only act on that user’s flows.

Static token (for clients without OAuth)

Not every client speaks OAuth 2.1 with PKCE. For those, Sobmit issues a personal access token (PAT) — a static bearer token scoped to your account that you paste into the client once:

  1. Open Account → API in Sobmit and create a token (give it a name, e.g. vryne.com) and choose its permissions:

    • Run only (default, recommended) — trigger your flows and read their results, but cannot create, edit or delete flows.
    • Full access — everything, including creating/editing flows.

    The full token is shown exactly once — copy it then.

  2. In the client, configure Sobmit as a remote MCP server with:

    Endpoint:      https://www.sobm.it/api/mcp
    Authorization: Bearer <token>
  3. The client sends Authorization: Bearer <token> on every request. Sobmit maps the token to its owning account (hashed at rest) and enforces the token’s permission level — a “run only” token can start your flows and read results, but has no way to change them.

The PAT path speaks the stateless MCP profile: plain JSON-RPC POSTs (initialize → tools/list → tools/call) with application/json / text/event-stream responses, and accepts an optional mcp-session-id header. Protocol 2025-06-18 and the 2025-era revisions are negotiated automatically, so older streamable-HTTP clients work without extra setup.

Available tools

The server exposes these tools, all scoped to the authenticated user. Tools marked edit are only available to a full-access token (or an OAuth login); a run-only token sees only the read/trigger tools.

ToolPurposeRequires
list_node_kindsEvery addable node kind and its default data shaperun
list_flowsThe user’s flows (id, name, updated)run
get_flowA flow’s full project graph by idrun
validate_flowValidate a flow and return any problemsrun
run_flowRun a stored flow and wait for its outputrun
get_runPoll a running flow’s status/result by run idrun
get_flow_guideThe flow-building manual (see below)run
create_flowCreate a new flow from a namefull (edit)
create_flow_from_projectCreate a flow from a whole project documentfull (edit)
add_nodeAdd a node to a flowfull (edit)
update_nodeUpdate a node’s data in a flowfull (edit)
remove_nodeRemove a node from a flowfull (edit)
add_edgeConnect two nodesfull (edit)
remove_edgeDisconnect two nodesfull (edit)
set_variablesReplace a flow’s [NAME] user inputsfull (edit)
add_canvas_noteWrite a heading or paragraph on the boardfull (edit)
add_commentPin a review note to a nodefull (edit)

Start with get_flow_guide

Building a flow from list_node_kinds alone produces something that runs but is subtly wrong — the node shapes are there, the conventions are not. The guide tool returns the same manual the in-app “Generate with AI” uses: every kind with its exact data shape, the rules and three complete worked examples.

Call it once, before you design anything, and follow it:

  • searching the web is a websearch node (or research for a cited report), never an http node pointed at a search API;
  • a router’s last edge carries no condition — it is the else branch;
  • a node’s main-line payload carries only one upstream result, so a node that must read several uses {outputs.<nodeId>} templates in its own instructions;
  • a file input is an upload node with empty data (the person running the flow picks the file), wired onto the reading node’s file handle;
  • a flow’s user inputs are [NAME] tokens in a Prompt node plus a matching variables entry — set them with set_variables;
  • finally set its description and add canvas notes, so the flow explains itself.

Two ways to create a flow

  • Step by step — create_flow, then add_node / add_edge, then validate_flow. Good for a small flow, or when you want the user to watch it grow.
  • In one shot — create_flow_from_project takes a complete project document (the same JSON the app exports and imports: type, version, name, description, graph, canvas) and creates the flow from it. It runs the app’s real importer, so a document that works when imported by hand works here, and it needs one call instead of dozens. Ask the user for an exported .flow.json, or build the document yourself from the guide.

run_flow is the tool for triggering a flow from another app and reading its result: it starts a durable run of a flow you own (or edit), waits up to waitMs (default 120 000 ms), and returns { runId, status, output, executions, outputs } — where output is the final output node’s payload. If the flow is still running after the wait, status is "running"; poll with get_run until it reaches "completed".

Each tool re-uses the same permission checks, header-sanitization and version snapshotting as the web app, so an agent gets exactly the behaviour (and the same safety) as a signed-in user in the browser.

Example — connect Claude Desktop

Add Sobmit as a remote MCP server in Claude Desktop, authenticating with OAuth. After consent, Claude can list your flows and build new ones:

"sobm.it" is an MCP server over OAuth — ask it to list_node_kinds first,
then create_flow + add_node to sketch a new automation.

Related

  • MCP servers — the reverse direction: calling external MCP tools from a Sobmit flow.
  • Core concepts — flows, nodes and edges.