paymo-mcp
This server provides read, write, and optional delete access to Paymo time-tracking and project management via MCP.
Read: get current user; list projects, tasklists, tasks, workflow statuses; fetch task by ID or human code (e.g., ABC-1); list task comments; check timer status. Depending on toolset: project details, templates/statuses, clients, contacts, company, invoices, payments, estimates, invoice templates.
Write (modify/full modes): create/update tasks, comments, timers (start/stop), projects, tasklists, clients, client contacts.
Delete (full mode only): delete time entries. No delete tools by default—archive clients/projects via active:false.
Configuration: PAYMO_TOOLSETS and PAYMO_TOOLS select available tools; permission modes are readonly, modify, full. Default toolset is context+tasks+time in modify mode. Env vars like PAYMO_DEFAULT_PROJECT_ID and PAYMO_STATUS_ALIASES customize behavior.
General: task arguments accept numeric IDs or human codes; list tools support pagination (limit/offset) and verbose:true for full fields; rich text supports HTML (not Markdown); handles 429 rate limiting; billing tools are read-only.
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., "@paymo-mcplog 2 hours to the website redesign project"
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.
paymo-mcp
An unofficial Model Context Protocol (MCP) server for the Paymo time-tracking API. Read and
write Paymo tasks, workflow statuses and time entries from any MCP client with npx.
Not affiliated with Paymo — no warranty and no endorsement.
Install
No install needed. Any MCP client can launch it with npx -y paymo-mcp into any project that has
a Paymo API key. Example .mcp.json:
{
"mcpServers": {
"paymo": {
"command": "npx",
"args": ["-y", "paymo-mcp"],
"env": {
"PAYMO_API_KEY": "your-key-here"
}
}
}
}Claude Desktop (claude_desktop_config.json):
{
"mcpServers": {
"paymo": {
"command": "npx",
"args": ["-y", "paymo-mcp"],
"env": {
"PAYMO_API_KEY": "your-key-here"
}
}
}
}Related MCP server: Paymo MCP Server
Configuration
Environment variables read by paymo-mcp:
Variable | Required | Default | Description |
| yes | — | Paymo API key used with HTTP Basic auth. |
| no |
| API base URL. |
| no | — | Project used when a project id argument is omitted. |
| no | discovered automatically | JSON object overriding status aliases, e.g. |
| no |
| Comma-separated toolset names, plus the keywords |
| no | — | Comma-separated tool names, additive on top of the toolsets. Matched exactly as registered. |
| no | — | One JS regex, matched against tool names and subtracted from the resolved set last. |
| no |
| One of |
| no | — | Deprecated. Use |
An unusable value in any of these aborts startup with an error instead of falling back to a default:
a typo that silently granted write access would be worse than a server that refuses to boot. Setting
both PAYMO_PERMISSION_MODE and PAYMO_READ_ONLY also aborts — drop the deprecated one rather than
guessing which variable won.
Toolsets
Toolset | Covers | Tools | Schema cost (chars) |
|
| 2 | 1,008 |
| tasks, tasklists (read), comments (read and write), subtasks | 9 | 6,796 |
| time entries: timer control, manual logging, deletion | 4 | 876 |
| project CRUD, project templates, project statuses, tasklists (write) — milestones deferred | 9 | 5,794 |
| client CRUD (no delete), client contacts, company — portal access included | 8 | 6,136 |
| invoices, invoice payments, estimates, invoice templates — read-only, deliberately | 6 | 4,124 |
| every toolset above | 36 | 23,134 |
default = context + tasks + time, which is approximately the surface the package exposed
before toolsets existed — an existing user upgrading sees no change. Names are additive and
order-independent, so PAYMO_TOOLSETS=default,billing would mean defaults plus billing.
Schema cost is measured in characters of inputSchema, not tokens: no count_tokens key was
available, and a characters-per-token estimate would be guessing. The projects toolset references
paymo_list_projects and paymo_list_tasklists by name from tasks, so selecting projects alone
still gives you the lookups you need to create a task.
How the tool set is resolved
PAYMO_TOOLSETSexpands to a set of tool names (default→ the default toolsets;all→ every toolset; names are additive).PAYMO_TOOLSis unioned in.PAYMO_DENIED_TOOLS_REGEXis subtracted.PAYMO_PERMISSION_MODEfilters last — never overridable by naming a tool explicitly.
The resolved set is fixed at startup and never changes mid-session. Changing any of these variables
requires restarting the MCP client; a fixed tools array is what keeps the prompt cache valid.
Permission modes
Mode | Registers |
| reads only |
| reads + create/update; all delete tools omitted |
| everything, deletes included |
modify is the default: an MCP server handing a model an API key with full account access should not
delete by default. paymo_delete_entry is the only delete tool, and it exists because Paymo refuses
to set an end_time on an entry under a minute old — such a timer can only be closed by deleting it.
It therefore requires PAYMO_PERMISSION_MODE=full; under modify, paymo_stop_timer's error names
that requirement instead of leaving you at a dead end.
Examples
Defaults — read and write, no deletes:
{
"mcpServers": {
"paymo": {
"command": "npx",
"args": ["-y", "paymo-mcp"],
"env": {
"PAYMO_API_KEY": "your-key-here"
}
}
}
}A single toolset — just identity and workflow statuses:
{
"mcpServers": {
"paymo": {
"command": "npx",
"args": ["-y", "paymo-mcp"],
"env": {
"PAYMO_API_KEY": "your-key-here",
"PAYMO_TOOLSETS": "context"
}
}
}
}A single-tool allowlist — the context toolset plus exactly one write tool:
{
"mcpServers": {
"paymo": {
"command": "npx",
"args": ["-y", "paymo-mcp"],
"env": {
"PAYMO_API_KEY": "your-key-here",
"PAYMO_TOOLSETS": "context",
"PAYMO_TOOLS": "paymo_create_task"
}
}
}
}Getting an API key
Your Paymo API key grants full read and write access to your Paymo account. Get it from your
Paymo account settings. Unless you need to create or mutate data, set PAYMO_PERMISSION_MODE=readonly
— an accident with a write tool is much harder to undo than a wrong read.
Tools
Read — registered in every permission mode, subject to the selected toolsets.
Tool | Args | Endpoint |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Write — registered under modify and full.
Tool | Args | Endpoint |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| — |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Delete — registered under full only.
Tool | Args | Endpoint |
|
|
|
A timer that ran for under a minute cannot be stopped: Paymo rejects an end_time that would make
the entry shorter than that. Delete it with paymo_delete_entry instead — that is the documented
way out, and the only reason this package ships a delete tool at all. Because full is not the
default, the stop error names that requirement when the tool is not registered.
Response size
Paymo answers with 20–40 fields per record; a project listing comes back several times larger than
the whole tool catalogue. The list and detail tools therefore return a documented field subset —
an agent needs id, name, code, not flat_billing or cover_file_id. List tools take
limit (default 50) and offset for paging, and return a narrower summary subset than
detail reads: a
listing exists to pick a record, so it carries id/name/code and the couple of fields needed to
choose, while paymo_get_task and paymo_me keep the fuller set. Pass verbose: true to any read
tool when you genuinely need every field Paymo provides — it bypasses both subsets.
Rate limiting
Paymo answers a 429 with X-Ratelimit-Decay-Period, and a request that hits one is retried once
after waiting exactly that long (capped at 60s) before the error surfaces. Bursts still hurt: a
single tool call can cost two or three requests, since resolving a task code and the current user
are separate lookups.
Where a task is expected, pass either a numeric id or a human task code (e.g. ABC-1).
Where a status is expected, pass a numeric id or a slug alias such as in_progress; aliases are
discovered from your workflow, overridable with PAYMO_STATUS_ALIASES.
Projects
There is no project or tasklist delete tool on purpose: DELETE /projects/{id} destroys the
project's tasks and their time entries — cascading, unrecoverable loss of billing data. Archive
instead with paymo_update_project and active: false; that is why the tool accepts it. Milestones
are not covered yet: paymo_update_tasklist accepts a milestone_id created in the Paymo UI.
Creating a project from a template_id may copy the template's tasklists and tasks into the new
project, and the created project is what comes back.
The project and tasklist writes are unverified live: the account this package was developed
against uses an Employee key, and Paymo answers POST /projects with a 403. The reads are verified
against a real account; the writes are covered by stub-client unit tests and await a human-run
verification pass with an administrator key. template_id is doubly unverified — that account has
no project templates.
Clients
There is no client or client-contact delete tool on purpose: DELETE /clients/{id} destroys every
project, task and time entry attached to the client — cascading, unrecoverable loss of billing data.
Archive instead with paymo_update_client and active: false, the same active-boolean pattern
projects uses. To reach a person at a client, list contacts with paymo_list_client_contacts; to
know your own billing identity and invoice defaults, read paymo_get_company.
Granting a contact access to the client portal is part of updating or creating the contact: send
access: true together with a password. paymo_update_client_contact with access: false
revokes it.
The client, client-contact, and company writes are unverified live: the package's example key is
an Employee, and Paymo answers admin-level creates (POST /clients, POST /clientcontacts) with a
403. The reads are verified against a real account; the writes are covered by stub-client unit tests
and are slated for the human-run admin verification pass once an administrator key is available.
Billing
The billing toolset is read-only, deliberately — it is the one toolset that ships no write tool on purpose, and this is a decision, not an oversight. An invoice is a client-facing financial document: a wrong write lands as a draft in an accounting export, a payment against the wrong invoice, or a document sent to a client, and none of that is recoverable the way a wrong task status is. Automated invoicing was never a requirement; reading state to answer "has this been paid" is. If invoicing writes are ever needed, that is a separate, separately-argued addition built after the admin verification pass.
The billing reads (invoices, estimates, invoice templates) return 403 on the account this package
was developed against — {"message":"Listing invoices denied"}. That is the account role, not
the plan: the same account reports a six-figure invoice allowance, and an Employee simply cannot read
company invoices. An Administrator key reads them. So those reads are unverified live and covered
by stub-client unit tests instead; paymo_list_invoice_payments is readable and
paymo_get_estimate reaches Paymo's estimate lookup. If these 403 for you, check the role of the
key before suspecting the request.
Comments
A comment is a resource of its own, not a field of the task, so the thread is read with
paymo_list_comments (filtered by task, accepting the same numeric id or human code as every other
task argument) rather than through paymo_get_task. The listing is returned oldest first: a
conversation reads in the order it was written, and Paymo documents no ordering on /comments, so
the server imposes it by created_on, breaking ties by id.
There is no comment delete tool, for the same reason the other toolsets ship none. PUT /comments
replaces the body wholesale, so paymo_update_comment is the repair path for a comment posted with
the wrong markup — pass the comment_id from the listing and the full new body, not a patch.
Both tools are verified live. paymo_list_comments was read against a real task and
paymo_update_comment rewrote a real comment: the response came back with edited_on set to the
edit time and created_on unchanged, which also confirms PUT /comments/{id} takes the same
form-encoded body as POST /comments rather than JSON.
scripts/field-diff.mjs has been run for the comment record kind. It dropped exactly one field
beyond the documented set, options — a notification envelope ({"notification_to": []}) that no
reader and no write tool consumes. edited_on was the other field it surfaced, and it is now part of
the subset: with an update tool in the toolset, it is the only thing separating a comment as written
from one rewritten afterwards.
Rich text
Task descriptions and comments accept HTML. Paymo keeps p, b, i, u, s, ul, ol, li,
h2, blockquote, a, br, code, pre and span (including inline style), adds
rel="noopener noreferrer" to links, and strips everything else — <script> included. Markdown is
not rendered: **bold** stays literal and backticks come back HTML-escaped, so use tags.
Note that a WAF sits in front of the Paymo API and can reject a request whose body merely looks
dangerous. Posting a comment containing <script> returns a 403 HTML page rather than a Paymo
error, even though Paymo itself would have stripped the tag.
Development
npm test # node --test, no framework
npm run build # tsc to dist/License
MIT — see LICENSE.
Available Tools
12 toolspaymo_add_commentB
Add a comment to a Paymo task.
| Name | Required | Description | Default |
|---|---|---|---|
| task | Yes | Numeric task id (e.g. 1234) or human task code (e.g. ABC-1). | |
| content | Yes | Comment text. Paymo renders HTML here (p, b, i, u, s, ul, ol, li, h2, blockquote, a, br, code, pre, span) and strips anything else. Markdown is not rendered: use tags, not ** or backticks. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden of behavioral disclosure, but it only states the action. It does not mention side effects, authentication requirements, or behavior like HTML rendering, which is only disclosed in the schema parameter description.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, concise sentence that is front-loaded and free of unnecessary words. It earns its place by clearly stating the tool's purpose.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The tool is relatively simple with only two well-documented parameters. However, as a write operation with no annotations or output schema, the description omits important context such as error conditions and response behavior, making it minimally complete but with clear gaps.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema provides complete descriptions for both parameters, including the acceptable formats for task id and the HTML rendering behavior for content. The description adds no additional parameter semantics, but the baseline for high schema coverage is 3.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb ('Add') and object ('comment') with a clear target ('Paymo task'). This distinguishes it clearly from sibling tools like create_task and update_task, which operate on tasks rather than comments.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides no explicit guidance on when to use this tool versus alternatives. It does not mention that this is for adding comments as opposed to creating or updating tasks, nor any prerequisites or exclusions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
paymo_create_taskA
Create a new Paymo task. Requires a name and either a project_id or a tasklist_id. Optional: description, due_date (YYYY-MM-DD), priority (100/75/50/25), users (list of user ids).
| Name | Required | Description | Default |
|---|---|---|---|
| name | Yes | Task title. | |
| users | No | Optional assignees (Paymo user ids). | |
| due_date | No | Optional due date in YYYY-MM-DD format. | |
| priority | No | Optional Priority: 100 critical, 75 high, 50 normal, 25 low. Paymo only uses these four. | |
| project_id | No | Required if tasklist_id is not given. | |
| description | No | Optional task description. Paymo renders HTML here (p, b, i, u, s, ul, ol, li, h2, blockquote, a, br, code, pre, span) and strips anything else. Markdown is not rendered: use tags, not ** or backticks. | |
| tasklist_id | No | Paymo tasklist (column) id. Required if project_id is not given. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description must disclose behavioral traits. It indicates the operation is a 'Create' (implying mutation) and lists required prerequisites, but it does not describe side effects, response behavior, error conditions, or any constraints beyond parameter requirements. It leaves the agent unaware of what happens on success or failure, which is a significant gap for a write operation.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is three sentences with no redundant information. It front-loads the primary purpose, states the essential requirements, and lists optional fields efficiently. Every sentence earns its place, and the structure is easy to parse.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a create tool with 7 parameters and no output schema, the description gives a solid high-level overview. It covers the required fields and optional parameters, and the schema fills in detailed constraints. It does not explain return values, but the absence of an output schema reduces the expectation. Minor gaps remain around behavioral details, but overall it is adequately complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the baseline is 3. The description adds a concise summary of required vs. optional parameters but does not provide meaning beyond the schema. It repeats priority values and due-date format already present in the schema, adding no new semantic detail.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's function: 'Create a new Paymo task.' It specifies the resource (task) and the action (create), distinguishing it from sibling tools like paymo_update_task and paymo_get_task. The explicit mention of required fields (name, project_id/tasklist_id) further clarifies the tool's scope.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides clear usage context by stating the mandatory parameters (name and one of project_id/tasklist_id) and listing optional fields. However, it does not explicitly contrast with alternatives (e.g., when to use paymo_update_task instead) or state exclusions. Since it's a create operation, the prerequisites are clear enough for basic guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
paymo_get_taskA
Fetch a Paymo task by numeric id or human code.
| Name | Required | Description | Default |
|---|---|---|---|
| task | Yes | Numeric task id (e.g. 1234) or human task code (e.g. ABC-1). | |
| verbose | No | When false (default) only the documented field subset is returned. Set true to return every field Paymo provides for each record. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description must disclose behavioral traits. It only states the action and identification method, omitting details on read-only behavior, error handling, or return format, leaving the agent uninformed about what happens on not-found or what fields are returned.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single sentence, no wasted words. It delivers the essential purpose quickly and is appropriately sized for a simple fetch operation.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given a simple read tool with complete schema, the description covers the core purpose. However, without an output schema, the absence of return-value or error information leaves some gap, but overall sufficient for a basic fetch.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema fully describes both parameters (task and verbose) with clear descriptions, so the baseline is 3. The description does not add additional meaning beyond restating that the task can be numeric or human code, already covered in the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states a specific verb ('Fetch') and resource ('Paymo task') with identification method (numeric id or human code), distinguishing it from sibling tools like paymo_list_tasks which list multiple tasks.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It implies usage when you have a specific task identifier, but does not explicitly contrast with alternatives like list_tasks for retrieval of multiple tasks. The context is clear enough for selection.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
paymo_list_projectsA
List Paymo projects the user has access to, with the documented field subset.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Maximum number of records to return (default 50). Raise it when you need more, and use offset to page. Large listings are expensive: they stay in context for the rest of the conversation. | |
| active | No | When true (default) only active projects are returned. | |
| offset | No | Number of records to skip before returning, for paging past the first page. | |
| verbose | No | When false (default) only the documented field subset is returned. Set true to return every field Paymo provides for each record. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description is the only source of behavioral context. It mentions 'documented field subset' and access filtering, but does not disclose side effects, permissions, or data volume. The note about the field subset is helpful but minimal.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single sentence with no redundant wording. It is front-loaded with the main action and resource, and every word contributes to meaning.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description is relatively thin. It does not specify the return format, the contents of the documented field subset, or pagination behavior, though pagination is partially covered by the schema. It is adequate but not complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema has 100% coverage with detailed descriptions for all four parameters, so the schema does the heavy lifting. The description adds no additional parameter semantics beyond what is already in the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the action (List), the resource (Paymo projects), and the scope (user has access to). It distinguishes itself from sibling tools like paymo_list_tasks and paymo_list_tasklists by focusing specifically on projects.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No guidance is provided on when to use this tool versus alternatives. The description does not mention any exclusions, prerequisites, or situations where another tool would be preferred.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
paymo_list_tasklistsA
List tasklists (columns) for a project, or across all tasks when unset.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Maximum number of records to return (default 50). Raise it when you need more, and use offset to page. Large listings are expensive: they stay in context for the rest of the conversation. | |
| offset | No | Number of records to skip before returning, for paging past the first page. | |
| verbose | No | When false (default) only the documented field subset is returned. Set true to return every field Paymo provides for each record. | |
| project_id | No | Restrict to a single project. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden of behavioral disclosure. It implies a read-only operation with 'List', but does not explicitly state that it is non-destructive, nor does it mention potential performance costs when querying across all projects. The schema's warning about expensive large listings is not echoed in the description.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, front-loaded sentence with no unnecessary words. It immediately conveys the action and resource, and the parenthetical clarification efficiently disambiguates the term 'tasklists'.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple list tool, the purpose and scoping are clear, but with no output schema or annotations, the description leaves gaps around return values and operational risks (e.g., large result sets when project_id is unset). The rich schema descriptions partially compensate, but the description itself is minimal.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema covers all parameters with descriptions (100% coverage), so the baseline is 3. The description adds context for project_id by noting 'across all tasks when unset', but the schema already states 'Restrict to a single project', so the added value is minimal.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the verb 'List' and the resource 'tasklists (columns)', and adds scoping detail ('for a project, or across all tasks when unset'). This distinguishes it from siblings like paymo_list_tasks and paymo_list_projects, which target different resources.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies usage context by explaining the project scoping option, but it does not explicitly mention alternatives or when not to use this tool. Sibling tools are visible but not referenced, leaving the agent without explicit selection criteria.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
paymo_list_tasksB
List tasks, defaults to incomplete tasks of the configured project.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Maximum number of records to return (default 50). Raise it when you need more, and use offset to page. Large listings are expensive: they stay in context for the rest of the conversation. | |
| offset | No | Number of records to skip before returning, for paging past the first page. | |
| verbose | No | When false (default) only the documented field subset is returned. Set true to return every field Paymo provides for each record. | |
| project_id | No | Paymo project id. When omitted, the configured default is used. | |
| include_completed | No | When true, include completed tasks. Defaults to false. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the burden of disclosing behavioral traits. It only mentions the default incomplete/project scope, which is already conveyed by the schema, and does not state that the operation is read-only, how pagination behaves, or the context cost of large listings. Minimal behavioral context is provided.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single brief sentence, front-loaded with the verb and resource, containing no filler. It is efficient and readable, though it omits behavioral detail that could have been included without much extra length.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema and no annotations, the description does not explain what fields a returned task includes, how paging works, or the effect of verbose mode. The rich parameter schema helps for parameters, but the overall tool context remains thin, leaving the agent to infer important runtime behavior.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema has 100% description coverage for all five parameters, so the tool description does not need to repeat them. The phrase 'configured project' and 'incomplete tasks' aligns with project_id and include_completed defaults but adds no new meaning beyond the schema. Baseline 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the action (List) and resource (tasks), and notes the default scope (incomplete tasks, configured project). It is specific, but it does not explicitly differentiate from sibling tools like paymo_get_task or paymo_list_tasklists.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies usage for listing tasks and highlights the default behavior, but it provides no explicit guidance on when to prefer this tool over alternatives such as get_task or list_tasklists, nor any exclusions. This is implied usage rather than clear directives.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
paymo_list_workflow_statusesA
List the workflow statuses available in Paymo (id, name, seq, action) — useful to map status_id to a human name.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Maximum number of records to return (default 50). Raise it when you need more, and use offset to page. Large listings are expensive: they stay in context for the rest of the conversation. | |
| offset | No | Number of records to skip before returning, for paging past the first page. | |
| verbose | No | When false (default) only the documented field subset is returned. Set true to return every field Paymo provides for each record. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden for behavioral disclosure. It only lists the returned fields and does not mention any behavioral traits such as cost, pagination behavior, or side effects. The input schema contains some behavioral notes, but the description itself lacks this context.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, front-loaded sentence that efficiently communicates the tool's purpose and a key use case. There is no redundant information, and every part earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The tool is simple, with clear purpose and well-documented parameters. The description also lists the output fields and use case, making it reasonably complete despite the lack of annotations. It could mention pagination or side effects, but these are not critical for understanding this tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, with detailed descriptions for limit, offset, and verbose. The description adds no additional parameter semantics beyond what the schema already provides, so the baseline score of 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool lists workflow statuses in Paymo, with a specific verb 'List' and resource 'workflow statuses'. It also notes the returned fields and a concrete use case, making its purpose unambiguous and distinct from sibling tools which deal with tasks, projects, or timers.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives a specific use case ('map status_id to a human name') which implies when to use it. It does not explicitly state exclusions or alternative tools, but the sibling context makes it clear this is the only status-listing tool, so the guidance is adequate.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
paymo_meA
Returns the authenticated Paymo user (id, name, email, timezone, workflows, assigned projects).
| Name | Required | Description | Default |
|---|---|---|---|
| verbose | No | When false (default) only the documented field subset is returned. Set true to return every field Paymo provides for each record. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden. It clearly discloses read-only behavior via 'Returns' and lists specific fields. It does not mention authentication or potential side effects, but for a simple read-only endpoint this is adequate transparency.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, focused sentence that front-loads the verb and resource, with no wasted words or redundant information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The tool is simple, with one optional parameter and no output schema. The description lists the return fields, which is sufficient for the agent to understand the result. It does not explain the field-subset behavior controlled by 'verbose', but that is already in the schema, so the description is complete enough.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% for the single 'verbose' parameter, which has its own description. The tool description adds no additional parameter context, but the schema fully documents the parameter, so the baseline score of 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Description uses a specific verb ('Returns') and resource ('authenticated Paymo user') and lists the exact fields returned, making it clear and distinct from sibling tools that operate on tasks, projects, timers, etc.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description does not explicitly state when to use this tool or provide alternatives, but the purpose is strongly implied by the name and description. No exclusion or selection guidance is given, so it stops at implied usage.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
paymo_start_timerA
Start a running Paymo time entry on a task. Any running timer for the user is closed first to avoid concurrency.
| Name | Required | Description | Default |
|---|---|---|---|
| task | Yes | Numeric task id (e.g. 1234) or human task code (e.g. ABC-1). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the burden. It discloses the key behavior that any running timer is closed first to avoid concurrency, which goes beyond a simple 'start' and adds real value. It does not detail response format or error cases, but these are not essential for a tool this simple.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences, front-loaded with the action, and every word adds value. Extremely concise and easy to scan.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool has only one parameter, no output schema, and a clear behavioral note, the description is adequately complete. It covers purpose, parameter (via schema), and an important side effect. Missing return-value details are minor.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, with the 'task' parameter clearly described as a numeric id or human task code. The description does not add additional parameter context, but the schema already covers it, so the baseline score of 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool starts a Paymo time entry on a task, using a specific verb and resource. It distinguishes itself from siblings like paymo_stop_timer and paymo_timer_status by focusing on the start action.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The purpose is self-evident from the name and description, and it implies a direct alternative to stopping/timing. It mentions the concurrency behavior but does not explicitly say when to use it over other timer-related tools, though the context makes it obvious.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
paymo_stop_timerA
Stop the running Paymo time entry of the authenticated user. No-op if none is active. If the entry is under a minute old Paymo may refuse the stop; delete it with paymo_delete_entry instead.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden. It discloses important behaviors: it is a no-op if no entry is active, and it may refuse to stop entries under a minute old. This goes beyond the basic action and helps the agent anticipate outcomes.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is compact: two sentences, front-loaded with the primary action, followed by essential edge cases. Every sentence earns its place; no redundant or peripheral information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple tool with no parameters and no output schema, the description covers all necessary context: the operation, the no-op case, a potential failure mode, and an alternative tool. It is complete for an agent to decide when and how to invoke it.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema shows zero parameters (100% schema coverage). With no parameters to explain, the baseline is 4. The description correctly makes no parameter-related claims, and no additional parameter semantics are needed.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the action: stop the running Paymo time entry of the authenticated user. It is specific (verb+resource) and distinguishes itself from siblings like paymo_start_timer and paymo_timer_status by focusing on stopping the time entry.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicit when-to-use instructions are present: stopping the running time entry. It also provides a clear when-not-to-use and alternative: if the entry is under a minute old, Paymo may refuse the stop, so delete it with paymo_delete_entry instead.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
paymo_timer_statusA
Returns the running Paymo time entry for the authenticated user, or null if no timer is active.
| Name | Required | Description | Default |
|---|---|---|---|
| verbose | No | When false (default) only the documented field subset is returned. Set true to return every field Paymo provides for each record. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden of behavioral disclosure. It clearly explains the return behavior, including the null case when no timer is active. Although it does not explicitly state that the operation is read-only or has no side effects, the 'Returns' language makes it evident for a status query.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, well-structured sentence that front-loads the primary purpose and includes the critical null behavior. There is no redundant or unnecessary text.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple status-check tool with one optional parameter, the description is complete. It specifies the scope (authenticated user), the output (running time entry or null), and the schema covers the verbose parameter. No additional context is needed.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema fully documents the only parameter 'verbose' with a clear description of its effect. The tool description adds no additional meaning about the parameter, so the baseline of 3 is appropriate given 100% schema coverage.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's function: it returns the currently running Paymo time entry for the authenticated user, or null if no timer is active. This is a specific verb+resource combination and is distinct from sibling tools like start_timer and stop_timer, which perform actions rather than queries.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies the tool is used to check the current timer status, especially in contrast to starting or stopping a timer. However, it does not explicitly state when to use this tool versus alternatives, nor does it mention any exclusion criteria.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
paymo_update_taskA
Update a Paymo task. status accepts a numeric id or a slug alias (e.g. in_progress). Do not send complete and status together: Paymo forces the status to Complete when completing and to Backlog when reopening, so the status argument would be overwritten.
| Name | Required | Description | Default |
|---|---|---|---|
| name | No | New title. | |
| task | Yes | Numeric task id (e.g. 1234) or human task code (e.g. ABC-1). | |
| users | No | Assignees (Paymo user ids). | |
| status | No | Workflow status id or alias. | |
| complete | No | Mark complete (true) or reopen (false). Also resets status, so do not pass status too. | |
| due_date | No | Due date in YYYY-MM-DD format. | |
| priority | No | Priority: 100 critical, 75 high, 50 normal, 25 low. Paymo only uses these four. | |
| description | No | New description. Paymo renders HTML here (p, b, i, u, s, ul, ol, li, h2, blockquote, a, br, code, pre, span) and strips anything else. Markdown is not rendered: use tags, not ** or backticks. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description reveals a critical behavior—that Paymo forces status to Complete/Backlog and will overwrite the status argument. However, the schema for the complete parameter already notes that it resets status, so this is partially redundant. It adds explanatory detail but lacks other behavioral disclosures like permissions or partial update semantics.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two sentences, front-loaded with the primary purpose. Every sentence earned its place, with no wasted words.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The schema covers all parameter descriptions, but the tool description does not explain whether omitted fields are left unchanged, nor does it describe the return value. These are important for an update tool, especially without an output schema. The description covers the main pitfall but leaves these gaps.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The description clarifies the status parameter by specifying 'numeric id or a slug alias' with an example (in_progress), which is more concrete than the schema's 'Workflow status id or alias.' It also highlights the cross-parameter conflict with complete. With 100% schema coverage, the baseline is 3, but the added example and interaction guidance elevate it.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with 'Update a Paymo task,' clearly stating the action and resource. This distinguishes it from sibling tools such as paymo_create_task and paymo_get_task.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides an explicit instruction not to send complete and status together, explaining the forced status behavior. It does not mention alternative tools for other scenarios, but the primary usage context is clear.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
12 tool updates
v0.2.0- First observed
paymo_add_comment - First observed
paymo_create_task - First observed
paymo_get_task - First observed
paymo_list_projects - First observed
paymo_list_tasklists - First observed
paymo_list_tasks - First observed
paymo_list_workflow_statuses - First observed
paymo_me - First observed
paymo_start_timer - First observed
paymo_stop_timer - First observed
paymo_timer_status - First observed
paymo_update_task
TDQS
Scored across 12 tools
Each tool targets a unique resource/action combination: tasks, tasklists, projects, statuses, comments, and timers are all clearly separated. No two tools appear to do the same thing, so an agent can reliably select the right one.
Most tools follow the paymo_verb_noun pattern (get_task, create_task, update_task, start_timer). Minor deviations like paymo_me and paymo_timer_status are still understandable and do not cause confusion, but they break the predominant pattern slightly.
Twelve tools is appropriate for a project management server covering tasks, projects, workflows, comments, and time tracking. Each tool has a clear purpose and the set is not bloated.
The core task lifecycle (create, get, list, update) is covered, along with useful supporting features like comments and timers. However, task deletion is missing, and the stop_timer description references a non-existent paymo_delete_entry tool, indicating an incomplete surface.
Maintenance
Related MCP Connectors
Nifty's MCP server — exposes tasks, projects, messages, and files as tools for AI agents.
- mcp-serverOAuthio.klokin
MCP server exposing klokin time-tracking operations (employees, time entries, stores) to AI clients.
MCP server that lets AI assistants use all OneSchema features exposed via the public API.
- mcpOAuthnet.todoist
Official Todoist MCP server for AI assistants to manage tasks, projects, and workflows.
Related MCP Servers
- FlicenseNot gradedqualityDmaintenanceA comprehensive MCP server for time tracking, project management, and AI-powered memory storage using semantic search. It enables users to log time, manage client billing, and capture shared or personal ideas through integrated tools and team collaboration features.1-
- FlicenseNot gradedqualityBmaintenanceAn MCP server for the Paymo platform that enables AI assistants to manage time entries, projects, and tasks through natural language. It supports tracking unbilled revenue and generating detailed invoice timesheets for efficient project management.6-
- FlicenseNot gradedqualityCmaintenanceAn MCP server for controlling the TimeLiner project management system, enabling AI clients to manage projects, tasks, members, and more via natural language.-
- AlicenseNot gradedqualityDmaintenanceAn MCP server for time tracking and billing that allows freelancers to control timers, manage projects, and export invoices via natural language in any MCP-compatible AI assistant.1 npmMIT