favro-mcp
by tecbay
README.md
# favro-mcp
An MCP server that gives your AI assistant read access to [Favro](https://favro.com) — collections, boards, cards, comments and checklists.
**Read-only by design.** Every one of the 14 tools issues a `GET` and nothing else. There is no code path in this package that can create, change, archive or delete anything in your Favro account — a test asserts it on every commit. You are handing over an API token, so that guarantee is the point.
## Install
Nothing to install. Point your MCP client at `npx`:
```jsonc
{
"mcpServers": {
"favro": {
"command": "npx",
"args": ["-y", "favro-mcp"],
"env": {
"FAVRO_EMAIL": "you@example.com",
"FAVRO_API_TOKEN": "your-api-token",
"FAVRO_ORGANIZATION_ID": ""
}
}
}
}
```
Requires Node 18 or newer.
### Getting a Favro API token
In Favro: **profile menu → My profile → API tokens → Create new token**. The token pairs with the email address you sign in with; both are needed.
`FAVRO_ORGANIZATION_ID` is optional. Leave it empty and ask your assistant to run `list-organizations` — it will return the ids you have access to, and you can either paste one into the config or let the assistant pass it per call.
### Per-client setup
<details>
<summary><b>Claude Code</b></summary>
```bash
claude mcp add favro --env FAVRO_EMAIL=you@example.com --env FAVRO_API_TOKEN=your-api-token -- npx -y favro-mcp
```
Or add the JSON block above to `.mcp.json` in your project root.
</details>
<details>
<summary><b>Claude Desktop</b></summary>
Edit `claude_desktop_config.json`:
- macOS — `~/Library/Application Support/Claude/claude_desktop_config.json`
- Windows — `%APPDATA%\Claude\claude_desktop_config.json`
Paste the JSON block above, then **fully quit and reopen** Claude Desktop — reloading the window is not enough.
</details>
<details>
<summary><b>Cursor</b></summary>
Edit `~/.cursor/mcp.json` (global) or `.cursor/mcp.json` (per project) and paste the JSON block above.
</details>
<details>
<summary><b>VS Code</b></summary>
Add to `.vscode/mcp.json`, using `servers` rather than `mcpServers`:
```jsonc
{
"servers": {
"favro": {
"command": "npx",
"args": ["-y", "favro-mcp"],
"env": {
"FAVRO_EMAIL": "you@example.com",
"FAVRO_API_TOKEN": "your-api-token"
}
}
}
}
```
</details>
## Tools
| Tool | Purpose | Required arguments |
|---|---|---|
| `list-organizations` | Organizations the account belongs to | — |
| `list-collections` | Collections shared with the account | — |
| `get-collection` | One collection | `collectionId` |
| `list-boards` | Boards and backlogs, optionally by collection | — |
| `get-board` | One board, with its columns and lanes | `widgetCommonId` |
| `list-columns` | A board's columns | `widgetCommonId` |
| `list-cards` | Cards on a board, in a collection, or in your todo list | one of `widgetCommonId`, `collectionId`, `cardCommonId`, `cardSequentialId`, or `todoList: true` |
| `get-card` | Full detail on one card | `cardId` |
| `search-cards` | Find cards by text in their name or description | `query` plus `widgetCommonId` or `collectionId` |
| `list-card-comments` | A card's comments | `cardCommonId` |
| `list-card-tasklists` | A card's checklists | `cardCommonId` |
| `list-card-tasks` | Checklist items | `cardCommonId` |
| `list-users` | Users in the organization | — |
| `get-user` | One user | `userId` |
Every tool also accepts an optional `organizationId` to override the configured default.
## Configuration
| Variable | Required | Default | Purpose |
|---|---|---|---|
| `FAVRO_EMAIL` | yes | — | The email you sign in to Favro with |
| `FAVRO_API_TOKEN` | yes | — | An API token from your Favro profile |
| `FAVRO_ORGANIZATION_ID` | no | — | Default organization; otherwise pass `organizationId` per call |
| `FAVRO_CACHE_TTL` | no | `600` | Seconds to cache slow-changing entities. `0` disables caching |
## Things worth knowing
### The API's vocabulary differs from the UI
| API term | What you see in Favro |
|---|---|
| widget | A board or backlog |
| tasklist | A checklist on a card |
| task | A single checklist item |
### Cards have two ids
- **`cardId`** identifies one card on one board. `get-card` takes this.
- **`cardCommonId`** identifies the card across every board it appears on. The comment and checklist tools take this.
Both come back from `list-cards` and `get-card`.
### A typical path through the hierarchy
```
list-organizations (only when FAVRO_ORGANIZATION_ID is unset)
→ list-collections find the collection
→ list-boards boards in that collection
→ get-board its columns and lanes, in one call
→ list-cards cards on the board or in a column
→ get-card full detail on one card
→ list-card-comments / list-card-tasklists / list-card-tasks
```
### Pagination
Listings return up to 100 entities. When more remain, the response carries a cursor:
```json
"pagination": {
"page": 0,
"pages": 3,
"requestId": "...",
"backendId": "...",
"next_page": { "page": 1, "requestId": "...", "backendId": "..." }
}
```
Call the same tool again passing `page`, `requestId` and `backendId` exactly as given. All three are required — Favro routes follow-up pages to the same backend server, and the `backendId` is what gets them there.
### `search-cards` is a local filter, not a search endpoint
Favro's API has no card search. `search-cards` reads cards from a board or collection and filters them by case-insensitive substring on name and description. It reads up to `maxPages` pages (default 3, maximum 10), each costing one API call, and reports what it covered:
```json
"scan": {
"cards_scanned": 250,
"matches_found": 4,
"pages_read": 3,
"pages_available": 5,
"complete": false,
"note": "Only 3 of 5 pages were searched. Raise maxPages..."
}
```
When `complete` is `false`, narrow the scope or raise `maxPages` rather than treating the result as exhaustive.
### Rate limits and caching
Favro's hourly budget is low and plan-dependent — 100/hour on Trial up to 10,000/hour on Enterprise, with `list-organizations` and the user tools sharing a separate 50/hour budget. Every response carries a `rate_limit` block showing what is left.
To conserve calls, organizations, users, collections, boards and columns are cached for `FAVRO_CACHE_TTL` seconds. Cached responses are marked `"cached": true`. Cards, comments and checklists are never cached, so they are always current.
## Not covered
Tags, custom field definitions, groups and webhooks are not exposed, and nothing writes to Favro. Open an issue if you need something added.
## Development
```bash
npm install
npm test
npm run build
```
Inspect the server interactively against your real account:
```bash
FAVRO_EMAIL=you@example.com FAVRO_API_TOKEN=your-token npx @modelcontextprotocol/inspector node dist/index.js
```
## License
MIT
TDQS
A4/5.0
Scored across 14 tools
Disambiguation5/5
Every tool targets a distinct resource and action, with clear boundaries between listing, getting, and searching. Even tools like list-cards and search-cards are differentiated by scoping and behavior.
Naming Consistency5/5
All tools follow a consistent verb_noun pattern using either 'list-' for collections or 'get-' for single entities, making the naming predictable and easy to understand.
Tool Count5/5
14 tools is a well-scoped set for a project management API, covering all major resource types without being bloated or sparse.
Completeness2/5
The tool set is entirely read-only, lacking any create, update, or delete operations for cards, boards, comments, etc. This is a significant gap for typical workflow automation, severely limiting the server's utility.
Maintenance
ActivitySlowing
ResponsivenessNo issues