Skip to main content
Glama

teamboard-mcp

MCP server for TeamBoard. Lets any MCP-aware client (Claude Code, etc.) read and write TeamBoard tasks over the HTTP API.

You never pass an ObjectId. Tasks are referenced by TASK-42 (any casing or zero-padding) or by title; people by name, email or username; projects by code or name. When a reference is ambiguous the tool returns the candidate list instead of guessing — so an edit never lands on the wrong task or the wrong assignee.

Usage (no install)

Add this to your Claude Code MCP config (~/.claude.json, or .mcp.json in any project):

{
  "mcpServers": {
    "teamboard": {
      "command": "npx",
      "args": ["-y", "github:uplsuman/teamboard-mcp"],
      "env": {
        "TEAMBOARD_BASE_URL": "https://teamboard.utplco.com",
        "TEAMBOARD_TOKEN": "tbp_..."
      }
    }
  }
}

Generate the token in TeamBoard → Settings → API Tokens. Grant the scopes for what you want it to do:

scope

unlocks

tasks:read tasks:write

search, read, create, edit, subtasks, links, attachments, saved filters, global search

comments:write

post, edit and delete comments

projects:read

project list and member rosters (needed to resolve an assignee)

users:read

people lookup, assignee: "me", people in global search

tags:read

the tag vocabulary

time:read time:write

time logs, timers, manual entries

notifications:read notifications:write

read your inbox, mark items read

MCP servers only pick up env changes on restart — run /mcp to reconnect after

changing the token.

Related MCP server: Trello MCP Server

Tools

Tool

What it does

search_teamboard_tasks

Find tasks by keyword and/or filters — assignee (incl. "me"), project, status[], priority[], type[], dueBefore, dueAfter — or raw jql, or a savedFilter by name. Call before creating, to catch duplicates.

search_teamboard

One query across tasks, projects, people, departments and saved filters.

get_teamboard_task

Full detail for one task, plus any of include: ["comments","subtasks","links","attachments","history","time"]. Comment ids are printed for the edit/delete tools.

create_teamboard_task

Create a task. Project by code or name, assignee/reporters by name.

edit_teamboard_task

Update title, description, status, priority, type, assignee, reporters, dates, progress, tags, project, parent task, watchers.

create_teamboard_subtask

Add a subtask under a task; inherits the parent's project.

link_teamboard_tasks / unlink_teamboard_tasks

Typed relationships: blocks, blocked_by, clones, cloned_by, splits_into, splits_from, causes, caused_by, duplicate_of, relates_to. The inverse is implied.

comment_teamboard_task

Post a comment (HTML), a threaded reply with replyTo, and/or attach local files.

react_to_teamboard_comment

Toggle an emoji reaction on a comment.

my_teamboard_notifications

Your inbox — mentions, assignments, due reminders, team digests.

read_teamboard_notifications

Mark one read, or all.

edit_teamboard_comment / delete_teamboard_comment

Change or remove a comment by id — your own, or any as an admin.

add_teamboard_attachment

Upload a local file onto a task.

download_teamboard_attachment

Save an attachment to a local file.

delete_teamboard_attachment

Detach a file and delete it from storage.

log_teamboard_time

Record work already done (minutes). Manual entries start pending approval.

start_teamboard_timer / stop_teamboard_timer

Run the clock on a task. One foreground timer at a time.

my_teamboard_timers

What you are tracking right now, and for how long.

list_teamboard_filters / save_teamboard_filter / delete_teamboard_filter

Saved JQL queries; run one with search_teamboard_tasks { savedFilter }.

list_teamboard_tags

The workspace tag vocabulary — reuse a name rather than inventing a variant.

delete_teamboard_task

Permanently delete a task (admin only, irreversible).

list_teamboard_projects

Projects you can see, with their codes.

list_teamboard_users

People by name/email; pass project for just that project's members.

Notes that bite:

  • Rich text is HTML. description and comment take literal <h3>/<ul>/<li>/<strong>/<code> markup, not plain text with newlines.

  • An assignee must be a member of the task's project. list_teamboard_users with project shows who is eligible; the assignee lookup is scoped to that roster, so a non-member name fails with the roster rather than picking someone.

  • tags replaces the whole list — pass every tag you want to keep.

  • "none" clears assignee, project, parent or type.

  • Statuses, priorities, task types and resolutions are read from the workspace at startup, so the tool descriptions list your real values and a typo is rejected locally. Resolutions are the one exception to local rejection: a project may override the workspace list, so the value is sent as given and the server judges it.

  • Moving a task to another project changes its task id; the tool reports the new one.

  • Two arguments are mandatory for the moves that need them, not optional extras:

    • resolution — moving a task into a done status (Completed, Cancelled, Closed…). A status says where a task is; the resolution says how it ended, and the move is refused without one.

    • trackerDecision — moving a task into an in-progress status, which would start the assignee's timer. Pass skip to change the status without starting a timer, or foreground to start it. The other values resolve a clash when that person is already tracking something.

  • Other server rules surface as tool errors and need a follow-up argument: clarification (10+ chars) when an active task's due date or status changes.

Development

pnpm install
node test.mjs            # resolution tests, no network (fetch is stubbed)

TEAMBOARD_BASE_URL=http://localhost:3000 TEAMBOARD_TOKEN=tbp_xxx node index.js

resolve.js holds the API client and the reference resolvers; index.js is only tool definitions and formatting.

Performance notes

  • Sections load in parallel. get_teamboard_task with a full include issues its five sub-requests together rather than one after another.

  • Resolutions are cached for 60s. The same project code or person's name costs one round trip per minute, not one per tool call. The TTL is deliberately short: a stale hit here would address the wrong row. invalidateCache() clears it.

  • Every request has a 30s timeout, and an unreachable server fails with the base URL in the message instead of hanging the tool call.

  • Long lists are capped (25 rows per section, 4 children per digest notification) with an "…and N more" line, so one busy task cannot bury the rest of a reply.

  • Tool schemas cost ~5.4k tokens for 28 tools. The workspace vocabulary is listed once per tool, on the field that needs it, not repeated in the description.

Attachments are addressed by name, never by their storage URL, and an ambiguous name lists the candidates rather than picking one — deleting the wrong file is not recoverable.

Requires

TeamBoard with personal-access-token support on /api/tasks, /api/tasks/meta, /api/tasks/statuses, /api/tasks/:id/{subtasks,links,activities}, /api/projects, /api/projects/:id/members, /api/users, /api/users/me, /api/comments, /api/comments/:id and /api/uploads/* (TB dev after Sep 2026).

Related MCP Connectors

Related MCP Servers