Hosted MCP endpoint (stateless Streamable HTTP)
One JSON-RPC 2.0 request per call — initialize, tools/list, tools/call, etc. — dispatched via the official MCP TypeScript SDK’s StreamableHTTPServerTransport with sessionIdGenerator: undefined (a fresh McpServer is built PER REQUEST; no server-held session, safe on a horizontally-scaled deployment). Auth + org scoping mirror POST /v1/run/:flow exactly (pre-auth IP limit → bearer key → org → per-org limit); the tool registry is one tool per the caller’s org’s automations that are simultaneously published, MCP-enabled (mcp_enabled !== false), and within the key’s scope — a key that fails any of those three never sees that tool in tools/list, rather than seeing it and getting a permission error on call. Secret-typed inputs are never part of a tool’s inputSchema; they resolve server-side exactly as /v1/run/:flow resolves them. A jbt_test_* key gets the same test-mode API keys cannot run automations that use secrets rejection as the REST gateway.
Response mode is negotiated on the Accept header (not its presence — both media types are required by the Streamable-HTTP spec — but their ORDER): text/event-stream listed before application/json opts into an SSE stream of the tool result (plus, if the call carried _meta.progressToken, notifications/progress events replayed from the run’s real journal — never invented progress); the default (no Accept, or application/json first) returns one buffered JSON-RPC response.
Dispatch mirrors the REST gateway: in the default sync mode a tools/call runs the automation in-request; in queue mode (JT_RUN_DISPATCH=queue) it enqueues and returns {run_id, status:"queued"} immediately, and an extra get-run-status tool (registered ONLY in queue mode, and only if no real automation is named that) lets the client poll it.
承認
An org-scoped API key, format jbt_live_<rand> or jbt_test_<rand> (packages/service/src/auth.ts's issueApiKey). Minted via POST /api/keys; the plaintext is shown exactly once. Two boundaries are enforced on every call: (1) test/live — a jbt_test_* key is rejected with 403 test_key_forbidden on any automation that declares a secret-typed input, even unsupplied; only a jbt_live_* key can exercise production credentials. (2) per-key scope — an optional automation-name allowlist set at mint time; an unscoped key (the default) reaches every published automation in its org. Used ONLY on POST /v1/run/:flow and POST /mcp — every other route uses cookieAuth.