Wakapi MCP Server
Query and analyze Wakapi development-time tracking data through an MCP server.
Retrieve coding statistics for a user over specified time ranges, filtered by project, language, editor, OS, machine, or label.
List and filter a user's projects.
Retrieve user profile information.
View leaderboard rankings.
Get all-time coding summary since today.
Retrieve detailed information for a specific project.
Fetch recent development logs/heartbeats across recent days, optionally filtered by project and limited in count.
Test connectivity to the Wakapi server.
Provides development time tracking tools by collecting logs from Wakapi REST API, including statistics, project details, leaderboards, and recent development activity logs
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., "@Wakapi MCP Servershow me my coding stats from last week"
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.
Wakapi MCP Server
This is an MCP (Model Context Protocol) server. It provides development time tracking tools by collecting logs from Wakapi REST API.
This repository is unofficial. Use at your own risk.
Quick Start
Prerequisites
Python 3.11 or higher
Wakapi server with API access
MCP Server Configuration Examples
Quickstart with Environment Variables
{
"mcpServers": {
"wakapi": {
"env": {
"WAKAPI_URL": "http://localhost:3000",
"WAKAPI_API_KEY": "your-api-key"
},
"command": "uv",
"args": [
"tool",
"run",
"--from",
"git+https://github.com/impure0xntk/mcp-wakapi",
"wakapi-mcp"
]
}
}
}Enhanced Security with Configuration File
{
"mcpServers": {
"wakapi": {
"command": "uv",
"args": [
"tool",
"run",
"--from",
"git+https://github.com/impure0xntk/mcp-wakapi",
"wakapi-mcp",
"--config",
"/path/to/config.toml"
]
}
}
}Related MCP server: WakaTime MCP Server
Features
Collects development time logs via the Wakapi API
Provides MCP tools for retrieving development data
Fast processing using FastMCP
Reproducible development environment with Nix flakes
Modular tool architecture
Improved testability through dependency injection
Design based on the single responsibility principle
Provided Tools
This server provides the following tools that can be used by MCP-compatible clients:
Note: {api_path} is configurable: by default, /compat/wakatime/v1.
Please see the Configuration section.
Tool Name | Description | API Endpoint |
Get Stats | Retrieve statistics for a given user over a specified time range | |
Get Projects | Retrieve and filter the user projects | |
Get User | Retrieve the given user information | |
Get Leaders | Retrieve leaderboard information | |
Get All Time Since Today | Retrieve all time information since today | |
Get Project Detail | Retrieve detailed information about a specific project | |
Get Recent Logs | Retrieve recent development logs | |
Test Connection | Test connection to the Wakapi server | None |
Configuration Details
Environment Variables Configuration
The most common way to configure the server is through environment variables:
export WAKAPI_URL="http://your-wakapi-server:3000"
export WAKAPI_API_KEY="your_actual_api_key_here"
export WAKAPI_API_PATH="/compat/wakatime/v1"Or pass to mcpServers:
{
"mcpServers": {
"wakapi": {
"env": {
"WAKAPI_URL": "http://localhost:3000",
"WAKAPI_API_KEY": "your-api-key"
},
...Configuration Files
You can also use configuration files in TOML or JSON format:
TOML format (config.toml):
[wakapi]
url = "http://your-wakapi-server:3000"
api_key = "your_actual_api_key_here"
api_path = "/compat/wakatime/v1"
timeout = 30
retry_count = 3
[server]
host = "0.0.0.0"
port = 8000
[logging]
level = "INFO"
format = "%(asctime)s - %(name)s - %(levelname)s - %(message)s"JSON format (config.json):
{
"wakapi": {
"url": "http://your-wakapi-server:3000",
"api_key": "your_actual_api_key_here",
"api_path": "/compat/wakatime/v1",
"timeout": 30,
"retry_count": 3
},
"server": {
"host": "0.0.0.0",
"port": 8000
},
"logging": {
"level": "INFO",
"format": "%(asctime)s - %(name)s - %(levelname)s - %(message)s"
}
}For Developers
Setup Development Environment
This project provides a reproducible development environment using Nix flakes:
# Start the development environment
nix develop
# Or start a shell
nix-shellAnd also use uv to activate, sync and run.
nix build for the packaged server does not currently succeed: MCP 2026-07-28
needs fastmcp 4.x on the mcp 2.x SDK, and no available nixpkgs carries it.
Use uv sync until nixpkgs ships fastmcp 4.
Starting the MCP Server from python command
# Set environment variables
export WAKAPI_URL="http://localhost:3000"
export WAKAPI_API_KEY="your_actual_api_key_here"
export WAKAPI_API_PATH="/compat/wakatime/v1"
# Start the server in STDIO mode (default)
python main.py --transport stdio
# Start the server in Streamable HTTP mode
python main.py --transport http
# Start with a configuration file
python main.py --config /path/to/config.tomlAuthentication Method: The API key is automatically base64-encoded and sent as a Bearer token.
--transport stdio: Uses STDIO transport (default). Can be used directly with MCP clients like opencode--transport http: Uses Streamable HTTP transport. The endpoint ishttp://<host>:<port>/mcp, with host and port taken from the[server]section of the config file
Streamable HTTP
MCP revision 2026-07-28 replaced the standalone SSE endpoint with a single Streamable HTTP endpoint. One route at /mcp carries initialize, tools/list and tools/call, including server-initiated SSE streams, so --transport sse no longer exists.
Add --stateless-http to run without server-side session state, which suits
serverless or horizontally scaled deployments that cannot keep sessions warm:
python main.py --transport http --stateless-httpTesting
You can test the server using pytest:
# Run all tests
pytest
# Run specific tests
pytest tests/test_mcp_server.py -vLicense
Apache License 2.0
Contributing
Issues and Pull Requests are welcome.
Available Tools
8 toolsget_all_time_since_todayGet All Time Since TodayC
Retrieve summary for all time since today for the specified user.
operationId: get-all-time summary: Retrieve summary for all time description: Mimics https://wakatime.com/developers#all_time_since_today tags: [wakatime] parameters:
name: user in: path description: User ID to fetch data for (or 'current') required: true schema: type: string responses: 200: description: OK schema: v1.AllTimeViewModel
Requires ApiKeyAuth: Set header Authorization to your API Key
encoded as Base64 and prefixed with Basic.
| Name | Required | Description | Default |
|---|---|---|---|
| user | No | current |
Output Schema
| Name | Required | Description |
|---|---|---|
| data | Yes | Model for all time data. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description must carry the behavioral burden. It discloses the authentication requirement (ApiKeyAuth with Base64 Basic header) and the response schema name, but it does not explicitly state that the operation is read-only or describe rate limits or side effects.
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 bloated with raw OpenAPI YAML including operationId, tags, and response details. The useful information is not front-loaded or structured for quick selection, and much of the embedded metadata is irrelevant to invocation.
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 one-parameter tool with an output schema, the description covers authentication and response type. It remains incomplete because it omits usage context, contradicts the schema on required/default status, and does not clarify what 'all time since today' returns beyond a schema reference.
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 0%, so the description must compensate. It does mention the user parameter can be an ID or 'current', which adds some meaning. However, it also states the parameter is required, while the actual input schema has no required parameters and sets a default of 'current'; this contradiction could mislead an agent.
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 first sentence states a specific verb and resource: retrieve a summary of all time since today for a user. It clearly identifies the operation, though it does not differentiate from siblings like get_stats or get_recent_logs.
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 no guidance on when to use this tool versus alternatives such as get_stats or get_recent_logs. It only restates the purpose and provides an API documentation link, leaving the agent to infer usage from the name alone.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_leadersGet LeadersB
List of users ranked by coding activity in descending order.
operationId: get-wakatime-leaders summary: List of users ranked by coding activity in descending order. description: Mimics https://wakatime.com/developers#leaders tags: [wakatime] responses: 200: description: OK schema: v1.LeadersViewModel
Requires ApiKeyAuth: Set header Authorization to your API Key
encoded as Base64 and prefixed with Basic.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| data | Yes | |
| page | Yes | |
| range | Yes | Model for leaders range. |
| language | Yes | |
| total_pages | Yes | |
| current_user | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full disclosure burden. It usefully discloses the ApiKeyAuth requirement and the response model name, but omits behavioral details like pagination, ranking period, or whether results are public, making it only minimally adequate for an unannotated read tool.
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 purpose is front-loaded in the first sentence, but the description then dumps raw OpenAPI metadata (operationId, tags, responses) that is redundant with structured data and clutters the definition. The auth note is useful, but overall structure could be much tighter.
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 zero-parameter read endpoint with an output schema, the description covers the essential auth requirement and basic purpose. With no annotations, it should ideally say more about safe read behavior or result scope, but the output schema reduces the need to explain return values.
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 tool has zero parameters, so there are no parameter semantics to document. The baseline score for a zero-parameter tool is 4, and nothing in the description misrepresents the empty input 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 first sentence clearly states a specific verb (List) and resource (users ranked by coding activity), which is enough to distinguish it from most siblings like get_user or get_stats. However, it does not explicitly name or contrast against any sibling tool, so it stops short of the top score.
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 no guidance about when to use this tool versus alternatives such as get_stats or get_user. It states an auth requirement, but that is not usage context or exclusions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_project_detailGet Project DetailB
Retrieve a single project.
Mimics undocumented endpoint related to https://wakatime.com/developers#projects.
Requires ApiKeyAuth: Set header Authorization to your API Key encoded as Base64
and prefixed with Basic.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | Project ID to fetch. | |
| user | No | User ID to fetch data for | current |
Output Schema
| Name | Required | Description |
|---|---|---|
No output 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 does disclose a genuinely useful behavioral fact — the ApiKeyAuth scheme with Basic-prefixed Base64 header — but says nothing about error behavior, rate limits, or what an unknown ID yields.
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?
Front-loaded with the purpose, then endpoint provenance, then auth. Three short lines with no filler, though the auth paragraph is somewhat verbose for a header that could be one clause.
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 single-resource fetch with a fully documented schema and an output schema, the description covers purpose and the non-obvious auth requirement. Only failure modes and pagination-adjacent concerns are absent.
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 both 'id' and 'user' are already documented with types, a default, and descriptions. The description adds no format or semantic detail beyond the schema, so baseline 3 applies.
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?
States a specific verb and resource ('Retrieve a single project'), which an agent can distinguish from the plural sibling get_projects. No explicit sibling comparison, but the singular scope is clear.
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 statement of when to use this versus get_projects, get_stats, or get_user. The only usage cue is the implied singular scope, and no exclusions or prerequisites (beyond auth) are given.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_projectsGet ProjectsB
Retrieve and filter the user's projects.
operationId: get-wakatime-projects summary: Retrieve and filter the user's projects description: Mimics https://wakatime.com/developers#projects tags: [wakatime] parameters:
name: user in: path description: User ID to fetch data for (or 'current') required: true schema: type: string
name: q in: query description: Query to filter projects by schema: type: string responses: 200: description: OK schema: v1.ProjectsViewModel
Requires ApiKeyAuth: Set header Authorization to your API Key
encoded as Base64 and prefixed with Basic.
| Name | Required | Description | Default |
|---|---|---|---|
| q | No | ||
| user | No | current |
Output Schema
| Name | Required | Description |
|---|---|---|
| data | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full behavioral burden. It usefully discloses the ApiKeyAuth requirement and header encoding, and 'Retrieve' implies a read operation, but it does not explain rate limits, pagination, filtering semantics, or what happens when no projects match.
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 useful first sentence is front-loaded, but the rest is an OpenAPI/YAML dump including operationId, tags, responses, and summary. Much of this is redundant or irrelevant to an AI agent selecting and invoking the tool, making the definition unnecessarily bloated.
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 description covers auth and both parameters, and an output schema exists so return values need not be explained. However, it lacks usage guidance relative to siblings like get_project_detail, leaving a meaningful gap for a list/filter 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 description coverage is 0%, so the description must compensate. It does provide meaning for both parameters: 'user' is described as the user ID or 'current', and 'q' as a query to filter projects by. The q description remains vague about syntax, but the core semantics are present.
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 and resource: 'Retrieve and filter the user's projects.' It is specific enough to distinguish this from generic data retrieval, but it does not explicitly differentiate itself from the sibling tool get_project_detail or explain list-versus-detail 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?
There is no explicit guidance on when to use this tool versus alternatives such as get_project_detail. The only implied usage is filtering by the q parameter, but no conditions, exclusions, or alternatives are provided.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_recent_logsGet Recent LogsA
Get heartbeats of user for recent days (extension of heartbeats GET).
Mimics https://wakatime.com/api/v1/users/{user}/heartbeats for multiple days.
Requires ApiKeyAuth: Set header Authorization to your API Key encoded as Base64
and prefixed with Basic.
| Name | Required | Description | Default |
|---|---|---|---|
| days | No | Number of days to retrieve. | |
| user | No | Username (or current). | current |
| limit | No | Maximum number of heartbeats. | |
| project_name | No | Filter by project. |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description must carry behavioral context, and it usefully discloses that ApiKeyAuth is required with a Base64-encoded API key in the Authorization header. It also implies a read operation via 'Get' and 'mimics ... heartbeats GET,' but it does not cover rate limits, pagination, or safety profile beyond the auth requirement.
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 and front-loads the core purpose before giving the API mimicry and authentication detail. The second sentence is slightly redundant with the first, but overall it is efficient and well-structured.
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 four optional parameters, no annotations, and an existing output schema, the description covers the essential purpose and authentication requirement. It does not need to explain return values, but it could be more complete by addressing when to prefer this over sibling tools.
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 four parameters, so the schema already documents days, user, limit, and project_name clearly. The description adds no parameter-level meaning beyond what the schema provides, making the baseline score of 3 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 states a specific verb and resource: 'Get heartbeats of user for recent days,' and clarifies it is an extension of the heartbeats GET for multiple days. It distinguishes itself from siblings like get_stats by focusing on raw heartbeats, though it does not explicitly contrast with those siblings.
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?
Usage is implied by 'extension of heartbeats GET' and 'for multiple days,' suggesting it should be used when multi-day heartbeat data is needed. However, there is no explicit guidance on when to use this tool versus alternatives like get_stats or get_all_time_since_today, and no exclusions are stated.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_statsGet StatsB
Retrieve statistics for a given user.
operationId: get-wakatime-stats summary: Retrieve statistics for a given user description: Mimics https://wakatime.com/developers#stats tags: [wakatime] parameters:
name: user in: path description: User ID to fetch data for (or 'current') required: true schema: type: string
name: range in: path description: Range interval identifier required: true schema: type: string enum: [ "today", "yesterday", "week", "month", "year", "7_days", "last_7_days", "30_days", "last_30_days", "6_months", "last_6_months", "12_months", "last_12_months", "last_year", "any", "all_time" ]
name: project in: query description: Project to filter by schema: type: string
name: language in: query description: Language to filter by schema: type: string
name: editor in: query description: Editor to filter by schema: type: string
name: operating_system in: query description: OS to filter by schema: type: str
name: machine in: query description: Machine to filter by schema: type: string
name: label in: query description: Project label to filter by schema: type: string responses: 200: description: OK schema: v1.StatsViewModel
Requires ApiKeyAuth: Set header Authorization to your API Key
encoded as Base64 and prefixed with Basic.
| Name | Required | Description | Default |
|---|---|---|---|
| user | Yes | ||
| label | No | ||
| range | Yes | ||
| editor | No | ||
| machine | No | ||
| project | No | ||
| language | No | ||
| operating_system | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| data | Yes | Model for stats data. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full behavioral burden. It usefully discloses the authentication requirement and encoding format, and 'Retrieve' implies a read operation, but it does not explicitly state read-only behavior, rate limits, pagination, or other operational traits.
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 useful opening sentence is followed by a large pasted OpenAPI/YAML block with operationId, summary, description, tags, parameter definitions, responses, and auth. Much of this is redundant with the input schema or overly low-level, making the description poorly structured and bloated.
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?
Because an output schema exists, return values need not be explained. The description compensates for 0% schema description coverage by documenting every parameter and the authentication method, making the tool callable, though it still lacks sibling-routing guidance.
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?
Input schema description coverage is 0%, but the description includes a detailed parameter list covering all 8 parameters. It explains that user can be 'current', provides the full enum for range, and describes each filter, adding substantial meaning beyond the raw 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 first sentence states a clear verb and resource: retrieve statistics for a given user. It does not differentiate the tool from siblings like get_user or get_projects, and 'statistics' is somewhat generic, but the core purpose is understandable.
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 no when-to-use or when-not-to-use guidance relative to alternatives. It mentions the API key requirement, but does not help an agent choose this tool over get_user, get_recent_logs, or other siblings.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_userGet UserC
Retrieve the given user.
operationId: get-wakatime-user summary: Retrieve the given user description: Mimics https://wakatime.com/developers#users tags: [wakatime] parameters:
name: user in: path description: User ID to fetch (or 'current') required: true schema: type: string responses: 200: description: OK schema: v1.UserViewModel
Requires ApiKeyAuth: Set header Authorization to your API Key
encoded as Base64 and prefixed with Basic.
| Name | Required | Description | Default |
|---|---|---|---|
| user | No | current |
Output Schema
| Name | Required | Description |
|---|---|---|
| data | Yes | Model for user. |
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 does add a genuinely useful behavioral detail: ApiKeyAuth is required, with the header formatted as Base64 Basic auth. However, it discloses nothing about reversibility, rate limits, or error behavior for this read call.
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 text is a raw spec dump mixing prose, YAML, path/parameter blocks, and a response schema reference. It is not front-loaded around the actionable content and includes redundant metadata like operationId and tags that add no invocation value.
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?
An output schema exists, so return values need not be explained, and auth is covered. For a one-parameter read tool this is roughly sufficient, but the messy structure and absent usage guidance leave the definition thinner than it should be.
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 0%, so the schema text alone gives no meaning for `user`. The description compensates partially by explaining the path parameter is a user ID, or 'current' for the authenticated user, but it does not clarify the default behavior or accepted formats beyond that.
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?
States the verb and resource ('Retrieve the given user'), so the operation is identifiable, but it offers no differentiation from siblings like get_stats or get_projects. The rest of the text is raw OpenAPI metadata (operationId, tags) rather than purposeful description.
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 when-to-use, when-not-to-use, or alternative guidance is given. The only implicit usage cue is the embedded path note that 'current' fetches the authenticated user, but this is not framed as guidance versus using a specific user ID.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
test_connectionTest ConnectionA
Test Wakapi server connection via simple API call to fetch projects.
Returns: A dictionary with the connection test result, including: - status (str): 'success' or 'error'. - message (str): Description of the result. - projects_count (int, optional): Number of projects if successful. - server_url (str): The Wakapi server URL. - api_path (str): The API path used for requests. - error (str, optional): Error message if failed.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
No output 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 behavioral burden. It discloses the response fields and success/error status, which is useful, but does not state whether the call is read-only, what authentication it requires, or rate-limit behavior.
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 first sentence is front-loaded and efficient. However, the subsequent 'Returns' list duplicates the rich output schema field-by-field, adding length without adding information the agent doesn't already have.
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?
Complexity is low and a full output schema exists, so the description is largely complete for this diagnostic tool. It still omits when-to-use guidance and any note about read-only/authentication behavior, but those gaps are minor given the tool's simplicity.
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?
There are zero input parameters, so per the rubric the baseline is 4. The description does not need to add parameter meaning, and it correctly does not invent any.
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?
States a specific verb and resource ('Test Wakapi server connection') and clarifies the mechanism ('via simple API call to fetch projects'). This clearly distinguishes it from the sibling get_* data-retrieval tools, which are not diagnostic.
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 implies usage (checking connectivity), but there is no explicit statement of when to call this versus alternatives, nor any prerequisites such as requiring configured credentials. It is only implicitly guided.
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.
8 tool updates
v0.2.0- Changed
get_all_time_since_today9 fields changed- added
Input schema / additionalPropertiesAdded value: +false - removed
Input schema / properties / user / titleRemoved value: -"User" - removed
Output schema / $defsRemoved value: -{ - "AllTimeData": { - "description": "Model for all time data.", - "properties": { - "is_up_to_date": { - "title": "Is Up To Date", - "type": "boolean" - }, - "range": { - "$ref": "#/$defs/AllTimeRange" - }, - "text": { - "title": "Text", - "type": "string" - }, - "total_seconds": { - "title": "Total Seconds", - "type": "number" - } - }, - "required": [ - "total_seconds", - "text", - "is_up_to_date", - "range" - ], - "title": "AllTimeData", - "type": "object" - }, - "AllTimeRange": { - "description": "Model for all time range.", - "properties": { - "end": { - "title": "End", - "type": "string" - }, - "end_date": { - "title": "End Date", - "type": "string" - }, - "start": { - "title": "Start", - "type": "string" - }, - "start_date": { - "title": "Start Date", - "type": "string" - }, - "timezone": { - "title": "Timezone", - "type": "string" - } - }, - "required": [ - "start", - "start_date", - "end", - "end_date", - "timezone" - ], - "title": "AllTimeRange", - "type": "object" - } -} - removed
Output schema / properties / data / $refRemoved value: -"#/$defs/AllTimeData" - added
Output schema / properties / data / descriptionAdded value: +"Model for all time data." - added
Output schema / properties / data / propertiesAdded value: +{ + "is_up_to_date": { + "type": "boolean" + }, + "range": { + "description": "Model for all time range.", + "properties": { + "end": { + "type": "string" + }, + "end_date": { + "type": "string" + }, + "start": { + "type": "string" + }, + "start_date": { + "type": "string" + }, + "timezone": { + "type": "string" + } + }, + "required": [ + "start", + "start_date", + "end", + "end_date", + "timezone" + ], + "type": "object" + }, + "text": { + "type": "string" + }, + "total_seconds": { + "type": "number" + } +} - added
Output schema / properties / data / requiredAdded value: +[ + "total_seconds", + "text", + "is_up_to_date", + "range" +] - added
Output schema / properties / data / typeAdded value: +"object" - removed
Output schema / titleRemoved value: -"AllTimeViewModel"
- Changed
get_leaders18 fields changed- added
Input schema / additionalPropertiesAdded value: +false - removed
Output schema / $defsRemoved value: -{ - "LeadersCurrentUser": { - "description": "Model for leaders current user.", - "properties": { - "page": { - "title": "Page", - "type": "integer" - }, - "rank": { - "title": "Rank", - "type": "integer" - }, - "user": { - "$ref": "#/$defs/User" - } - }, - "required": [ - "page", - "rank", - "user" - ], - "title": "LeadersCurrentUser", - "type": "object" - }, - "LeadersEntry": { - "description": "Model for leaders entry.", - "properties": { - "rank": { - "title": "Rank", - "type": "integer" - }, - "running_total": { - "$ref": "#/$defs/LeadersRunningTotal" - }, - "user": { - "$ref": "#/$defs/User" - } - }, - "required": [ - "rank", - "running_total", - "user" - ], - "title": "LeadersEntry", - "type": "object" - }, - "LeadersLanguage": { - "description": "Model for leaders language.", - "properties": { - "name": { - "title": "Name", - "type": "string" - }, - "total_seconds": { - "title": "Total Seconds", - "type": "number" - } - }, - "required": [ - "name", - "total_seconds" - ], - "title": "LeadersLanguage", - "type": "object" - }, - "LeadersRange": { - "description": "Model for leaders range.", - "properties": { - "end_date": { - "title": "End Date", - "type": "string" - }, - "end_text": { - "title": "End Text", - "type": "string" - }, - "name": { - "title": "Name", - "type": "string" - }, - "start_date": { - "title": "Start Date", - "type": "string" - }, - "start_text": { - "title": "Start Text", - "type": "string" - }, - "text": { - "title": "Text", - "type": "string" - } - }, - "required": [ - "end_date", - "end_text", - "name", - "start_date", - "start_text", - "text" - ], - "title": "LeadersRange", - "type": "object" - }, - "LeadersRunningTotal": { - "description": "Model for leaders running total.", - "properties": { - "daily_average": { - "title": "Daily Average", - "type": "number" - }, - "human_readable_daily_average": { - "title": "Human Readable Daily Average", - "type": "string" - }, - "human_readable_total": { - "title": "Human Readable Total", - "type": "string" - }, - "languages": { - "items": { - "$ref": "#/$defs/LeadersLanguage" - }, - "title": "Languages", - "type": "array" - }, - "total_seconds": { - "title": "Total Seconds", - "type": "number" - } - }, - "required": [ - "daily_average", - "human_readable_daily_average", - "human_readable_total", - "languages", - "total_seconds" - ], - "title": "LeadersRunningTotal", - "type": "object" - }, - "User": { - "description": "Model for user.", - "properties": { - "created_at": { - "title": "Created At", - "type": "string" - }, - "display_name": { - "title": "Display Name", - "type": "string" - }, - "email": { - "title": "Email", - "type": "string" - }, - "full_name": { - "title": "Full Name", - "type": "string" - }, - "id": { - "title": "Id", - "type": "string" - }, - "is_email_confirmed": { - "title": "Is Email Confirmed", - "type": "boolean" - }, - "is_email_public": { - "title": "Is Email Public", - "type": "boolean" - }, - "last_heartbeat_at": { - "title": "Last Heartbeat At", - "type": "string" - }, - "last_plugin_name": { - "title": "Last Plugin Name", - "type": "string" - }, - "last_project": { - "title": "Last Project", - "type": "string" - }, - "modified_at": { - "title": "Modified At", - "type": "string" - }, - "photo": { - "title": "Photo", - "type": "string" - }, - "timezone": { - "title": "Timezone", - "type": "string" - }, - "username": { - "title": "Username", - "type": "string" - }, - "website": { - "title": "Website", - "type": "string" - } - }, - "required": [ - "id", - "username", - "display_name", - "full_name", - "email", - "photo", - "website", - "timezone", - "created_at", - "modified_at", - "last_heartbeat_at", - "last_plugin_name", - "last_project", - "is_email_confirmed", - "is_email_public" - ], - "title": "User", - "type": "object" - } -} - changed
Output schema / properties / current_user / anyOfPrevious value: -[ - { - "$ref": "#/$defs/LeadersCurrentUser" - }, - { - "type": "null" - } -]New value: +[ + { + "description": "Model for leaders current user.", + "properties": { + "page": { + "type": "integer" + }, + "rank": { + "type": "integer" + }, + "user": { + "description": "Model for user.", + "properties": { + "created_at": { + "type": "string" + }, + "display_name": { + "type": "string" + }, + "email": { + "type": "string" + }, + "full_name": { + "type": "string" + }, + "id": { + "type": "string" + }, + "is_email_confirmed": { + "type": "boolean" + }, + "is_email_public": { + "type": "boolean" + }, + "last_heartbeat_at": { + "type": "string" + }, + "last_plugin_name": { + "type": "string" + }, + "last_project": { + "type": "string" + }, + "modified_at": { + "type": "string" + }, + "photo": { + "type": "string" + }, + "timezone": { + "type": "string" + }, + "username": { + "type": "string" + }, + "website": { + "type": "string" + } + }, + "required": [ + "id", + "username", + "display_name", + "full_name", + "email", + "photo", + "website", + "timezone", + "created_at", + "modified_at", + "last_heartbeat_at", + "last_plugin_name", + "last_project", + "is_email_confirmed", + "is_email_public" + ], + "type": "object" + } + }, + "required": [ + "page", + "rank", + "user" + ], + "type": "object" + }, + { + "type": "null" + } +] - removed
Output schema / properties / data / items / $refRemoved value: -"#/$defs/LeadersEntry" - added
Output schema / properties / data / items / descriptionAdded value: +"Model for leaders entry." - added
Output schema / properties / data / items / propertiesAdded value: +{ + "rank": { + "type": "integer" + }, + "running_total": { + "description": "Model for leaders running total.", + "properties": { + "daily_average": { + "type": "number" + }, + "human_readable_daily_average": { + "type": "string" + }, + "human_readable_total": { + "type": "string" + }, + "languages": { + "items": { + "description": "Model for leaders language.", + "properties": { + "name": { + "type": "string" + }, + "total_seconds": { + "type": "number" + } + }, + "required": [ + "name", + "total_seconds" + ], + "type": "object" + }, + "type": "array" + }, + "total_seconds": { + "type": "number" + } + }, + "required": [ + "daily_average", + "human_readable_daily_average", + "human_readable_total", + "languages", + "total_seconds" + ], + "type": "object" + }, + "user": { + "description": "Model for user.", + "properties": { + "created_at": { + "type": "string" + }, + "display_name": { + "type": "string" + }, + "email": { + "type": "string" + }, + "full_name": { + "type": "string" + }, + "id": { + "type": "string" + }, + "is_email_confirmed": { + "type": "boolean" + }, + "is_email_public": { + "type": "boolean" + }, + "last_heartbeat_at": { + "type": "string" + }, + "last_plugin_name": { + "type": "string" + }, + "last_project": { + "type": "string" + }, + "modified_at": { + "type": "string" + }, + "photo": { + "type": "string" + }, + "timezone": { + "type": "string" + }, + "username": { + "type": "string" + }, + "website": { + "type": "string" + } + }, + "required": [ + "id", + "username", + "display_name", + "full_name", + "email", + "photo", + "website", + "timezone", + "created_at", + "modified_at", + "last_heartbeat_at", + "last_plugin_name", + "last_project", + "is_email_confirmed", + "is_email_public" + ], + "type": "object" + } +} - added
Output schema / properties / data / items / requiredAdded value: +[ + "rank", + "running_total", + "user" +] - added
Output schema / properties / data / items / typeAdded value: +"object" - removed
Output schema / properties / data / titleRemoved value: -"Data" - removed
Output schema / properties / language / titleRemoved value: -"Language" - removed
Output schema / properties / page / titleRemoved value: -"Page" - removed
Output schema / properties / range / $refRemoved value: -"#/$defs/LeadersRange" - added
Output schema / properties / range / descriptionAdded value: +"Model for leaders range." - added
Output schema / properties / range / propertiesAdded value: +{ + "end_date": { + "type": "string" + }, + "end_text": { + "type": "string" + }, + "name": { + "type": "string" + }, + "start_date": { + "type": "string" + }, + "start_text": { + "type": "string" + }, + "text": { + "type": "string" + } +} - added
Output schema / properties / range / requiredAdded value: +[ + "end_date", + "end_text", + "name", + "start_date", + "start_text", + "text" +] - added
Output schema / properties / range / typeAdded value: +"object" - removed
Output schema / properties / total_pages / titleRemoved value: -"Total Pages" - removed
Output schema / titleRemoved value: -"LeadersViewModel"
- Changed
get_project_detail5 fields changed- added
Input schema / additionalPropertiesAdded value: +false - added
Input schema / properties / id / descriptionAdded value: +"Project ID to fetch." - removed
Input schema / properties / id / titleRemoved value: -"Id" - added
Input schema / properties / user / descriptionAdded value: +"User ID to fetch data for" - removed
Input schema / properties / user / titleRemoved value: -"User"
- Changed
get_projects11 fields changed- added
Input schema / additionalPropertiesAdded value: +false - removed
Input schema / properties / q / titleRemoved value: -"Q" - removed
Input schema / properties / user / titleRemoved value: -"User" - removed
Output schema / $defsRemoved value: -{ - "Project": { - "description": "Model for project.", - "properties": { - "created_at": { - "title": "Created At", - "type": "string" - }, - "human_readable_last_heartbeat_at": { - "title": "Human Readable Last Heartbeat At", - "type": "string" - }, - "id": { - "title": "Id", - "type": "string" - }, - "last_heartbeat_at": { - "title": "Last Heartbeat At", - "type": "string" - }, - "name": { - "title": "Name", - "type": "string" - }, - "urlencoded_name": { - "title": "Urlencoded Name", - "type": "string" - } - }, - "required": [ - "id", - "name", - "urlencoded_name", - "created_at", - "last_heartbeat_at", - "human_readable_last_heartbeat_at" - ], - "title": "Project", - "type": "object" - } -} - removed
Output schema / properties / data / items / $refRemoved value: -"#/$defs/Project" - added
Output schema / properties / data / items / descriptionAdded value: +"Model for project." - added
Output schema / properties / data / items / propertiesAdded value: +{ + "created_at": { + "type": "string" + }, + "human_readable_last_heartbeat_at": { + "type": "string" + }, + "id": { + "type": "string" + }, + "last_heartbeat_at": { + "type": "string" + }, + "name": { + "type": "string" + }, + "urlencoded_name": { + "type": "string" + } +} - added
Output schema / properties / data / items / requiredAdded value: +[ + "id", + "name", + "urlencoded_name", + "created_at", + "last_heartbeat_at", + "human_readable_last_heartbeat_at" +] - added
Output schema / properties / data / items / typeAdded value: +"object" - removed
Output schema / properties / data / titleRemoved value: -"Data" - removed
Output schema / titleRemoved value: -"ProjectsViewModel"
- Changed
get_recent_logs11 fields changed- added
Input schema / additionalPropertiesAdded value: +false - added
Input schema / properties / days / descriptionAdded value: +"Number of days to retrieve." - removed
Input schema / properties / days / titleRemoved value: -"Days" - added
Input schema / properties / limit / descriptionAdded value: +"Maximum number of heartbeats." - removed
Input schema / properties / limit / titleRemoved value: -"Limit" - added
Input schema / properties / project_name / descriptionAdded value: +"Filter by project." - removed
Input schema / properties / project_name / titleRemoved value: -"Project Name" - added
Input schema / properties / user / descriptionAdded value: +"Username (or current)." - removed
Input schema / properties / user / titleRemoved value: -"User" - removed
Output schema / properties / result / titleRemoved value: -"Result" - removed
Output schema / titleRemoved value: -"_WrappedResult"
- Changed
get_stats16 fields changed- added
Input schema / additionalPropertiesAdded value: +false - removed
Input schema / properties / editor / titleRemoved value: -"Editor" - removed
Input schema / properties / label / titleRemoved value: -"Label" - removed
Input schema / properties / language / titleRemoved value: -"Language" - removed
Input schema / properties / machine / titleRemoved value: -"Machine" - removed
Input schema / properties / operating_system / titleRemoved value: -"Operating System" - removed
Input schema / properties / project / titleRemoved value: -"Project" - removed
Input schema / properties / range / titleRemoved value: -"Range" - removed
Input schema / properties / user / titleRemoved value: -"User" - removed
Output schema / $defsRemoved value: -{ - "StatsData": { - "description": "Model for stats data.", - "properties": { - "branches": { - "anyOf": [ - { - "items": { - "$ref": "#/$defs/SummariesEntry" - }, - "type": "array" - }, - { - "type": "null" - } - ], - "default": [], - "title": "Branches" - }, - "categories": { - "anyOf": [ - { - "items": { - "$ref": "#/$defs/SummariesEntry" - }, - "type": "array" - }, - { - "type": "null" - } - ], - "default": [], - "title": "Categories" - }, - "daily_average": { - "title": "Daily Average", - "type": "number" - }, - "days_including_holidays": { - "title": "Days Including Holidays", - "type": "integer" - }, - "editors": { - "items": { - "$ref": "#/$defs/SummariesEntry" - }, - "title": "Editors", - "type": "array" - }, - "end": { - "title": "End", - "type": "string" - }, - "human_readable_daily_average": { - "title": "Human Readable Daily Average", - "type": "string" - }, - "human_readable_range": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Human Readable Range" - }, - "human_readable_total": { - "title": "Human Readable Total", - "type": "string" - }, - "is_coding_activity_visible": { - "title": "Is Coding Activity Visible", - "type": "boolean" - }, - "is_other_usage_visible": { - "title": "Is Other Usage Visible", - "type": "boolean" - }, - "languages": { - "items": { - "$ref": "#/$defs/SummariesEntry" - }, - "title": "Languages", - "type": "array" - }, - "machines": { - "items": { - "$ref": "#/$defs/SummariesEntry" - }, - "title": "Machines", - "type": "array" - }, - "operating_systems": { - "items": { - "$ref": "#/$defs/SummariesEntry" - }, - "title": "Operating Systems", - "type": "array" - }, - "projects": { - "items": { - "$ref": "#/$defs/SummariesEntry" - }, - "title": "Projects", - "type": "array" - }, - "range": { - "title": "Range", - "type": "string" - }, - "start": { - "title": "Start", - "type": "string" - }, - "status": { - "title": "Status", - "type": "string" - }, - "total_seconds": { - "title": "Total Seconds", - "type": "number" - }, - "user_id": { - "title": "User Id", - "type": "string" - }, - "username": { - "title": "Username", - "type": "string" - } - }, - "required": [ - "total_seconds", - "human_readable_total", - "daily_average", - "human_readable_daily_average", - "languages", - "projects", - "editors", - "operating_systems", - "machines", - "range", - "start", - "end", - "status", - "is_coding_activity_visible", - "is_other_usage_visible", - "days_including_holidays", - "user_id", - "username" - ], - "title": "StatsData", - "type": "object" - }, - "SummariesEntry": { - "description": "Model for summaries entry.", - "properties": { - "digital": { - "title": "Digital", - "type": "string" - }, - "hours": { - "title": "Hours", - "type": "integer" - }, - "minutes": { - "title": "Minutes", - "type": "integer" - }, - "name": { - "title": "Name", - "type": "string" - }, - "percent": { - "title": "Percent", - "type": "number" - }, - "seconds": { - "anyOf": [ - { - "type": "integer" - }, - { - "type": "null" - } - ], - "default": null, - "title": "Seconds" - }, - "text": { - "title": "Text", - "type": "string" - }, - "total_seconds": { - "title": "Total Seconds", - "type": "number" - } - }, - "required": [ - "name", - "percent", - "total_seconds", - "text", - "digital", - "hours", - "minutes" - ], - "title": "SummariesEntry", - "type": "object" - } -} - removed
Output schema / properties / data / $refRemoved value: -"#/$defs/StatsData" - added
Output schema / properties / data / descriptionAdded value: +"Model for stats data." - added
Output schema / properties / data / propertiesAdded value: +{ + "branches": { + "anyOf": [ + { + "items": { + "description": "Model for summaries entry.", + "properties": { + "digital": { + "type": "string" + }, + "hours": { + "type": "integer" + }, + "minutes": { + "type": "integer" + }, + "name": { + "type": "string" + }, + "percent": { + "type": "number" + }, + "seconds": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null + }, + "text": { + "type": "string" + }, + "total_seconds": { + "type": "number" + } + }, + "required": [ + "name", + "percent", + "total_seconds", + "text", + "digital", + "hours", + "minutes" + ], + "type": "object" + }, + "type": "array" + }, + { + "type": "null" + } + ], + "default": [] + }, + "categories": { + "anyOf": [ + { + "items": { + "description": "Model for summaries entry.", + "properties": { + "digital": { + "type": "string" + }, + "hours": { + "type": "integer" + }, + "minutes": { + "type": "integer" + }, + "name": { + "type": "string" + }, + "percent": { + "type": "number" + }, + "seconds": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null + }, + "text": { + "type": "string" + }, + "total_seconds": { + "type": "number" + } + }, + "required": [ + "name", + "percent", + "total_seconds", + "text", + "digital", + "hours", + "minutes" + ], + "type": "object" + }, + "type": "array" + }, + { + "type": "null" + } + ], + "default": [] + }, + "daily_average": { + "type": "number" + }, + "days_including_holidays": { + "type": "integer" + }, + "editors": { + "items": { + "description": "Model for summaries entry.", + "properties": { + "digital": { + "type": "string" + }, + "hours": { + "type": "integer" + }, + "minutes": { + "type": "integer" + }, + "name": { + "type": "string" + }, + "percent": { + "type": "number" + }, + "seconds": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null + }, + "text": { + "type": "string" + }, + "total_seconds": { + "type": "number" + } + }, + "required": [ + "name", + "percent", + "total_seconds", + "text", + "digital", + "hours", + "minutes" + ], + "type": "object" + }, + "type": "array" + }, + "end": { + "type": "string" + }, + "human_readable_daily_average": { + "type": "string" + }, + "human_readable_range": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null + }, + "human_readable_total": { + "type": "string" + }, + "is_coding_activity_visible": { + "type": "boolean" + }, + "is_other_usage_visible": { + "type": "boolean" + }, + "languages": { + "items": { + "description": "Model for summaries entry.", + "properties": { + "digital": { + "type": "string" + }, + "hours": { + "type": "integer" + }, + "minutes": { + "type": "integer" + }, + "name": { + "type": "string" + }, + "percent": { + "type": "number" + }, + "seconds": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null + }, + "text": { + "type": "string" + }, + "total_seconds": { + "type": "number" + } + }, + "required": [ + "name", + "percent", + "total_seconds", + "text", + "digital", + "hours", + "minutes" + ], + "type": "object" + }, + "type": "array" + }, + "machines": { + "items": { + "description": "Model for summaries entry.", + "properties": { + "digital": { + "type": "string" + }, + "hours": { + "type": "integer" + }, + "minutes": { + "type": "integer" + }, + "name": { + "type": "string" + }, + "percent": { + "type": "number" + }, + "seconds": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null + }, + "text": { + "type": "string" + }, + "total_seconds": { + "type": "number" + } + }, + "required": [ + "name", + "percent", + "total_seconds", + "text", + "digital", + "hours", + "minutes" + ], + "type": "object" + }, + "type": "array" + }, + "operating_systems": { + "items": { + "description": "Model for summaries entry.", + "properties": { + "digital": { + "type": "string" + }, + "hours": { + "type": "integer" + }, + "minutes": { + "type": "integer" + }, + "name": { + "type": "string" + }, + "percent": { + "type": "number" + }, + "seconds": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null + }, + "text": { + "type": "string" + }, + "total_seconds": { + "type": "number" + } + }, + "required": [ + "name", + "percent", + "total_seconds", + "text", + "digital", + "hours", + "minutes" + ], + "type": "object" + }, + "type": "array" + }, + "projects": { + "items": { + "description": "Model for summaries entry.", + "properties": { + "digital": { + "type": "string" + }, + "hours": { + "type": "integer" + }, + "minutes": { + "type": "integer" + }, + "name": { + "type": "string" + }, + "percent": { + "type": "number" + }, + "seconds": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null + }, + "text": { + "type": "string" + }, + "total_seconds": { + "type": "number" + } + }, + "required": [ + "name", + "percent", + "total_seconds", + "text", + "digital", + "hours", + "minutes" + ], + "type": "object" + }, + "type": "array" + }, + "range": { + "type": "string" + }, + "start": { + "type": "string" + }, + "status": { + "type": "string" + }, + "total_seconds": { + "type": "number" + }, + "user_id": { + "type": "string" + }, + "username": { + "type": "string" + } +} - added
Output schema / properties / data / requiredAdded value: +[ + "total_seconds", + "human_readable_total", + "daily_average", + "human_readable_daily_average", + "languages", + "projects", + "editors", + "operating_systems", + "machines", + "range", + "start", + "end", + "status", + "is_coding_activity_visible", + "is_other_usage_visible", + "days_including_holidays", + "user_id", + "username" +] - added
Output schema / properties / data / typeAdded value: +"object" - removed
Output schema / titleRemoved value: -"StatsViewModel"
- Changed
get_user9 fields changed- added
Input schema / additionalPropertiesAdded value: +false - removed
Input schema / properties / user / titleRemoved value: -"User" - removed
Output schema / $defsRemoved value: -{ - "User": { - "description": "Model for user.", - "properties": { - "created_at": { - "title": "Created At", - "type": "string" - }, - "display_name": { - "title": "Display Name", - "type": "string" - }, - "email": { - "title": "Email", - "type": "string" - }, - "full_name": { - "title": "Full Name", - "type": "string" - }, - "id": { - "title": "Id", - "type": "string" - }, - "is_email_confirmed": { - "title": "Is Email Confirmed", - "type": "boolean" - }, - "is_email_public": { - "title": "Is Email Public", - "type": "boolean" - }, - "last_heartbeat_at": { - "title": "Last Heartbeat At", - "type": "string" - }, - "last_plugin_name": { - "title": "Last Plugin Name", - "type": "string" - }, - "last_project": { - "title": "Last Project", - "type": "string" - }, - "modified_at": { - "title": "Modified At", - "type": "string" - }, - "photo": { - "title": "Photo", - "type": "string" - }, - "timezone": { - "title": "Timezone", - "type": "string" - }, - "username": { - "title": "Username", - "type": "string" - }, - "website": { - "title": "Website", - "type": "string" - } - }, - "required": [ - "id", - "username", - "display_name", - "full_name", - "email", - "photo", - "website", - "timezone", - "created_at", - "modified_at", - "last_heartbeat_at", - "last_plugin_name", - "last_project", - "is_email_confirmed", - "is_email_public" - ], - "title": "User", - "type": "object" - } -} - removed
Output schema / properties / data / $refRemoved value: -"#/$defs/User" - added
Output schema / properties / data / descriptionAdded value: +"Model for user." - added
Output schema / properties / data / propertiesAdded value: +{ + "created_at": { + "type": "string" + }, + "display_name": { + "type": "string" + }, + "email": { + "type": "string" + }, + "full_name": { + "type": "string" + }, + "id": { + "type": "string" + }, + "is_email_confirmed": { + "type": "boolean" + }, + "is_email_public": { + "type": "boolean" + }, + "last_heartbeat_at": { + "type": "string" + }, + "last_plugin_name": { + "type": "string" + }, + "last_project": { + "type": "string" + }, + "modified_at": { + "type": "string" + }, + "photo": { + "type": "string" + }, + "timezone": { + "type": "string" + }, + "username": { + "type": "string" + }, + "website": { + "type": "string" + } +} - added
Output schema / properties / data / requiredAdded value: +[ + "id", + "username", + "display_name", + "full_name", + "email", + "photo", + "website", + "timezone", + "created_at", + "modified_at", + "last_heartbeat_at", + "last_plugin_name", + "last_project", + "is_email_confirmed", + "is_email_public" +] - added
Output schema / properties / data / typeAdded value: +"object" - removed
Output schema / titleRemoved value: -"UserViewModel"
- Changed
test_connection1 field changed- added
Input schema / additionalPropertiesAdded value: +false
8 tool updates
- First observed
get_all_time_since_today - First observed
get_leaders - First observed
get_project_detail - First observed
get_projects - First observed
get_recent_logs - First observed
get_stats - First observed
get_user - First observed
test_connection
TDQS
Scored across 8 tools
Most tools target clearly different resources: user, projects, leaders, heartbeats, project detail, and connection test. However, get_stats and get_all_time_since_today could be confused when using the 'any' or 'all_time' range, and get_projects vs get_project_detail is close but distinguishable.
Tool names follow a mostly consistent get_* snake_case pattern for retrieval operations. test_connection is a reasonable exception for an action tool, though it slightly breaks the retrieval-oriented naming pattern.
Eight tools is well-scoped for a read-oriented Wakapi API wrapper. Each tool covers a distinct endpoint or operation without excessive redundancy.
The surface covers core read workflows: user info, stats, projects, project detail, leaders, recent heartbeats, all-time summary, and connection testing. Some WakaTime/Wakapi endpoints like summaries, durations, or heartbeat posting are missing, but common retrieval needs are mostly covered.
Maintenance
Related MCP Connectors
Read your WakaTime coding time: summaries, stats, projects, goals, commits and leaderboards.
231Connects AI assistants to TrackingTime for querying time entries, projects, tasks, customers, and team data using natural language.
Track time in Clockify: time entries, projects, clients, tags and reports; start, stop and log time.
211Access and interact with anime and manga data seamlessly. Retrieve detailed information about your…
Related MCP Servers
- FlicenseNot gradedqualityDmaintenanceEnables users to measure, track, and compare response times of GitHub Copilot and other AI models. Provides statistical analysis and performance comparison tools for evaluating AI model efficiency.-
- AlicenseNot gradedqualityDmaintenanceProvides access to WakaTime coding analytics data through MCP tools. Enables querying coding stats, activity summaries, project lists, and time tracking information from your WakaTime account.MIT
- AlicenseBqualityDmaintenanceEnables time tracking and project management through the Clockify API. Supports starting/stopping timers, logging time entries, managing projects and tasks, and generating reports with natural language commands.2114 npmMIT
- AlicenseNot gradedqualityCmaintenanceEnables LLM agents to query and analyze ActivityWatch time tracking data, including window activity, web browsing, and category management with natural language time periods and automatic data aggregation.12GPL 3.0