MCP · Engineering
What an AI agent actually needs from a project management tool
Bolting an MCP server onto a project management tool is a weekend of work. Making an agent useful inside it is not. These are the four requirements we only understood after getting each of them wrong first, in production, with the FrameOn MCP server.
1. The tool list has to answer questions, not mirror your database
The instinct is to expose CRUD: one tool per table, one verb per HTTP method. It reads well in a changelog and fails in practice, because an agent does not want rows. It wants an answer, and it has a limited number of turns to get there.
Our 20 tools are grouped by the question they close, not by the table they touch. Four questions cover almost every real session:
| The question | Tools |
|---|---|
| What is the state of this project? | get_project_structure, list_tasks, get_task, get_task_stats, get_project_alerts |
| What was decided, and why? | search_documents, list_documents_brief, get_document_full_content, get_project_memory |
| Who does this, and how long did it take? | get_project_team, get_time_report, log_time |
| Record what just happened | create_task, update_task, add_comment, create_wiki_page, save_classified_memory, report_ai_usage |
The grouping is not cosmetic. get_project_structure exists because the
obvious decomposition — list epics, then list stories per epic, then list tasks per story —
costs an agent a dozen round trips to learn something it needs before it can do anything
at all.
2. A list that silently truncates is worse than an error
Our document listing shipped with limit: 50 hardcoded, no page argument, and
no total in the response. On a wiki with 217 pages, an agent saw the 50 newest and
concluded the rest did not exist — and nothing in the payload gave it a way to suspect
otherwise. It did not fail. It answered confidently and wrongly, which is the expensive
kind.
A truncated list needs three things an agent can act on: the true total, an explicit
has_more, and a message that distinguishes "this page is empty" from "this
project has nothing." Page 9 of a 217-document wiki must not say no documents
found.
The same rule applies to hierarchy. Our listing returned flat ids, so every page an agent created landed at the wiki root — not because writing was broken, but because nothing in the read path ever mentioned that the wiki has a shape. Discovery bugs look like write bugs.
3. Permission has to be decided per call, from the credential
The pattern that keeps appearing in MCP servers: resolve the caller once, cache the identity, pass it down as an optional parameter. Optional is the word that costs you. One call site that forgets to pass it degrades to tenant-wide access, silently, and no test fails — because the tests all exercise the call sites that remember.
In our server the access scope is derived from the bearer token on every single call, and
never from the JSON-RPC body. A field in a request payload is forgeable; a write gated on
client-supplied data is privilege escalation with extra steps. Where an identity argument
is genuinely optional in the underlying service, the MCP layer passes an explicit
fail-closed identity rather than undefined, because in that service
absent means system, unrestricted.
4. Ship a guide, and make the guide part of the server
Tool descriptions are read one at a time, in isolation, at the moment of the call. They cannot teach sequencing — that you should read the project structure before creating an epic, that a wiki page wants a parent, that recording a decision belongs in the wiki and not in a task comment.
We serve that as an MCP resource at frameon://guide: a document the client
can pull once and keep in context, describing the workflows rather than the endpoints.
It is the single highest-leverage file in the server, and it is
public,
along with the protocol types and the skill playbooks.
Where this leaves the traditional tools
Jira, Asana, Monday and ClickUp were designed around a human reading a board. Their MCP servers, where they exist, are faithful to that design: they expose the API that was built for integrations, which is the CRUD surface. That is not a mistake, it is a consequence — the shape of the tool list follows the shape of the product, and the product predates the agent by fifteen years.
It also means the gap is temporary and closes with a redesign, not with a moat. What does not close as quickly is the second thing an agent needs and a tracker rarely has: the decisions. A task tells an agent what is being done. It almost never says why, what was rejected, or what the team already learned and does not want to relearn. We put the wiki and the project memory behind the same MCP server as the tasks for exactly that reason, and it remains the part of the design we are least certain we got right.
Try it against your own workspace
The FrameOn MCP server is a remote endpoint over OAuth 2.1 — no API key, no local install. The free plan connects.
Endpoint and setup Connect ChatGPT in two minutes