Skip to main content
Glama

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.


Related MCP server: timing-mcp-server

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).

focus_list_statuses

List task statuses. Optional name, type, pagination.

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.


License

MIT

Install Server
A
license - permissive license
A
quality
A
maintenance

Maintenance

Maintainers
Response time
0dRelease cycle
3Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Servers

View all related MCP servers

Related MCP Connectors

  • MCP server for generating rough-draft project plans from natural-language prompts.

  • Personal assistant MCP server with search, execute, packages, jobs, secrets, and integrations.

  • MCP server for Argo RPG Platform — connects AI assistants to campaign data via OAuth2

View all MCP Connectors

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/copperline-ai/toggl-focus-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server