> ## Documentation Index
> Fetch the complete documentation index at: https://docs.veecle.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# CI/CD

> Run Chiplab from a pipeline with a personal access token, without a browser login.

<Info>
  This page describes what your AI agent, or your CI job, can do with Chiplab.
  This is a reference for the curious, not a set of instructions you have to follow by hand.
</Info>

CI uses the same MCP endpoint as an interactive agent, `https://chiplab.veecle.ai/mcp`.
A pipeline cannot complete the browser login, so it authenticates with a personal access token and then calls [ask](/tools/ask), [build](/tools/build), [run](/tools/run), and [test](/tools/test) the same way an agent does.

## Personal access tokens

On the [API Keys](/platform/api-keys) page, create a token and give it a name.
Chiplab shows the token once. Copy it into a CI secret.
Revoke it from the same list when you rotate it or when a pipeline should lose access.

The MCP client reads that secret as a bearer token.
The dashboard's snippet is:

```json theme={null}
{
  "mcpServers": {
    "chiplab": {
      "type": "http",
      "url": "https://chiplab.veecle.ai/mcp",
      "headers": {
        "Authorization": "Bearer ${CHIPLAB_API_KEY}"
      }
    }
  }
}
```

`CHIPLAB_API_KEY` stays in the CI environment.
The config file holds the `${CHIPLAB_API_KEY}` placeholder, so the token is expanded when the job connects.

## What the job does

A Chiplab CI job follows the same loop as a local session:

1. Call `ask` so the job has the current boards, tools, and gotchas.
2. Produce an ELF, either in the job or through [build](/tools/build).
3. Upload it and [run](/tools/run) it on the target board, with the UART the firmware writes.
4. Wait for the job and download `stdout`.
5. Fail the pipeline unless that output contains what you expect. The public examples expect `Hello world!`.

The examples repository ships a reference GitHub Actions workflow, [`.github/workflows/claude-chiplab-smoke.yml`](https://github.com/veecle/chiplab/blob/main/.github/workflows/claude-chiplab-smoke.yml).
It runs when someone comments `/smoke-test` on a pull request, builds `examples/bare-metal/stm32f4-discovery`, and checks the captured UART.
Treat it as a template: the trigger, the agent, and the example path are yours to change.
The endpoint, the bearer token, and the upload-run-check loop stay.
