zube-mcp
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@zube-mcp List cards in workspace 'Backlog' for project 'Web App'"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
zube-mcp
MCP server for the Zube.io project management API. Exposes Zube boards, cards, epics, tickets, sprints, and workspaces as tools that AI assistants can call.
Setup
Prerequisites
Python 3.10+
uv:
macOS:
brew install uvWindows:
powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"orwinget install astral-sh.uvAny platform:
pip install uv
SSH access to this GitHub repo
1. Get your Zube API credentials
Go to Zube.io → Account Settings → API Keys
Create a new API key — this gives you a Client ID and a private key file (PEM)
Save the private key somewhere safe (e.g.
~/.zube/private-key.pem)
2. Configure in Cursor
Add to your .cursor/mcp.json (project-level or global ~/.cursor/mcp.json):
{
"mcpServers": {
"zube": {
"command": "uvx",
"args": ["--from", "git+ssh://git@github.com/reachreporting/zube-mcp", "zube-mcp"],
"env": {
"ZUBE_CLIENT_ID": "your-client-id-here",
"ZUBE_PRIVATE_KEY_PATH": "/path/to/your/private-key.pem"
}
}
}
}Replace the env values with your own Zube credentials. uvx will install the package directly from GitHub — no clone needed.
To pin a specific version, tag a release and append it to the URL:
git+ssh://git@github.com/reachreporting/zube-mcp@v0.3.0Alternative: local install
If you prefer to clone and run locally:
git clone git@github.com:reachreporting/zube-mcp.git
cd zube-mcp
pip install -e .Then point the Cursor config at your local path:
"args": ["--from", "/path/to/zube-mcp", "zube-mcp"]Related MCP server: Fizzy Do MCP
Development
Making changes
After editing the source code, you must bump the version in pyproject.toml for Cursor to pick up changes. This is because uvx caches the built package by version — if the version hasn't changed, it serves the stale cached copy.
# 1. Edit code in zube_mcp/
# 2. Bump version in pyproject.toml (e.g. 0.2.0 → 0.3.0)
# 3. Commit and push
# 4. In Cursor: Settings → MCP → toggle zube off, then onTo verify your changes locally before restarting Cursor:
uvx --from . python3 -c "
from zube_mcp.server import mcp
import inspect
from zube_mcp.server import list_cards
print(inspect.signature(list_cards))
"Zube API reference
Full API docs: https://zube.io/docs/api
Key concepts for adding new filters:
List endpoints support
where[field]=valuequery params for filteringThe
_build_params()helper inserver.pyconverts awheredict into these query params automaticallyArray filters (e.g.
assignee_ids) usewhere[field][]=value(handled by_build_paramswhen the value is a list)Card numbers (the
#12345visible in the UI) are distinct from internal card IDs — usewhere[number]to filter by the visible number
Known Zube API quirks
get_cardrequires the internal card ID, not the visible card number. Useget_card_by_numberto look up by the human-visible#number.search_keyon list endpoints is a full-text search and can be unreliable for finding cards by number.List responses return items in
dataarray with apaginationobject.Rate limit: 1 request/second. Short bursts are tolerated but sustained higher rates will be rejected.
Available Tools
Person & Accounts
Tool | Description |
| Get the authenticated user's profile |
| List organizations the user belongs to |
| Get details for a specific account |
Projects
Tool | Description |
| List projects (optionally by account) |
| Get project details |
| Create a new project |
Workspaces (Kanban Boards)
Tool | Description |
| List workspaces (optionally by project) |
| Get workspace details |
| Create a new workspace |
Cards (Issues / PRs)
Tool | Description |
| List cards with filters (project, workspace, sprint, epic, number, state, search) |
| List cards scoped to a project (also supports number filter) |
| List cards in a project's triage |
| Get full card details by internal ID |
| Look up a card by its visible |
| Create a card |
| Update a card |
| Move a card to a column or triage |
| Archive a card |
Card Comments
Tool | Description |
| List comments on a card |
| Add a comment |
| Edit a comment |
| Delete a comment |
Epics
Tool | Description |
| List epics for a project |
| Get epic details |
| Create an epic |
| Update an epic |
| List cards in an epic |
Sprints
Tool | Description |
| List sprints for a workspace |
| Get sprint details |
| Create a sprint |
| Update a sprint |
Tickets
Tool | Description |
| List tickets for a project |
| Get ticket details |
| Create a ticket |
| Update a ticket |
Labels & Members
Tool | Description |
| List project labels |
| Create a label |
| List connected GitHub repos |
| List project members |
| List account members |
Architecture
zube_mcp/
auth.py # RS256 JWT creation for Zube's refresh token flow
client.py # Async HTTP client with automatic token management
server.py # FastMCP tool definitions (40 tools)The auth flow:
Sign a 60-second JWT with your private key
Exchange it at
POST /api/users/tokensfor a 24-hour access tokenThe client auto-refreshes when the token is near expiry
Available Tools
42 toolsarchive_cardC
Archive a card.
Inputs: card_id (required). Returns: object
create_cardB
Create a new card (issue) in a project.
priority: 1-5 (1=highest). category_name: column name on the workspace board.
Inputs: title (required), project_id (required), body, points, +7 more. Returns: object
create_card_commentB
Add a comment to a card.
Inputs: body (required), card_id (required). Returns: object
create_card_relationA
Create a Related Card link between two cards (Zube "Related cards" feature).
card_id: the card that will show the link; linked_card_id: the card it is linked to.
Inputs: card_id (required), linked_card_id (required). Returns: object
create_epicC
Create an epic in a project. color: hex without '#'. due_on: ISO timestamp.
Inputs: title (required), project_id (required), color, due_on, +4 more. Returns: object
create_labelB
Create a label in a project. color: hex code without '#' (e.g. 'FF5733').
Inputs: name (required), color (required), project_id (required). Returns: object
create_projectC
Create a new project within an account.
Inputs: name (required), account_id (required), description. Returns: object
create_sprintB
Create a sprint. Dates are ISO timestamps (e.g. '2026-03-01T00:00:00Z').
Inputs: title (required), end_date (required), start_date (required), workspace_id (required), +1 more. Returns: object
create_ticketC
Create a ticket. type: task/bug/feature/question. priority: 1-4 (1=highest).
Inputs: title (required), project_id (required), due_on, priority, +6 more. Returns: object
create_workspaceA
Create a new workspace (Kanban board) within a project.
Inputs: name (required), project_id (required), description. Returns: object
delete_card_commentB
Delete a comment from a card.
Inputs: card_id (required), comment_id (required). Returns: result
get_accountA
Get details for a specific Zube account (organization).
Inputs: account_id (required). Returns: object
get_cardA
Get full details for a specific card by its internal ID.
Inputs: card_id (required). Returns: object
get_card_by_numberA
Look up a card by its visible card number (e.g. #15293).
Optionally scope to a project_id. Returns full card details including assignees and labels. Returns an error dict if no card is found.
Inputs: number (required), project_id. Returns: object
get_current_personA
Get the currently authenticated Zube user's profile information.
Inputs: no named parameters. Returns: object
get_epicC
Get details for a specific epic.
Inputs: epic_id (required), project_id (required). Returns: object
get_projectA
Get details for a specific project including its workspaces and sources.
Inputs: project_id (required). Returns: object
get_sprintC
Get details for a specific sprint.
Inputs: sprint_id (required), workspace_id (required). Returns: object
get_ticketB
Get details for a specific ticket.
Inputs: ticket_id (required), project_id (required). Returns: object
get_workspaceA
Get details for a specific workspace.
Inputs: workspace_id (required). Returns: object
list_account_membersB
List all members of an account (organization).
Inputs: account_id (required), page, per_page. Returns: object
list_accountsB
List all Zube organizations (accounts) the current user belongs to.
Inputs: page, per_page. Returns: object
list_card_commentsC
List comments on a card.
Inputs: card_id (required), page, per_page. Returns: object
list_cardsA
List cards (issues/PRs) with optional filters.
Filters: project_id, workspace_id, sprint_id, epic_id, number (visible card number), state (open/closed), category_name (column name), search_key (text search). Order by any card field; direction is 'asc' or 'desc'.
Inputs: page, state, number, epic_id, +8 more. Returns: object
list_epic_cardsB
List all cards belonging to an epic.
Inputs: epic_id (required), page, per_page. Returns: object
list_epicsA
List epics for a project. state: open/closed. status: new/queued/in_progress/completed/closed/archived.
Inputs: project_id (required), page, state, status, +1 more. Returns: object
list_labelsB
List all labels for a project.
Inputs: project_id (required), page, per_page. Returns: object
list_project_cardsA
List cards scoped to a specific project with filtering and ordering.
number: filter by visible card number (e.g. 15293). assignee_ids: filter to cards assigned to these person IDs. label_names: filter to cards with these label names.
Inputs: project_id (required), page, state, number, +8 more. Returns: object
list_project_membersB
List all members of a project.
Inputs: project_id (required), page, per_page. Returns: object
list_projectsA
List all projects. Optionally filter by account_id.
Inputs: page, per_page, account_id. Returns: object
list_sourcesA
List all connected GitHub repositories (sources).
Inputs: page, per_page. Returns: object
list_sprintsC
List sprints for a workspace. state: open/closed.
Inputs: workspace_id (required), page, state, per_page. Returns: object
list_ticketsB
List tickets for a project. state: open/closed. status: new/queued/in_progress/completed/closed/archived. priority: 1-4.
Inputs: project_id (required), page, state, status, +3 more. Returns: object
list_triage_cardsA
List cards in a project's triage (unassigned to any workspace column).
Inputs: project_id (required). Returns: object
list_workspacesA
List all workspaces (Kanban boards). Optionally filter by project_id.
Inputs: page, per_page, project_id. Returns: object
move_cardA
Move a card to a column on a workspace board or to project triage.
destination_type: 'category' (move to a board column) or 'project' (move to triage). For 'category', workspace_id and category_name are required.
Inputs: card_id (required), position (required), workspace_id, category_name, +1 more. Returns: object
update_cardA
Update an existing card. Only provided fields are changed.
state: 'open' or 'closed'. priority: 1-5 or null.
Inputs: card_id (required), body, state, title, +8 more. Returns: object
update_card_commentC
Update an existing comment on a card.
Inputs: body (required), card_id (required), comment_id (required). Returns: object
update_epicC
Update an epic. state: open/closed. status: new/queued/in_progress/completed/closed/archived.
Inputs: epic_id (required), project_id (required), color, state, +7 more. Returns: object
update_projectA
Update a project's name, description, or settings.
color: hex code without '#' (e.g. 'FF5733'). Zube requires name on PUT — it is fetched from the current project if not provided.
Inputs: project_id (required), name, color, description, +2 more. Returns: object
update_sprintC
Update a sprint. state: 'open' or 'closed'.
Inputs: sprint_id (required), workspace_id (required), state, title, +3 more. Returns: object
update_ticketB
Update a ticket. state: open/closed. status: new/queued/in_progress/completed/closed/archived.
Inputs: ticket_id (required), project_id (required), state, title, +9 more. Returns: object
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 42 tools
The set includes multiple card-listing tools with overlapping scopes: list_cards, list_project_cards, list_triage_cards, and list_epic_cards. While filters could consolidate these, the redundancy creates ambiguity about which tool to select. Most other tools are clearly distinct.
All tools follow a consistent verb_noun pattern in snake_case (list_, get_, create_, update_, move_, archive_, delete_). No style mixing or vague verbs; one can predict tool names from the resource.
With 42 tools, the surface is heavy for a project management server. Several tools overlap (card listers) and some entities have many CRUD variants, inflating the count beyond what is necessary.
Core card lifecycle is well covered (create, read, update, move, archive, comment), but notable gaps include no update/delete for workspaces, no label update/delete, and no relation listing/deletion. These are workable but not full CRUD.
Maintenance
Related MCP Connectors
Nifty's MCP server — exposes tasks, projects, messages, and files as tools for AI agents.
MCP server for your apps' tools and custom tools, plus hosted AI agents and approval-gated workflows
MCP server that lets AI assistants use all OneSchema features exposed via the public API.
Task & board management for AI agents + humans. Kanban, comments, digests via MCP.
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceMCP server that wraps the jira-cli command-line tool to enable AI assistants to interact with Jira.14 npm9MIT
- AlicenseNot gradedqualityDmaintenanceOpen-source MCP server that connects AI assistants to Fizzy (Basecamp's task management) with 70+ tools for boards, cards, workflows, and AI-powered project management.24 npm3MIT
- AlicenseNot gradedqualityBmaintenanceMCP server that enables AI agents to manage tasks, boards, lists, and comments on a Kanban-style project management system through JSON-RPC methods.9 npm2AGPL 3.0
- AlicenseBqualityDmaintenanceFull-featured MCP server for Taiga project management, enabling AI agents to manage projects, epics, user stories, tasks, issues, sprints, wiki pages, memberships, and roles via Taiga API v1.10039 npm6MIT