Automat Workflows MCP Server
OfficialClick on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@Automat Workflows MCP Serverlist my workflows"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Robotic Workflows MCP Server
Claude Build Day submission. A remote MCP server that lets a Claude agent build, deploy, run, and debug real RPA workflows on Automat — browser/API automations that then run on their own schedule, deterministically, with zero LLM tokens per run.
The agent writes the automation once (using tokens); the workflow then runs forever on a cron with no tokens per run. Token-cheap to create, token-free to operate.
The brief
Problem. Back-office/RPA automations take days to build and stay locked inside builder UIs. An AI agent can do a task once, but re-doing it every run burns tokens and isn't repeatable or schedulable.
Who it's for. Anyone with a recurring browser/API task — ops, back-office, founders — and the agents acting on their behalf.
Done looks like. From a chat/agent: "build a workflow that does X on a schedule." The agent authors it through this MCP server, deploys it live, runs it, and returns a recording — and it keeps running on its schedule with no tokens.
Related MCP server: mmc-mcp
What we built at Build Day
This repo is the agent-facing layer: one Vercel Function (api/mcp.ts) exposing 32 MCP tools that forward to Automat studio's project-scoped agent API. Built during the event:
Full tool surface — discover (
get_docs,get_workflow_schema,list_*), build (create_workflow,edit_workflowcomposite-patch model,read_workflow), manage (versions, lifecycle, schedules), run & debug (run_workflow,get_runwith timeline/io/recording,cancel_run), plus secrets, resources, extractors, and HITL.get_docs— serves the runtime authoring model (code-node globals,$('NodeName'),fetch, worked examples) so an agent writes workingcodenodes with no source access.Pass-through auth — the caller's project key is forwarded per request; no secrets stored in this public repo.
(The backend it forwards to — studio's
/api/agent/*— was built in parallel in our private studio repo.)
Demo — "Sauce Demo Shopper"
A Claude agent built this through the MCP server: a deterministic Playwright code node that logs into saucedemo.com, adds an item, and checks out — recorded, ~9s/run, 0 tokens per run, deployed active and schedulable.
Authored via
create_workflow+edit_workflow, executed viarun_workflow, recording fetched viaget_run(include:["recording"]).When the live run hit a native Chrome "breached-password" dialog that swallowed clicks, the agent reproduced it with Chrome DevTools and rewrote the clicks as
page.evaluate(() => el.click())— self-corrected, then re-ran green.
Try it / verify
Live, and "done" is verifiable by the model with no human in the loop:
Responding URL —
https://workflows.runautomat.com/api/mcpanswerstools/listandtools/callover Streamable HTTP.Connect any MCP client with a project key (see Connect a client) and run the loop:
get_docs→create_workflow→run_workflow→get_run.Acceptance checklist (rubric). (1) endpoint lists 32 tools; (2)
create_workflow+edit_workflow(patch)each save a new version; (3)run_workflow→get_runreturnsstatus:"completed"with structuredoutput; (4) a browser workflow returns arecordingUrl.
How Claude built it (Opus 4.8)
Opus 4.8 drove the whole build: it explored the studio + runtime repos to design the tool schemas, grounded the descriptions in MCP best practices, and self-verified — running a full stress test across every tool and real workflow runs through its own tools, then fixing a live browser failure with Chrome DevTools. It's repeatable: push to main auto-deploys, and get_docs + the tool surface let any agent rerun the build loop on a brand-new task.
Endpoint
https://workflows.runautomat.com/api/mcpStreamable HTTP, stateless. The Vercel default URL (https://robotic-workflows-mcp-server.vercel.app/api/mcp) also resolves.
Authentication
Pass-through. The caller supplies a project-scoped studio key (ak_…); the server forwards it to the studio API per request. No keys are stored or committed. The key is read three ways (checked in order):
Source | Use |
| Claude web/desktop connector (its UI has no header field) |
| generic clients |
| Claude Code CLI |
Configuration (Vercel env)
Var | Purpose |
| Origin of the studio agent API. Studio preview URLs change per deploy — update this each studio redeploy (or point at a stable alias once preview protection is lifted). |
| Optional — only if the studio deployment is protected. |
Connect a client
Replace ak_… with your project-scoped studio key.
Claude web / desktop — Settings → Connectors → Add custom connector → URL:
https://workflows.runautomat.com/api/mcp?api_key=ak_…Claude Code
claude mcp add --transport http automat \
"https://workflows.runautomat.com/api/mcp?api_key=ak_…"MCP Inspector
npx @modelcontextprotocol/inspector
# Streamable HTTP → https://workflows.runautomat.com/api/mcp?api_key=ak_…Development
npm install
npm run dev # vercel dev → http://localhost:3000/api/mcp
npm run inspector # MCP Inspector
vercel --prod # deploy (requires vercel login)Stack
mcp-handler (wrapping @modelcontextprotocol/sdk) as a single Vercel Function — no framework. The whole server is api/mcp.ts. It serves /api/mcp; a /mcp rewrite is not used because it collides with Vercel's built-in /api routing guard.
Tools
Live reference for the 32 tools. Each forwards to the studio agent API (STUDIO_API_BASE_URL + /api/agent/*), passing the caller's project-scoped key; the project is resolved from the key. The build/edit flow mirrors studio's own builder agent: read_workflow → edit_workflow(patch) with server-side validation.
Conventions
Transport. Streamable HTTP (stateless), at
https://workflows.runautomat.com/api/mcp.Scope. One key = one project. No tool takes a
projectId.Workflow definition. The
@automat/runtimeWorkflowSchema:{ name, description?, instructions?, notes?, settings, nodes[], edges[], sessionFields?, inputSchema?, outputSchema?, helpers?, files?, runtimeVersion? }. Nodes are a discriminated union ontype(start,end,block,decision,document,hitl). Edges are{ from, to, handle? }. Callget_workflow_schemafor the exact shape.Errors. On failure a tool returns result text
{ "error": { "code", "message", "issues"? } }. Codes:not_found,validation_failed,version_conflict,conflict,lifecycle_gated,forbidden,bad_request,rate_limited,unauthorized,internal_error.issues[]accompaniesvalidation_failed.Pagination. List tools take
limit(default 25, max 100) andcursor, and return{ items, nextCursor }(the cursor wraps the API's page number).
Each tool lists its input, output, and the backing /api/agent call.
Context & schema
get_docs
Authoring guide — call first. How to write code/decision nodes: globals ($('NodeName'), fetch, secrets, page/context, logger), async/return semantics, node types, browser/recording, schedules, and worked examples.
Input:
{ topic?: 'overview'|'codeNodes'|'nodeTypes'|'browser'|'secrets'|'schedules'|'examples' }Output: the docs (all sections, or one
topic)
list_runtime_versions
Input: none
Output:
{ versions: [{ version, isLatest }], note }Runtime-version selection isn't exposed by the API; returns
latest.
get_workflow_schema
Input:
{ runtimeVersion?: string }(defaultlatest)Output:
{ runtimeVersion, jsonSchema }→
GET /api/agent/schema
Workflows
list_workflows
Input:
{ status?, search?, limit?, cursor? }(status: development | preview | active | disabled)Output:
{ items: [{ workflowId, name, description, status, activeVersionId, apiEnabled, apiUrlSlug, sessionCount, lastRunAt, updatedAt }], nextCursor }→
GET /api/agent/workflows(status/searchfiltered client-side)
create_workflow
Input:
{ name, description?, definition?, runtimeVersion? }— omitdefinitionfor a minimalstart → endscaffoldOutput:
{ workflowId, versionId, versionNumber, status }→
POST /api/agent/workflows
copy_workflow
Input:
{ workflowId, name? }Output:
{ workflowId, name }Client-side: reads the source's active definition, then
create_workflowwith it. Schedules/runs not copied.
read_workflow
Input:
{ workflowId, view: 'graph' | 'node' | 'full', nodeName? }(nodeNamerequired fornode)Output:
{ _meta: { workflowId, versionId, versionNumber, status, apiEnabled, apiUrlSlug }, ... }—graph(nodes/edges + metadata, no node code),node(one node),full(entire definition). Pass_meta.versionIdtoedit_workflow.→
GET /api/agent/workflows/{id};graph/nodeviews derived client-side.
update_workflow
Input:
{ workflowId, name?, description?, status?, apiEnabled?, apiUrlSlug? }Output: the updated workflow
status: activeneeds a published version;disabledauto-pauses schedules. →PATCH /api/agent/workflows/{id}
delete_workflow
Input:
{ workflowId }· Output:{ success: true }· soft delete →DELETE /api/agent/workflows/{id}
Editing
edit_workflow
Input:
{ workflowId, patch, expectedActiveVersionId? }patch = { nodes?: { add?: Node[], update?: [{ name, patch }], remove?: string[] }, edges?: { add?: Edge[], remove?: Edge[] }, // any top-level WorkflowSchema field: settings deep-merges, others replace }Output:
{ ok: true, versionId, versionNumber, deduped }or{ error: { code, message, issues? } }Client reads the active definition, applies the patch (order:
nodes.remove→nodes.add→nodes.update[rename rewrites edges] →edges.remove→edges.add→ top-level), then PUTs the full definition. The server validates → a new version (one edit, one version).expectedActiveVersionId(fromread_workflow's_meta) gives optimistic concurrency. →GET+PUT /api/agent/workflows/{id}
Versions
list_versions
Input:
{ workflowId, limit?, cursor?, named?, source? }Output:
{ items: [{ versionId, versionNumber, name, source, createdAt }], nextCursor, activeVersionId }→GET /api/agent/workflows/{id}/versions
get_version
Input:
{ workflowId, versionId }· Output:{ versionId, versionNumber, name, source, createdAt, definition }→GET …/versions/{versionId}
revert_to_version
Input:
{ workflowId, versionId, expectedActiveVersionId? }· Output:{ versionId, versionNumber, revertedFromVersionNumber }· non-destructive (appends a new version) →POST …/versions/{versionId}/revert
Schedules
All schedules run in UTC. A workflow may have many; run input comes from a linked project resource (inputResourceName), gated against the workflow's inputSchema.
list_schedules
Input:
{ workflowId }· Output:{ items: [{ scheduleId, name, recurrenceRule, startAt, status, nextFireAt, inputResourceName }] }
create_schedule
Input:
{ workflowId, recurrenceRule (RFC 5545 RRULE, UTC), name?, startAt? (UTC), enabled?, inputResourceName? }—enabled: falsecreates it pausedOutput:
{ scheduleId }→POST /api/agent/workflows/{id}/schedules
update_schedule
Input:
{ workflowId, scheduleId, recurrenceRule?, name?, startAt?, enabled?, inputResourceName? }—enabledmaps to status active/pausedOutput:
{ scheduleId }→PATCH …/schedules/{scheduleId}
delete_schedule
Input:
{ workflowId, scheduleId }· Output:{ success: true }→DELETE …/schedules/{scheduleId}
Runs
run_workflow
Input:
{ workflowId, input?, environment? }(environment: development | staging | preview | production, default production)Output:
{ sessionId, status: 'queued' }·inputvalidated againstinputSchema;lifecycle_gatedif disabled / no active version.environmentis sent as a query param. →POST /api/agent/workflows/{id}/run
list_runs
Input:
{ workflowId?, status?, limit?, cursor? }· Output:{ items: [{ sessionId, workflowId, status, source, startedAt, endedAt, durationMs }], nextCursor }→GET /api/agent/sessions
get_run
Input:
{ sessionId, include?: ('timeline' | 'io' | 'logs' | 'recording')[], logsCursor? }Output:
{ sessionId, workflowId, versionId, status, source, input, output, startedAt, endedAt, durationMs }plus, when requested:timeline[{ name, type, status, startedAt, endedAt, durationMs }],nodeIO[{ name, input, output }],recordingUrl,logs{ entries, nextCursor }.timeline/io ←
GET /sessions/{id}/nodes; recording ← the session; logs ←/sessions/{id}/logs(best-effort — returnsnull+logsNoteuntil that endpoint is deployed).
cancel_run
Input:
{ sessionId }· Output:{ success: true, status: 'canceled' }→POST /sessions/{id}/stop
Human-in-the-loop
list_hitl_tasks
Input:
{ sessionId?, status?, limit?, cursor? }(status: pending | completed | expired)Output:
{ items: [{ taskId, sessionId, workflowId, nodeName, prompt, actions, isApproval, fields, status, createdAt, expiresAt }], nextCursor }→GET /api/agent/hitl/tasks
complete_hitl_task
Input:
{ taskId, action, fields? }· Output:{ success: true }→POST /api/agent/hitl/tasks/{taskId}/complete
Secrets
Project-scoped. Values are never returned.
list_secrets
Input:
{ lifecycle?, limit?, cursor? }· Output:{ items: [{ key, last4, lifecycle, updatedAt }], nextCursor }
set_secrets
Input:
{ secrets: [{ key, value, description?, lifecycle? }] }· Output:{ updated: [keys] }· upsert by key (resolves key→id, then PUT or POST)
delete_secret
Input:
{ key }· Output:{ success: true }· resolves key→id
Resources
Data resources, referenced by name from block/document nodes and schedule inputs. Each has a lifecycle (development | preview | active).
list_resources
Input:
{ kind?, lifecycle?, search?, limit?, cursor? }· Output:{ items: [{ name, kind, description, lifecycle, updatedAt }], nextCursor }
get_resource
Input:
{ name, lifecycle? }· Output:{ name, kind: 'data', value, description, lifecycle, updatedAt }
set_resource
Input:
{ name, value, description?, lifecycle? }· Output:{ name }· upsert by name; omittinglifecycleseeds all stages. File-resource uploads not supported.
delete_resource
Input:
{ name, lifecycle? }· Output:{ success: true }
Extractors
Read-only. document nodes reference an extractorId; authoring is not exposed.
list_extractors
Input:
{ search?, limit?, cursor? }· Output:{ items: [{ extractorId, name, activeVersionId, description }], nextCursor }
get_extractor
Input:
{ extractorId, view?: 'summary' | 'full' }· Output:{ extractor }
Known gaps
Session logs: studio
/api/agent/sessions/{id}/logsis pending;get_runlogs returnnull+ a note until it's deployed.Schedules are UTC-only.
File-resource uploads and extractor authoring are not yet available.
Roadmap
Per-project API keys (today the caller's project-scoped studio key is forwarded as-is).
Session logs + recording surfaced once the studio endpoint lands.
Extractor authoring and file-resource uploads.
This server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Latest Blog Posts
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/AutomatAI/robotic-workflows-mcp-server'
If you have feedback or need assistance with the MCP directory API, please join our Discord server