EasyTopic MCP Server
OfficialProvides tools to manage EasyTopic Kanban boards stored in Firebase, including creating, updating, and transitioning topics, and adding comments via Firebase Cloud Functions.
Click on "Install 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
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: Planka MCP Server for Claude
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.
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.
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
Tool | Purpose |
| Auth check, echoes resolved config |
| Topics filtered by status |
| Topic + comments + legal transitions + |
| Post a comment |
| Write the plan custom field (versioned) |
| Change status via the matching Workflow transition |
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.
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Servers
- Flicense-quality-maintenanceA 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.Last updated
- Alicense-qualityCmaintenanceEnables AI-powered project management by connecting Claude to Planka kanban boards via 75+ MCP tools for creating, updating, and managing projects, boards, lists, and cards.Last updated1GPL 3.0
- AlicenseAqualityDmaintenanceEnables managing KanbanFlow boards, tasks, and workflows directly from Cursor/Claude with a one-command setup.Last updated16356MIT
- FlicenseBqualityCmaintenanceEnables Claude to automate project management on DutyHub, including tasks, sprints, and comments.Last updated16
Related MCP Connectors
Pull change requests from your Amendor board into your coding agent to build and open PRs.
Connect AI assistants to GitHub - manage repos, issues, PRs, and workflows through natural language.
Live SEO workflow tools for Claude Code, Codex, and AI agents.
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/EB-CON-GmbH/easytopic-mcp-server'
If you have feedback or need assistance with the MCP directory API, please join our Discord server