Guest Machines

Documentation over MCP

Use the public documentation MCP server, and manage remote MCP connectors through the Guest Machines API.

Guest Machines publishes its documentation as a remote Model Context Protocol server. Point any MCP client at it and your assistant can read these pages directly instead of guessing or scraping rendered HTML.

The server is public, unauthenticated, and read-only.

https://guestmachines.com/api/mcp

It speaks Streamable HTTP. No authentication or configuration beyond the URL is needed.

You can add this same URL as a custom app and grant it to a Guest Machines agent. Use Streamable HTTP and no authentication. Your workspace's outbound access policy still applies. The exception covers this exact endpoint; other platform URLs and hosting IPs remain protected.

Connect a client

For Claude Code:

claude mcp add --transport http gm-docs https://guestmachines.com/api/mcp

For clients configured through JSON, such as Claude Desktop, Cursor, or VS Code:

{
  "mcpServers": {
    "gm-docs": {
      "type": "http",
      "url": "https://guestmachines.com/api/mcp"
    }
  }
}

Tools

ToolPurpose
list_docsEvery page with its path, title, and summary
get_docOne page as Markdown, by path (developers/webhooks) or URL
search_docsFull-text search returning matching pages with excerpts

The documentation is small enough to browse. Listing the pages and reading the ones that look relevant generally beats searching, and the tool descriptions say so — expect an assistant to start with list_docs.

Without MCP

The same content is available over plain HTTP, which is often enough:

URLContents
/llms.txtAn index of every page, for AI agents
/llms-full.txtThe entire documentation as one Markdown file
/docs/<page>.mdA single page as Markdown

Any documentation URL also returns Markdown when the request sends Accept: text/markdown:

curl -H 'Accept: text/markdown' https://guestmachines.com/docs/developers/webhooks

Manage agent connectors through the API

The documentation server above is separate from the remote MCP connectors you register for agents. In the app, each connector is a custom app: members add their own from Apps → Add Custom App, admins add and publish them for the workspace and set each tool's limit in Settings → Apps, and an agent is granted one from its Tools page. The API below manages the same connectors. Delegated applications can list connectors, create a connector, and update a connector through the public API. Use a delegated token with only the mcp_servers:list, mcp_servers:read, mcp_servers:create, mcp_servers:edit, mcp_servers:delete, and mcp_servers:publish scopes it needs.

Connector registration and runtime availability are independent:

  1. Register or update a connector with /api/v1/mcp-servers.
  2. Optionally call /api/v1/mcp-servers/test to check the connection and list its tools.
  3. Read /api/v1/capabilities and the selected model in /api/v1/models.
  4. For provider-hosted execution, attach the connector only when that model is available, returns supports_mcp: true, and lists the connector's require_approval value in mcp_approval_policies. For local execution, use the catalog and attachment APIs below instead.

The test is advisory: it verifies that Guest Machines can connect and list tools. During a run, legacy SSE connectors are reached by the selected model provider directly, so a successful test does not guarantee that the provider can reach them.

Local execution

Set an attachment's execution_mode to local to have Guest Machines connect to the MCP server on the agent's behalf. The model never receives the connector's credentials or endpoint. Here, local describes where the MCP client runs, not where the remote server is hosted. This mode supports HTTPS Streamable HTTP, not legacy SSE or stdio.

  1. Call POST /api/v1/mcp-servers/{server_id}/sync-tools to create an immutable, versioned catalog of the remote tools and their schemas.
  2. Read GET /api/v1/mcp-servers/{server_id}/tools to page through that catalog.
  3. Create a local attachment with POST /api/v1/agents/{agent_id}/mcp-attachments, supplying server_id, catalog_version, and tool_grant. This works without first creating a provider-hosted attachment, including on supported Gemini models.
  4. For an existing attachment, read GET /api/v1/agents/{agent_id}/mcp-attachments/{attachment_id} for its current behavior version, then patch that URL with the version and finite list of remote tool names:
{
  "expected_attachment_behavior_version": 1,
  "execution_mode": "local",
  "catalog_version": 1,
  "tool_grant": ["create_job", "job_status"]
}

Synchronizing a new catalog does not repin existing attachments. Select the new version explicitly when you want to accept changed schemas. An empty grant permits no tools. Both the grant and the connector's current tool filter must allow each call.

Local tools use ordinary function calling on supported OpenAI, Anthropic, and Gemini models; the hosted supports_mcp flag does not control local-mode availability. Each call uses the run's approval and outbound-access controls. Remote readOnlyHint and idempotentHint annotations do not grant trust: local MCP tools are conservatively treated as state-changing. If the reply is lost after dispatch, the run reports an uncertain outcome instead of automatically issuing the call again. Resolve that outcome through the run interaction API before continuing.

Every local call asks a person first unless the run is set to No Approvals, even a read-only call, and neither AI Review nor the tool's own approval setting changes that. A run started by a schedule or an inbound webhook has nobody to ask, so each local call it makes is denied, and its run can't be set to No Approvals. Unattended runs on the agent's page, and Running unattended on a workflow's page, name each connector that would stop such a run, and creating a schedule or inbound webhook for the agent is refused until you fix it. Remove the connector from the agent, or run the agent from a workflow step with a Person to ask, whose runs ask that person instead.

Schedules and inbound webhooks that already run the agent, directly or through a workflow, keep firing. So when creating or patching an attachment leaves one of them unable to run, the response lists it in broken_triggers, as saving an agent does. Each entry has the trigger's kind and id and the agent_id or workflow_id it starts, plus a name and reason when it's your trigger or you're a workspace admin. They stay on, failing each local call, until someone turns them off in the app.

Detaching a connector, changing its permissions or credentials, or changing the remote tool schemas can stop an in-progress run. Returned resources and URLs remain data; they are not downloaded automatically and your application's handlers are not invoked.

Credentials and trust boundary

Guest Machines encrypts connector tokens at rest and never returns the plaintext; read responses contain only a masked auth_hint. A saved token can be reused only with the connector's saved URL. Re-enter it when testing or saving a different URL. A delegated application testing an organization-library connector with its saved credential needs both mcp_servers:edit and mcp_servers:publish, and its user must currently be an organization admin or owner.

The connector URL itself is metadata and may be visible to organization-library readers. Query strings and fragments are rejected, and you must not embed a credential in the URL path; use the encrypted token field instead.

oauth_token is currently a stored bearer-token mode, not a Guest Machines-managed OAuth refresh flow. Your integration must obtain, rotate, and explicitly update the token before it expires.

Provider-hosted MCP gives the selected model provider the tool definitions, arguments, and results needed to execute the call. When the Guest Machines relay is enabled, every Streamable HTTP connector uses it, with credentials or without. Guest Machines adds the connector's credentials and applies your workspace's outbound network policy without sharing those credentials with the provider.

Legacy SSE bypasses the relay. The provider receives the connector's URL and any configured bearer token, sign-in access token, or request credentials so it can connect directly. Streamable HTTP connectors also connect directly when the relay is disabled. The relay's assurances apply only to connections that use it. Register only servers you trust, limit each connector to the tools the agent needs, and assume the server can change the tools it advertises.

The relay forwards tool listing and tool calls only, for the tools the connector's filter allows. A response that contains one of the connector's own credentials is replaced by an error for that call. The text a tool call returns comes back marked as information for the model, never as instructions, as every other tool's result is; a response the relay can't read is replaced by an error rather than passed on unchecked.

Anthropic currently documents its hosted MCP connector as a beta feature that uses standard provider retention and is not covered by Zero Data Retention arrangements. Consider those terms before attaching a connector to an Anthropic model.

In the app, require_approval: "always" is Ask a Person (a person approves each call) and "never" is No Approval (each call runs without a check). OpenAI models support both. Anthropic models support only No Approval, so their connectors must use require_approval: "never". Integrations that use approval should answer approval requests through the run interaction API.

A run with nobody to answer can't use a connector set to Ask a Person: a run an automation account starts, or one a schedule or an inbound webhook starts, fails before the model is called, with the error code mcp.approval_unanswered, and a trigger's run can't be set to No Approvals. Unattended runs on the agent's page, and Running unattended on a workflow's page, name each such connector, and creating a schedule or inbound webhook for the agent is refused until you fix it. Adding one through mcp_server_ids to an agent that schedules or inbound webhooks already run lists them in the update's broken_triggers. Set the connector to No Approval, remove it from the agent, or run the agent from a workflow step with a Person to ask, who then approves each call. If an Anthropic agent ends up with a connector set to Ask a Person, because the connector's approval or the agent's model changed after it was attached, every run of the agent fails with mcp.approval_unsupported, and the same check names that connector.

Changing a connector can also stop the schedules and inbound webhooks that run its agents: setting it to Ask a Person, turning it off, or unpublishing it. So can any other edit except new credentials, even to its name or description, when an agent runs it locally: that agent can't start until you sync the connector's tools and select the new catalog. The PATCH /api/v1/mcp-servers/{server_id} and unpublish responses list each trigger the change left unable to run once in broken_triggers_by_agent, under an agent it runs that you can edit, and count the rest in other_broken_trigger_count. A delegated application needs agents:edit to see which agents. In the app, saving offers to turn them off.

Manage the organization library

Delegated applications can publish or unpublish a connector through the connector API when they carry the exact mcp_servers:publish scope and represent a current organization admin or owner. Publishing makes a private connector's saved credentials the workspace's, so only its own owner publishes it: an application acting for another admin gets 403. Likewise only the owner can set oauth_account to owner, which makes every run use their sign-in. Creating a connector directly as org_shared requires both mcp_servers:create and mcp_servers:publish.

The mcp_servers:* wildcard deliberately excludes publishing, so existing broad grants cannot begin sharing credentials without a new consent decision. Automation accounts cannot manage connector records. They can invoke an agent shared with them that already has an organization-library connector attached; use require_approval: "never" because an automation account can't answer a provider approval request.

Connectors execute through agents. The public API does not expose a standalone endpoint that calls an arbitrary MCP tool.

Read MCP results in your application

Use List MCP results to retrieve tool outputs directly, without asking the model to reproduce them in its final answer:

curl "https://api.guestmachines.com/api/v1/runs/$RUN_ID/mcp-results?limit=20" \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H "X-Org-Id: $ORG_ID"

The endpoint accepts the run owner's session, user API key, or delegated token with runs:read. An automation account needs both runs:read and the explicit runs:read_results scope, and may read only non-private runs started by that same account. The runs:* wildcard does not include result-content permission. For a private chat lineage, only its private owner can read these results. Being a workspace administrator does not grant access to the payloads.

Each result includes a stable id, an ascending sequence, server and attachment IDs, the tool name, arguments, provider-visible content, error, is_error, structured_content, execution_mode, and recorded_at. Local receipts also identify the logical_call_key and attempt_number. OpenAI's original arguments_text is also retained; arguments is null if it cannot be parsed as an unambiguous JSON object. An error result can still contain useful content. Text that happens to contain JSON stays text: validate and decode it using your MCP server's own contract before importing assets or taking other actions.

Follow next_cursor while has_more is true. Save the cursor after processing the page, then reuse it to poll for later results even when has_more is false. An empty page preserves your cursor. The default page size is 20, the maximum is 50, and a content-size budget may shorten a page. A cursor only works for its original run; fetch child runs separately.

Results become available after a tool call finishes and remain available after the run finishes until the run is deleted. They cover hosted OpenAI and Anthropic calls and local calls, including failures, but not pending calls or tool discovery. Historical results discarded before this feature was deployed cannot be reconstructed. No MCP payload is added to ordinary run events or webhooks.

Deduplicate processing on (run_id, id). Retrying delivery does not create a second receipt, but deliberately replaying a run can execute a remote tool again. This is not an exactly-once guarantee for remote effects. Returned URLs are not downloaded automatically and your application's handlers are not invoked.

Import a returned remote asset

Submit an explicit import when a result contains a file URL:

POST /api/v1/artifacts/imports
Idempotency-Key: image-result-123-1
Content-Type: application/json

{
  "source": {
    "kind": "mcp_result",
    "run_id": 123,
    "result_sequence": 1,
    "json_pointer": "/structured_content/image_url"
  },
  "file_name": "generated-image.png",
  "max_bytes": 20971520,
  "expected_media_type": "image/png"
}

The response is a 202 job. Poll GET /api/v1/artifacts/imports/{import_id} until it succeeds, then use its artifact_id with the normal download API or as an artifact_inputs entry for a later run. A direct source of {"kind":"url","url":"https://assets.example/image.png"} is also supported. The pointer selects a string in the stored receipt; it does not parse JSON embedded in text. Use only a successful receipt you are authorized to read.

Imports deduplicate identical submissions and never repeat the MCP generation call, including when recovering an interrupted import. Signed URLs stay encrypted and are omitted from job responses. Downloads enforce network, byte, type, and optional checksum checks. Redirects, compression, and arbitrary authentication headers are not supported. Remote imports support the same file formats as Knowledge. The import API reference lists the supported extensions.

Newly accepted formats are untrusted, download-only files, preserved byte-for-byte. Existing PNG/JPEG/GIF/WebP/PDF/MP4/MP3/WAV import previews remain available. HTML is always download-only. Artifact, run-binding, and approval-file responses expose download_only; when true, clients must not create inline previews, and both URL endpoints force attachment disposition with application/octet-stream.

Importing does not execute scripts, follow references, parse document contents, extract archives, or start Knowledge ingestion. XML entities and stylesheets, Markdown resources, and CSV formulas remain uninterpreted. Source/markup/data text must be UTF-8 without binary control characters; an upstream charset must be omitted, utf-8, or utf8. DOCX/PPTX/XLSX imports reject encrypted, split, ZIP64 and recognized macro-bearing containers. Other newly accepted binaries are not validated as well-formed documents or scanned for malware.

The limit is the smallest of max_bytes, the shared category limit, and 100 MiB (text: 25 MiB; images: 50 MiB). Downloaded files are not sanitized or made safe to open. If you open one separately, that execution context is your responsibility.

The resulting file is an untrusted input, not a verified output of the source run. Importing it does not change that run's completion, satisfy its artifact requirement, or pause its model. The import job retains the receipt reference. List, cancel, and explicitly retry jobs through the corresponding /artifacts/imports endpoints; retry also requires an Idempotency-Key.

Model support and limits

Do not infer hosted MCP support or approval behavior from a provider name. supports_mcp and mcp_approval_policies on each /api/v1/models entry are authoritative; /api/v1/capabilities reports whether any currently available model supports hosted MCP.

All currently offered OpenAI and Anthropic models report hosted MCP support. Clients should still read the catalog instead of hard-coding a model list, because availability and capabilities can change.

Keep connector tool filters narrow. A run can be rejected if the combined tool set exceeds the selected model's or provider's limits; Guest Machines does not silently remove tools to make a request fit.

Anthropic does not guarantee a hard cap on MCP calls before Guest Machines can stop a run that exceeds its limits. A remote server may already have performed a side effect. Use autonomous execution only with trusted servers, make side-effecting tools idempotent where possible, and set appropriate run limits.

Every currently offered OpenAI model advertises always and never; every currently offered Anthropic model advertises never only. Other models may not support MCP. Always negotiate the catalog fields for the selected model.

On this page