toggl-focus-mcp

toggl-focus-mcp

MCP server for Toggl Focus 2.0, enabling project, task, and time-entry management with live timer control through natural language.

Category
访问服务器

README

toggl-focus-mcp

MCP server for Toggl Focus (2.0) — not Toggl Track 1.0.

Connect Claude, Cursor, Codex, or OpenCode to your Focus workspace with a Bearer API key (toggl_sk_…) and npx. No OAuth browser flow required.

npx -y toggl-focus-mcp
Auth Focus Bearer API key (Authorization: Bearer toggl_sk_…)
API https://focus.toggl.com/api
Transport stdio MCP
Node ≥ 20 (CI / .nvmrc → latest Current)

Track “API Token” values (Basic Auth / profile token for Track) do not work. Create a Focus / Toggl 2.0 key in settings. Official OAuth MCP: @togglhq/mcp.


Prerequisites

  1. A Toggl Focus / 2.0 API key (toggl_sk_…) — shown once when created
  2. Your organization ID and workspace ID (strongly recommended)
  3. Node.js 20+ (for npx)

Find org/workspace IDs in the Focus URL, e.g.
https://focus.toggl.com/.../organizations/21504582/workspaces/21503801/...

Setting both IDs avoids extra discovery calls and protects against Focus hourly quota limits.


Environment variables

Variable Required Description
TOGGL_FOCUS_API_TOKEN Yes* Focus API key (toggl_sk_…)
TOGGL_API_KEY Yes* Alias for the Focus API key
TOGGL_API_TOKEN Yes* Additional alias
TOGGL_ORGANIZATION_ID Recommended Default organization ID
TOGGL_WORKSPACE_ID Recommended Default workspace ID
TOGGL_FOCUS_BASE_URL No API base (default https://focus.toggl.com/api)

* Exactly one of TOGGL_FOCUS_API_TOKEN, TOGGL_API_KEY, or TOGGL_API_TOKEN is required.

Most tools accept optional organization_id / workspace_id arguments that override the env defaults for that call.


Install

Replace toggl_sk_..., 123, and 456 with your real key and IDs.

Claude Code

claude mcp add toggl-focus \
  -e TOGGL_FOCUS_API_TOKEN=toggl_sk_... \
  -e TOGGL_ORGANIZATION_ID=123 \
  -e TOGGL_WORKSPACE_ID=456 \
  -- npx -y toggl-focus-mcp

Verify:

claude mcp list

Claude Desktop

Edit claude_desktop_config.json, then restart Claude Desktop.

  • macOS: ~/Library/Application Support/Claude/claude_desktop_config.json
  • Windows: %APPDATA%\Claude\claude_desktop_config.json
{
  "mcpServers": {
    "toggl-focus": {
      "command": "npx",
      "args": ["-y", "toggl-focus-mcp"],
      "env": {
        "TOGGL_FOCUS_API_TOKEN": "toggl_sk_...",
        "TOGGL_ORGANIZATION_ID": "123",
        "TOGGL_WORKSPACE_ID": "456"
      }
    }
  }
}

Cursor

Add to project .cursor/mcp.json or your global Cursor MCP settings:

{
  "mcpServers": {
    "toggl-focus": {
      "command": "npx",
      "args": ["-y", "toggl-focus-mcp"],
      "env": {
        "TOGGL_FOCUS_API_TOKEN": "toggl_sk_...",
        "TOGGL_ORGANIZATION_ID": "123",
        "TOGGL_WORKSPACE_ID": "456"
      }
    }
  }
}

Enable the server in Cursor Settings → MCP, then confirm tools like focus_whoami appear.

Codex

CLI (recommended):

codex mcp add toggl-focus \
  --env TOGGL_FOCUS_API_TOKEN=toggl_sk_... \
  --env TOGGL_ORGANIZATION_ID=123 \
  --env TOGGL_WORKSPACE_ID=456 \
  -- npx -y toggl-focus-mcp

Or edit ~/.codex/config.toml (or project .codex/config.toml in a trusted repo):

[mcp_servers.toggl-focus]
command = "npx"
args = ["-y", "toggl-focus-mcp"]

[mcp_servers.toggl-focus.env]
TOGGL_FOCUS_API_TOKEN = "toggl_sk_..."
TOGGL_ORGANIZATION_ID = "123"
TOGGL_WORKSPACE_ID = "456"

To keep secrets out of the file, set them in your shell and forward by name:

[mcp_servers.toggl-focus]
command = "npx"
args = ["-y", "toggl-focus-mcp"]
env_vars = ["TOGGL_FOCUS_API_TOKEN", "TOGGL_ORGANIZATION_ID", "TOGGL_WORKSPACE_ID"]

Shared across Codex CLI, IDE extension, and ChatGPT desktop Codex host. Docs: developers.openai.com/codex/mcp.

OpenCode

Add to opencode.json / opencode.jsonc (project or global):

{
  "$schema": "https://opencode.ai/config.json",
  "mcp": {
    "toggl-focus": {
      "type": "local",
      "command": ["npx", "-y", "toggl-focus-mcp"],
      "enabled": true,
      "environment": {
        "TOGGL_FOCUS_API_TOKEN": "toggl_sk_...",
        "TOGGL_ORGANIZATION_ID": "123",
        "TOGGL_WORKSPACE_ID": "456"
      }
    }
  }
}

You can also reference shell env vars with OpenCode’s {env:VAR} syntax where supported. Docs: opencode.ai/docs/mcp-servers.


Quick start prompts

Once the server is connected, try:

  • “Who am I in Toggl Focus?”
  • “List my projects”
  • “Start a timer on project X”
  • “Create a task called Ship MCP docs on project Y”
  • “Show time entries for this week”

Creates, updates, deletes, and timer start/stop apply immediately (no confirmation token).


Tools

24 tools. All are Focus/2.0 only. Shared optional args on almost every tool:

Arg Type Notes
organization_id number Overrides TOGGL_ORGANIZATION_ID
workspace_id number Overrides TOGGL_WORKSPACE_ID
page number Default 1 (list tools)
per_page number Default 50, max 100 (list tools)

Account & context

focus_whoami

Account metadata + user settings for the authenticated Focus key.

Arg Type Required Description
include_settings boolean No Default true — also fetch GET /users/me/settings
organization_id / workspace_id number No Optional scope

focus_get_workspace_context

Resolve and cache organization_id / workspace_id for later tools. Prefer setting both env vars. Does not call the session-only /workspaces/{id}/context endpoint (that returns 403 for API keys).

focus_list_org_users

List organization users (assignee lookup). Read-only.

Arg Type Required Description
filter string No Search name/email
active_status string No Active-status filter when supported
page / per_page number No Pagination

Projects

focus_list_projects

List workspace projects.

Arg Type Description
name string Filter by project or client name
archived / completed / pinned boolean Status filters
client_id number[] Filter by client IDs
tag_id number[] Filter by tag IDs

focus_get_project

Arg Type Required
project_id number Yes

focus_create_project

Creates immediately. Requires name.

Arg Type Description
name string Required
description string
client_id number Supported on create
color string
private / pinned / billable boolean
start_date / end_date string YYYY-MM-DD
tag_ids number[] Applied via follow-up PATCH; may be forbidden on some plans/roles — project still creates and a warning is returned
parent_project_id number

focus_update_project

Partial update (PATCH). Requires project_id. Same optional fields as create, plus nullable client_id and optional archived.

Tasks

focus_list_tasks

Arg Type Description
name string Name filter
project_id number[] Project IDs
status_id number[] Status IDs
assignee_user_id number[] Assignees
tag_id number[] Tags
pinned / archived boolean
parent_task_id number[] Parent tasks
include_assignees boolean Expand assignees

focus_get_task

Requires task_id. Optional include_assignees.

focus_create_task

Creates immediately. Requires name.

Arg Type Description
name string Required
description / notes string
project_id / parent_task_id / status_id number
assignee_user_ids / tag_ids number[]
estimated_mins number
priority "none" | "low" | "medium" | "high"
pinned / private / billable boolean
start_date / end_date string YYYY-MM-DD

focus_update_task

Partial update. Requires task_id. Same mutable fields as create (all optional).

Live tracking

focus_get_current_timer

Returns the running timer for the workspace, or { "running": false }.

focus_start_timer

Starts immediately. type defaults to "activity".

Arg Type Description
type "activity" | "break" Default activity
task_id / project_id number
description string
billable boolean
tag_ids number[]
time_block_id number
start string RFC3339; server default = now

focus_stop_timer

Stops the running timer. Optional end (RFC3339); defaults to current UTC.

Time entries

focus_list_time_entries

Requires a date range. Accepts YYYY-MM-DD or RFC3339 (YYYY-MM-DD is expanded to start/end of day UTC).

Arg Type Required Description
date_from string Yes Range start
date_to string Yes Range end
task_id number No
type "activity" | "break" No
archived / include_taskless boolean No
time_block_id number No

focus_create_time_entry

Creates a completed entry immediately. If task_id is set, uses the task-scoped endpoint; otherwise creates a taskless entry. type defaults to "activity".

Arg Type Description
task_id / project_id number
description string
start string RFC3339
duration number Seconds
billable boolean
tag_ids number[]
time_block_id number
type "activity" | "break"

focus_update_time_entry

Partial update. Requires time_entry_id. Optional task_id selects the task-scoped path.

focus_delete_time_entry

Deletes immediately. Requires time_entry_id. Optional task_id for the task-scoped path.

Clients

focus_list_clients

Optional name filter plus pagination.

focus_create_client

Requires name. Optional currency (ISO 4217).

Tags

focus_list_tags

Optional name, tag_id (array), pagination.

focus_create_tag

Requires name and color (hex or Focus color token).

Statuses & search

focus_list_statuses

List task statuses. Optional name, type, pagination.

focus_search

Unified search across time entries, tasks, and projects.

Arg Type Required Description
keyword string Yes Search text
per_group number No Results per group
project_id / task_id number No Scope
only_me / include_drafts boolean No

Behavior notes

  • Mutations are immediate — create / update / delete / start / stop have no confirmation step.
  • Project tags on create — some Focus plans/roles reject tag_ids on POST. The tool creates the project first, then PATCHes tags; on failure you still get the project plus a warning.
  • Workspace context — session cookie endpoints are not used; set org + workspace env vars.
  • Quota — Focus enforces per-user-per-org hourly limits (e.g. Free ~30/hour). HTTP 402 means quota exhausted; wait for X-Toggl-Quota-Resets-In. Prefer env IDs so tools do not rediscover context every call.

Development

git clone https://github.com/copperline-ai/toggl-focus-mcp.git
cd toggl-focus-mcp
npm install
npm run check          # typecheck + unit/mocked MCP tests + build (CI gate)
npm run test:live      # optional — real Focus API; local only, needs .env
node dist/index.js

npm run check is the same gate used by GitHub Actions on PRs and before publish. It uses mocked Focus responses — CI never calls your real Toggl account.

Live MCP tests (local only)

Optional suite against a real Focus workspace. Not run in CI.

  1. Copy .env.example.env and set your Focus key + org/workspace IDs
  2. Run:
npm run test:live

Reuses stable fixtures (client Toggl Focus, project Toggl Focus MCP, task MCP live test, tag MCP live). Disposable time entries are deleted. Paces ~1 req/sec for rate limits. .env is gitignored and not published.

Publishing

Releases use release-it + AI Gateway (semver bump, changelog, GitHub Release, npm publish):

npm run release:dry-run
npm pack --dry-run

CI secrets: NPM_ACCESS_TOKEN, AI_GATEWAY_API_KEY.

Vendored OpenAPI: openapi/focus.json from Focus OpenAPI.


Related

License

MIT

推荐服务器

Baidu Map

Baidu Map

百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。

官方
精选
JavaScript
Playwright MCP Server

Playwright MCP Server

一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。

官方
精选
TypeScript
Magic Component Platform (MCP)

Magic Component Platform (MCP)

一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。

官方
精选
本地
TypeScript
Audiense Insights MCP Server

Audiense Insights MCP Server

通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。

官方
精选
本地
TypeScript
VeyraX

VeyraX

一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。

官方
精选
本地
graphlit-mcp-server

graphlit-mcp-server

模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。

官方
精选
TypeScript
Kagi MCP Server

Kagi MCP Server

一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。

官方
精选
Python
e2b-mcp-server

e2b-mcp-server

使用 MCP 通过 e2b 运行代码。

官方
精选
Neon MCP Server

Neon MCP Server

用于与 Neon 管理 API 和数据库交互的 MCP 服务器

官方
精选
Exa MCP Server

Exa MCP Server

模型上下文协议(MCP)服务器允许像 Claude 这样的 AI 助手使用 Exa AI 搜索 API 进行网络搜索。这种设置允许 AI 模型以安全和受控的方式获取实时的网络信息。

官方
精选