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.
Automat Workflows MCP Server
A remote MCP server that lets AI agents build, run, and manage Automat RPA workflows — the same operations humans perform in the studio.
The server is a thin forwarder: each tool calls an API-key-authenticated, single-project endpoint in the studio app (the "thin client"), which reuses studio's existing validation, versioning, and execution code.
Status: all 31 tools are implemented as schema-complete stubs — each has its real input schema and returns spec-shaped data marked
_stub: true; handlers forward to the thin client as it comes online. (Connection liveness uses MCP's built-in protocol-level ping, so there is nopingtool.)
Endpoint
https://workflows.runautomat.com/api/mcpStreamable HTTP, stateless. The Vercel default URL (https://robotic-workflows-mcp-server.vercel.app/api/mcp) also resolves.
Related MCP server: PyMCPAutoGUI
Authentication
A single shared API key, accepted three ways (checked in order):
Source | Use |
| Claude web/desktop connector (its UI has no header field) |
| generic clients |
| Claude Code CLI |
The v1 key is hardcoded in
api/mcp.tsand committed to this repo. It guards stub tools only. Before the tools touch real data, setMCP_API_KEYin the Vercel project environment to override it.
Connect a client
Replace <KEY> with the API key.
Claude web / desktop — Settings → Connectors → Add custom connector → URL:
https://workflows.runautomat.com/api/mcp?api_key=<KEY>Claude Code
claude mcp add --transport http automat \
"https://workflows.runautomat.com/api/mcp?api_key=<KEY>"MCP Inspector
npx @modelcontextprotocol/inspector
# Streamable HTTP → https://workflows.runautomat.com/api/mcp?api_key=<KEY>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
The tool contract — the source of truth for both this server (api/mcp.ts) and the studio thin client that backs each tool. The design mirrors studio's own builder agent (studio/lib/builder/ai/tools.ts): a read_workflow + edit_workflow(patch) loop with server-side validation.
Conventions
Transport. Streamable HTTP (stateless), at
https://workflows.runautomat.com/api/mcp.Integration. The MCP server is a thin forwarder. Each tool calls an API-key-authenticated, single-project endpoint in studio that reuses existing code (
WorkflowSchema,applyWorkflowPatch,runWorkflowWithGates, the version RPCs). The MCP server holds no database credentials and no@automat/runtimeinternals.Auth & scope. One API key maps to one
project_id. No tool takesprojectId; the thin client resolves it from the key and enforces org/project RLS.IDs. All UUIDs:
workflowId,versionId,sessionId,scheduleId,taskId.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;api/processreserved). Edges are{ from, to, handle? }.Errors. On failure a tool returns a result whose text is
{ "error": { "code", "message", "issues"? } }. Codes:not_found,validation_failed,version_conflict,duplicate_name,lifecycle_gated,forbidden,bad_request,rate_limited.issues[]accompaniesvalidation_failed.Pagination. List tools take
limit(default 25, max 100) andcursor, and return{ items, nextCursor }.Payload size. Large data (logs, full definitions, run I/O) is opt-in or paginated.
Each tool below lists its input, output, and the studio code the thin client should reuse.
Context & schema
list_runtime_versions
Runtime versions a workflow can pin to. Needed only to choose a non-default version; get_workflow_schema and create_workflow default to latest.
Input: none
Output:
{ versions: [{ version, isLatest, releasedAt }] }Reuse: runtime version registry.
get_workflow_schema
The workflow/node JSON schema, node catalog, and examples — how the agent learns to construct definitions and patches.
Input:
{ runtimeVersion?: string }(defaultlatest)Output:
{ runtimeVersion, jsonSchema, nodeCatalog: [{ type, summary, requiredFields, optionalFields, example }], edgeRules, examples: [{ title, definition }] }Reuse: serialize
WorkflowSchema/NodeSchemato JSON Schema at the requested version. The in-studio agent reads the runtime repo for this; external agents can't, so the thin client serves it.
Workflows
list_workflows
Input:
{ status?, search?, limit?, cursor? }(status: development | preview | active | disabled)Output:
{ items: [{ workflowId, name, description, status, activeVersionId, apiEnabled, apiUrlSlug, sessionCount, updatedAt }], nextCursor }Reuse:
GET /api/workflows.
create_workflow
Input:
{ name, description?, definition?, runtimeVersion? }—runtimeVersiondefaults tolatest; omittingdefinitioncreates astart → endscaffold.Output:
{ workflowId, versionId, versionNumber, status: 'development' }Reuse:
createWorkflowWithVersionViaRpc(); validate withWorkflowSchema.
copy_workflow
Clone a workflow (v1 = clone of the source's active version) into the same project. Schedules and runs are not copied.
Input:
{ workflowId, name? }Output:
{ workflowId, name }Reuse:
POST /api/projects/[projectId]/workflows/[workflowId]/clone.
read_workflow
Read the active workflow at one of three granularities.
Input:
{ workflowId, view: 'graph' | 'node' | 'full', nodeName? }(nodeNamerequired fornode)Output:
{ _meta: { workflowId, versionId, versionNumber, status, apiEnabled, apiUrlSlug }, ... }graph: metadata, nodes (name/type/position + routing fields), edges — no per-node codenode: the named node's full contentfull: the entire definition
Reuse:
buildGraphView+ the workflow row.
update_workflow
Workflow metadata, lifecycle, and API-trigger config — not the graph (use edit_workflow).
Input:
{ workflowId, name?, description?, status?, apiEnabled?, apiUrlSlug? }Output:
{ workflowId, name, description, status, apiEnabled, apiUrlSlug }Reuse:
PATCH /api/workflows/[workflowId].Notes:
status: 'active'requires anactiveVersionId(elselifecycle_gated). Moving todisabledauto-pauses schedules.name/descriptionalso live in the definition; keep the row and active definition consistent.
delete_workflow
Input:
{ workflowId }Output:
{ success: true }Reuse:
DELETE /api/builder/workflow(soft delete; cascades to sessions, schedules, channels).
Editing
edit_workflow
Apply a composite patch to the active definition. Validates against WorkflowSchema; on success, saves a new immutable version (one edit, one version); on failure, returns issues[]. There is no separate save tool.
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 }Apply order:
nodes.remove(drops touching edges) →nodes.add→nodes.update(renaming viapatch.namerewrites edges) →edges.remove→edges.add→ top-level.Output:
{ ok: true, versionId, versionNumber, deduped }or{ error: { code, message, issues? } }Reuse:
WorkflowPatchSchema+applyWorkflowPatch+validateAndUpdateWorkflow+create_workflow_version.Notes:
expectedActiveVersionIdgives optimistic concurrency against concurrent human edits.
Versions
list_versions
Input:
{ workflowId, limit?, cursor?, named?, source? }Output:
{ items: [{ versionId, versionNumber, name, source, author, createdAt, isActive }], nextCursor, activeVersionId }Reuse:
GET …/workflows/[workflowId]/versions.
get_version
Input:
{ workflowId, versionId }Output:
{ versionId, versionNumber, name, source, createdAt, definition }Reuse:
GET …/versions/[versionId].
revert_to_version
Non-destructive: appends the target definition as a new version.
Input:
{ workflowId, versionId, expectedActiveVersionId? }Output:
{ versionId, versionNumber, revertedFromVersionNumber }Reuse:
POST …/versions/[versionId]/revert.
Schedules
A workflow can have multiple schedules. A schedule uses an RFC 5545 recurrence rule; run input comes from a linked project resource (inputResourceName), validated against the workflow's inputSchema. Source: schedules/route.ts.
list_schedules
Input:
{ workflowId }Output:
{ items: [{ scheduleId, name, recurrenceRule, startAt, timezone, enabled, lastSession?: { id, status, createdAt, durationMs, errorMessage } }] }Reuse:
GET …/schedules.
create_schedule
Input:
{ workflowId, recurrenceRule, name?, startAt?, timezone?, enabled?, inputResourceName? }Output:
{ scheduleId }Reuse:
POST …/schedules(CreateScheduleBodySchema; checks the resource exists and gates input againstinputSchema).
update_schedule
Input:
{ workflowId, scheduleId, recurrenceRule?, name?, startAt?, timezone?, enabled?, inputResourceName? }(setenabledto pause/resume)Output:
{ scheduleId }Reuse:
PATCH …/schedules/[scheduleId].
delete_schedule
Input:
{ workflowId, scheduleId }Output:
{ success: true }Reuse:
DELETE …/schedules/[scheduleId].
Runs
run_workflow
Trigger a run of the active version.
Input:
{ workflowId, input?, environment? }(environment: development | staging | preview | production)Output:
{ sessionId, status: 'queued' }Reuse:
runWorkflowWithGates(). ValidatesinputagainstinputSchema;lifecycle_gatedif disabled or no active version.
list_runs
Input:
{ workflowId?, status?, limit?, cursor? }(status: pending | queued | executing | paused | completed | failed | canceled)Output:
{ items: [{ sessionId, workflowId, status, source, startedAt, endedAt, durationMs }], nextCursor }Reuse:
GET /api/sessions.
get_run
Run summary by default; deeper data via include.
Input:
{ sessionId, include?: ('timeline' | 'io' | 'logs' | 'recording')[], logsCursor? }Output:
{ sessionId, workflowId, versionId, status, source, input, output, outputSchemaValid, startedAt, endedAt, durationMs }plus, when requested:timeline:[{ name, type, status, startedAt, endedAt, durationMs }]nodeIO:[{ name, input, output }]logs:{ entries: [{ ts, level, nodeName, message }], nextCursor }recordingUrl: string (when browser recording is enabled)
Reuse:
sessions+session_attempts(recording_path) +session_nodes; logs from Trigger.dev.
cancel_run
Input:
{ sessionId }Output:
{ success: true, status: 'canceled' }Reuse: Trigger.dev cancel + session status update. Not a public endpoint today; the thin client must wrap it.
Human-in-the-loop
list_hitl_tasks
Input:
{ sessionId?, status?, limit?, cursor? }(status: pending | completed | expired)Output:
{ items: [{ taskId, sessionId, workflowId, nodeName, prompt, actions: [{ id, label }], isApproval, fields, status, createdAt, expiresAt }], nextCursor }Reuse:
GET /api/projects/[projectId]/hitl/tasks.
complete_hitl_task
Submit a human decision to resume a paused run.
Input:
{ taskId, action, fields? }Output:
{ success: true }Reuse:
POST /api/projects/[projectId]/hitl/complete(validates against the task's field schema; completes the wait token).
Secrets
Project-scoped. Values are never returned. Final shape pending the studio secrets manager (the one open item).
list_secrets
Input:
{ limit?, cursor? }Output:
{ items: [{ key, description?, updatedAt }], nextCursor }— names only
set_secrets
Upsert one or more secrets.
Input:
{ secrets: [{ key, value, description? }] }Output:
{ updated: string[] }— keys only
delete_secret
Input:
{ key }Output:
{ success: true }
Resources
Project resources are referenced by name from block/document nodes and schedule inputs.
list_resources
Input:
{ kind?: 'data' | 'file', search?, limit?, cursor? }Output:
{ items: [{ name, kind, description?, updatedAt }], nextCursor }— no valuesReuse:
project_resources.
get_resource
Input:
{ name }Output: data →
{ name, kind: 'data', value, description?, updatedAt }; file →{ name, kind: 'file', downloadUrl, sizeBytes, contentType, updatedAt }Reuse:
project_resources(signed URL for files).
set_resource
Upsert a data resource. File uploads are deferred (need a signed-URL or base64 path).
Input:
{ name, value, description? }— data resources onlyOutput:
{ name }Reuse:
project_resourcesupsert.
delete_resource
Input:
{ name }Output:
{ success: true }
Extractors
document nodes reference an extractor by extractorId. v1 is discover/reference only — authoring an extractor is a separate builder surface (its own definition, fields, and versions) and is deferred. When added, it should reuse this read/edit(patch) pattern.
list_extractors
Input:
{ search?, limit?, cursor? }Output:
{ items: [{ extractorId, name, activeVersionId, description? }], nextCursor }Reuse: studio extractors API.
get_extractor
Input:
{ extractorId, view?: 'summary' | 'full' }Output: summary (name, fields overview, activeVersionId) or the full definition.
Reuse: studio extractor read.
Thin-client contract
Expose API-key-authenticated, single-project endpoints backing the tools above, reusing existing studio code:
Capability | Reuse |
project from key | key → |
schema | serialize |
list/get/create/copy/delete workflow |
|
read (graph view) |
|
edit (patch) |
|
update metadata/lifecycle/api |
|
versions |
|
schedules |
|
runs |
|
HITL |
|
secrets | new secrets manager (shape TBD) |
resources / extractors |
|
New work required (not reusable as-is):
API-key auth middleware that resolves
project_idfrom a single-project key.A
cancel_runwrapper (no public endpoint today).get_workflow_schemaserving a runtime-version-pinned JSON schema.Secrets-manager endpoints (list = names only, set = upsert, delete).
Decisions
Resolved:
One edit, one version. Every
edit_workflowappends an immutable version; no coalescing.get_runis a single tool with anincludeparameter (logs paginated).No standalone
validate_workflow; validation is inline inedit_workflow.Tools only, no MCP resources, for v1.
list_runtime_versionsreplaces a project-context tool; schema/create default tolatest.Extractor authoring and file-resource uploads are deferred; v1 is discover/reference only. Data-resource CRUD is included.
Open:
Secrets shape — finalize against the studio secrets manager.
Roadmap
Wire tools to the studio thin client (replace the stubs).
Per-project API keys (v1 uses one shared key).
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
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