diff --git a/SUMMARY.md b/SUMMARY.md index f07092a..8fd1e8f 100644 --- a/SUMMARY.md +++ b/SUMMARY.md @@ -71,6 +71,7 @@ ## AI Agents & MCP +* [Connect an AI Agent](mcp/connect.md) * [MCP Server](mcp/overview.md) * [Tools Reference](mcp/tools.md) diff --git a/cli/dcd-login.md b/cli/dcd-login.md index 07b771b..51d2fef 100644 --- a/cli/dcd-login.md +++ b/cli/dcd-login.md @@ -82,4 +82,4 @@ The session from `dcd login` is written to: - `$XDG_CONFIG_HOME/dcd/config.json`, or - `~/.dcd/config.json` if `XDG_CONFIG_HOME` is not set -The file is created with `0600` permissions (owner read/write only) and holds your session tokens and the active team. When a command starts, the CLI refreshes the session if it's about to expire, so you should rarely need to log in again. A process that keeps running, such as the [MCP server](../mcp/overview.md), doesn't refresh its session, so use an API key for long-running processes. +The file is created with `0600` permissions (owner read/write only) and holds your session tokens and the active team. The CLI refreshes the session when it's about to expire, both when a command starts and while a process keeps running, such as the [MCP server](../mcp/connect.md), so you should rarely need to log in again. diff --git a/cli/overview.md b/cli/overview.md index 88050bd..e696cbb 100644 --- a/cli/overview.md +++ b/cli/overview.md @@ -2,7 +2,7 @@ The DCD CLI is the primary way to interact with DeviceCloud from your terminal or CI/CD pipeline. It is a drop-in replacement for `maestro cloud` — in most cases you can swap `maestro cloud` for `dcd cloud`. -The CLI is published as `@devicecloud.dev/dcd` on npm and as a standalone binary. The npm package also ships an [MCP server](../mcp/overview.md) (`dcd-mcp`) so AI agents can drive DeviceCloud directly. The standalone binary doesn't include the MCP server. +The CLI is published as `@devicecloud.dev/dcd` on npm and as a standalone binary. Both include `dcd mcp`, an [MCP server](../mcp/connect.md) that lets AI agents run cloud tests and read their results. The npm package also ships `dcd-mcp`, the [older MCP server](../mcp/overview.md). ::: info **New in v5:** browser-based [`dcd login`](dcd-login.md) (no more passing a key on every command), a standalone binary installer with `dcd upgrade`, interactive [`dcd live`](dcd-live.md) device sessions, and an [MCP server](../mcp/overview.md). Existing API keys and `dcd cloud` usage continue to work unchanged. diff --git a/getting-started/api-keys.md b/getting-started/api-keys.md index 72f915f..e3b71fb 100644 --- a/getting-started/api-keys.md +++ b/getting-started/api-keys.md @@ -16,7 +16,7 @@ This opens your browser, where you sign in (email OTP or Enterprise SSO) and aut - `$XDG_CONFIG_HOME/dcd/config.json`, or - `~/.dcd/config.json` if `XDG_CONFIG_HOME` is not set -The file is written with `0600` permissions (owner read/write only). When a command starts, the CLI refreshes the session if it's about to expire — you generally only log in again if you log out or switch machines. Long-running processes such as the [MCP server](../mcp/overview.md) don't refresh their session, so use an API key for those. +The file is written with `0600` permissions (owner read/write only). The CLI refreshes the session when it's about to expire, both when a command starts and while a process keeps running, such as the [MCP server](../mcp/connect.md). You generally only log in again if you log out or switch machines. ::: info No browser on the box (e.g. over SSH)? Run `dcd login --no-browser` and the CLI prints a URL to open elsewhere. diff --git a/mcp/connect.md b/mcp/connect.md new file mode 100644 index 0000000..34aea9c --- /dev/null +++ b/mcp/connect.md @@ -0,0 +1,111 @@ +--- +description: "Connect Claude Code, Cursor, VS Code, Claude Desktop, Codex or another MCP client to DeviceCloud with dcd mcp, on your machine or headless in CI." +--- + +# Connect an AI Agent + +`dcd mcp` is DeviceCloud's [MCP](https://modelcontextprotocol.io) server. It lets an AI agent, such as Claude Code, Cursor, VS Code, Claude Desktop or Codex, run cloud tests and read their results. It comes with the [CLI](../cli/overview.md), and it works the same on your machine and headless, such as in CI. + +You don't run it yourself. You add it to your MCP client's config, and the client starts it. + +::: warning +We accept no liability for anything your agent may read or execute. LLMs are a new technology: use them with care and at your own risk. +::: + +## Set it up + +1. Install the CLI, as in the [Quick Start](../getting-started/quickstart.md). +2. Sign in with [dcd login](../cli/dcd-login.md). For an agent that runs without you, use an API key instead: see [Headless, with an API key](#headless-with-an-api-key). +3. Add the server to your client: + +```bash +dcd mcp install claude-code # or claude-desktop, codex, cursor, vscode +``` + +If your dcd has no `dcd mcp`, or `dcd mcp install` doesn't list your client, update the CLI first (`dcd upgrade`, or `npm install -g @devicecloud.dev/dcd` for the npm package). Leave out the client to pick from a list. Add `--read-only` for a server that offers only the tools that change nothing, or `--print` to see what it would add without changing anything. For Claude Code, Codex and VS Code it runs their own `mcp add` command. For Claude Desktop and Cursor it adds an entry to their config file and keeps everything else in it. Restart the app afterwards. + +## Headless, with an API key + +For an agent that runs without you, such as in CI or a script, sign in with an [API key](../getting-started/api-keys.md) instead of `dcd login`. Give it to the server as `DEVICE_CLOUD_API_KEY` in its environment. For example, for Claude Code in CI: + +```bash +claude mcp add --scope user devicecloud -e DEVICE_CLOUD_API_KEY="$DEVICE_CLOUD_API_KEY" -- dcd mcp +``` + +In a JSON config, put it in the server's `env`: + +```json +{ + "mcpServers": { + "devicecloud": { + "command": "/Users/you/.dcd/bin/dcd", + "args": ["mcp"], + "env": { "DEVICE_CLOUD_API_KEY": "" } + } + } +} +``` + +::: info +Store the key as a secret in your CI provider (for example, a GitHub Actions secret). Never commit it to your repository. +::: + +## Setting it up by hand + +Start dcd by its **full path**. Desktop apps are usually opened from the Dock or Start menu, so they don't see the `PATH` your shell sets up, and a bare `dcd` fails with "command not found". The installer prints the path when it finishes. It's `~/.dcd/bin/dcd` by default, written out in full, because config files don't expand `~`. + +Claude Desktop (`claude_desktop_config.json`) and Cursor (`~/.cursor/mcp.json`): + +```json +{ + "mcpServers": { + "devicecloud": { + "command": "/Users/you/.dcd/bin/dcd", + "args": ["mcp"] + } + } +} +``` + +VS Code (`.vscode/mcp.json`, or your user `mcp.json`): + +```json +{ + "servers": { + "devicecloud": { + "type": "stdio", + "command": "/Users/you/.dcd/bin/dcd", + "args": ["mcp"] + } + } +} +``` + +Codex (`~/.codex/config.toml`, shared by the Codex CLI, IDE extension and ChatGPT desktop app): + +```toml +[mcp_servers.devicecloud] +command = "/Users/you/.dcd/bin/dcd" +args = ["mcp"] +``` + +Claude Code and the Codex CLI run from a terminal, so they do see your `PATH`: + +```bash +claude mcp add --scope user devicecloud -- dcd mcp +codex mcp add devicecloud -- dcd mcp +``` + +To run the npm package instead of an installed dcd, use `npx` as the command, with the arguments `-y`, `@devicecloud.dev/dcd` and `mcp`. That needs Node 22 or later. + +`dcd mcp` signs in like the CLI: with your `dcd login` session, which it renews as it runs, or with `DEVICE_CLOUD_API_KEY`. + +## Tools + +`dcd mcp` serves the `dcd_*` tools: list devices, submit a cloud test run, follow its status and download its artifacts. The [Tools Reference](tools.md) describes each one. + +`dcd_run_cloud_test` starts a test run, which is billable. For an agent that should only look, add `--read-only` after `mcp` in the arguments, or set `DCD_MCP_READONLY=1`. The server then leaves out every tool that changes anything. + +## The older `dcd-mcp` server + +The npm package also has `dcd-mcp`, an older server with the same `dcd_*` tools. `dcd mcp` covers it, so you only need `dcd-mcp` for a setup that already uses it. See [MCP Server](overview.md). diff --git a/mcp/overview.md b/mcp/overview.md index ff04ac8..50731c5 100644 --- a/mcp/overview.md +++ b/mcp/overview.md @@ -1,5 +1,9 @@ # MCP Server +::: info +This page covers `dcd-mcp`, the older server. For new setups, use `dcd mcp` from the CLI: see [Connect an AI Agent](connect.md). +::: + The `@devicecloud.dev/dcd` package ships a second binary, `dcd-mcp` — a [Model Context Protocol](https://modelcontextprotocol.io) server that lets AI agents (Claude, Cursor, VS Code, and other MCP clients) drive DeviceCloud directly: list devices, submit cloud test runs, check status, and download artifacts. ::: warning @@ -29,7 +33,7 @@ Add the server to your MCP client's configuration. It runs over stdio via `npx` The `--package=` form matters: it tells `npx` to run the package's `dcd-mcp` binary. Without it, `npx` runs the `dcd` CLI instead, which rejects `dcd-mcp` as an unknown command. ::: info -The MCP server ships in the npm package only. The standalone `dcd` binary doesn't include it, so you need Node even if you installed the CLI with the binary installer. +`dcd-mcp` ships in the npm package only, so it needs Node even if you installed the CLI with the binary installer. The standalone binary has [`dcd mcp`](connect.md) instead, which serves the same tools. ::: ## Authentication @@ -43,8 +47,8 @@ When both are present, the environment variable wins. Credentials are resolved lazily on the first tool call, not at startup — so your client can connect and enumerate the tools before you've supplied a key, and a bad credential surfaces as a tool error rather than a server that won't start. -::: warning -The server resolves credentials once and reuses them for as long as it runs. A `dcd login` session is not refreshed after that, so a long-running server starts failing once the session expires, until you restart it. Use an API key for servers that stay running. +::: info +The server renews a `dcd login` session as it runs. If the session ends, for example after `dcd logout`, run `dcd login` again. You don't need to restart the server. For an agent that runs unattended, such as in CI, use an API key. ::: ## Tools