EasyTopic MCP Server
OfficialAuthentication: Call easytopic_whoami first to authenticate and retrieve configuration.
Kanban / Task Management:
List and get topics (tasks), including descriptions, plans, comments, and status.
Transition topic statuses through a predefined workflow (e.g., todo → planning → planned → in_progress → done), enforcing checks; never self-approve or close.
Write implementation plans and add comments for communication.
Documentation:
List documentation projects and their page trees.
Get full page content (rich-text HTML).
Update existing pages (title, content, meta description); changes are versioned.
Create new pages (requires admin role).
Conventions: The bot respects human-only steps (approval, closure) and maps errors to familiar check IDs.
Provides tools to manage EasyTopic Kanban boards stored in Firebase, including creating, updating, and transitioning topics, and adding comments via Firebase Cloud Functions.
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., "@EasyTopic MCP Serverpull the next topic from the ToDo column and begin planning"
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.
EasyTopic MCP server
Also mirrored publicly at
github.com/EB-CON-GmbH/easytopic-mcp-server
for reuse outside this monorepo (one-way export via git subtree split,
re-run manually after a significant change here — see Topic
c6seMyvsgYKaQjEOdzt8).
Lets a Claude Code agent in any project pull its work from an EasyTopic Kanban board instead of a human typing prompts into the console: it picks up Topics in "ToDo", plans, asks questions via comments, waits for a human approval column, implements, and closes the ticket.
EasyTopic's data model: companies/{companyId}/projects/{projectId}/topics/{topicId}
is the actual task/ticket, gated by participancy (a participantUids: string[]
array on the Topic, not company employment) — see "Why sign in as a real
Firebase Auth user" below for why that matters for this server specifically.
Standalone package (own package.json/tsconfig.json, no dependency on any
other part of the EasyTopic app).
Why sign in as a real Firebase Auth user, not Admin SDK
firestore.rules requires changedBy == request.auth.uid on history
writes, plus an exact participantUids array match against the live
Topic. Only a genuine client-SDK sign-in satisfies that — so this server
authenticates (signInWithEmailAndPassword) as a dedicated bot Firebase
Auth account, onboarded exactly like a human teammate (Company employee +
Project participant). That also means rules enforcement and Topic History
bookkeeping work automatically, with zero extra code.
Comments are the one write this authenticated client does NOT make
directly: firestore.rules' comments create rule is if false for
every caller (rate-limiting reasons) — addComment()
(src/topics.ts) instead calls the app's createTopicComment Cloud
Function via client.functions, the same callable the app's own web UI
uses. The onTopicCommentCreated notification fan-out still fires either
way, since it triggers off the resulting Firestore write regardless of
whether that write came from a direct client SDK call or a Cloud
Function.
Related MCP server: vibeops
One-time EasyTopic setup (per target Company/Project — no app code changes)
All of this is done through the existing app UI (Workflow / Topic / Board Designer are already shipped):
Bot account — sign up through the normal app Sign-Up flow using an invite code for the target Company (e.g. email
claude-bot@yourcompany.com). Store the password only in.secrets/(new file, following this repo's existing convention) or your routine host's secret store — never in a committed.mcp.json.Project participant, role
admin(NOTmember— real bug found 2026-07-17:Topic.participantUidsis seeded at creation from the project's current admins only, and firestore.rules' Topicget/listrule is purelyparticipantUids-array-based with noisProjectAdminbypass, unlikeupdate. Amemberbot never gets auto-included in new Topics and can't see old ones either — it would structurally never find any work). An existing Project admin adds the bot's uid as a participant withrole: "admin", then fans outparticipantUidsto every already-existing Topic/Board in the project (replicateuseUpdateProjectParticipantRole's fan-out,src/hooks/useProjects.ts:272-334— promoting alone only affects future Topics).Workflow "Claude Automation" (Workflow Designer) — statuses, in this exact array order (board columns render in
statusesarray order, not by any separate sort field —closedMUST be last, not right aftercreatedwhereseedStatusesAndTransitions()puts it by default, or "Fertig"/"Closed" renders as the first visible column):created (fixed) → todo → planning → planned → approved → in_progress → done → closed (fixed).closedis deliberately the real reserved status key (not a custom "done"), soisCompleted/admin-only-reopen come for free —doneis a separate, ordinary status just before it (the agent's own "I'm finished" signal;closedstays the human's exclusive final sign-off, seeeasytopic_transition_status's tool description). Forward transitions — place eachbeforeCheckson the transition that gates entry into the NEXT phase, not on the transition leaving that phase (a Topic must not be able to enter a phase it doesn't yet qualify for — getting this backwards was an actual bug in the first real setup). The live "Claude Automation" Workflow (verified against the real Firestore config, not just this original design doc) only actually needs two:created → todo—beforeChecks: [descriptionRequired]. A Topic can't enter the queue at all without a prompt already written — otherwise a human could queue an empty Topic and the agent would waste a cycle "planning" against nothing.planned → approved—beforeChecks: [requiredFieldsFilled](gates on theplanfield being non-empty) — a human must not be able to approve a Topic that has no plan on it, or the agent starts "In Progress" with nothing to execute. Otherwise human-driven only. The agent must never perform this transition itself — it's the human's sole approval step.Every other forward transition (
todo → planning,planning → planned,approved → in_progress,in_progress → done,done → closed) has nobeforeChecksat all. Also add backward transitions with emptybeforeChecks/afterActions— moving a card back must always be possible (e.g. a plan turns out wrong, or an approval was premature). The live setup isn't limited to one step back — it also has a few direct shortcuts to an earlier stage for convenience:todo → created,planning → todo,planned → planning,planned → todo,approved → planned,in_progress → approved,done → in_progress,done → todo,closed → todo, plusclosed → createdas the dedicated "Reopen" action.
TopicType "Claude Task" (Topic Designer) —
workflowIdset to the above Workflow, plus one multiline fieldkey: "plan",label: "Plan",required: true(safe —requiredonly gates the transitions above, not Topic creation/save).BoardType (Board Designer) — references the Workflow,
hiddenStatusKeys: ["created"].Enable both in Project settings — add the new TopicType id to
Project.settings.allowedTopicTypeIdsand the new BoardType id toProject.settings.allowedBoardTypeIds(arrayUnion, don't overwrite — a Project may already have other allowed types). Both are empty by default; skipping this step means neither shows up in the app's own pickers even though the underlying Workflow/TopicType/BoardType exist. Any current Project participant may writeProject.settings(it's an "ordinary field" per firestore.rules) — the bot's own session is enough for this one step, no admin needed.Creating work — a human creates "Claude Task" Topics with
description= the prompt, and drags them from backlog intotodowhen ready.
Status lifecycle (Workflow "Claude Automation")
A Topic moves through the "Claude Automation" Workflow in one canonical order:
created → todo → planning → planned → approved → in_progress → done → closed
That array order is also the board column order (see setup step 3 for why
that matters and why closed has to be last).
Every status has one designated actor who is supposed to set it — the human and the agent alternate:
Status | Set by | When / meaning |
| Human | The story is being written: |
| Human | Queues the Topic. From here on the agent may pick it up and plan it. |
| Agent | Set the moment the agent starts planning. |
| Agent | The plan is written to the |
| Human | The approval itself. The agent may only set this if the human has explicitly approved — via a Topic comment or directly in conversation — never on its own initiative. |
| Agent | Set when implementation starts. |
| Agent | Set once the work is finished from the agent's own perspective. |
| Human only | The final sign-off, after the human has actually verified the work. The agent never sets this, under any circumstance. |
Gated transitions
Only two forward transitions carry beforeChecks at all:
created → todo—descriptionRequired, so an empty Topic can never enter the queue and leave the agent planning against nothing.planned → approved—requiredFieldsFilled, which gates on theplanfield being non-empty (it'srequired: trueon the "Claude Task" TopicType), so nobody can approve a Topic that has no plan on it.
Every other forward transition (todo → planning, planning → planned,
approved → in_progress, in_progress → done, done → closed) has no
checks. Checks sit by convention on the transition that gates entry into
the next phase, not on the one leaving a phase — see setup step 3.
Going backwards
Backward transitions exist throughout, all with empty
beforeChecks/afterActions: moving a card back must always be possible
(a plan turns out wrong, an approval was premature). The live setup isn't
limited to one step back — it also has direct shortcuts to an earlier
stage: todo → created, planning → todo, planned → planning,
planned → todo, approved → planned, in_progress → approved,
done → in_progress, done → todo, closed → todo, plus
closed → created as the dedicated "Reopen" action.
done vs. closed
These two are routinely confused, and they are not interchangeable:
doneis an ordinary custom status just before the end. It carries no special semantics of its own — it is purely the agent's "I'm finished" signal.closedis the real reserved status key, which is whyisCompletedand the admin-only reopen behaviour apply to it automatically, and it stays the human's exclusive closing signature after real verification.
So a Topic in done has been handed in, not accepted.
Convention, not enforcement
The actor assignment in the table above is convention only. It is
enforced exclusively by the prompt text in easytopic_transition_status's
tool description — not by firestore.rules, not by any beforeChecks,
and not by the role/permission model, which has no notion of "this
transition is human-only". Nothing structurally prevents an agent from
jumping straight to approved or closed; it relies entirely on the tool
description telling it not to, and on the agent honouring that.
The one gate that is enforced in code is the project-admin requirement
for leaving closed — and that applies identically to a human and to the
bot.
agent-worker/src/orchestrate.ts adds its own deterministic checks on top:
the plan step refuses to run unless the Topic is in todo, and the
implement step requires both approved and a non-empty plan field.
That hardens that one worker, though — it is not a server-side guarantee,
and any other client can still move a Topic however it likes.
Where the keys live
The status keys (not the display names) are mirrored in several places:
EASYTOPIC_*_STATUS_KEY in the .mcp.json env block or in
mcp-server/.env, and as defaults in src/config.ts; easytopic_whoami
echoes the resolved values. Renaming a key in the Workflow Designer means
updating these in the same change — a mismatch fails silently:
easytopic_list_topics simply returns nothing, with no error.
See loop-prompt-template.md for the prompt that drives this lifecycle.
Configuration
Copy .env.example to .env (local testing) or supply the same variables
through your /schedule routine's env/secret mechanism. See
.env.example for the full list — the Firebase web config values are
public (same as what ships in the EasyTopic app bundle); EASYTOPIC_BOT_PASSWORD
is the one real secret.
config.ts also loads mcp-server/.env itself as a fallback (fills only
env vars not already set — never overrides a real .mcp.json env block),
so a self-hosted setup (the MCP server living in the same repo it serves,
like this one does for EasyTopic itself) can point .mcp.json at the
bundle with no env block at all, keeping the committed .mcp.json
secret-free.
App Check
If your Firebase project enforces App Check on Firestore/Storage, this bot
needs EASYTOPIC_FIREBASE_APPCHECK_DEBUG_TOKEN set (see .env.example) or
every tool call fails with a permission error — a Node process can't do the
real reCAPTCHA/DeviceCheck/Play Integrity attestation a browser or native app
does.
Register a debug token per bot instance, not one shared across bots: Firebase Console → your project → Build → App Check → Apps → (your web app) → Manage debug tokens → Add debug token, give it a name that identifies which bot it's for. Each debug token is independently revocable — if one bot is ever suspected of misbehaving, delete just its token and it's immediately locked out of Firestore/Storage, with zero effect on any other bot instance or on that bot's own Firebase Auth password.
Deliberately not using an Admin SDK-minted App Check token here, even
though that's also an officially supported pattern for trusted server
environments: minting a token that way needs a service account with
roles/firebaseappcheck.admin, and that role's actual permission set
includes firebaseappcheck.services.update (very likely the App Check
enforcement on/off switch itself) and .debugTokens.update (manage debug
tokens for any app) — no narrower "just mint tokens" permission exists. A
leaked key with that role could disable App Check enforcement project-wide,
not just impersonate one bot. A leaked per-bot debug token, by contrast, can
only ever impersonate that one bot to App Check — a much smaller blast
radius, and it costs nothing to register (no new service account, no IAM
grant).
App Check only answers "is this a request from a client we recognize?" —
never confuse it with a behavioral leash on what a bot can then do. That's
still entirely down to Firestore/Storage security rules (participantUids/
role checks) and the bot's own Firebase Auth credentials, both completely
unaffected by any of this.
Why a committed, dependency-free bundle (dist/bundle.cjs), not lib/
Real incident (2026-07-17): a /schedule cloud routine's very first
run failed because the MCP server declared in .mcp.json is spawned by
the Claude Code host at session bootstrap, before the routine's own
prompt-driven Bash steps ever run. In a fresh git clone, neither
mcp-server/lib/ (tsc output) nor mcp-server/node_modules/ exist yet —
both are gitignored — so node mcp-server/lib/index.js crashed
immediately with a module-not-found error. By the time the agent's prompt
got around to running npm install && npm run build, the already-spawned
(dead) process was never retried — there's no in-session way to restart an
MCP connection.
Fix: npm run bundle (esbuild, src/index.ts → dist/bundle.cjs,
--bundle --platform=node --format=cjs) produces a single file with every
dependency (firebase, @modelcontextprotocol/sdk, zod) inlined — zero
node_modules needed at runtime. This file is committed to git
(unlike lib/, which stays gitignored dev output) specifically so it
exists immediately in any fresh clone, before any build step could
possibly run. Verified by copying just dist/bundle.cjs (+ a .env) into
an empty directory with no node_modules anywhere nearby and confirming
it starts and serves tool calls correctly. npm run build runs tsc && npm run bundle together — always re-run and re-commit dist/bundle.cjs
after any src/ change, or a /schedule routine keeps running stale
code indefinitely (a git-ignored build artifact would silently drift;
this one doesn't because it's tracked and reviewable in diffs).
.mcp.json in the target project
{
"mcpServers": {
"easytopic": {
"command": "node",
"args": ["/absolute/path/to/easytopic/mcp-server/dist/bundle.cjs"],
"env": {
"EASYTOPIC_FIREBASE_API_KEY": "...",
"EASYTOPIC_FIREBASE_AUTH_DOMAIN": "...",
"EASYTOPIC_FIREBASE_PROJECT_ID": "...",
"EASYTOPIC_FIREBASE_STORAGE_BUCKET": "...",
"EASYTOPIC_FIREBASE_MESSAGING_SENDER_ID": "...",
"EASYTOPIC_FIREBASE_APP_ID": "...",
"EASYTOPIC_BOT_EMAIL": "...",
"EASYTOPIC_BOT_PASSWORD": "...",
"EASYTOPIC_COMPANY_ID": "...",
"EASYTOPIC_PROJECT_ID": "...",
"EASYTOPIC_BOARD_ID": "...",
"EASYTOPIC_TODO_STATUS_KEY": "todo",
"EASYTOPIC_PLANNING_STATUS_KEY": "planning",
"EASYTOPIC_PLANNED_STATUS_KEY": "planned",
"EASYTOPIC_APPROVED_STATUS_KEY": "approved",
"EASYTOPIC_IN_PROGRESS_STATUS_KEY": "in_progress",
"EASYTOPIC_DONE_STATUS_KEY": "done",
"EASYTOPIC_PLAN_FIELD_KEY": "plan"
}
}
}
}Open point (verify before real use): a /schedule cloud routine runs in
a cloud sandbox, not on this machine — a local absolute args path is only
reachable if that sandbox has this easytopic repo checked out too, which
isn't guaranteed. If it doesn't, publish this package to an npm registry the
sandbox can reach and use "command": "npx", "args": ["-y", "@easytopic/mcp-server"]
instead (npx fetches on demand, same "no local build step required"
property as the committed bundle). Also don't commit EASYTOPIC_BOT_PASSWORD
in a real .mcp.json — reference it as an env var name and inject the
actual value through whatever secret storage the routine host provides.
Loop prompt
See loop-prompt-template.md for the full prompt to give the scheduled
Claude Code agent — implements the pick-up/plan/wait-for-approval/
implement/close lifecycle, including the "never self-approve" and
question/reply detection rules. Since the bundle needs no build step, the
only thing a routine's prompt must still do before its first tool call is
write mcp-server/.env (config is loaded lazily per tool call — see
config.ts — so the server process itself is already up and running by
the time that file appears).
Development
npm install
npm run build # tsc (lib/, dev-only) + esbuild bundle (dist/bundle.cjs, committed)
npm start # runs the stdio MCP server against .env, from lib/Tool reference
Every Topic tool takes an optional projectId; omitted, it uses the
configured EASYTOPIC_PROJECT_ID. Passing another Project only works as far
as the Firestore rules let the bot in — that hangs on its role there, not on
the parameter.
Tool | Purpose |
| Auth check, echoes resolved config + the bot's role in the configured Project |
| Topics filtered by status |
| Title substring search; without |
| Topic + comments + legal transitions + parent/children + links + |
| Post a comment |
| Write the plan custom field (versioned) |
| Change status via the matching Workflow transition |
| Create a Topic (admin only; optional parent, assignee, custom fields, due date) |
| Change title/description/custom fields/due date — versioned, in Topic History |
| Re-hang a Topic in the Project's tree ( |
| Link two Topics; the inverse direction is written automatically |
| The Topic's links, with the |
| Remove a link (best-effort on the far side) |
| Assign or clear — this is what the autonomous worker routes on |
| Switch Topic Type; reports |
| Permanent delete; direct children are re-hung onto the deleted Topic's parent |
Plus the Documentation-Project tools: easytopic_list_doc_projects,
easytopic_list_doc_tree, easytopic_get_doc_page,
easytopic_write_doc_page, easytopic_create_doc_page.
Errors from easytopic_transition_status use the same vocabulary as the
app's own useTransitionTopicStatus hook: a WorkflowCheckId
(assigneeRequired/dueDateRequired/descriptionRequired/
requiredFieldsFilled), notProjectAdmin, hasActiveConflict, or
noMatchingTransition. The Topic tools answer in the same shape
({ "error": "<code>" }, never a raw permission error):
Code | Meaning |
| Creating a Topic needs the |
| The Topic does not exist or the bot may not read it. The two are indistinguishable to any client: the |
| The race-condition detector has locked the Topic; every client write is refused until a human resolves the conflict in the app. |
| The proposed parent is the Topic itself or one of its own descendants. |
| Topic Type gate, same vocabulary as |
| A Topic Type change would reset the status into one the Workflow's status rights do not let this role enter. |
|
|
Two behaviours worth knowing before using the write tools:
easytopic_link_topicswrites BOTH directions in one call. A link is two mirror documents sharing one id, one under each Topic, and the far side gets the inverse type (blocks↔isBlockedBy,relatesTois its own inverse). Never call it twice to "build the other side". There is no way to change a link's type — remove it and make a new one.easytopic_set_topic_parentwrites no Topic History entry and does not renumber siblings, exactly like the app: placement in the tree is metadata of the same tier asboardId, not a tracked field change.
Available Tools
11 toolseasytopic_add_commentEasyTopic: add commentA
Posts a comment on a Topic — the only channel to communicate with the human (questions, progress notes, completion summaries). The human is notified automatically.
| Name | Required | Description | Default |
|---|---|---|---|
| body | Yes | ||
| topicId | Yes |
easytopic_create_doc_pageEasyTopic: create Documentation pageA
Creates a new Documentation page (Topic) under the given parent (null = top-level page) in a Documentation Project. Firestore rules only allow Topic creation by a Project ADMIN (no plain-participant fallback) — this tool checks that up front and returns { error: "notProjectAdmin" } instead of a raw permission error if the bot is only a member. Ask the human to promote the bot to admin on that Project's participants if you hit this.
| Name | Required | Description | Default |
|---|---|---|---|
| title | Yes | ||
| projectId | Yes | ||
| topicTypeId | No | ||
| parentTopicId | No | ||
| descriptionHtml | No |
easytopic_get_doc_pageEasyTopic: get Documentation pageA
Fetches one Documentation page (Topic) in full: title, description (the page's rich-text HTML body), parentTopicId, isPublic, metaDescription, and its direct child pages (id/title only). Get projectId from easytopic_list_doc_projects and topicId from easytopic_list_doc_tree.
| Name | Required | Description | Default |
|---|---|---|---|
| topicId | Yes | ||
| projectId | Yes |
easytopic_get_topicEasyTopic: get topicA
Fetches one Topic in full: title, description (the prompt), custom field values (incl. the plan field), current status, the subset of workflow transitions currently legal from this status, all comments oldest-first, and awaitingHumanReply (true if the bot's own question is still the most recent comment — do not re-ask, wait for a reply).
| Name | Required | Description | Default |
|---|---|---|---|
| topicId | Yes |
easytopic_list_doc_projectsEasyTopic: list Documentation projectsA
Lists every Documentation Project (Project.isDocumentationProject === true) in the configured company that the bot currently participates in. A Documentation Project holds its content as a tree of publishable Topics (see easytopic_list_doc_tree/easytopic_get_doc_page). The bot only sees a Project here once a human has added it as a Project participant in that Project's settings — company employment alone is not enough (Firestore rules require real participancy for list queries). To also create new pages (easytopic_create_doc_page) or read the Project's FULL existing tree, the bot needs to be added as an ADMIN participant specifically, not just a member — see CLAUDE.md's participancy/admin-visibility notes.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
easytopic_list_doc_treeEasyTopic: list Documentation project's page treeA
Lists every page (Topic) the bot can see in the given Documentation Project, flattened, ordered by sortOrder within each parent — use parentTopicId to reconstruct the tree (null = top-level page). Returns id/title/parentTopicId/isPublic only; call easytopic_get_doc_page for a page's actual content. Get projectId from easytopic_list_doc_projects.
| Name | Required | Description | Default |
|---|---|---|---|
| projectId | Yes |
easytopic_list_topicsEasyTopic: list topics by statusA
Lists Topics in the configured company/project whose currentStatusKey is one of the given statusKeys, oldest-updated first. Use the configured todoStatusKey/planningStatusKey/plannedStatusKey/approvedStatusKey/inProgressStatusKey/doneStatusKey values from easytopic_whoami.
| Name | Required | Description | Default |
|---|---|---|---|
| statusKeys | Yes |
easytopic_transition_statusEasyTopic: transition topic statusA
Moves a Topic to a new status via the matching Workflow transition (runs the same beforeChecks the human UI runs, e.g. requiredFieldsFilled). Errors use the same vocabulary as the app: a WorkflowCheckId (assigneeRequired/dueDateRequired/descriptionRequired/requiredFieldsFilled), notProjectAdmin, hasActiveConflict, or noMatchingTransition. Status lifecycle convention (created -> todo -> planning -> planned -> approved -> in_progress -> done -> closed): you may set planning/planned yourself once you start/finish planning, and in_progress/done yourself once you start/finish the work. Never set the approved status yourself unless the human has given explicit approval via a Topic comment or directly in conversation — otherwise wait for them to set it. Never set the closed status yourself under any circumstance — that is the human's exclusive final sign-off after verifying the work.
| Name | Required | Description | Default |
|---|---|---|---|
| comment | No | ||
| topicId | Yes | ||
| toStatusKey | Yes |
easytopic_whoamiEasyTopic: who am IA
Authenticates against EasyTopic and returns the bot's identity plus the configured company/project/board/status-key/plan-field settings. Call this first in every run — if it errors, stop immediately (auth/config problem), do not attempt any workaround.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
easytopic_write_doc_pageEasyTopic: write Documentation pageA
Updates an existing Documentation page's title and/or rich-text HTML content (descriptionHtml) and/or metaDescription. Only fields you pass are touched; title/descriptionHtml changes are versioned into Topic History like every other Topic edit, metaDescription is not. Requires the bot to already be a participant of the page's Project (see easytopic_list_doc_projects) — does not require admin.
| Name | Required | Description | Default |
|---|---|---|---|
| title | No | ||
| topicId | Yes | ||
| projectId | Yes | ||
| descriptionHtml | No | ||
| metaDescription | No |
easytopic_write_planEasyTopic: write planA
Writes the implementation plan into the Topic's configured plan custom field (versioned, recorded in Topic History). Call this before transitioning a Topic out of the todo status — write the plan first, then transition.
| Name | Required | Description | Default |
|---|---|---|---|
| topicId | Yes | ||
| planHtml | Yes |
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
11 tool updates
v0.1.0- First observed
easytopic_add_comment - First observed
easytopic_create_doc_page - First observed
easytopic_get_doc_page - First observed
easytopic_get_topic - First observed
easytopic_list_doc_projects - First observed
easytopic_list_doc_tree - First observed
easytopic_list_topics - First observed
easytopic_transition_status - First observed
easytopic_whoami - First observed
easytopic_write_doc_page - First observed
easytopic_write_plan
TDQS
Scored across 11 tools
Tools are clearly separated into topic management and documentation project management groups, with each tool having a distinct purpose (list vs get vs add vs write vs transition vs create). No overlapping functionalities.
All tools follow the 'easytopic_verb_noun' pattern with consistent verbs (list, get, add, write, transition, create). The only outlier is 'whoami', which is a standard authentication term and fits the pattern.
With 11 tools covering two main domains (topic management and documentation projects), the number is well-scoped. Each tool serves a necessary role without redundancy.
Significant gaps exist: no create_topic or delete_topic for topic management, and no delete_doc_page for documentation. Updates to custom fields beyond the plan field are missing. However, core workflows (list, get, update status, add comments, and documentation CRUD for creation/reading/updating) are covered.
Maintenance
Related MCP Connectors
Read and manage your EasyKanban kanban boards: to-do summaries, create, update, and move cards.
AI-native Kanban board — connect Claude to claim, work and move your tasks over MCP.
Remote MCP for Kanban AI boards—manage projects, tasks, and comments from AI tools.
Task & board management for AI agents + humans. Kanban, comments, digests via MCP.
Related MCP Servers
- FlicenseNot gradedqualityNot gradedmaintenanceA Kanban board MCP server and Claude Code plugin that allows AI agent teams to create, track, and manage tasks through a structured workflow. It features a web UI for real-time status monitoring and enables users to review, approve, or reject task submissions.-
- AlicenseNot gradedqualityCmaintenanceEnables agents to read and drive a local-first Kanban board for issue tracking, allowing them to list, create, update, and resolve issues from Claude Code sessions.7 npm1MIT
- AlicenseAqualityBmaintenanceEnables Claude Code to control a Planka 2.x board via 15 MCP tools, with writes re-read and verified so reported success matches the board, plus an optional workflow that turns the board into durable agent memory.1554 npm4MIT
- FlicenseNot gradedqualityCmaintenanceEnables managing GitHub Projects v2 boards through Claude Code and Codex, including project and item administration, field updates, sprint boards, epic rollups, and desired-state planning.-