trello-mcp
# trello-mcp
A self-hostable [Model Context Protocol](https://modelcontextprotocol.io/) server that lets MCP-compatible clients work with [Trello](https://trello.com/) cards, lists, labels, attachments, checklists, members, and card activity.
The project is intentionally self-hostable and reusable. Contributions, adaptations, and focused issue reports are welcome.
The roadmap is, of course, tracked on Trello, and `trello-mcp` helps keep it up to date: [trello-mcp roadmap](https://trello.com/b/GnKmvuHz/trello-mcp-enthouan-trello-mcp).
## Disclaimer
trello-mcp is an independent, community-maintained project. It is not an official Trello or Atlassian product, service, or MCP implementation, and it is not affiliated with, endorsed by, or sponsored by Trello or Atlassian.
This project exists to make it easier for MCP-compatible LLM clients to interface with Trello through Trello's [public API](https://developer.atlassian.com/cloud/trello/guides/rest-api/api-introduction/) and user-provided API credentials.
Looking for Trello's official hosted MCP server? Visit [Trello MCP](https://trello.com/mcp) and use the endpoint documented by Trello: `https://mcp.trello.com/v1`.
## Documentation
The complete project documentation is available at [trello-mcp.com](https://trello-mcp.com/):
- [Get started](https://trello-mcp.com/getting-started/)
- [Create a Trello API key and token](https://trello-mcp.com/getting-started/trello-api-key/)
- [Set up your MCP client](https://trello-mcp.com/getting-started/clients/)
- [Browse the tool catalog](https://trello-mcp.com/reference/tools/)
- [Review API coverage and non-goals](https://trello-mcp.com/reference/api-coverage/)
- [Understand Security & Data](https://trello-mcp.com/guides/security/)
- [Operate a running deployment](https://trello-mcp.com/guides/operations/)
- [Troubleshoot an installation](https://trello-mcp.com/guides/troubleshooting/)
- [Official MCP Registry installation, releases, and recovery](docs/mcp-registry.md)
- [Glama listing](https://glama.ai/mcp/servers/enthouan/trello-mcp) ([validation status](docs/glama-readiness.md#acceptance-checklist))
## Features
### Board Discovery
- List boards visible to the authenticated Trello member.
- Read basic board metadata.
- List open, closed, or all lists on a board.
- List open, closed, visible, or all cards on a board.
- List board labels, members, and memberships.
- Create, inspect, update, and delete board labels.
- Create, inspect, rename, archive, unarchive, and move lists between boards.
### Card Workflows
- Read cards by id, short id, or Trello card URL.
- Create cards with title, description, due date, position, members, and labels.
- Update card metadata including title, description, due date, due completion, and archived state.
- Move cards between lists or boards.
- Apply and remove existing labels on cards.
- Permanently delete cards only when explicitly requested.
### Card Context
- List cards in a Trello list.
- List card attachments, inspect individual attachments, add public URL attachments, and upload server-local files from an explicitly configured directory.
- List, create, rename, and delete card checklists, and manage checklist items.
- List card members and add or remove members.
- Read card actions and activity history.
- Add, edit, and delete Trello card comments.
### Search Workflows
- Search Trello cards, boards, members, and workspaces using Trello search text and operators.
- Scope search results to specific boards, cards, or workspaces.
- Look up Trello members by name or username before assignment.
- Read member profiles, assigned cards, boards, and workspaces.
### Workspace Discovery
- List Trello workspaces visible to the authenticated member.
- Read workspace metadata, boards, and members.
### Self-Hosted Runtime
- Run with Docker Compose using the published GHCR image.
- Build locally with a separate Compose file.
- Use Streamable HTTP for container deployments.
- Use stdio for local MCP clients that launch the server as a child process.
- Keep stdio logs on stderr so local MCP clients receive protocol-only stdout.
- Expose HTTP health and readiness endpoints.
- Optionally require a bearer token for HTTP MCP endpoint requests.
- Validate config, tool input, and Trello API responses with Zod.
- Redact Trello credentials from logs.
- Run typecheck, lint, build, tests, and coverage in GitHub Actions.
## Quick Start
### 1. Get Trello API Credentials
Trello API keys are created from an app in Trello's App Admin Portal. Each person running this server should use their own Trello account and token. Follow the dedicated [Trello API credentials guide](docs/trello-api-key.md) for the current, security-focused walkthrough.
In short: create or select an app at [trello.com/apps/admin](https://trello.com/apps/admin), generate a key from its **API Key** tab, then use the nearby **Token** link to review and authorize access for the intended Trello member.
You will use those values as:
```bash
TRELLO_API_KEY=your-api-key
TRELLO_TOKEN=your-token
```
### 2. Choose an Install Path
#### Option A: Run the Published Docker Image
Use this path if you just want to run the server. It pulls the prebuilt image from GHCR and does not build anything locally.
```bash
git clone https://github.com/enthouan/trello-mcp.git
cd trello-mcp
cp .env.example .env
```
Edit `.env` and replace the placeholder values:
```bash
TRELLO_API_KEY=your-api-key
TRELLO_TOKEN=your-token
TRANSPORT=http
LOG_LEVEL=info
TRELLO_RATE_LIMIT_CAPACITY=100
TRELLO_RATE_LIMIT_REFILL_INTERVAL_MS=10000
TRELLO_RETRY_MAX_ATTEMPTS=3
TRELLO_RETRY_BASE_DELAY_MS=100
TRELLO_RETRY_MAX_DELAY_MS=2000
# MCP_AUTH_TOKEN=optional-shared-secret
TRELLO_MCP_HOST_BIND_IP=127.0.0.1
TRELLO_MCP_HOST_PORT=3000
TRELLO_MCP_IMAGE_TAG=latest
TRELLO_MCP_NETWORK=trello-mcp_network
```
Start the published image:
```bash
docker compose up -d --wait --wait-timeout 120
```
The default `docker-compose.yml` uses:
```text
ghcr.io/enthouan/trello-mcp:latest
```
Docker Compose values such as image tag, host bind IP, host port, and network name can be overridden with environment variables or the `.env` file. The compose files document their defaults at the top; for example, `TRELLO_MCP_IMAGE_TAG` defaults to the `latest` tag in `docker-compose.yml` (`latest` follows the `main` branch, and release tags such as `X.Y` and `X.Y.Z` are available for versioned deployments), `TRELLO_MCP_HOST_BIND_IP` defaults to `127.0.0.1` for local-only access, `TRELLO_MCP_HOST_PORT` defaults to `3000` and maps that host port to the container's fixed internal `3000` listener, while `TRELLO_MCP_NETWORK` defaults to `trello-mcp_network`. Set `TRELLO_MCP_HOST_BIND_IP=0.0.0.0` only when you intentionally want Docker to publish the service on all host interfaces, such as for LAN access.
Set `MCP_AUTH_TOKEN` to require `Authorization: Bearer <token>` on HTTP MCP requests to `/mcp`. Leave it unset for the default unauthenticated local behavior. Health and readiness endpoints remain unauthenticated for container and reverse-proxy checks.
Container health follows `TRANSPORT`: HTTP checks `/healthz` on `PORT` (default
`3000`), while stdio uses process liveness and lets the attached MCP client check
protocol responsiveness. Compose inherits this image health check.
Keep the Trello rate-limit and retry values at their defaults unless logs show `trello rate limit wait` or `trello request rate limited; retrying` during large workflows. Lower the capacity for shared tokens or constrained deployments; raise it carefully only after narrowing the workflow's board, card, field, and pagination scope.
For repeatable deployments, select a release and pin its verified index digest.
See [image trust and read-only verification](docs/mcp-registry.md#image-trust-and-verification)
for SBOM/provenance inspection, the GHCR signing policy, and the separate
Docker-built catalog path. Metadata integrity checks do not authenticate a
publisher. Published Docker image tags use these conventions:
| Tag | Use case |
| --- | --- |
| `latest` | Follows the current `main` branch build. Use it when you intentionally want the newest main-branch image. |
| `X.Y` | Follows the newest patch release in a minor line, moving to the image built from the latest matching `vX.Y.Z` tag. |
| `X.Y.Z` | Identifies an exact release, preserved by project policy. Pin its verified digest for immutable bytes. |
| `sha-<commit>` | Identifies a commit build; a stable release can repair this alias to its verified release digest. |
You can also run the published image directly without Compose:
```bash
docker run --rm -p 127.0.0.1:3000:3000 \
-e TRELLO_API_KEY=your-api-key \
-e TRELLO_TOKEN=your-token \
ghcr.io/enthouan/trello-mcp:latest
```
#### Option B: Build Locally from Source
Use this path if you want to develop the project, test local changes, or build the Docker image yourself.
Local development uses Node.js 24.x and the pinned `pnpm@10.34.1` package manager through Corepack.
```bash
git clone https://github.com/enthouan/trello-mcp.git
cd trello-mcp
cp .env.example .env
```
Edit `.env` with your Trello credentials, then build and run locally:
```bash
docker compose -f docker-compose.local.yml up --build -d --wait --wait-timeout 120
```
This uses `docker-compose.local.yml`, which builds from the local `Dockerfile` and tags the image as `trello-mcp:local`.
For a non-Docker local build:
```bash
corepack enable
corepack prepare pnpm@10.34.1 --activate
corepack pnpm install --frozen-lockfile
corepack pnpm build:clean
```
Then run the compiled server directly:
```bash
TRELLO_API_KEY=your-api-key TRELLO_TOKEN=your-token TRANSPORT=stdio node dist/index.js
```
Treat the token like a password. Do not commit it, paste it in logs, or share it in PRs.
### 3. Connect Your MCP Client
Choose the transport by where the server runs:
| Your setup | Choose | Client receives |
| --- | --- | --- |
| A built clone and the MCP client are on the same machine | `stdio` | A local command plus Trello credentials in the child-process environment |
| The server runs in Docker, behind a reverse proxy, or on another host | Streamable HTTP | An `/mcp` URL plus an optional bearer token; Trello credentials stay on the server |
The [Set up your MCP client guide](docs/client-setup.md) has current, sanitized
examples for Claude Desktop, Claude Code, Codex CLI, VS Code, OpenCode, MCP
Inspector, and other manual clients. It also covers restart
requirements, HTTP bearer support, secret handling, and tested limitations.
For dated client versions and evidence, see
[MCP Client Compatibility](docs/mcp-client-compatibility.md).
### 4. Verify
If you chose Streamable HTTP, check the server:
```bash
curl http://127.0.0.1:3000/healthz
curl http://127.0.0.1:3000/readyz
```
If you changed `TRELLO_MCP_HOST_PORT`, replace `3000` with that host port. If you changed `TRELLO_MCP_HOST_BIND_IP` from `127.0.0.1`, use a hostname or IP address that can reach the bound host interface.
Then confirm the MCP client discovers the current 77-tool surface. With an
intentional read-only credential check, call `auth_whoami` or `auth_token_info`
from the client. Do not make a write-side Trello call just to prove setup.
## Trello Credentials
This server currently uses Trello API key + token authentication. Follow the dedicated [Trello API credentials guide](docs/trello-api-key.md) for a security-focused walkthrough, with links to Trello's official App Admin Portal, authorization, and revocation documentation.
Use the read-only `auth_whoami` and `auth_token_info` tools to verify which Trello member the configured credentials authenticate as and to inspect the configured token's owner, expiration, and permissions. These tools are diagnostics only; this server does not implement OAuth redirects, token creation, token refresh, token revocation, or other token lifecycle management.
## Set up your MCP client
Use the canonical [Set up your MCP client guide](docs/client-setup.md) for transport
selection and client-specific configuration. Keep Trello credentials in the
`stdio` child environment or on the HTTP server; an HTTP client needs only the
`/mcp` endpoint and, when `MCP_AUTH_TOKEN` is enabled, a supported bearer-header
configuration.
The [compatibility record](docs/mcp-client-compatibility.md) distinguishes an
official-doc review from a real client connection, tool discovery, and an actual
Trello workflow.
## Environment
See the [configuration reference](docs/configuration.md) for deployment-specific
applicability, secret handling, rate-limit tuning, Compose controls, and local
attachment-upload requirements.
| Variable | Required | Default | Description |
| --- | --- | --- | --- |
| `TRELLO_API_KEY` | yes | | Trello API key. |
| `TRELLO_TOKEN` | yes | | Trello token for token auth. |
| `MCP_AUTH_TOKEN` | no | | If set, HTTP MCP requests to `/mcp` require `Authorization: Bearer <token>`. Leave unset for no HTTP bearer-token check. |
| `TRELLO_ATTACHMENT_UPLOAD_ROOT` | no | | Absolute server-side directory that enables local file attachment uploads. Leave unset to disable local uploads. |
| `TRELLO_RATE_LIMIT_CAPACITY` | no | `100` | Token-bucket capacity for Trello requests before the client waits for a refill. Must be a positive integer. |
| `TRELLO_RATE_LIMIT_REFILL_INTERVAL_MS` | no | `10000` | Token-bucket refill interval in milliseconds. Must be a positive integer. |
| `TRELLO_RETRY_MAX_ATTEMPTS` | no | `3` | Total attempts for a Trello request when Trello returns HTTP `429`. Must be a positive integer. |
| `TRELLO_RETRY_BASE_DELAY_MS` | no | `100` | Exponential backoff base delay in milliseconds for HTTP `429` retries, with bounded jitter. Must be a positive integer. |
| `TRELLO_RETRY_MAX_DELAY_MS` | no | `2000` | Maximum delay in milliseconds for any HTTP `429` retry wait. Must be a positive integer. |
| `TRANSPORT` | no | `http` | `http` or `stdio`. |
| `PORT` | no | `3000` | HTTP listen port for the Node process. Docker Compose keeps the container listener on `3000` and uses `TRELLO_MCP_HOST_PORT` for the published host port. |
| `LOG_LEVEL` | no | `info` | Pino log level. |
| `TRELLO_MCP_HOST_BIND_IP` | no | `127.0.0.1` | Docker Compose host interface bind address. Keep `127.0.0.1` for local-only access; set `0.0.0.0` to publish on all host interfaces for intentional network/LAN exposure. |
| `TRELLO_MCP_HOST_PORT` | no | `3000` | Docker Compose host port mapped to the container's fixed internal `3000` listener. |
| `TRELLO_MCP_IMAGE_TAG` | no | `latest` | Published image tag; `latest` follows `main`, `X.Y` follows the newest patch in that minor release line, and `X.Y.Z` pins to an exact release. |
| `TRELLO_MCP_NETWORK` | no | `trello-mcp_network` | Docker Compose bridge network name. |
## Live Trello Smoke Tests
Normal tests are mocked and offline. `corepack pnpm test`, `corepack pnpm test:coverage`, and the default CI workflow never require Trello credentials and never contact Trello.
For release validation against real Trello, use the explicit live smoke command:
```bash
TRELLO_LIVE_SMOKE=1 \
TRELLO_LIVE_SMOKE_BOARD_ID=your-disposable-board-id-or-short-link \
TRELLO_API_KEY=your-api-key \
TRELLO_TOKEN=your-token \
corepack pnpm smoke:live
```
You may use `TRELLO_LIVE_SMOKE_BOARD_URL` instead of `TRELLO_LIVE_SMOKE_BOARD_ID`; Trello `trello.com/b/...` board URLs are normalized to their short link, then the harness resolves the canonical board id with `board_get` before creating anything. Non-board URLs are rejected without logging their raw value or query string. `TRELLO_LIVE_SMOKE_RUN_ID` is optional and is included in temporary artifact names when set.
Set `TRELLO_LIVE_REQUIRE_PUBLIC_BOARD=1` when output may be published. The harness then verifies Trello reports the board as public before recording its identity or performing writes. This is optional for local private disposable-board validation.
Safety model:
- The command exits before any Trello request unless `TRELLO_LIVE_SMOKE=1`, Trello credentials, and a smoke board id or URL are all present.
- The configured board should be a disposable board reserved for validation, not an active production board.
- The harness creates uniquely named temporary lists, one card, one label, one checklist, one checklist item, and one comment. It deletes the card and label, archives the temporary lists, and verifies that no open temporary lists, cards, or labels remain.
- Cleanup runs even when an intermediate validation step fails. It also searches for uniquely prefixed lists, cards, and labels that Trello created before a response validation failure could track them. Cleanup failures are reported and cause the command to fail.
- The harness invokes the existing tool handlers with a real `TrelloClient`, so tool input validation, Trello response validation, retry/rate-limit handling, and credential redaction stay on the normal code path.
- The harness does not log API keys, tokens, credential-bearing URLs, raw environment objects, or raw request data.
The smoke flow validates representative v1.0 workflows:
- Auth and discovery: `auth_whoami`, `auth_token_info`, `list_boards`, board reads, lists, cards, labels, members, memberships, and custom-field discovery.
- List and card writes: disposable list creation/rename/archive, card create/read/update/due-date/position/archive/restore/move/delete.
- Checklist and item behavior: checklist creation/rename/deletion plus item create/list/update/check/delete.
- Labels and members: disposable label create/read/update/apply/remove/delete, plus authenticated-member assignment/removal when that member is visible on the smoke board.
- Card activity: comment create/update/list/delete on the disposable card.
## Live Trello Regression Tests
`corepack pnpm smoke:live` is the shallow release smoke check: it proves the most important workflow can authenticate, create disposable artifacts, mutate them, and clean up. `corepack pnpm regression:live` is the broader opt-in release-validation suite. It walks the public MCP tool surface by domain, reports live coverage against the registered tool catalog, and makes skipped or missing live coverage visible.
The regression suite has a separate opt-in gate from smoke tests:
```bash
TRELLO_LIVE_REGRESSION=1 \
TRELLO_LIVE_REGRESSION_BOARD_ID=your-disposable-board-id-or-short-link \
TRELLO_API_KEY=your-api-key \
TRELLO_TOKEN=your-token \
corepack pnpm regression:live
```
Use `TRELLO_LIVE_REGRESSION_BOARD_URL` instead of `TRELLO_LIVE_REGRESSION_BOARD_ID` when a `trello.com/b/...` board URL is more convenient. Non-board URLs are rejected before any Trello request and without logging raw query strings.
Set `TRELLO_LIVE_REQUIRE_PUBLIC_BOARD=1` when output or the JSON report may be published. The harness then verifies Trello reports every configured board as public before recording its identity or performing writes. Local private disposable-board runs can omit this flag and keep their output private.
Set `TRELLO_LIVE_REGRESSION_SECONDARY_BOARD_ID` or `TRELLO_LIVE_REGRESSION_SECONDARY_BOARD_URL` when you want live coverage for cross-board list moves. The secondary board is optional for local runs; when it is absent, `list_move_to_board` is reported as an intentional runtime skip instead of missing coverage. When it is present, the suite resolves it with `board_get`, confirms the token can see it through `list_boards`, verifies it is open and different from the primary board, then moves only disposable lists between the two boards.
Targeted runs are useful when debugging a domain or one tool:
```bash
TRELLO_LIVE_REGRESSION=1 \
TRELLO_LIVE_REGRESSION_BOARD_ID=your-disposable-board-id-or-short-link \
TRELLO_API_KEY=your-api-key \
TRELLO_TOKEN=your-token \
corepack pnpm regression:live --domain cards
```
```bash
TRELLO_LIVE_REGRESSION=1 \
TRELLO_LIVE_REGRESSION_BOARD_ID=your-disposable-board-id-or-short-link \
TRELLO_API_KEY=your-api-key \
TRELLO_TOKEN=your-token \
corepack pnpm regression:live --tool card_attachment_upload
```
```bash
TRELLO_LIVE_REGRESSION=1 \
TRELLO_LIVE_REGRESSION_BOARD_ID=your-primary-disposable-board-id-or-short-link \
TRELLO_LIVE_REGRESSION_SECONDARY_BOARD_ID=your-secondary-disposable-board-id-or-short-link \
TRELLO_API_KEY=your-api-key \
TRELLO_TOKEN=your-token \
corepack pnpm regression:live --tool list_move_to_board
```
You may also use `TRELLO_LIVE_REGRESSION_DOMAINS=cards,attachments` and `TRELLO_LIVE_REGRESSION_TOOLS=card_get,card_update`. Supported domains are `auth`, `boards`, `lists`, `cards`, `labels`, `checklists`, `members`, `workspaces`, `search`, `custom-fields`, `comments-actions`, and `attachments`.
Set `TRELLO_LIVE_REGRESSION_REPORT_JSON=reports/live-regression.json` to emit a machine-readable report in addition to the human-readable terminal report. The report groups tools by domain and shows:
- `covered`: tool handlers successfully exercised against Trello.
- `skipped`: intentional runtime skips, such as no visible workspace, no board custom fields, or upload coverage not configured.
- `unsupported`: non-goal live cases that are intentionally outside regression coverage, such as `board_create`.
- `missing`: selected public tools with no regression coverage classification. Missing coverage fails the command so new public tools do not silently disappear from release validation.
- cleanup status, including attempted/completed cleanup steps and any remaining prefix-matched open artifacts.
Regression safety model:
- The command exits before any Trello request unless `TRELLO_LIVE_REGRESSION=1`, Trello credentials, and a regression board id or URL are all present.
- The configured board should be a disposable board reserved for validation, not an active production board.
- The optional secondary board should also be disposable. It is only mutated for `list_move_to_board`, and only with lists created by the regression run.
- Temporary artifacts use a unique run id and the `trello-mcp live regression ...` prefix. Set `TRELLO_LIVE_REGRESSION_RUN_ID` when you want a human-readable run marker.
- Cleanup runs after intermediate failures. It removes tracked temporary cards, labels, attachments, member/label assignments, custom-field values, and archives temporary lists. It also searches all configured regression boards for prefix-matched lists, cards, and labels that were created before the response could be tracked.
- The suite invokes registered tool handlers with a real `TrelloClient`; it does not call Trello through a separate ad hoc client.
- The suite does not log API keys, tokens, credential-bearing URLs, raw environment objects, or raw request data.
Local file upload coverage is skipped by default. To include `card_attachment_upload`, both the normal upload root and an explicit regression test file must be configured:
```bash
TRELLO_ATTACHMENT_UPLOAD_ROOT=/absolute/path/to/trello-uploads \
TRELLO_LIVE_REGRESSION_UPLOAD_FILE=sample.txt \
TRELLO_LIVE_REGRESSION=1 \
TRELLO_LIVE_REGRESSION_BOARD_ID=your-disposable-board-id-or-short-link \
TRELLO_API_KEY=your-api-key \
TRELLO_TOKEN=your-token \
corepack pnpm regression:live --domain attachments
```
The upload file path may be relative to `TRELLO_ATTACHMENT_UPLOAD_ROOT` or absolute, but it must resolve inside the upload root.
If the live env vars are absent during local validation, record the live command as skipped. The skipped state is explicit: `corepack pnpm smoke:live` and `corepack pnpm regression:live` fail before contacting Trello and print the missing variable names. Do not add either command to normal CI unless the job is intentionally secret-backed and opt-in.
### GitHub Actions
The repository includes a `Live Trello Smoke` workflow for PR, post-merge `main`, and release validation. It runs on same-repository pull requests, pushes to `main`, and manual dispatch. Fork pull requests are skipped so Trello credentials are not exposed to untrusted PR code.
The workflow runs the offline gates (`pnpm typecheck`, `pnpm lint`, `pnpm build`, and `pnpm test`) before the secret-backed live smoke step.
Before using it, configure a GitHub Environment named `live-smoke` with these secrets:
| Secret | Description |
| --- | --- |
| `TRELLO_LIVE_SMOKE_API_KEY` | Trello API key for a dedicated smoke-test Trello member. |
| `TRELLO_LIVE_SMOKE_TOKEN` | Trello token for that same member, with write access to the disposable smoke board. |
Use environment required reviewers if the repository has more than one maintainer or if the token can access anything beyond the smoke board. The workflow maps those secrets to `TRELLO_API_KEY` and `TRELLO_TOKEN` only for the `pnpm smoke:live` step. The job sets `environment.deployment: false`, so the GitHub Environment still scopes secrets and protection rules without creating Deployment records. Do not use `pull_request_target` for this workflow.
The hosted smoke workflow is fixed to the public disposable test board short link `hUaItfNq` and sets `TRELLO_LIVE_REQUIRE_PUBLIC_BOARD=1`, so it fails before identity output or writes if Trello no longer reports that board as public. It does not accept a board override, so a maintainer cannot accidentally publish a private board's identifiers through public Actions logs or summaries. A public board is acceptable for smoke testing when temporary artifact names and activity history can be visible, but public visibility does not remove the need for Trello credentials because the harness performs writes. For another disposable board, use the local command above and keep private-board output out of public logs and artifacts.
The broader `Live Trello Regression` workflow is manual-only and should be used for release candidates or focused live debugging, not as an ordinary PR gate. Configure a GitHub Environment named `live-regression` with:
| Secret | Description |
| --- | --- |
| `TRELLO_LIVE_REGRESSION_API_KEY` | Trello API key for a dedicated regression-test Trello member. |
| `TRELLO_LIVE_REGRESSION_TOKEN` | Trello token for that same member, with write access to the disposable regression board. |
The hosted regression workflow is fixed to the public disposable primary and secondary boards `hUaItfNq` and `r9BpowfZ` and sets `TRELLO_LIVE_REQUIRE_PUBLIC_BOARD=1`, so it fails before identity output or writes if Trello no longer reports either board as public. It accepts optional `domains` and `tools` inputs and uploads `reports/live-regression.json` when the command produces it. To use different boards, run the command locally and do not publish a report for a private board. The workflow also sets `environment.deployment: false` because live regression is secret-backed validation, not an app deployment. Fork pull requests must not receive Trello credentials; keep live regression on `workflow_dispatch` or another explicitly secret-backed workflow.
The `Release` workflow builds the published multi-architecture Docker image for `linux/amd64` and `linux/arm64` on pushes to `main` and `v*.*.*` tags. It can also be run manually from a branch with `push=false` to perform a no-push multi-platform validation before release-image changes merge. Leave `push=false` for dry runs; only use `push=true` when intentionally publishing to GHCR.
## Usage Examples
Once connected to an MCP client, ask for Trello actions in natural language:
For inspect-first multi-tool sequences with explicit proposal, approval, and
verification stages, follow the [workflow guide](docs/workflows.md).
```text
Show me my Trello boards.
Show me the lists on my job scout board.
Show me the cards in my "Today" list.
Create a card called "Review invoices" in the bookkeeping list.
Move this card to Done.
Archive the card about the old onboarding checklist.
Show the recent activity for this card.
Add a comment to this card saying the invoices are ready for review.
Edit this card comment to include the updated invoice total.
Add this public URL as an attachment to the card.
Upload the file invoice.pdf from my Trello upload folder to this card.
Show me the custom fields configured on this board.
Set this card's Priority custom field to the High option.
Clear this card's Estimate custom field.
```
The exact wording depends on your MCP client. The server can discover your boards and board lists first, then use those ids for card workflows.
## Large Trello Responses
Collection tools default to compact Trello reads so MCP clients do not receive unnecessarily large payloads. High-volume card, label, and action reads default to `limit: 50`; Trello caps these collection reads at `1000`.
Use `fields` to request only the properties needed for a workflow. Tools that validate object names, ids, or action types automatically add schema-required fields even when you request a smaller field set. Use `fields: "all"` only for detailed follow-up reads where the larger response is useful.
Use `since` and `before` on card collection and action tools to page through older or newer Trello objects. These cursors accept an ISO-8601 timestamp, a Trello/Mongo id, or `null` where Trello supports it. Action reads also expose zero-based `page` for Trello's action pagination.
Use `card_actions`, `board_actions`, `list_actions`, and `workspace_actions` for bounded activity audits. Set `filter: "commentCard"` to focus on comments, `filter: "all"` for broader activity, and combine `limit`, `since`, `before`, and `page` so board, list, card, or workspace histories stay small enough for MCP clients.
Member-returning tools default to compact member fields (`username,fullName,initials,avatarUrl`). Use member field inputs such as `fields`, `memberFields`, or `memberCreatorFields` when a workflow needs additional member profile properties.
## Search
Use `search` when a user gives a natural language term and you need to find matching cards or boards before taking action. It searches cards and boards by default, returns compact fields, and defaults to 10 results per resource type. Add `members` or `organizations` to `modelTypes` when member or workspace result types are useful.
Use `boardIds: "mine"` or specific board ids to narrow card and board search. Use `organizationIds` for workspace ids, plus `cardIds`, `partial`, `cardsPage`, and the per-type limit inputs when a query needs tighter scope or pagination. Use `search_members` for assignee lookup by name or username, especially when scoped by a board or workspace.
## Attachment Uploads
Public URL attachments work without extra setup. Local file uploads are implemented, but they are disabled by default because the MCP client asks the server process to read a file from the server's filesystem.
To enable `card_attachment_upload`, set `TRELLO_ATTACHMENT_UPLOAD_ROOT` to an absolute directory path the server may read. Upload tool `filePath` values can be relative to that directory, or absolute paths that still resolve inside it. The server resolves symlinks with `realpath`, rejects directories, and rejects files outside the configured root before it sends any Trello request.
For local stdio use:
```bash
TRELLO_ATTACHMENT_UPLOAD_ROOT=/Users/you/trello-uploads \
TRELLO_API_KEY=your-key \
TRELLO_TOKEN=your-token \
TRANSPORT=stdio \
node dist/index.js
```
For Docker, mount the upload directory into the container and set the root to the container path:
```bash
docker run --rm -p 127.0.0.1:3000:3000 \
-v "$PWD/trello-uploads:/uploads:ro" \
-e TRELLO_ATTACHMENT_UPLOAD_ROOT=/uploads \
-e TRELLO_API_KEY=your-api-key \
-e TRELLO_TOKEN=your-token \
ghcr.io/enthouan/trello-mcp:latest
```
MCP clients do not upload bytes directly through this tool; they provide a path that must exist on the server host or inside the container. For remote servers, copy or mount the file into `TRELLO_ATTACHMENT_UPLOAD_ROOT` first.
## Custom Fields
Custom field definitions live on Trello boards, and card values are exposed as card `customFieldItems`. Use `board_custom_fields` to discover board-level field definitions and their ids, `custom_field_options` to list dropdown/list options for a field, and `card_custom_field_items` to inspect values currently set on a card.
The write tool `card_custom_field_set` accepts one custom field at a time with a type-specific input shape:
| Custom field type | Input shape | Notes |
| --- | --- | --- |
| `text` | `{ "type": "text", "text": "Hello" }` | Plain text value. |
| `number` | `{ "type": "number", "number": "42" }` | Trello expects numbers as strings. |
| `date` | `{ "type": "date", "date": "2026-06-03T16:00:00.000Z" }` | Must be an ISO-8601 date/time string. |
| `checkbox` | `{ "type": "checkbox", "checked": true }` | The server sends Trello the string value Trello expects. |
| `list` | `{ "type": "list", "optionId": "<custom-field-option-id>" }` | Discover option ids with `board_custom_fields` or `custom_field_options`. |
Use `card_custom_field_clear` to clear an existing card custom field value. Trello clears custom field items with an empty PUT request shape rather than a DELETE request, so clearing is intentionally separate from setting values.
## Board Creation
`board_create` creates a new Trello board with `prefs_permissionLevel` defaulting to `private`. Pass `workspaceId` to place the board in a Trello workspace/organization and set `permissionLevel` explicitly only when you intend workspace-visible (`org`) or public (`public`) board visibility.
## API Coverage
See [docs/api-coverage.md](docs/api-coverage.md) for the Trello REST API group coverage matrix, deferred endpoint families, and current non-goals.
## Tool Catalog
<!-- tools:start -->
**77 tools** are registered. Names, descriptions, and key inputs are generated from `allTools`.
| Name | When to use | Key inputs |
| --- | --- | --- |
| `auth_whoami` | Use as a read-only credential diagnostic to confirm which Trello member the configured API key and token authenticate as. | fields |
| `auth_token_info` | Use as a read-only credential diagnostic to inspect the configured Trello token's owner, expiration, and permissions; it does not create, refresh, revoke, or manage tokens. | fields |
| `list_boards` | Use first when the user has not provided a board, list, card id, or Trello URL; returns boards visible to the authenticated Trello member. | filter, fields |
| `board_create` | Use when creating a new Trello board. Creates boards as private by default, can place them in a workspace with workspaceId, and only supports explicit private, workspace, or public visibility. | name, desc, workspaceId, permissionLevel |
| `board_get` | Use when you need board details, common board preferences, or label names for a known Trello board before listing or summarizing it. | boardId, fields |
| `board_field_get` | Use when you need one specific board field, such as prefs, labelNames, subscribed, name, description, or URL. | boardId, field |
| `board_actions` | Use when auditing recent activity or comments across a board; use filter, limit, page, since, before, and fields to keep large histories bounded. | boardId, filter, fields, limit, since, before, page, member, memberFields, memberCreator, memberCreatorFields |
| `board_lists` | Use when you need the lists on a known Trello board so you can find the right list id before listing or creating cards. | boardId, filter, fields |
| `board_cards` | Use when you need cards across all lists on a known Trello board for personal planning, review, or summarization. | boardId, filter, fields, limit, since, before |
| `board_custom_fields` | Use when inspecting custom field definitions on a known Trello board, including dropdown/list options when Trello returns them. | boardId |
| `board_labels` | Use when discovering labels available on a board before creating or updating cards with labels. | boardId, limit, fields |
| `board_members` | Use when you need the members who can access a known Trello board before assigning cards or reviewing collaboration; requires token visibility of private boards. | boardId, fields |
| `board_memberships` | Use when you need board membership records, member roles, or permission context for a known Trello board; use the admins filter when checking board-admin-only operations. | boardId, filter, member, memberFields |
| `list_workspaces` | Use first when the user asks to show Trello workspaces or needs to choose a workspace before drilling into its boards or members. | filter, fields, paidAccount |
| `workspace_get` | Use when you need basic Trello workspace metadata, such as display name, description, URL, website, board ids, or preferences. | workspaceId, fields |
| `workspace_boards` | Use when you need boards in a known Trello workspace so the user can drill into a workspace board. | workspaceId, filter, fields |
| `workspace_members` | Use when you need members in a known Trello workspace before assignment, auditing, or permission review. | workspaceId, filter, fields |
| `workspace_actions` | Use when auditing recent activity or comments across a Trello workspace; use filter, limit, page, since, before, and fields to keep large histories bounded. | workspaceId, filter, fields, limit, since, before, page, member, memberFields, memberCreator, memberCreatorFields |
| `member_get` | Use after member search or board member listing to inspect a Trello member profile by id, username, or me before assignment or auditing. | memberId, fields |
| `member_boards` | Use when you need boards associated with a known Trello member by id, username, or me; results are limited to boards visible to the configured token. | memberId, filter, fields |
| `member_cards` | Use when you need cards assigned to a known Trello member by id, username, or me; private board cards require token access to those boards. | memberId, filter, fields, limit, since, before |
| `member_workspaces` | Use when you need Trello workspaces associated with a known member by id, username, or me; workspace visibility and role permissions constrain results. | memberId, filter, fields, paidAccount |
| `list_get` | Use when you need metadata for a known Trello list before creating cards in it or changing it. | listId, fields |
| `list_create` | Use when creating a new Trello list on an existing board. | boardId, name, pos |
| `list_update` | Use when renaming a Trello list, changing its position, or setting its archive state. | listId, name, closed, pos |
| `list_archive` | Use when archiving or unarchiving a Trello list while keeping its cards recoverable. | listId, closed |
| `list_move_to_board` | Move an existing list and its cards to another board, changing who can access them. Use list_update to reorder within the current board. | listId, boardId |
| `list_actions` | Use when auditing recent activity or comments for a list; use filter, limit, page, since, before, and fields to keep large histories bounded. | listId, filter, fields, limit, since, before, page, member, memberFields, memberCreator, memberCreatorFields |
| `card_get` | Use when you need the current details of one Trello card by id, short link, or URL before editing or summarizing it. | cardId, fields |
| `card_board` | Use when you need the board relationship for a known Trello card before moving, labeling, or summarizing its context. | cardId, fields |
| `card_list` | Use when you need the current list relationship for a known Trello card before moving or reporting its status. | cardId, fields |
| `card_labels` | Use when listing the labels currently applied to a card, including label ids for add/remove workflows. | cardId |
| `list_cards` | Use when you need cards in a specific Trello list; use limit, since, before, and fields to keep large lists small. | listId, filter, fields, limit, since, before |
| `card_create` | Use when the user asks to create a new Trello card in a known list; accepts title, description, due date, members, and labels. | listId, name, desc, due, pos, memberIds, labelIds |
| `card_update` | Use when changing card metadata such as title, description, due date, due completion, or archive state without moving it. | cardId, name, desc, due, dueComplete, closed |
| `card_due_date_set` | Use when setting, clearing, or marking completion of a card due date without changing other card metadata. Provide at least one of due or dueComplete. | cardId, due, dueComplete |
| `card_position_set` | Use when changing only a card's position within its current list; use card_move when changing lists or boards too. | cardId, pos |
| `card_cover_set` | Use when setting a card cover to an existing attachment id, changing cover display size, or clearing the current attachment cover. | cardId, attachmentId, size, brightness |
| `card_label_create_and_add` | Create a new board label and apply it to this card. Use card_label_add for an existing label; repeating this creation can create duplicates. | cardId, name, color |
| `card_delete` | Use only when the user explicitly asks to permanently delete a Trello card; archive instead for reversible removal. | cardId |
| `card_move` | Use when moving a card to another list, another board, or a different position; this is distinct from general card metadata updates. | cardId, listId, boardId, pos |
| `card_archive` | Use when the user wants to archive or unarchive a card while keeping it recoverable; do not use for permanent deletion. | cardId, closed |
| `card_attachments` | Use when listing files or links attached to a card, optionally narrowed by Trello attachment fields or filter. | cardId, fields, filter |
| `card_attachment_get` | Use when inspecting one existing card attachment by attachment id, including upload metadata when Trello returns it. | cardId, fields, attachmentId |
| `card_attachment_add_url` | Use when attaching an existing public URL to a card; this does not upload local files. | cardId, url, name, setCover |
| `card_attachment_upload` | Read a server-local file inside TRELLO_ATTACHMENT_UPLOAD_ROOT and transmit its contents to Trello as a new card attachment. Disabled unless that root is configured; repeated uploads can create duplicates. Use card_attachment_add_url for public links. | cardId, filePath, name, mimeType, setCover |
| `card_attachment_delete` | Permanently delete an attachment from a card, including Trello's stored file for uploads. This cannot be undone; use card_cover_set to clear a cover without deleting its attachment. | cardId, attachmentId |
| `card_checklists` | Use when viewing all checklists and checklist items currently on a card. | cardId |
| `card_checklist_create` | Use when adding a new checklist to an existing card, optionally copied from another checklist. | cardId, name, sourceChecklistId |
| `card_checklist_update` | Use when renaming a Trello card checklist or changing the checklist's position on its card. Provide at least one of name or pos. | checklistId, name, pos |
| `card_checklist_delete` | Permanently delete a checklist and all its items from a card. This cannot be undone; use card_checklist_item_delete to remove only one item. | cardId, checklistId |
| `card_checklist_item_create` | Use when adding a new item to an existing Trello checklist on a card. | checklistId, name, pos, checked, due, dueReminder, memberId |
| `card_checklist_items` | Use when listing the items in one Trello checklist, including complete and incomplete items by default. | checklistId, filter, fields |
| `card_checklist_item_update` | Use when editing a Trello card checklist item text, due date, member assignment, completion state, checklist, or position. | cardId, checkItemId, name, state, checklistId, pos, due, dueReminder, memberId |
| `card_checklist_item_set_checked` | Use when checking or unchecking a Trello card checklist item without changing other item fields. | cardId, checkItemId, checked |
| `card_checklist_item_move` | Use when moving a Trello checklist item to another checklist on the same card or to a different position. | cardId, checkItemId, checklistId, pos |
| `card_checklist_item_delete` | Permanently delete one checklist item. This cannot be undone; use card_checklist_item_set_checked to mark completion while keeping the item. | cardId, checkItemId |
| `card_custom_field_items` | Use when reading all custom field item values currently set on a Trello card. | cardId |
| `card_custom_field_set` | Set or replace one card custom field value, using the existing definition's type from custom_field_get. Use custom_field_options to find list option ids and card_custom_field_clear to remove a value. | cardId, customFieldId, type, text, number, date, checked, optionId |
| `card_custom_field_clear` | Clear one card's custom field value without deleting the board's field definition. Restoring it requires setting the previous value with card_custom_field_set. | cardId, customFieldId |
| `card_members` | Use when listing members assigned to a card; requires token access to the card's board. Use fields to keep member output small. | cardId, fields |
| `card_member_add` | Use when assigning a Trello member to a card by member id; requires write access to the card's board and a member who can be assigned to that board. | cardId, memberId |
| `card_member_remove` | Use when unassigning a Trello member from a card by member id; requires write access to the card's board. | cardId, memberId |
| `card_comment_add` | Add a new comment to a Trello card and return its comment action. Repeating the call creates another comment; use card_comment_update to edit an existing comment. | cardId, text |
| `card_comment_update` | Use when editing the text of an existing Trello card comment by its comment action id. | actionId, text |
| `card_comment_delete` | Permanently delete a card comment by its action id. This cannot be undone; use card_comment_update to edit the text instead. | actionId |
| `card_actions` | Use when auditing recent activity or comments for a card; use filter, limit, page, since, before, and fields to page large histories. | cardId, filter, fields, limit, since, before, page, member, memberFields, memberCreator, memberCreatorFields |
| `label_get` | Use when you need the current name, color, or board for a specific Trello label before editing it. | labelId |
| `label_create` | Use when creating a new reusable label on a Trello board before applying it to cards. | boardId, name, color |
| `label_update` | Use when renaming a Trello label or changing its color without changing any card assignments. | labelId, name, color |
| `label_delete` | Use only when explicitly asked to permanently delete a board label, removing it from every card using it. Use card_label_remove to unassign it from just one card while preserving the label. | labelId |
| `card_label_add` | Use when applying an existing Trello label to a card by label id. | cardId, labelId |
| `card_label_remove` | Use when removing an existing Trello label from a card by label id. | cardId, labelId |
| `custom_field_get` | Use when you need one Trello custom field definition by id, including its type and any dropdown/list options Trello returns. | customFieldId |
| `custom_field_options` | Use when listing the available options for a Trello dropdown/list custom field before setting a card list custom field value. | customFieldId |
| `search` | Search Trello and return grouped cards, boards, members, and workspaces visible to the token. Defaults to cards and boards; scope and limit results, and use cardsPage for card pagination. Use search_members for a focused member lookup. | query, modelTypes, boardIds, organizationIds, cardIds, cardFields, boardFields, memberFields, organizationFields, cardsLimit, boardsLimit, membersLimit, organizationsLimit, cardsPage, partial, includeCardBoard, includeCardList, includeCardMembers, includeBoardOrganization |
| `search_members` | Use when looking up Trello members by name or username, optionally scoped to a board or workspace; scoped searches require token access to that board or workspace. | query, limit, boardId, organizationId, onlyOrgMembers |
<!-- tools:end -->
Regenerate the catalog with:
```bash
corepack pnpm docs:tools
```
## Architecture
Read [How trello-mcp works](docs/how-it-works.md) for the complete request
lifecycle, transport and credential boundaries, HTTP sessions, validation,
rate limiting, retries, and result handling.
```text
MCP client
-> stdio or Streamable HTTP transport
-> MCP server and tool registry
-> Trello tool handlers
-> Trello REST client
-> Trello REST API
```
- `src/index.ts` starts stdio or HTTP transport.
- `src/server.ts` creates the MCP server and registers tools.
- `src/http-auth.ts` enforces the optional `MCP_AUTH_TOKEN` bearer check on HTTP MCP requests.
- `src/trello/auth.ts` defines the read-only `auth_whoami` and `auth_token_info` credential diagnostics.
- `src/trello/client.ts` owns Trello HTTP requests, auth query parameters, retries, and response parsing.
- `src/trello/boards.ts` defines board discovery and board-level list, card, label, member, and custom field tools.
- `src/trello/workspaces.ts` defines workspace discovery, metadata, board, and member tools.
- `src/trello/members.ts` defines member profile, board, card, and workspace lookup tools.
- `src/trello/lists.ts` defines list create, inspect, update, archive, and move tools.
- `src/trello/cards.ts` defines card tools, including attachment, checklist, member, comment, action, and card custom field item helpers.
- `src/trello/labels.ts` defines label CRUD and card label assignment tools.
- `src/trello/custom-fields.ts` defines custom field definition and option lookup tools.
- `src/trello/search.ts` defines search tools for cards, boards, members, and workspaces.
- `src/trello/fields.ts` defines shared Trello field list validation helpers.
- `src/trello/types.ts` contains Trello response schemas.
- `src/utils/*` contains logging, error mapping, pagination, and tool registration helpers.
## Security Notes
- Trello credentials stay in your environment or MCP client config.
- Logs redact `TRELLO_API_KEY`, `TRELLO_TOKEN`, `MCP_AUTH_TOKEN`, authorization headers, and common key/token fields.
- Trello API requests use HTTPS.
- Set `MCP_AUTH_TOKEN` for a basic shared-secret check on HTTP MCP traffic. This does not replace HTTPS, reverse-proxy authentication, IP allowlists, or careful host binding.
- Local file attachment uploads are disabled unless `TRELLO_ATTACHMENT_UPLOAD_ROOT` is configured; upload paths are restricted to that directory.
- Tests use mocks and injected fetchers instead of live Trello calls.
- Do not publish `.env` files or paste tokens into issues and PRs.
## Security, Privacy, And Support
- See [SECURITY.md](SECURITY.md) for supported versions, vulnerability reporting, credential-handling expectations, and threat-model notes.
- See [PRIVACY.md](PRIVACY.md) for self-hosted data handling, external services, and public issue privacy guidance.
- See [SUPPORT.md](SUPPORT.md) for support channels, boundaries, and useful bug report context.
## Development
Install dependencies:
```bash
corepack enable
corepack prepare pnpm@10.34.1 --activate
corepack pnpm install --frozen-lockfile
```
Rebuild the project from scratch:
```bash
corepack pnpm build:clean
```
Run the local checks:
```bash
corepack pnpm verify
```
Run the coverage gate:
```bash
corepack pnpm verify:coverage
```
Run the opt-in live Trello smoke test:
```bash
TRELLO_LIVE_SMOKE=1 \
TRELLO_LIVE_SMOKE_BOARD_ID=your-disposable-board-id-or-short-link \
TRELLO_API_KEY=your-api-key \
TRELLO_TOKEN=your-token \
corepack pnpm smoke:live
```
Run locally in watch mode:
```bash
TRELLO_API_KEY=your-key TRELLO_TOKEN=your-token corepack pnpm dev
```
Build the Docker image locally:
```bash
corepack pnpm docker:build
```
## Codex Cloud Environments
Codex Cloud tasks run a setup script before the agent starts, and can run an optional maintenance script when a cached container resumes on a task branch. Use these repository scripts in the Codex environment settings:
```bash
./scripts/codex/setup.sh
```
```bash
./scripts/codex/maintenance.sh
```
The setup script enables Corepack, activates the pinned pnpm version, installs dependencies with `--frozen-lockfile` when `pnpm-lock.yaml` exists, and runs `pnpm typecheck`. The maintenance script repeats dependency sync and typecheck for cached containers so branch changes do not use stale dependencies.
## Troubleshooting
Start with the complete [troubleshooting guide](docs/troubleshooting.md) for a
boundary-by-boundary diagnosis of startup, stdio, HTTP sessions, Docker,
Trello API, rate-limit, and attachment failures.
### The server starts but my MCP client does not show tools
- Confirm the client is using the right transport.
- For stdio, set `TRANSPORT=stdio`.
- For HTTP, point the client to `/mcp`, not `/healthz` or `/readyz`.
- Follow the client-specific restart or reload step in the
[Set up your MCP client guide](docs/client-setup.md).
### Trello says the credentials are invalid
- Run the `auth_whoami` and `auth_token_info` tools from your MCP client to confirm the authenticated member and the token's expiration and permissions.
- Confirm the token was generated from the same Power-Up/API key.
- Regenerate the token if it was revoked.
### Docker Compose cannot find `.env`
- Copy `.env.example` to `.env`.
- Fill in `TRELLO_API_KEY` and `TRELLO_TOKEN`.
- Keep `.env` uncommitted.
### I hit Trello rate limits
- The client uses a token-bucket limiter before each Trello request. `TRELLO_RATE_LIMIT_CAPACITY` controls how many requests can run in one bucket window, and `TRELLO_RATE_LIMIT_REFILL_INTERVAL_MS` controls how often the bucket refills.
- When Trello returns HTTP `429`, the client retries with exponential backoff. `TRELLO_RETRY_MAX_ATTEMPTS` controls the total request attempts, `TRELLO_RETRY_BASE_DELAY_MS` controls the starting delay and jitter range, and `TRELLO_RETRY_MAX_DELAY_MS` caps each retry wait.
- At `LOG_LEVEL=debug`, token-bucket waits are logged as `trello rate limit wait`. HTTP `429` retries are logged as `trello request rate limited; retrying` at warn level. These logs include safe metadata such as method, resource type, resource id, attempt, max attempts, status code, and wait duration; they do not include Trello credentials, full URLs, query strings, or raw request paths.
- First narrow the prompt or workflow: target one board or list, request only needed fields, use `limit`, `since`, `before`, and `page` where available, and avoid asking an LLM to inspect every card when a smaller search or filtered read will work.
- If large workflows still wait too often, tune cautiously. For a shared token or automation that should be gentler, lower the bucket:
```bash
TRELLO_RATE_LIMIT_CAPACITY=50
TRELLO_RATE_LIMIT_REFILL_INTERVAL_MS=10000
```
- For a deliberately large, user-triggered workflow, you can allow more retries without increasing the request bucket:
```bash
TRELLO_RETRY_MAX_ATTEMPTS=5
TRELLO_RETRY_BASE_DELAY_MS=250
TRELLO_RETRY_MAX_DELAY_MS=5000
```
- Avoid raising `TRELLO_RATE_LIMIT_CAPACITY` aggressively unless you understand the Trello account and token's real workload. Higher capacity can make a broad LLM-driven workflow hit Trello's server-side limits faster.
- Wait a few minutes before retrying a workflow after repeated `429` responses.
## Contributing
PRs are welcome. Keep changes focused, add tests for behavior changes, and avoid
committing secrets or local build and test output. When canonical documentation
or public tool data changes, run `corepack pnpm docs:tools` and include the
legitimate checked-in generated documentation mirrors.
Before opening a PR, run:
```bash
corepack pnpm typecheck
corepack pnpm lint
corepack pnpm build
corepack pnpm test
```
## License
MIT License. See [LICENSE](./LICENSE).
TDQS
Scored across 77 tools
Descriptions work hard to draw boundaries (card_archive vs card_delete, card_move vs card_position_set, card_label_add vs card_label_create_and_add, and the four *_actions tools scoped by resource). However, real overlaps remain: card_update explicitly covers due dates and archive state that card_due_date_set and card_archive also handle, and card_checklist_item_update claims completion state, checklist, and position — all owned by card_checklist_item_set_checked and card_checklist_item_move.
The dominant pattern is <resource>_<action> (board_get, card_create, label_delete), which is readable and mostly followed. But the `list_` prefix is overloaded: list_boards/list_workspaces mean 'enumerate', while list_get/list_update/list_archive mean 'the list resource' — and card_list vs list_cards are near-identical names with opposite meanings. That collision is a genuine trap for an agent.
77 tools is far beyond a reasonable surface and the granularity is excessive: board_get vs board_field_get, card_list vs card_board vs card_get, and separate tools for due date, position, cover, and archive on a card. While Trello is a large domain, many tools could be folded into a single card_update or board_get variant.
Coverage is broad and deep: full card lifecycle (create/update/move/archive/delete), checklists, labels, attachments, custom field values, members, workspaces, actions, and search. Gaps remain — no board update/archive/delete, no custom field definition create/update/delete (only get/options), and no board member add/remove, so board-level mutation is a dead end.