Skip to main content
Glama
idea-base-mcp-server

idea-base-mcp-server

Official

Server Configuration

Describes the environment variables required to run the server.

NameRequiredDescriptionDefault
IDEA_BASE_API_KEYYesYour API key from Settings > API Keys
IDEA_BASE_API_URLNoCustom API URL (default: https://app.idea-base.us/api)https://app.idea-base.us/api

Instructions

Guidance the server publishes about itself, which clients place ahead of the tool catalog so the model reads it before choosing anything.

This server publishes no instructions, or was last inspected before Glama recorded them.

Capabilities

Features and capabilities supported by this server

Protocol revision2025-11-25

CapabilityDetails
tools
{}
prompts
{}

Tools

Functions exposed to the LLM to take actions

NameDescription
list_projectsA

List all projects accessible to the authenticated user. Returns project names, IDs, status, and task counts.

create_projectA

Create a new project. A TOP-LEVEL project requires product_id; a sub-project (parent_project_id set) inherits its parent's product. Returns the created project with its ID.

update_projectA

Update a project: its name, description, status, or where it sits in the hierarchy. Omitted fields are left exactly as they are. Set parent_project_id to re-parent the project, or to null to DETACH it into a top-level project; a detached project keeps the product it had inherited, so product_id is only needed to move it to a DIFFERENT product. A sub-project inherits its parent's product, so re-parenting under a parent in a different product moves the project there too. The API refuses a move that is circular, crosses accounts, or exceeds the plan's nesting depth or sub-project count, and says which.

get_projectA

Get details of a specific project including name, description, status, and task statistics.

list_tasksA

List all tasks for a specific project. Returns compact rows (id, title, status, priority, estimated_minutes, time_spent, due_date, snippet) by default to keep payloads small; pass verbose:true for full rows including description, acceptance_criteria, tags, and assignments.

get_taskA

Get detailed information about a specific task including description, acceptance criteria, time entries, and status.

create_taskC

Create a new task in a project. Returns the created task with its ID.

update_taskC

Update task details like title, description, estimates, or acceptance criteria.

update_task_statusA

Change the status of a task (todo, in_progress, blocked, done). This triggers a real-time notification to users viewing the project. Note that a task with subtasks or dependencies also has a DERIVED status which can differ from the one set here — see effective_status / status_reason on get_task.

SETTING "done" IS GATED (GH #387). A task holding any subtask that is not done is REFUSED with 403 OPEN_SUBTASKS, naming the blocking children. The bar is "done": a subtask that is todo, in progress or blocked all refuse it for the same reason. This is not advisory and there is no automated way around it — the override is reserved for a human account owner or admin, and an automated identity is refused it explicitly (403 FORCE_NOT_PERMITTED, reason actor_is_agent). So finish the subtasks; do not attempt to force the parent.

add_assigneeA

Assign a user to a task WITHOUT disturbing anyone already assigned. task_assignments holds one row per (task_id, user_id) — POST /api/tasks/:id/assignments upserts exactly that one row and leaves every other assignee alone, unlike update_task's assignee_user_id (which REPLACES the whole set — use that only when you actually want a single owner). This is the fix for the defect where a second MCP assignment silently dropped the first.

Idempotent and is_active-safe: this checks the task's current assignees first, and if the user already holds a row (assigned OR actively working) it does nothing and says so, rather than re-POSTing. That matters because the REST endpoint's upsert OVERWRITES is_active on conflict — a blind re-assign of someone with a running timer (is_active=1, set by start_working) would silently stop their clock. Skipping the no-op re-POST is what keeps assignment and active-work presence independent.

Rejects a user who is not a member of this account (404, surfaced as an error) rather than creating a dangling assignment.

remove_assigneeA

Remove exactly one user's assignment from a task, leaving every other assignee untouched. DELETE /api/tasks/:id/assignments?user_id=... removes that one task_assignments row outright (both the assignment and any is_active flag on it) — this is a full unassign, not stop_working's "still assigned, no longer active" (use stop_working to end a work session without unassigning).

verify_taskA

Run AI verification: grades this task's acceptance_criteria against the diff of its linked PR (a Haiku relevance pre-screen, then a Sonnet deep review) and PERSISTS the result to ai_completion_score / ai_completion_notes. This is exactly what update_task_status checks when the task's verification_mode is "ai_review" or "all" — call this to satisfy that gate yourself rather than repeatedly hitting 403 VERIFICATION_REQUIRED with no way through it.

COSTS MONEY — DO NOT LOOP THIS. Every call is metered via recordAIUsage and recorded to ai_generations (Sonnet, large PR-diff context) for audit. It runs FREE while your account is within its plan's included monthly verification cap; once over that cap each call is billed as AI credit overage — 2 credits per call on this account. Calling this repeatedly hoping for a higher score spends real credits for no guaranteed gain; if a genuine score lands below the 0.8 gate, that is a finding about the work, not a reason to retry.

GRADES THE DIFF, NOT THE RUNNING SYSTEM. A high score means the PR's code changes look like they satisfy the criteria on paper — it is NOT proof the deployed/running behavior actually works. Never report this score as end-to-end verification; that is a human's job or an independent task-verify sub-agent's, not this tool's.

Requires the task to already have non-empty acceptance_criteria (set via update_task) and a way to see the work: either the task's own github_pr_url (set via update_task) or a pr_url/work_description passed here. Fails with a clear message naming what is missing rather than grading an empty contract — refusal is free, no credits spent.

record_verification_feedbackA

Record whether the most recent verify_task verdict on this task was accurate — calibration data, not a correction. Attaches to the latest ai_generations row of type completion_review for this task, so verify_task must have run at least once first. Does NOT change the stored ai_completion_score or re-run any model — it costs nothing (no Anthropic call, just an audit-log row) and is safe to call as often as useful.

log_timeA

Log MEASURED time on a task — time you actually observed, never an estimate and never a guess.

IN ALMOST EVERY CASE YOU SHOULD NOT CALL THIS. Use start_working and stop_working instead: stop_working writes the task's time entry itself, from the work session's measured duration, read back out of the database. You have no clock, so a number you type here is a guess about how long something felt.

An estimate goes in the task's estimated_minutes (create_task / update_task), NOT here. Logged time is a measurement; an estimate is a plan. They are different fields and must not be confused — writing an estimate into logged time is what this tool's description used to invite, and an agent did it: 75 minutes logged for work its own sessions measured at 15.7, 14.5 and 8.1.

Use it ONLY for work no session measured — something done away from the keyboard, or work from before you started a session — and say in the notes why there is no measurement. An AGENT logging by hand on a task that already has measured time is REFUSED, whatever the amount. Negative minutes are refused too: correct the original entry rather than filing an offsetting one.

search_tasksA

Search for tasks across all projects by title or description. Returns compact rows (id, title, status, priority, project_id, project_name, product_name, customer_name, estimated_minutes, time_logged, due_date, snippet) ranked with title matches first, then description matches, then recency. Pass verbose:true for full rows.

quick_logA

Quick workflow for recording work that is ALREADY FINISHED: creates a task, marks it done, and logs time in one call.

minutes must be MEASURED time, not an estimate. This is a hand-entry path — there is no work session behind it — so only use it for work you actually observed the duration of, and prefer start_working / stop_working whenever the work is still ahead of you, because stop_working writes the time entry from the measured session and you type no number at all.

An estimate goes in estimated_minutes, which is a separate optional argument here precisely so the two cannot be the same number by accident. Omit it and it defaults to minutes, as before.

start_workingA

Start work on a task. Two things happen: you are shown to the team as actively working on it (and a todo task moves to in_progress), and a TIMED WORK SESSION is opened with a UTC start instant, so how long the task was actually worked becomes measurable instead of guessed.

Calling it a second time on the same task NEVER opens a second session. If your session is paused it is resumed; if it is already running you are told so, with how long it has been going. The response always says which of the three happened.

It also orients a cold session: the response carries the task's resume context and its recent work notes, so read the whole thing before you start. Pair it with stop_working — which is what LOGS the time, from the measured session, with no number typed by you — and use pause_working when you have to wait on something.

stop_workingA

Stop working on a task: close your open work session with a UTC end instant, and drop the "actively working" flag (you stay assigned).

THIS IS WHAT LOGS YOUR TIME, and you supply no number. Closing the session writes the task's time entry from the session's measured worked duration — computed by the database from the recorded start and end instants, minus any waiting_on_human pause — and the response tells you the entry it wrote. Do NOT call log_time afterwards: the time is already recorded, and a hand entry on a task that already has measured time is refused. A session shorter than half a minute rounds to zero and logs nothing rather than being rounded up, and the response says so.

Requires an open session — if you have none this FAILS and writes nothing, rather than inventing a session with no start. Call start_working first.

This ENDS the session. If you are only waiting on something and intend to carry on afterwards, use pause_working instead: a pause keeps the session open and records why you stopped, which is what decides whether the interval counts as worked time.

Optionally capture your state on the way out: pass note to append a work note and/or resume_context to overwrite the resume block, so the next session can pick up where you left off.

pause_workingA

Pause your open work session without ending it, and record WHY. Use this whenever work stops but is not finished — you asked the human a question, you are waiting on another agent, you are blocked on a build.

THE REASON IS THE POINT, and it decides the number: waiting_on_human — you are blocked on a person and CANNOT proceed. The paused interval is EXCLUDED from worked time. waiting_on_agent — you are blocked on another agent or an automated run that is itself active. The interval IS COUNTED as worked time: a sub-agent blocked on another active sub-agent is still working. other — anything else. Counted as worked.

Only waiting on the human is not working. Choose waiting_on_human ONLY when a person has to act before you can continue; if a machine or another agent is doing the work, it is waiting_on_agent.

Resume with resume_working. Do NOT use stop_working for a pause — that ends the session and the reason is lost.

resume_workingA

Resume your paused work session — closes the pause by recording the UTC instant you came back, so the paused interval has both boundaries and can be measured. The session itself was never closed and keeps its original start.

Fails if the session is not paused, rather than pretending to resume something. start_working also resumes a paused session, so use whichever reads better; this one does not re-fetch the orientation block.

add_work_noteA

Append a timestamped work note (status update) to a task's activity log. Use this to record progress so a future session can pick up where you left off (e.g. "finished auth handler, tests green, next: wire the callback"). Notes are append-only and never overwrite each other.

add_commentA

Add a comment to a task's discussion thread. Unlike work notes (progress journal), comments are for communication and are customer-visible by default.

set_resume_contextA

Set (overwrite) the task's resume context — a single pinned block describing the current state, what is done, what is next, and where to look. This is read first when a work session restarts cold (e.g. via start_working) so you can re-orient immediately. Update it at the end of a work session.

list_productsA

List all products accessible to the authenticated user. Products are top-level containers for organizing related projects.

list_sprintsB

List a product's sprints, newest first, with real task counts and its cadence. Sprints are owned by the PRODUCT: the product sets the rhythm and owns the lifecycle, while projects add and remove the work. A sprint can hold tasks from any project under that product, sub-projects included.

get_sprintA

Get one sprint: its tasks with derived status, counts taken from real task rows, and — for a CLOSED sprint — the commitment ledger saying what it committed to and what became of each item. Pass candidates:true to also get the open work that could be pulled in, and the work being held back as blocked (with the reason).

create_sprintA

Open a sprint on a product. With no dates it opens the NEXT one on the product's cadence, which is the normal case; pass starts_on/ends_on only to set an explicit window. One sprint per product per period — a second for the same period is refused rather than duplicated.

add_tasks_to_sprintA

Commit tasks to a sprint. Each task is checked on its own and the result says which were added and which were refused and why — a task already in another sprint is REFUSED, not moved, because a task belongs to at most one. Tasks must belong to a project under the sprint's product.

remove_tasks_from_sprintA

Take tasks out of a sprint. The tasks themselves are untouched — the sprint is the time box, not the owner of the work.

close_sprintA

Close a sprint. Unfinished work moves into the next sprint and its carry count increments (unless the product's cadence has carry-over off, in which case it is released); finished work stays attached. Every task held is written to the commitment ledger first, so what the sprint committed to survives the carry. This is an action, not a status edit — closing is irreversible.

get_sprint_cadenceA

Get a product's sprint rhythm: length in days, which weekday it starts, whether unfinished work carries over, and whether sprints open unattended. A product with no cadence row still reports the weekly-Monday default, flagged as not configured.

set_sprint_cadenceA

Set a product's sprint rhythm. "Mon-Sun weekly" is length_days 7 + start_weekday 1; a Wednesday fortnight is 14 + 3. Changing it does not move sprints that already exist — it applies from the next sprint opened. Setting a cadence is also what opts a product into having sprints opened and closed on the schedule.

get_productA

Get details of a specific product including linked projects, team members, and statistics.

create_productA

Create a new product. Products are top-level containers for projects. Every product belongs to a customer (customer_id is required) — use an internal/own-company customer for internal work. Find customer ids via list_products (each shows its customer_id).

link_project_to_productB

Link an existing project to a product.

report_bugA

File a bug report against IDEA Base itself as a support ticket, through the existing Help Desk intake (POST /api/tickets, category "bug") — not a second intake path. Use this when something in IDEA Base is broken, not for a customer project's own bugs. Staff see it in the Help Desk queue.

Prompts

Interactive templates invoked by user choice

NameDescription
start_sprintLoad a sprint and lay out its work so you can start processing it: the goal, the window, and every item split into assigned-to-you, unassigned, and blocked (with the reason). Omit the id to use the sprint covering today.
sprint_reportReport on a sprint from its commitment ledger: what it committed to, what was completed, and what carried over and how many times. Works on a closed sprint; an open one has nothing judged yet and says so.
plan_sprintPlan a product's next sprint: its cadence, the window the next sprint would cover, the work eligible to commit, and the work being held back as blocked with the reason.
setupCheck whether this project emits IDEA Base session tracking, and say plainly whether your sessions are being tracked. Reports every missing piece with the literal text to add, states what it could not check rather than passing over it, and writes nothing. Safe to run as often as you like - re-running it IS the audit.
featuresInventory of IDEA Base capabilities as they are actually wired on THIS machine, not as the product advertises them: each one on, off, configured-but-not-firing, or undetermined - and for the undetermined ones, why nothing here can tell.
updateReport the installed and the latest published version of the IDEA Base MCP server, and give the one command that updates it and refreshes the files it installed in this repo. Reads only; the command does the work, and a session restart is what loads a new server.

Resources

Contextual data attached and managed by the client

NameDescription

No resources

TDQS

A3.7/5.0

Scored across 36 tools

Disambiguation4/5

Most tools map to a distinct resource+action, and the descriptions go out of their way to separate easily-confused pairs (add_comment vs add_work_note, log_time vs stop_working, add_assignee vs update_task's assignee_user_id). The remaining overlaps are mild: resume_working duplicates start_working's resume behavior by the author's own admission, and log_time / quick_log / stop_working all touch time recording, requiring careful reading to pick correctly.

Naming Consistency5/5

Nearly every name is snake_case verb_noun with a predictable verb vocabulary (create_/get_/list_/update_/add_/remove_/set_/start_/stop_/pause_/resume_/close_), making resource and action readable at a glance. Deviations like quick_log, report_bug, and update_task_status are still idiomatic and unambiguous within the same convention.

Tool Count3/5

36 tools is heavy and sits above the comfortable band, but the domain genuinely spans products, projects, tasks, sprints, work sessions, assignments, verification, and support, so most tools earn a place. There is still consolidation headroom (log_time vs stop_working, resume_working vs start_working, record_verification_feedback), which pushes it to borderline rather than well-scoped.

Completeness3/5

Core workflows are covered end to end: product/project/task CRUD-ish surfaces, sprint lifecycle with cadence, measured work sessions, assignments, and AI verification. Notable gaps remain, though: no delete anywhere (tasks, projects, products, sprints), no update_product, no list_comments or way to read a task's comment thread, and no way to list or correct existing time entries other than the initial write.

Maintenance

ActivityMaintained
ResponsivenessMixed handling