npm package: @florianindustries/saku-mcp
Description: Official Saku MCP server — lets AI agents and tools interact with your Saku boards, lists, and cards.
Latest version: 1.0.1

# @florianindustries/saku-mcp

Official [Model Context Protocol (MCP)](https://modelcontextprotocol.io) server for **[Saku](https://saku.ie)** — boards, lists, and cards exposed as tools so Claude Desktop, Cursor, and other MCP hosts can read and update your work over the Saku REST API.

The process runs **locally** (stdio transport). Your API key is passed via environment variables; traffic goes to Saku’s servers only.

---

## Requirements

- **Node.js 20+**
- A Saku account on a team with the **Max** plan (API keys are a Max feature)
- A **scoped Saku API key** (`saku_live_…`) with the permissions you need (see [Permissions](#permissions))

---

## Quick start

1. **Create an API key** (browser): [https://saku.ie/mcp/authorize](https://saku.ie/mcp/authorize)  
   Pick the team, key name, and **only** the scopes your assistant should have.

2. **Configure your MCP host** so the server runs with `SAKU_API_KEY` set (examples below).

3. **Restart** the host and confirm Saku tools appear (e.g. hammer icon in Claude Desktop).

One-off test from a terminal (prints a fatal error if the key is missing, then exits — useful only to verify the binary runs):

```bash
export SAKU_API_KEY="saku_live_…"
npx -y @florianindustries/saku-mcp
```

Normal use is always via an MCP host that spawns this command and keeps stdio open.

---

## Environment variables

| Variable | Required | Description |
|----------|----------|-------------|
| `SAKU_API_KEY` | **Yes** | Your Saku API key (`saku_live_…`). |
| `SAKU_BASE_URL` | No | API origin. Default: `https://saku.ie` (no trailing slash). Use this for self-hosted or staging installs. |

You can also use a `.env` file in the **current working directory** when the process starts (the package loads `dotenv/config`). MCP hosts usually set `env` in JSON config instead.

---

## Host configuration

### Claude Desktop

Edit `claude_desktop_config.json`:

- **macOS:** `~/Library/Application Support/Claude/claude_desktop_config.json`
- **Windows:** `%APPDATA%\Claude\claude_desktop_config.json`

```json
{
  "mcpServers": {
    "saku": {
      "command": "npx",
      "args": ["-y", "@florianindustries/saku-mcp"],
      "env": {
        "SAKU_API_KEY": "saku_live_your_key_here"
      }
    }
  }
}
```

Replace the key value with your real key. Restart Claude Desktop.

### Cursor

**Settings → MCP → Add server** (or edit your MCP config JSON). Use the same `command`, `args`, and `env` as above (you can keep the server id `saku` or rename it).

### Other hosts

Any client that supports **stdio** MCP servers can run:

- **Command:** `npx`
- **Arguments:** `-y`, `@florianindustries/saku-mcp`
- **Environment:** `SAKU_API_KEY` (and optionally `SAKU_BASE_URL`)

---

## Tools

| Tool | API scope | What it does |
|------|-----------|----------------|
| `list_boards` | `boards:read` | List boards with lists, labels, and board-level member roles. |
| `get_board` | `boards:read` | Full board with lists and cards. |
| `create_card` | `cards:create` | Create a card in a list. |
| `get_card` | `cards:read` | Card details, checklists, assignees, labels. |
| `update_card` | `cards:update` | Patch title, description, priority, due date. |
| `create_list` | `lists:create` | Add a list (column) to a board. |
| `list_members` | `members:read` | Team member IDs, names, and emails (via `GET /api/v1/members`). |

Typical flow: **`list_boards`** or **`get_board`** to discover `boardId` / `listId`, then create or update cards.

Card priorities (for `update_card`): `CRITICAL`, `URGENT`, `HIGH`, `MEDIUM`, `LOW`, `MINOR`, or `null` to clear.

---

## Permissions

Keys are **immutable** after creation — to change scopes, create a new key and revoke the old one in **Dashboard → Settings → API**.

| Scope | Enables |
|-------|---------|
| `boards:read` | `list_boards`, `get_board` |
| `cards:read` | `get_card` |
| `cards:create` | `create_card` |
| `cards:update` | `update_card` |
| `lists:create` | `create_list` |
| `members:read` | `list_members` |

**Note:** `boards:read` does **not** include the team member directory. Names and emails for assignees require **`members:read`**; without it, board payloads omit the `teamMembers` field and you should use **`list_members`** when that scope is granted.

---

## Documentation

- **MCP overview & security:** [https://saku.ie/docs/mcp](https://saku.ie/docs/mcp)  
- **REST API (same key and scopes):** [https://saku.ie/docs/api](https://saku.ie/docs/api)  
- **Create / manage keys:** [https://saku.ie/mcp/authorize](https://saku.ie/mcp/authorize) and **Dashboard → Settings → API**

---

## Troubleshooting

| Symptom | What to check |
|---------|----------------|
| `SAKU_API_KEY is not set` | `env.SAKU_API_KEY` in MCP config; restart the host after editing. |
| `Unauthorized` | Key revoked, typo, or wrong team. Create a new key if needed. |
| `Missing permission: …` | Tool needs a scope your key does not have. Create a new key with that scope. |
| Timeouts | Default HTTP timeout is 60s; very slow networks or large boards may need a retry or smaller requests via the REST API. |
| Tools missing in the UI | Node 20+ on `PATH`; restart the host after config changes. |

---

## Development (from this repo)

```bash
cd mcp
npm install
npm run build
export SAKU_API_KEY="saku_live_…"
node dist/index.js
```

Or `npm run dev` (watch mode) while iterating.

---

## Security notes

- One key is tied to **one Saku team**. Use separate keys for separate teams or tools.
- Prefer the **minimum** permissions for the workflow.
- The server does not store your boards; it forwards requests to Saku’s API.
- Revoke keys you no longer use.

---

## Licence

MIT — see `package.json` in the published package.

---

## Publisher

Published under the **`@florianindustries`** scope on npm. Saku is a product of [saku.ie](https://saku.ie).