Skip to main content
Glama
Roms504318
by Roms504318

Clockify MCP Server

A scoped Clockify MCP server for mcp.sco-mo.com. Exposes a fixed read/write tool set plus a code-defined structure scaffold that replaces Clockify's paid-gated project templates. The structure lives as code (lib/structure.ts) — a single source of truth that's editable, re-runnable, and version-controlled.

v0.1 DRAFT. The STRUCTURE config is a draft pending Oel's Excel reconciliation. The mechanism is built; do not run scaffoldStructure against the live workspace yet (see Build sequence).


Stack

  • Next.js App Router route handler + mcp-handler (Vercel adapter)

  • Pipeline: GitHub → Vercel → Cloudflare, custom domain mcp.sco-mo.com

  • Clockify base API: https://api.clockify.me/api/v1

MCP endpoint (streamable-http): https://mcp.sco-mo.com/api/mcp Health probe (open): https://mcp.sco-mo.com/api/health


Related MCP server: clockify-mcp

Environment variables

Set these in the Vercel dashboard (never in code, never committed):

Var

Value

Notes

CLOCKIFY_API_KEY

the raw NDQ… key

Sent as X-Api-Key. Never logged.

CLOCKIFY_WORKSPACE_ID

69476cbc9bfb39506eedab0a

Fixed target workspace.

MCP_BEARER_TOKEN

a strong random token

Guards the endpoint. Clients send Authorization: Bearer <token>.

.env is git-ignored. Copy .env.example → .env.local for local dev. If MCP_BEARER_TOKEN is unset the endpoint fails closed (401), never open.


Tools — the complete scoped set (do not add to this)

Read — getCurrentUser, listUsers, listTimeEntries, getTimeEntry, listProjects, listClients, listTasks, listTags

Write — upsertTimeEntry, upsertProject, upsertClient, upsertTask, upsertTag, archiveProject, archiveClient, deleteProject (gated), deleteClient (gated), scaffoldStructure, newProjectFromShape

Delete discipline (the one irreversible surface)

  • Clockify enforces archive-before-delete. deleteProject / deleteClient verify the target is archived and refuse otherwise.

  • Both require an explicit confirm: true argument (typed as literal(true)), and are never called by an unattended agent — the review gate.

  • Deleting a project removes it from time entries but leaves the underlying time data intact.

scaffoldStructure

Idempotent, additive-only reconcile of the workspace toward STRUCTURE: creates any missing client/project/task/tag, skips what exists, never deletes.

dryRun defaults to true — it returns the plan without writing. Pass dryRun: false to apply. Idempotency is by name.

newProjectFromShape

The template replacement. Instantiates a project + its standard task list from a shape in STRUCTURE.shapes (e.g. matter). Creates the client if a clientName is given and missing.


Local development

npm install
cp .env.example .env.local   # fill in the three vars
npm run dev                  # http://localhost:3000/api/mcp
npm run typecheck

Smoke-test the endpoint (expects 401 without the token):

curl -s http://localhost:3000/api/health

Deploy

  1. Push to GitHub; import into Vercel (framework auto-detected as Next.js).

  2. Add the three environment variables in Vercel → Settings → Environment Variables.

  3. Add the domain mcp.sco-mo.com (Vercel → Domains); point Cloudflare DNS per the existing pipeline.

  4. Redeploy. Verify GET /api/health returns config all true.


Build sequence

  1. ✅ Now: server, scoped tool set, delete gate, and scaffoldStructure / newProjectFromShape built and deployed.

  2. ⛔ Do not run scaffoldStructure with dryRun:false against the live workspace yet.

  3. Oel sends the Excel of the existing structure. Reconcile lib/structure.ts against it — Scottmoore project granularity, kill dead old-company projects, confirm the Personal breakdown.

  4. Then run scaffoldStructure to build/adjust the live workspace, and archive/delete old-company remnants (delete gated, one confirm each).

Maintenance

ActivityStale
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers