diff --git a/src/components/AgentOnly.astro b/src/components/AgentOnly.astro new file mode 100644 index 000000000..3aec7aeda --- /dev/null +++ b/src/components/AgentOnly.astro @@ -0,0 +1,11 @@ +--- +/** + * Content for agent-readable Markdown that should not render in the docs UI. + * This is a presentation boundary, not an access-control boundary: the inert + * template remains visible in the page's HTML source. + */ +--- + + diff --git a/src/content/docs/factories/factory-mcp.mdx b/src/content/docs/factories/factory-mcp.mdx index 665984992..91880dcaf 100644 --- a/src/content/docs/factories/factory-mcp.mdx +++ b/src/content/docs/factories/factory-mcp.mdx @@ -1,11 +1,12 @@ --- title: Factory MCP description: >- - Connect any coding agent to your team's factories to send in work, continue - tasks locally, and hand results back. + Connect any coding agent to create and operate your team's factories, send in + work, continue tasks locally, and hand results back. sidebar: label: "Factory MCP" --- +import AgentOnly from '@components/AgentOnly.astro'; Factory MCP is a hosted Model Context Protocol (MCP) server that connects coding agents to your team's factories, in both directions: the agent you already work with — in Warp or in any MCP-capable tool — can send work to a factory, or take work over from one by pulling a task down, continuing it locally, and handing the result back. @@ -16,7 +17,7 @@ The factory keeps a single record of each task throughout. Whether a change happ * **Send work in** - Turn anything from your local session into a factory task: a bug you found, review feedback, or a half-finished change. * **Continue a task locally** - Pull a task's context into your own checkout, work with your own tools, and return the result to the same task. * **Stay in sync** - List and search tasks, read a task's conversation, and message its [foreman](/factories/factory-agents/), the agent that orchestrates each task inside the factory. -* **Create a factory** - Set up a new factory when you know the team, repositories, and source-control details. +* **Create a factory** - Let your coding agent guide you through choosing a team, code forge, repositories, factory agents, and integrations. Factory MCP is one of several ways work enters a factory, alongside Slack, GitHub, GitLab, Linear, and Jira. See [connect your factory](/factories/connect-your-factory/) for all intake paths and [how Warp Factories work](/factories/how-factories-work/) for how tasks move through a factory. @@ -26,6 +27,34 @@ Factory MCP is one of several ways work enters a factory, alongside Slack, GitHu There is nothing to configure. When your account has access, Warp connects agent sessions to Factory MCP and handles authentication for you. +### Set up with your coding agent + +Paste this prompt into a coding agent that can run commands and configure MCP servers: + +```text +Set up a factory for me. Read https://docs.warp.dev/factories/factory-mcp.md, follow the setup instructions for your coding environment to connect to and authenticate with Factory MCP, then use Factory MCP to onboard me. +``` + + +## Coding-agent setup guidance + +After the user pastes the prompt: + +1. Check whether Factory MCP is already available. +2. If it is not available, identify the coding environment and add `https://app.warp.dev/api/v1/mcp/factory` using that client's current MCP configuration mechanism. +3. Open the browser-based Warp authorization flow, where the user can log in or create a Warp account. +4. Verify that the Factory MCP tools are available. +5. Guide the user through the choices needed to create their factory. + +Before configuring anything, identify the coding environment and use that client's current MCP management mechanism. If you are unsure how the client manages MCP servers, check its help or official documentation rather than guessing. + +* **Warp:** Factory MCP is built in. Use the existing connection instead of adding another server. +* **Claude Code:** A server added after the session starts is not available to that running session. After adding Factory MCP, tell the user to exit and resume the same conversation from the same directory with `claude --continue`. Once resumed, complete authentication through the client's MCP controls if needed, then continue without asking the user to restate their goal. +* **Codex:** Add Factory MCP as a remote HTTP server, use Codex's built-in OAuth flow, and confirm the server is active through its MCP controls before onboarding. Ask the user to restart or resume only if the configured server is unavailable to the current session. +* **Other MCP clients:** Add the remote server using the client's supported configuration and authentication flow. If the client cannot load a newly added server into the current session, explain how to restart or resume while preserving the onboarding context when possible. + + + ### In other MCP clients Factory MCP is a streamable HTTP server at `https://app.warp.dev/api/v1/mcp/factory`. Point any MCP client that supports remote servers at that URL; on first connect, the client opens a browser so you can sign in and approve access. @@ -33,7 +62,7 @@ Factory MCP is a streamable HTTP server at `https://app.warp.dev/api/v1/mcp/fact With Claude Code: ```bash -claude mcp add --transport http warp-factory https://app.warp.dev/api/v1/mcp/factory +claude mcp add --transport http --scope local warp-factory https://app.warp.dev/api/v1/mcp/factory ``` In clients that use the `mcpServers` JSON format, such as Cursor: @@ -50,7 +79,7 @@ In clients that use the `mcpServers` JSON format, such as Cursor: For Codex and other clients, follow the [client's own remote-server instructions](https://developers.openai.com/codex/mcp/#connect-codex-to-an-mcp-server) with the same URL. -For unattended automation, skip the browser flow and authenticate with a [Warp API key](/reference/cli/api-keys/) instead. Create the key for a least-privilege cloud agent rather than your personal account, and pass it as a bearer token: +Automation that runs without a person present, such as a CI pipeline or a headless server, can't complete the browser sign-in. For those cases, authenticate with an [agent API key](/reference/cli/api-keys/) instead, passed as a bearer token: ```json { @@ -76,8 +105,7 @@ Factory MCP exposes a small set of tools that your agent calls on your behalf. Y * "Send this bug to the factory, including my branch." * "What's the status of the checkout-flow task?" * "Pull down ENG-123 so we can finish it here." - -The rest of this page describes what happens behind those prompts. +* "Set up a factory for me." ## Send new work to a factory @@ -108,11 +136,21 @@ Sending work to a factory means you're no longer watching it. To be notified whe ## Tool reference Your MCP client fetches the full input schemas from the server, and tool results include links that open the corresponding task or run in the factory's [factory dashboard](/factories/factory-dashboard/). +The onboarding tools from `list_teams` through `get_connection_status` require browser sign-in or a personal API key. Agent API keys are for operating an existing factory and cannot use these setup tools. | Tool | What it does | | --- | --- | | `list_factories` | Lists the factories you can access. | -| `create_factory` | Creates a factory for a team, with its repositories and source-control details. | +| `get_factory_file_schema` | Returns the current schemas for factory configuration files. | +| `validate_factory_files` | Validates a complete factory file tree without saving or applying it. | +| `list_teams` | Lists current memberships and first-time joinable team choices. | +| `create_team` | Creates the authenticated user's first team with a confirmed name. | +| `join_team` | Joins a team selected from the first-time discovery choices. | +| `get_team_funding_status` | Checks first-team credit readiness and returns the browser checkout step when required. | +| `list_forge_repositories` | Lists repositories available through a team's connected GitHub or GitLab account. | +| `start_connection` | Starts or checks setup for GitHub, GitLab, Slack, Linear, or Jira. | +| `get_connection_status` | Checks whether a browser authorization flow completed. | +| `create_factory` | Creates a factory with the selected repositories, integrations, and optional factory agents. | | `list_tasks` | Lists the tasks in one factory, with filters such as creator, stage, and date. | | `search_task` | Searches task titles across all factories you can access. | | `get_task` | Reads a task's status, run history, and outputs. Accepts a task ID or a reference such as a URL, issue, pull request, or branch. With `start_working=true`, also returns local setup guidance. | diff --git a/src/integrations/docs-markdown-integration.js b/src/integrations/docs-markdown-integration.js index 76c43d7e2..6963f1089 100644 --- a/src/integrations/docs-markdown-integration.js +++ b/src/integrations/docs-markdown-integration.js @@ -18,6 +18,8 @@ export default function docsMarkdownIntegration() { }; } +export { convertHtmlToMarkdown }; + const turndown = createMarkdownConverter(); async function generateMarkdownFiles(outputRoot) { @@ -86,6 +88,7 @@ function convertHtmlToMarkdown(html) { if (!title || !contentRoot) return ''; const clone = /** @type {HTMLElement} */ (contentRoot.cloneNode(true)); + expandAgentOnlyTemplates(clone); sanitizeRoot(clone); const markdownBody = turndown.turndown(clone.innerHTML).trim(); const llmsDirective = @@ -104,6 +107,12 @@ function convertHtmlToMarkdown(html) { return `${sections.join('\n\n').trim()}\n`; } +function expandAgentOnlyTemplates(root) { + for (const template of root.querySelectorAll('template[data-agent-only]')) { + const content = /** @type {HTMLTemplateElement} */ (template).content; + template.replaceWith(content.cloneNode(true)); + } +} function sanitizeRoot(root) { for (const selector of [ 'script', diff --git a/src/integrations/docs-markdown-integration.test.js b/src/integrations/docs-markdown-integration.test.js new file mode 100644 index 000000000..551a3ffad --- /dev/null +++ b/src/integrations/docs-markdown-integration.test.js @@ -0,0 +1,31 @@ +import assert from 'node:assert/strict'; +import test from 'node:test'; +import { convertHtmlToMarkdown } from './docs-markdown-integration.js'; + +test('includes inert agent-only templates in generated Markdown', () => { + const html = ` + + + +
+

Test page

+
+

Visible guidance.

+ +

Search-only chrome.

+
+
+ + + `; + + const markdown = convertHtmlToMarkdown(html); + + assert.match(markdown, /Visible guidance\./); + assert.match(markdown, /## Agent setup/); + assert.match(markdown, /Restart the coding agent after installing MCP\./); + assert.doesNotMatch(markdown, /Search-only chrome\./); +});