HeadlessOps
MCP Setup

MCP Setup Overview

Connect AI agents to HeadlessOps via the Model Context Protocol. Full reference for MCP tools, OAuth 2.1 authentication, workspace resolution, push-run execution modes, and synchronous run output.

MCP Setup (AI Agents)

HeadlessOps provides a native Model Context Protocol (MCP) server that lets AI agents (Claude Desktop, Cursor, Roo Code, and others) interact with the platform directly — reading, writing, deploying, and running integrations without leaving the IDE.

What Is MCP?

The Model Context Protocol is an open standard for connecting AI assistants to external tools and data sources. HeadlessOps implements an MCP server that exposes platform operations as typed tools callable by any MCP-compatible AI client.

With MCP connected, your AI agent can:

  • List, create, and deploy integrations
  • Push code files and trigger test runs
  • Read run logs and debug failures
  • Manage credentials and data stores
  • Browse the workspace knowledge base
  • List labels accessible to the caller

Authentication: OAuth 2.1 + PKCE

The MCP server uses OAuth 2.1 with PKCE (Proof Key for Code Exchange) for authentication. This is the recommended flow for public clients without a client secret.

OAuth is user-level — each user authenticates with their own HeadlessOps account and receives an individual access token. This design supports multiple users connecting their own AI clients independently, each acting under their own identity and permissions.

AI Client                HeadlessOps MCP
    │                          │
    │─── OAuth authorize ─────▶│
    │◀── redirect to browser ──│
    │                          │
    │  [User logs in + approves scopes in browser]
    │                          │
    │─── code + verifier ─────▶│
    │◀── access token ─────────│
    │                          │
    │─── tool calls (Bearer) ─▶│
    │◀── tool results ─────────│

Steps

  1. The AI client initiates an OAuth authorization request with a code challenge
  2. The user logs in to HeadlessOps in the browser and grants the requested scopes
  3. The authorization code is exchanged for an access token
  4. The access token is included in all subsequent MCP tool calls

MCP Server URL

https://app.headlessops.ai/mcp

All MCP-compatible clients connect to this single endpoint. There is no separate configuration per workspace — workspace selection happens at the tool call level (see below).

MCP Tool Scopes

ScopeDescription
mcp:toolsCore tools: workspaces, knowledge base, data stores, labels
integrations:readList and read integrations and their files
integrations:writeCreate, update, push, deploy, and run integrations
runs:readList runs and read step logs
runs:writeTrigger manual runs
credentials:useList, create, and manage credentials

Label-Based Access and MCP

MCP tool calls respect the caller's label grants, the same way direct API calls do.

  • integrations_list returns only integrations the caller has a label grant for (or all integrations for ADMINs)
  • credentials_list returns only credentials the caller has a label grant for
  • knowledge_docs_list returns only docs the caller has a label grant for
  • labels_list returns all labels in the workspace the caller has access to

Important for integration builders: An integration or credential must be labeled before non-admin members or AI agents (using non-admin API keys) can access it. Unlabeled resources are admin-only. See Labels & Permissions for the full guide.

OAuth for Multiple Users

OAuth is user-level authentication — each user who connects an AI client via MCP authenticates independently with their own HeadlessOps account. This makes OAuth the right choice when multiple users need to connect: every user gets their own token, their own identity, and their own permission scope.

How Each User Connects

  1. The user configures their AI client with the MCP server URL
  2. On first use, their client opens a browser window for login
  3. The user logs in to their HeadlessOps account and grants access
  4. An access token is issued to that user's session — no sharing required

Because tokens are tied to individual users, each person's AI client acts under their own role and label grants automatically.

Workspace Resolution

When using the MCP via OAuth, your token grants access to all workspaces you are a member of.

Always call workspaces_list first to discover available workspaces and their IDs:

Tool: workspaces_list
Args: {}

Response example:

[
  { "id": "ws_abc123", "name": "Client A", "slug": "client-a", "description": "Production CRM automation for Client A" },
  { "id": "ws_def456", "name": "Client B", "slug": "client-b", "description": "Staging environment for Client B integrations" }
]

Resolve workspaceId in this priority order:

  1. Config file — if iterator/iterator.config.json exists in the repo with a workspaceId field, use that value.
  2. Repo name match — match the current repo/folder name against workspace slugs.
  3. Explicit user input — ask the user to specify if ambiguous.
  4. Error — if resolution fails, return: "workspaceId is required — call workspaces_list to find your workspace ID"

Never rely on alphabetical order. Workspace IDs are CUIDs — alphabetical fallback will silently target the wrong workspace.

iterator.config.json Convention

Create this file at iterator/iterator.config.json in your repository to pin a workspace:

{
  "workspaceId": "ws_abc123"
}

This is the canonical source of truth for workspaceId in the repo. All MCP tool calls automatically resolve to this workspace when this file is present.

Push-Run Execution Modes

integration_files_push_run supports two execution modes controlled by the optional mode parameter. Choosing the right mode lets agents balance responsiveness against the need for immediate output.

Default — Fire-and-Forget (Asynchronous)

Omit mode (or leave it unset) to trigger an asynchronous run. The server pushes the files, creates a run, and returns the runId immediately. The run executes in the background and the agent polls for completion separately.

{
  "name": "my-automation",
  "files": {
    "integration.yaml": "...",
    "step.ts": "..."
  },
  "payload": {}
}

Response (201 Created):

{ "runId": "run_abc123", "status": "RUNNING" }

After receiving the runId, poll for the result using runs_list_get or GET /api/runs/:runId.

Use fire-and-forget when:

  • The run is long-running or its output is large.
  • You want non-blocking execution.
  • You plan to inspect logs afterward via runs_list_get or runs_steps.

mode=sync — Synchronous Execution (Wait for Result)

Pass "mode": "sync" to wait for the run to complete and receive the output directly in the response body. The connection is held open until the run finishes, then the full result is returned in a single response.

{
  "name": "my-automation",
  "files": {
    "integration.yaml": "...",
    "step.ts": "..."
  },
  "payload": {},
  "mode": "sync"
}

Successful response (200 OK):

{
  "runId": "run_abc123",
  "status": "SUCCEEDED",
  "output": { "result": "ok", "records_processed": 42 }
}
  • output contains the value passed to ctx.output() in the final step, or null if ctx.output() was never called.
  • status reflects the final run status: SUCCEEDED, FAILED, CANCELLED, etc.

Use mode=sync when:

  • The run is short (seconds, not minutes) and you need the output immediately.
  • You want to avoid a separate polling loop.
  • The output payload is small (under 50 KB).

50 KB Output Guard — Truncation Handling

When the run output exceeds 50 KB, the server does not return the full payload inline to avoid flooding the agent's context window. Instead, the response contains a truncation notice:

{
  "runId": "run_abc123",
  "status": "SUCCEEDED",
  "output": null,
  "truncated": true,
  "warning": "Run output exceeds 50KB size limit (73KB). Use runs_steps with outputPath to download full logs instead."
}

When you receive truncated: true, download the full output using runs_steps with an outputPath to save logs to a local file:

Tool: runs_steps
Args: { "runId": "run_abc123", "outputPath": "/tmp/run-abc123-logs.json" }

This keeps the agent context clean and prevents token overflow on large automations.

Available MCP Tools Reference

All workspace-scoped tools accept an optional workspaceId argument. Always pass it explicitly.

Workspace Tools

ToolOperationScope
workspaces_listList all workspaces the user has access tomcp:tools
workspaces_createCreate a new workspacemcp:tools
workspace_members_listList members and pending invitesmcp:tools
workspace_members_inviteInvite a user by email and rolemcp:tools

Label Tools

ToolOperationScope
labels_listList all labels in the workspace the caller has access tomcp:tools
label_grants_listList all label grants for a specific workspace member, including any expiresAt value (ADMIN only)mcp:tools
label_grants_createGrant a workspace member access to a label (read or write). Accepts an optional expiresAt for a temporary, time-boxed grant. Auto-creates the label if it does not exist. (ADMIN only)mcp:tools
label_grants_deleteRevoke a label grant from a workspace member by grant ID (ADMIN only)mcp:tools

Integration Tools

ToolOperationScope
integrations_listList integrations (supports search, filter by trigger/label). Results are scoped to the caller's label grants and automatically returned in a compact form (core metadata only, no code/deployed files) to keep responses small for AI agents.integrations:read
integrations_getGet a single integration by nameintegrations:read
integrations_createCreate a new integrationintegrations:write
integrations_updateUpdate integration settings (trigger, schedule, webhook, requirements)integrations:write
integrations_deleteDelete an integrationintegrations:write
integrations_activateActivate an integrationintegrations:write
integrations_deactivateDeactivate an integrationintegrations:write
integrations_cloneClone an integrationintegrations:write
integrations_labelsSet labels on an integrationintegrations:write

File & Deployment Tools

ToolOperationScope
integration_files_listList files (read mode: snippets; download mode: full content)integrations:read
integration_files_pushPush files without running (syncs packagesrequirements from YAML)integrations:write
integration_files_push_runPush files and trigger a run atomically. Supports mode=sync for synchronous output.integrations:write
integration_files_deploySnapshot current files as a versioned deploymentintegrations:write

Run Tools

ToolOperationScope
runs_list_getList runs for an integration (with step logs)runs:read
runs_createTrigger a manual run with an optional payloadruns:write
runs_cancelCancel a running runruns:write

Credential Tools

ToolOperationScope
credentials_listList credentials the caller has access to (scoped by label grants for non-admins)credentials:use
credentials_createCreate a new API key or OAuth2 credentialcredentials:use
credentials_updateUpdate a credential's value or metadatacredentials:use
credentials_deleteDelete a credentialcredentials:use
credentials_apps_listList available credential app templatescredentials:use
credentials_app_createCreate a credential from an app templatecredentials:use
credentials_invite_createGenerate a public invite link for external credential fillcredentials:use

Data Store Tools

ToolOperationScope
data_stores_listList all data storesmcp:tools
data_stores_createCreate a new data store with column schemamcp:tools
data_stores_deleteDelete a data store (permanent)mcp:tools

Knowledge Base Tools

ToolOperationScope
knowledge_docs_listList documents the caller has access to (scoped by label grants for non-admins)mcp:tools
knowledge_docs_getGet the full content of a documentmcp:tools
knowledge_docs_createCreate a new Markdown documentmcp:tools
knowledge_docs_updateUpdate an existing documentmcp:tools
knowledge_docs_deleteDelete a documentmcp:tools

Local MCP Proxy (Required for folderPath)

The @headlessops-ai/mcp npm package provides a local proxy that:

  • Sits between the AI client (stdio) and the remote /mcp endpoint
  • Handles OAuth 2.1 + PKCE authentication via mcp-remote
  • Resolves folderPath parameters to inline file contents from the local filesystem

Install the Proxy

npm install -g @headlessops-ai/mcp

This installs the headlessops-mcp binary globally.

Configure Your MCP Client

Instead of pointing directly at the remote MCP URL, use the headlessops-mcp command:

{
  "command": "headlessops-mcp",
  "args": ["--mcp-url", "https://app.headlessops.ai/mcp"]
}

Once the proxy is running, folderPath works transparently — the proxy reads files locally and forwards them to the remote server via OAuth.

Notes

  • macOS Homebrew Node: If you installed Node via Homebrew, the binary lands at /opt/homebrew/bin/headlessops-mcp. Use the absolute path if your client doesn't inherit the shell PATH.
  • Authentication: Auth is handled automatically on first run via browser OAuth flow. No manual token management is needed.
  • folderPath requirement: folderPath support requires the local proxy. Plain URL connections directly to https://app.headlessops.ai/mcp cannot resolve local filesystem paths.

If you do not have the proxy set up, use the files inline mode instead. Pass the file content directly in the tool call payload.

Next Steps