tdcflow
README.md
# TDC Flow MCP Server
A stdio MCP server over the TDC Flow REST API, so Claude Code can read your assigned tasks, propose tasks and subtasks, update them, and log time with real start and end instants taken from git history.
## Setup
Authentication is the browser session cookie. Open any authenticated request on `tdcflow.tdcapps.com` in devtools, copy the `__Secure-better-auth.session_token` cookie, and put it in `.env`:
```bash
cp .env.example .env
$EDITOR .env
```
Register the server with Claude Code:
```bash
claude mcp add tdcflow --scope user /home/yashasvi/Developer/tdcflow-mcp/run.sh
```
The cookie expires after seven days. When calls start failing with `Session cookie is invalid or expired`, refresh it in `.env`.
## Validation
`test.mjs` spawns the server, speaks real JSON-RPC over stdio, and exercises every tool. Write tests create their own fixtures and retire them afterwards:
```bash
node test.mjs
```
## Tools
Reading:
- **tdcflow_whoami**: the signed-in user and organization
- **tdcflow_list_tasks**: your open tasks by default; filter by assignee, status, project, or title
- **tdcflow_get_task**: one task with assignees and subtasks
- **tdcflow_list_drafts**: proposed tasks awaiting approval, yours and your team's
- **tdcflow_list_projects**, **tdcflow_list_phases**, **tdcflow_list_sprints**, **tdcflow_list_project_members**, **tdcflow_list_project_tasks**
- **tdcflow_list_users**, **tdcflow_list_tags**, **tdcflow_list_time_categories**
- **tdcflow_list_approvers**: who can approve a timesheet
Writing:
- **tdcflow_create_task**: propose a task, or a subtask with `parentTaskId`. Assigns it to you unless you pass `assignToMe: false`.
- **tdcflow_update_task**: change status, title, dates, estimate, or placement
- **tdcflow_assign_task**: assign a task to yourself
- **tdcflow_log_time**: one entry with explicit `startedAt` and `endedAt`
- **tdcflow_add_timesheet_entry**: a duration-based entry on a timesheet day
- **tdcflow_get_timesheet**: the weekly timesheet with its entries and totals
- **tdcflow_submit_timesheet**: send a timesheet to an approver
- **tdcflow_delete_time_entry**, **tdcflow_delete_task**, **tdcflow_add_tag**
## Logging Time from Git History
Pass real instants rather than the current clock. Take the range from the commits themselves:
```bash
git log --since=2026-08-20 --author=Yashasvi --date=iso-strict \
--pretty='%ad %h %s'
```
Feed the first and last commit timestamps of a working block to `tdcflow_log_time` as `startedAt` and `endedAt`. The tool rejects an `endedAt` at or before `startedAt`.
## Permission Limits
The server surfaces whatever the account can do. On Yashasvi's account:
- `tdcflow_create_task` returns a draft with `isDraft: true`. A lead approves it before it becomes live.
- Time cannot be booked against a draft task. `tdcflow_add_timesheet_entry` checks this and fails with a clear reason instead of the API's misleading "does not belong to this project".
- `tdcflow_add_tag` needs `projects:write` and returns 403.
- `tdcflow_delete_task` needs `tasks:delete` and returns 403. Set `status` to `cancelled` instead.
- Per-assignee effort is read-only in the UI, so no tool sets it. Use the task-level `estimatedMinutes` instead.
- Re-assigning someone who is already an assignee returns 400. `tdcflow_assign_task` reports that as `alreadyAssigned` rather than failing.
## Submitting a Timesheet
Submission notifies a real person and locks the period, so `test.mjs` never fires it. Nine approvers exist, so `approverId` has to be explicit; the tool lists them in its error when you omit it.
```
tdcflow_submit_timesheet {
date: '2026-08-26',
note: 'Week of 24 August',
approverId: '019ea732-17d2-704a-9e52-c8dc2af0bfec'
}
```
## Timesheet Periods
Periods run Monday to Sunday and the API keys them by the Monday date. `tdcflow_get_timesheet` and `tdcflow_add_timesheet_entry` work that out from any date inside the week.
This server cannot be deployed
Maintenance
ActivityMaintained
ResponsivenessNo issues