worksection-mcp
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., "@worksection-mcp List all tasks assigned to me that are due this 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.
worksection-mcp
A Model Context Protocol (MCP) server for the Worksection project-management API. It speaks MCP over stdio, so any MCP-capable client can drive Worksection projects, tasks, subtasks, comments, tags, people, time tracking, files, search and reporting through a consistent set of tools.
Requirements
Python 3.11+
A Worksection account, with either an admin API key or an OAuth2 application
Related MCP server: weeek-mcp
Install
git clone https://github.com/atlantdak/worksection-mcp.git
cd worksection-mcp
uv sync
uv run worksection-mcpConfiguration
All settings are read from environment variables (or a local .env file — see
.env.example). None have a prefix.
Variable | Default | Purpose |
|
|
|
| (empty) | Bare account slug from |
| (empty) | Admin API key (admin_key mode) |
| (unset) | OAuth2 application client id (oauth mode) |
| (unset) | OAuth2 application client secret (oauth mode) |
|
| Loopback port the login listener binds to; |
| (unset) | Key used to encrypt stored OAuth tokens (oauth mode) |
|
| Registers |
| (unset) | Absolute path to the only directory |
|
| Where tokens, certificates, cache and offloaded responses are stored |
|
| HTTP request timeout |
|
| Retry attempts for retryable HTTP failures |
|
| Outbound request rate limit |
|
| Enables the in-process response cache |
|
| Cache entry lifetime |
|
| Responses larger than this are written to disk instead of returned inline |
|
| Standard Python logging level |
Authentication — two modes
Admin API key (recommended for a single user)
Find your admin API key in Worksection under account settings, then set:
AUTH_MODE=admin_key
WORKSECTION_ACCOUNT=your-account
WORKSECTION_API_KEY=your-keyThere is no browser step at all in this mode. The server authenticates every request directly with the key.
OAuth2 (per-user)
Register an OAuth2 application in Worksection, then set:
AUTH_MODE=oauth
OAUTH_CLIENT_ID=your-client-id
OAUTH_CLIENT_SECRET=your-client-secret
FERNET_KEY=your-generated-keyGenerate the Fernet key with:
uv run python -m worksection_mcp.auth.token_storeThen call the worksection_login tool from your MCP client to complete the one-time
login. A short-lived HTTPS listener starts on 127.0.0.1:18030 (configurable via
OAUTH_REDIRECT_PORT) to receive the OAuth2 redirect. Its certificate is self-signed,
so your browser will show a one-time warning before you can continue. Once
authenticated, tokens are stored Fernet-encrypted with 0600 permissions under
~/.worksection-mcp/ (or STATE_DIR), and refreshed automatically as needed —
no further browser interaction is required.
Two-factor authentication: if your Worksection account has two-factor authentication enabled, it affects only the one-time browser login step of OAuth2 mode — you complete the 2FA prompt in the browser exactly as you normally would. Nothing in this server touches, stores or bypasses your second factor. For a fully non-interactive setup, use admin API key mode, which needs no browser login at all.
Safety: destructive operations
ALLOW_DESTRUCTIVE_OPERATIONS defaults to false. While it is false, the
destructive tools — delete_task, delete_comment and delete_costs — are not even
listed to the connected client; they simply don't exist as far as the client can see.
When it is set to true, they become available, and each additionally requires the
caller to pass confirm: true before it will run. This two-layer guard exists
specifically to protect against prompt-injection-driven data loss: a client has to be
deliberately configured to allow destructive actions, and every individual call has to
opt in explicitly.
Safety: file access
No tool accepts an arbitrary filesystem path. upload_file takes either inline
base64 content or the name of a file inside the configured FILE_WORKSPACE_DIR —
any path outside that directory, including via traversal or symlinks, is rejected.
download_file returns attachment content inline as base64, capped at a maximum
size, and never writes anything to disk.
Large responses
Responses larger than OFFLOAD_THRESHOLD_BYTES are written to disk instead of
returned inline. The tool call instead gets back a summary containing a
worksection://offload/... resource URI. The full content can be read back in
bounded chunks with the read_offloaded_response tool, or fetched directly as an
MCP resource.
Client configuration
Example configuration for an MCP client, using admin API key mode:
{
"mcpServers": {
"worksection": {
"command": "uv",
"args": ["--directory", "/absolute/path/to/worksection-mcp", "run", "worksection-mcp"],
"env": {
"AUTH_MODE": "admin_key",
"WORKSECTION_ACCOUNT": "your-account",
"WORKSECTION_API_KEY": "your-key"
}
}
}
}Tools
Tool | Description |
| Restore an archived project to active status. |
| Log time (and optionally money) against a task. |
| Add tags to a task, keeping the tags it already has. |
| Close a project and move it to the archive. Reversible with activate_project. |
| Report the active authentication mode and, in oauth mode, whether the server has stored login credentials. This reflects whether credentials are on file, not whether the access token happens to be fresh right now - an expired token is refreshed automatically as long as a refresh token is stored. Never returns token values. |
| Mark a task as done, closing it in Worksection. |
| Create a project, optionally with a manager, description and dates. |
| Create a subtask under an existing task. |
| Create a task in a project, optionally assigned, dated and prioritised. |
| Permanently delete a comment. Only available when ALLOW_DESTRUCTIVE_OPERATIONS=true, and requires confirm=true. |
| Permanently delete a time entry. Only available when ALLOW_DESTRUCTIVE_OPERATIONS=true, and requires confirm=true. |
| Permanently delete a task. Only available when ALLOW_DESTRUCTIVE_OPERATIONS=true, and requires confirm=true. |
| Fetch one attachment and return it inline as base64. Refuses files larger than max_bytes instead of writing anywhere on disk. |
| List recent account or project activity events over a date range. |
| List tasks across every project the account can see. Status and assignee filters are re-applied locally because the API's own filtering is unreliable for some combinations. |
| List the comments on a task, oldest first. |
| List external contacts (clients) registered in the account. |
| List logged time and cost entries, optionally scoped to a project or task, a date range, or one person. |
| Find one account member by email or id. |
| List the member groups (teams) configured for the account. |
| List the people in the account with their ids, emails and roles. |
| List open tasks whose due date has passed, most overdue first. |
| Fetch a single project by id, including its status and dates. |
| List the task groups (folders) configured inside a project. |
| List the people who have access to one project. |
| Count a project's tasks by status and priority bucket. |
| List projects visible to the authenticated account. |
| List every timer currently running in the account. |
| List the subtasks of a task. |
| List the tag groups and tags configured for the account. |
| Fetch one task, optionally with its description text, files and subtasks. |
| List the files attached to a task, with their ids, names and sizes. |
| List the tag names currently applied to a task. |
| List tasks inside one project, with local status and assignee filtering. |
| Group tasks into high, normal and low priority buckets. |
| Group tasks by status, with counts and the tasks in each group. |
| Group open and completed tasks by assignee across the account or one project. |
| Summarise logged time and money for an account, project or task over a date range, totalled per person. |
| Verify that the configured credentials can reach the Worksection API. Returns a status report instead of raising when the call fails. |
| List the files available in the configured workspace directory. Returns an empty list when FILE_WORKSPACE_DIR is not set. |
| Add a comment to a task. |
| Read one bounded chunk of a response that was too large to return inline. Use the resource_uri and total_chunks from the offload summary. |
| Reopen a previously completed task. |
| Search tasks by text, status, assignee, priority and due date, across the account or inside one project. Filtering is applied locally for reliability. |
| Replace every tag on a task with the given list. |
| Start a running timer on a task. |
| Stop the running timer on a task and store the elapsed time. |
| Replace the text of an existing comment. |
| Change the hours, comment, date or amount of an existing time entry. |
| Change a project's title, description, manager or dates. |
| Change the title, description, assignee, due date or priority of a subtask. |
| Change the title, description, assignee, dates or priority of a task. |
| Attach a file to a task. Provide the content inline as base64, or name a file inside the configured workspace directory. Arbitrary filesystem paths are rejected. |
| Report the server's effective configuration and the result of every local startup check. Contacts no external service and never returns secret values. |
| Start the OAuth2 browser login. Opens the authorization page, waits for the loopback redirect, and stores the resulting tokens encrypted on disk. Has nothing to do in admin_key mode and reports that instead of failing. |
| Delete the stored OAuth tokens from disk. Only local credentials are removed; nothing in Worksection itself is affected. |
Development
uv sync
uv run pytest
uv run ruff check .
uv run mypy
uv run python scripts/import_sweep.py
uv run python scripts/preflight.pyAPI limitations
Known quirks and undocumented behaviour of the upstream Worksection API, and how
each was verified, are tracked in docs/API-LIMITATIONS.md.
Security
See SECURITY.md for the project's security posture and how to
report a vulnerability.
Acknowledgments
This project's design was informed by ideas from a few existing community Worksection MCP servers, including novgorodskii/worksection-mcp-server, PavloPopravkin/worksection-mcp, and pbv7/worksection-mcp. Thanks to their authors for publishing their work. This codebase is an independent, from-scratch implementation, not a fork of any of them.
Licence
MIT
Available Tools
53 toolsactivate_projectB
Restore an archived project to active status.
Inputs: project_id (required).
add_costsC
Log time (and optionally money) against a task.
Inputs: hours (required), task_id (required), project_id (required), date, +3 more.
add_task_tagsA
Add tags to a task, keeping the tags it already has.
Inputs: tags (required), task_id (required), project_id (required).
archive_projectA
Close a project and move it to the archive. Reversible with activate_project.
Inputs: project_id (required).
auth_statusA
Report the active authentication mode and, in oauth mode, whether the server has stored login credentials. This reflects whether credentials are on file, not whether the access token happens to be fresh right now - an expired token is refreshed automatically as long as a refresh token is stored. Never returns token values.
Inputs: no named parameters.
complete_taskB
Mark a task as done, closing it in Worksection.
Inputs: task_id (required), project_id (required).
create_projectB
Create a project, optionally with a manager, description and dates.
Inputs: title (required), text, due_date, start_date, +2 more.
create_subtaskB
Create a subtask under an existing task.
Inputs: title (required), task_id (required), project_id (required), text, +3 more.
create_taskC
Create a task in a project, optionally assigned, dated and prioritised.
Inputs: title (required), project_id (required), text, due_date, +5 more.
download_fileA
Fetch one attachment and return it inline as base64. Refuses files larger than max_bytes instead of writing anywhere on disk.
Inputs: file_id (required), task_id (required), project_id (required), max_bytes.
get_activity_logA
List recent account or project activity events over a date range.
Inputs: date_to, date_from, project_id.
get_all_tasksA
List tasks across every project the account can see. Status and assignee filters are re-applied locally because the API's own filtering is unreliable for some combinations.
Inputs: status, assignee_email.
get_commentsA
List the comments on a task, oldest first.
Inputs: task_id (required), project_id (required).
get_contactsA
List external contacts (clients) registered in the account.
Inputs: no named parameters.
get_costsB
List logged time and cost entries, optionally scoped to a project or task, a date range, or one person.
Inputs: date_to, task_id, date_from, project_id, +1 more.
get_memberA
Find one account member by email or id.
Inputs: email, member_id.
get_member_groupsB
List the member groups (teams) configured for the account.
Inputs: no named parameters.
get_membersA
List the people in the account with their ids, emails and roles.
Inputs: no named parameters.
get_overdue_tasksA
List open tasks whose due date has passed, most overdue first.
Inputs: project_id.
get_projectA
Fetch a single project by id, including its status and dates.
Inputs: project_id (required), include_extra.
get_project_groupsA
List the task groups (folders) configured inside a project.
Inputs: project_id (required).
get_project_membersA
List the people who have access to one project.
Inputs: project_id (required).
get_projectsC
List projects visible to the authenticated account.
Inputs: status, include_extra.
get_project_statsA
Count a project's tasks by status and priority bucket.
Inputs: project_id (required).
get_running_timersA
List every timer currently running in the account.
Inputs: no named parameters.
get_subtasksC
List the subtasks of a task.
Inputs: task_id (required), project_id (required).
get_tagsA
List the tag groups and tags configured for the account.
Inputs: no named parameters.
get_taskB
Fetch one task, optionally with its description text, files and subtasks.
Inputs: task_id (required), project_id (required), include_extra.
get_task_filesA
List the files attached to a task, with their ids, names and sizes.
Inputs: task_id (required), project_id (required).
get_tasksA
List tasks inside one project, with local status and assignee filtering.
Inputs: project_id (required), status, assignee_email.
get_tasks_by_priorityC
Group tasks into high, normal and low priority buckets.
Inputs: project_id.
get_tasks_by_statusB
Group tasks by status, with counts and the tasks in each group.
Inputs: project_id.
get_task_tagsA
List the tag names currently applied to a task.
Inputs: task_id (required), project_id (required).
get_team_workloadA
Group open and completed tasks by assignee across the account or one project.
Inputs: project_id.
get_time_reportA
Summarise logged time and money for an account, project or task over a date range, totalled per person.
Inputs: date_to, task_id, date_from, project_id, +2 more.
health_checkB
Verify that the configured credentials can reach the Worksection API. Returns a status report instead of raising when the call fails.
Inputs: no named parameters.
list_workspace_filesB
List the files available in the configured workspace directory. Returns an empty list when FILE_WORKSPACE_DIR is not set.
Inputs: no named parameters.
post_commentA
Add a comment to a task.
Inputs: text (required), task_id (required), project_id (required), hidden, +1 more.
read_offloaded_responseA
Read one bounded chunk of a response that was too large to return inline. Use the resource_uri and total_chunks from the offload summary.
Inputs: resource_uri (required), chunk_index.
reopen_taskC
Reopen a previously completed task.
Inputs: task_id (required), project_id (required).
search_tasksA
Search tasks by text, status, assignee, priority and due date, across the account or inside one project. Filtering is applied locally for reliability.
Inputs: text, limit, status, due_after, +4 more.
set_task_tagsA
Replace every tag on a task with the given list.
Inputs: tags (required), task_id (required), project_id (required).
start_timerC
Start a running timer on a task.
Inputs: task_id (required), project_id (required), user_email.
stop_timerA
Stop the running timer on a task and store the elapsed time.
Inputs: task_id (required), project_id (required), comment, user_email.
update_commentA
Replace the text of an existing comment.
Inputs: text (required), task_id (required), comment_id (required), project_id (required).
update_costsB
Change the hours, comment, date or amount of an existing time entry.
Inputs: cost_id (required), task_id (required), project_id (required), date, +3 more.
update_projectC
Change a project's title, description, manager or dates.
Inputs: project_id (required), text, title, due_date, +2 more.
update_subtaskB
Change the title, description, assignee, due date or priority of a subtask.
Inputs: task_id (required), project_id (required), subtask_id (required), text, +4 more.
update_taskB
Change the title, description, assignee, dates or priority of a task.
Inputs: task_id (required), project_id (required), text, title, +4 more.
upload_fileB
Attach a file to a task. Provide the content inline as base64, or name a file inside the configured workspace directory. Arbitrary filesystem paths are rejected.
Inputs: task_id (required), project_id (required), filename, content_base64, +1 more.
validate_configurationA
Report the server's effective configuration and the result of every local startup check. Contacts no external service and never returns secret values.
Inputs: no named parameters.
worksection_loginA
Start the OAuth2 browser login. Opens the authorization page, waits for the loopback redirect, and stores the resulting tokens encrypted on disk. Has nothing to do in admin_key mode and reports that instead of failing.
Inputs: timeout_seconds.
worksection_logoutA
Delete the stored OAuth tokens from disk. Only local credentials are removed; nothing in Worksection itself is affected.
Inputs: no named parameters.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 53 tools
The read surface is dense: get_tasks, get_all_tasks, get_tasks_by_status, get_tasks_by_priority, get_overdue_tasks, and search_tasks all return task lists with overlapping filters/grouping, and get_costs/get_time_report plus auth_status/health_check/validate_configuration occupy similar niches. Descriptions are detailed enough to separate them, but an agent can easily pick the wrong variant.
The vast majority use a clear verb_noun pattern (get_*, create_*, update_*), with state changes as verb_noun (complete_task, reopen_task, archive_project). Minor deviations like post_comment instead of create_comment, add_costs instead of create_cost, and noun-style auth_status/health_check keep it from a perfect 5.
53 tools is far above the 3-15 well-scoped range and even above the 25+ 'too many' threshold; it is an extreme count for an MCP server. Many variants could be consolidated (e.g., task listing/grouping/search).
The surface covers the main Worksection workflow: projects, tasks, subtasks, comments, tags, files, time/costs, timers, members, and activity. The main gap is the lack of delete operations (tasks, projects, comments, files) and no ability to move a task between projects, but these are workable rather than blocking.
Maintenance
Related MCP Connectors
Read and write Mission Control state via MCP — projects, tasks, subtasks, templates, status updates.
Read and write shared BitsWeave context, projects, tasks, and work sessions through MCP.
timesheet.io MCP server - manage timers, projects, tasks and reports
Toggl 2.0 MCP server for tasks, projects, time entries, and workspace operations.
Related MCP Servers
- FlicenseBqualityCmaintenanceLocal MCP server for essential ClickUp workflows over stdio, exposing a bounded set of tools for search, task management, comments, tags, and workspace hierarchy.32-
- AlicenseAqualityCmaintenanceLocal, read-only-by-default MCP server for Weeek that connects AI clients to your workspace over stdio, enabling listing projects, tasks, boards, members, and tags with opt-in write tools for task management.1066 npmMIT
- AlicenseNot gradedqualityBmaintenanceEnables MCP clients to manage Toggl Track time entries, timers, projects, clients, tags, and reports through a self-hosted stdio server.298 npmMIT
- AlicenseNot gradedqualityCmaintenanceEnables MCP clients to interact with the Crewmeister API over local stdio, covering operations for members, teams, time tracking, salary exports, and related platform resources.Apache 2.0