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
Visit Server

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

Recommended Servers

playwright-mcp

playwright-mcp

A Model Context Protocol server that enables LLMs to interact with web pages through structured accessibility snapshots without requiring vision models or screenshots.

Official
Featured
TypeScript
Magic Component Platform (MCP)

Magic Component Platform (MCP)

An AI-powered tool that generates modern UI components from natural language descriptions, integrating with popular IDEs to streamline UI development workflow.

Official
Featured
Local
TypeScript
Audiense Insights MCP Server

Audiense Insights MCP Server

Enables interaction with Audiense Insights accounts via the Model Context Protocol, facilitating the extraction and analysis of marketing insights and audience data including demographics, behavior, and influencer engagement.

Official
Featured
Local
TypeScript
VeyraX MCP

VeyraX MCP

Single MCP tool to connect all your favorite tools: Gmail, Calendar and 40 more.

Official
Featured
Local
graphlit-mcp-server

graphlit-mcp-server

The Model Context Protocol (MCP) Server enables integration between MCP clients and the Graphlit service. Ingest anything from Slack to Gmail to podcast feeds, in addition to web crawling, into a Graphlit project - and then retrieve relevant contents from the MCP client.

Official
Featured
TypeScript
Kagi MCP Server

Kagi MCP Server

An MCP server that integrates Kagi search capabilities with Claude AI, enabling Claude to perform real-time web searches when answering questions that require up-to-date information.

Official
Featured
Python
E2B

E2B

Using MCP to run code via e2b.

Official
Featured
Neon Database

Neon Database

MCP server for interacting with Neon Management API and databases

Official
Featured
Exa Search

Exa Search

A Model Context Protocol (MCP) server lets AI assistants like Claude use the Exa AI Search API for web searches. This setup allows AI models to get real-time web information in a safe and controlled way.

Official
Featured
Qdrant Server

Qdrant Server

This repository is an example of how to create a MCP server for Qdrant, a vector search engine.

Official
Featured