@souravpn/toggl-mcp 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +171 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +192 -0
- package/dist/index.js.map +1 -0
- package/dist/toggl.d.ts +77 -0
- package/dist/toggl.d.ts.map +1 -0
- package/dist/toggl.js +170 -0
- package/dist/toggl.js.map +1 -0
- package/package.json +45 -0
package/README.md
ADDED
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
# toggl-mcp
|
|
2
|
+
|
|
3
|
+
A [Model Context Protocol (MCP)](https://modelcontextprotocol.io) server that gives Claude access to your [Toggl Track](https://toggl.com/track/) time tracking data.
|
|
4
|
+
|
|
5
|
+
Ask Claude things like:
|
|
6
|
+
- *"What am I tracking right now?"*
|
|
7
|
+
- *"How much time did I spend on each project this week?"*
|
|
8
|
+
- *"Start a timer for writing documentation on the Blog project"*
|
|
9
|
+
- *"Stop my timer"*
|
|
10
|
+
- *"What did I work on yesterday?"*
|
|
11
|
+
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
## Tools
|
|
15
|
+
|
|
16
|
+
| Tool | What it does |
|
|
17
|
+
|------|-------------|
|
|
18
|
+
| `get_current_timer` | Shows the currently running time entry |
|
|
19
|
+
| `get_recent_entries` | Time entries for the past N days (default 7) |
|
|
20
|
+
| `get_projects` | Lists all your projects |
|
|
21
|
+
| `get_summary` | Total time by project for a date range |
|
|
22
|
+
| `start_timer` | Starts a new time entry |
|
|
23
|
+
| `stop_timer` | Stops the current timer |
|
|
24
|
+
| `get_profile` | Your Toggl profile and workspaces |
|
|
25
|
+
|
|
26
|
+
---
|
|
27
|
+
|
|
28
|
+
## Setup
|
|
29
|
+
|
|
30
|
+
### 1. Get your API token
|
|
31
|
+
|
|
32
|
+
1. Go to **https://track.toggl.com/profile**
|
|
33
|
+
2. Scroll to the bottom
|
|
34
|
+
3. Click **"Click to reveal"** under API Token
|
|
35
|
+
4. Copy the token
|
|
36
|
+
|
|
37
|
+
### 2. Install
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
npm install -g toggl-mcp
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
Find the installed path:
|
|
44
|
+
```bash
|
|
45
|
+
which toggl-mcp
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
### 3. Add to Claude Desktop
|
|
49
|
+
|
|
50
|
+
Edit `~/Library/Application Support/Claude/claude_desktop_config.json` (macOS):
|
|
51
|
+
|
|
52
|
+
```json
|
|
53
|
+
{
|
|
54
|
+
"mcpServers": {
|
|
55
|
+
"toggl": {
|
|
56
|
+
"command": "/path/from/which/toggl-mcp",
|
|
57
|
+
"env": {
|
|
58
|
+
"TOGGL_API_TOKEN": "your_token_here"
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
Or if running from source:
|
|
66
|
+
|
|
67
|
+
```json
|
|
68
|
+
{
|
|
69
|
+
"mcpServers": {
|
|
70
|
+
"toggl": {
|
|
71
|
+
"command": "node",
|
|
72
|
+
"args": ["/path/to/toggl-mcp/dist/index.js"],
|
|
73
|
+
"env": {
|
|
74
|
+
"TOGGL_API_TOKEN": "your_token_here"
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
Restart Claude Desktop. You should see a green "running" badge in **Settings → Developer**.
|
|
82
|
+
|
|
83
|
+
### 4. Test it
|
|
84
|
+
|
|
85
|
+
```
|
|
86
|
+
What am I currently tracking in Toggl?
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
---
|
|
90
|
+
|
|
91
|
+
## Example queries
|
|
92
|
+
|
|
93
|
+
**Daily check-in:**
|
|
94
|
+
```
|
|
95
|
+
What have I tracked today in Toggl?
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
**Weekly review:**
|
|
99
|
+
```
|
|
100
|
+
Give me a summary of how I spent my time this week by project
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
**Start tracking:**
|
|
104
|
+
```
|
|
105
|
+
Start a Toggl timer for "reviewing PRs" on my Engineering project
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
**Stop and summarize:**
|
|
109
|
+
```
|
|
110
|
+
Stop my timer and tell me how long I worked
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
**Productivity analysis:**
|
|
114
|
+
```
|
|
115
|
+
How much time did I track last week vs the week before?
|
|
116
|
+
Which project took the most time?
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
---
|
|
120
|
+
|
|
121
|
+
## Development
|
|
122
|
+
|
|
123
|
+
```bash
|
|
124
|
+
git clone https://github.com/yourusername/toggl-mcp
|
|
125
|
+
cd toggl-mcp
|
|
126
|
+
npm install
|
|
127
|
+
npm run build
|
|
128
|
+
|
|
129
|
+
# Test locally
|
|
130
|
+
TOGGL_API_TOKEN=your_token node dist/index.js
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
### Project structure
|
|
134
|
+
|
|
135
|
+
```
|
|
136
|
+
toggl-mcp/
|
|
137
|
+
├── src/
|
|
138
|
+
│ ├── index.ts # MCP server + tool definitions
|
|
139
|
+
│ └── toggl.ts # Toggl API v9 client + formatters
|
|
140
|
+
├── package.json
|
|
141
|
+
├── tsconfig.json
|
|
142
|
+
└── README.md
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
---
|
|
146
|
+
|
|
147
|
+
## Rate limits
|
|
148
|
+
|
|
149
|
+
Toggl's free plan allows 30 requests/hour per workspace. This MCP server batches calls where possible (e.g. fetching projects and entries in parallel) to stay well within limits for normal use.
|
|
150
|
+
|
|
151
|
+
---
|
|
152
|
+
|
|
153
|
+
## Contributing
|
|
154
|
+
|
|
155
|
+
PRs welcome. Ideas for extension:
|
|
156
|
+
- Tags management
|
|
157
|
+
- Client listing
|
|
158
|
+
- Detailed reports (daily breakdown)
|
|
159
|
+
- Time entry editing
|
|
160
|
+
|
|
161
|
+
---
|
|
162
|
+
|
|
163
|
+
## License
|
|
164
|
+
|
|
165
|
+
MIT
|
|
166
|
+
|
|
167
|
+
---
|
|
168
|
+
|
|
169
|
+
## Acknowledgements
|
|
170
|
+
|
|
171
|
+
Built with the [MCP TypeScript SDK](https://github.com/modelcontextprotocol/typescript-sdk) and the [Toggl Track API v9](https://engineering.toggl.com/docs/track/).
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// =============================================================================
|
|
3
|
+
// index.ts — toggl-mcp server
|
|
4
|
+
//
|
|
5
|
+
// Exposes Toggl Track data as MCP tools Claude can call.
|
|
6
|
+
//
|
|
7
|
+
// TOOLS:
|
|
8
|
+
// get_current_timer — what you're tracking right now
|
|
9
|
+
// get_recent_entries — time entries for the past N days
|
|
10
|
+
// get_projects — list all your projects
|
|
11
|
+
// get_summary — total time by project for a date range
|
|
12
|
+
// start_timer — start tracking time on a description/project
|
|
13
|
+
// stop_timer — stop the currently running timer
|
|
14
|
+
// get_profile — your Toggl profile and workspace info
|
|
15
|
+
//
|
|
16
|
+
// AUTH:
|
|
17
|
+
// Set TOGGL_API_TOKEN env variable.
|
|
18
|
+
// Get it from https://track.toggl.com/profile → scroll to bottom → API Token
|
|
19
|
+
//
|
|
20
|
+
// USAGE IN claude_desktop_config.json:
|
|
21
|
+
// {
|
|
22
|
+
// "mcpServers": {
|
|
23
|
+
// "toggl": {
|
|
24
|
+
// "command": "node",
|
|
25
|
+
// "args": ["/path/to/toggl-mcp/dist/index.js"],
|
|
26
|
+
// "env": { "TOGGL_API_TOKEN": "your_token" }
|
|
27
|
+
// }
|
|
28
|
+
// }
|
|
29
|
+
// }
|
|
30
|
+
// =============================================================================
|
|
31
|
+
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
32
|
+
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
33
|
+
import { z } from 'zod';
|
|
34
|
+
import { TogglClient, formatDuration, formatTimeEntry, isRunning, getActualDuration, } from './toggl.js';
|
|
35
|
+
// ---- Validate env -----------------------------------------------------------
|
|
36
|
+
const apiToken = process.env.TOGGL_API_TOKEN;
|
|
37
|
+
if (!apiToken) {
|
|
38
|
+
process.stderr.write('[toggl-mcp] Error: TOGGL_API_TOKEN is not set.\n' +
|
|
39
|
+
'[toggl-mcp] Get your token from https://track.toggl.com/profile\n');
|
|
40
|
+
process.exit(1);
|
|
41
|
+
}
|
|
42
|
+
const client = new TogglClient(apiToken);
|
|
43
|
+
// ---- MCP Server -------------------------------------------------------------
|
|
44
|
+
const server = new McpServer({
|
|
45
|
+
name: 'toggl',
|
|
46
|
+
version: '1.0.0',
|
|
47
|
+
});
|
|
48
|
+
// Helper — wraps tool handlers with consistent error handling
|
|
49
|
+
function safe(fn) {
|
|
50
|
+
return fn()
|
|
51
|
+
.then(text => ({ content: [{ type: 'text', text }] }))
|
|
52
|
+
.catch(err => ({
|
|
53
|
+
content: [{
|
|
54
|
+
type: 'text',
|
|
55
|
+
text: `Error: ${err instanceof Error ? err.message : String(err)}`,
|
|
56
|
+
}],
|
|
57
|
+
}));
|
|
58
|
+
}
|
|
59
|
+
// ---- Tools ------------------------------------------------------------------
|
|
60
|
+
// 1. Current running timer
|
|
61
|
+
server.tool('get_current_timer', 'Get the currently running Toggl time entry, if any', {}, () => safe(async () => {
|
|
62
|
+
const entry = await client.getCurrentTimeEntry();
|
|
63
|
+
if (!entry)
|
|
64
|
+
return 'No timer is currently running.';
|
|
65
|
+
const wsId = await client.getDefaultWorkspaceId();
|
|
66
|
+
const projects = await client.getProjectMap(wsId);
|
|
67
|
+
return formatTimeEntry(entry, projects);
|
|
68
|
+
}));
|
|
69
|
+
// 2. Recent time entries
|
|
70
|
+
server.tool('get_recent_entries', 'Get time entries from the past N days (default 7). Useful for reviewing what you worked on.', {
|
|
71
|
+
days: z.number().min(1).max(90).default(7)
|
|
72
|
+
.describe('Number of days to look back (max 90)'),
|
|
73
|
+
}, ({ days }) => safe(async () => {
|
|
74
|
+
const [entries, wsId] = await Promise.all([
|
|
75
|
+
client.getRecentTimeEntries(days),
|
|
76
|
+
client.getDefaultWorkspaceId(),
|
|
77
|
+
]);
|
|
78
|
+
const projects = await client.getProjectMap(wsId);
|
|
79
|
+
if (entries.length === 0)
|
|
80
|
+
return `No time entries found in the past ${days} days.`;
|
|
81
|
+
const lines = entries
|
|
82
|
+
.slice(0, 50) // cap at 50 to avoid context overflow
|
|
83
|
+
.map(e => formatTimeEntry(e, projects))
|
|
84
|
+
.join('\n\n---\n\n');
|
|
85
|
+
const totalSeconds = entries
|
|
86
|
+
.filter(e => !isRunning(e))
|
|
87
|
+
.reduce((sum, e) => sum + getActualDuration(e), 0);
|
|
88
|
+
return `${entries.length} entries in the past ${days} days\nTotal tracked: ${formatDuration(totalSeconds)}\n\n${'='.repeat(40)}\n\n${lines}`;
|
|
89
|
+
}));
|
|
90
|
+
// 3. List projects
|
|
91
|
+
server.tool('get_projects', 'List all Toggl projects in your workspace', {}, () => safe(async () => {
|
|
92
|
+
const wsId = await client.getDefaultWorkspaceId();
|
|
93
|
+
const projects = await client.getProjects(wsId);
|
|
94
|
+
if (projects.length === 0)
|
|
95
|
+
return 'No projects found. Create one at https://track.toggl.com';
|
|
96
|
+
const active = projects.filter(p => p.active);
|
|
97
|
+
const archived = projects.filter(p => !p.active);
|
|
98
|
+
const lines = [
|
|
99
|
+
`${active.length} active projects:`,
|
|
100
|
+
...active.map(p => ` • ${p.name} (id: ${p.id})${p.billable ? ' 💰' : ''}`),
|
|
101
|
+
];
|
|
102
|
+
if (archived.length > 0) {
|
|
103
|
+
lines.push(`\n${archived.length} archived projects (not shown)`);
|
|
104
|
+
}
|
|
105
|
+
return lines.join('\n');
|
|
106
|
+
}));
|
|
107
|
+
// 4. Summary by project
|
|
108
|
+
server.tool('get_summary', 'Get total time tracked per project for a date range. Defaults to the current week.', {
|
|
109
|
+
start_date: z.string().optional()
|
|
110
|
+
.describe('Start date in YYYY-MM-DD format (default: start of current week)'),
|
|
111
|
+
end_date: z.string().optional()
|
|
112
|
+
.describe('End date in YYYY-MM-DD format (default: today)'),
|
|
113
|
+
}, ({ start_date, end_date }) => safe(async () => {
|
|
114
|
+
const wsId = await client.getDefaultWorkspaceId();
|
|
115
|
+
// Default to current week
|
|
116
|
+
const now = new Date();
|
|
117
|
+
const startOfWeek = new Date(now);
|
|
118
|
+
startOfWeek.setDate(now.getDate() - now.getDay());
|
|
119
|
+
startOfWeek.setHours(0, 0, 0, 0);
|
|
120
|
+
const start = start_date ?? startOfWeek.toISOString().split('T')[0];
|
|
121
|
+
const end = end_date ?? now.toISOString().split('T')[0];
|
|
122
|
+
const summary = await client.getSummary(wsId, start, end);
|
|
123
|
+
if (summary.byProject.length === 0) {
|
|
124
|
+
return `No time tracked between ${start} and ${end}.`;
|
|
125
|
+
}
|
|
126
|
+
// Sort by most time first
|
|
127
|
+
const sorted = summary.byProject.sort((a, b) => b.seconds - a.seconds);
|
|
128
|
+
const lines = [
|
|
129
|
+
`Time summary: ${start} → ${end}`,
|
|
130
|
+
`Total: ${formatDuration(summary.totalSeconds)}`,
|
|
131
|
+
'',
|
|
132
|
+
...sorted.map(p => {
|
|
133
|
+
const pct = ((p.seconds / summary.totalSeconds) * 100).toFixed(0);
|
|
134
|
+
return ` ${p.name}: ${formatDuration(p.seconds)} (${pct}%)`;
|
|
135
|
+
}),
|
|
136
|
+
];
|
|
137
|
+
return lines.join('\n');
|
|
138
|
+
}));
|
|
139
|
+
// 5. Start a timer
|
|
140
|
+
server.tool('start_timer', 'Start a new Toggl time entry. Provide a description and optionally a project name.', {
|
|
141
|
+
description: z.string().describe('What you are working on'),
|
|
142
|
+
project_name: z.string().optional()
|
|
143
|
+
.describe('Project name to log time against (must match an existing project name exactly)'),
|
|
144
|
+
tags: z.array(z.string()).optional()
|
|
145
|
+
.describe('Optional tags to apply to this time entry'),
|
|
146
|
+
}, ({ description, project_name, tags }) => safe(async () => {
|
|
147
|
+
const wsId = await client.getDefaultWorkspaceId();
|
|
148
|
+
let projectId;
|
|
149
|
+
if (project_name) {
|
|
150
|
+
const projects = await client.getProjects(wsId);
|
|
151
|
+
const match = projects.find(p => p.name.toLowerCase() === project_name.toLowerCase() && p.active);
|
|
152
|
+
if (!match) {
|
|
153
|
+
const names = projects.filter(p => p.active).map(p => p.name).join(', ');
|
|
154
|
+
return `Project "${project_name}" not found. Available projects: ${names}`;
|
|
155
|
+
}
|
|
156
|
+
projectId = match.id;
|
|
157
|
+
}
|
|
158
|
+
const entry = await client.startTimer(wsId, description, projectId, tags);
|
|
159
|
+
const projects = await client.getProjectMap(wsId);
|
|
160
|
+
return `✅ Timer started!\n\n${formatTimeEntry(entry, projects)}`;
|
|
161
|
+
}));
|
|
162
|
+
// 6. Stop current timer
|
|
163
|
+
server.tool('stop_timer', 'Stop the currently running Toggl time entry', {}, () => safe(async () => {
|
|
164
|
+
const current = await client.getCurrentTimeEntry();
|
|
165
|
+
if (!current)
|
|
166
|
+
return 'No timer is currently running.';
|
|
167
|
+
const wsId = await client.getDefaultWorkspaceId();
|
|
168
|
+
const stopped = await client.stopTimer(wsId, current.id);
|
|
169
|
+
const projects = await client.getProjectMap(wsId);
|
|
170
|
+
return `⏹ Timer stopped!\n\n${formatTimeEntry(stopped, projects)}`;
|
|
171
|
+
}));
|
|
172
|
+
// 7. Profile
|
|
173
|
+
server.tool('get_profile', "Get the user's Toggl profile — name, email, timezone, and workspace info", {}, () => safe(async () => {
|
|
174
|
+
const [me, workspaces] = await Promise.all([
|
|
175
|
+
client.getMe(),
|
|
176
|
+
client.getWorkspaces(),
|
|
177
|
+
]);
|
|
178
|
+
return [
|
|
179
|
+
`Name: ${me.fullname}`,
|
|
180
|
+
`Email: ${me.email}`,
|
|
181
|
+
`Timezone: ${me.timezone}`,
|
|
182
|
+
`Default workspace ID: ${me.default_workspace_id}`,
|
|
183
|
+
'',
|
|
184
|
+
`Workspaces (${workspaces.length}):`,
|
|
185
|
+
...workspaces.map(w => ` • ${w.name} (id: ${w.id})${w.premium ? ' [Premium]' : ' [Free]'}`),
|
|
186
|
+
].join('\n');
|
|
187
|
+
}));
|
|
188
|
+
// ---- Start ------------------------------------------------------------------
|
|
189
|
+
const transport = new StdioServerTransport();
|
|
190
|
+
await server.connect(transport);
|
|
191
|
+
process.stderr.write('[toggl-mcp] Server running\n');
|
|
192
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/toggl.d.ts
ADDED
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
export interface TogglUser {
|
|
2
|
+
id: number;
|
|
3
|
+
email: string;
|
|
4
|
+
fullname: string;
|
|
5
|
+
timezone: string;
|
|
6
|
+
default_workspace_id: number;
|
|
7
|
+
beginning_of_week: number;
|
|
8
|
+
}
|
|
9
|
+
export interface TogglWorkspace {
|
|
10
|
+
id: number;
|
|
11
|
+
name: string;
|
|
12
|
+
premium: boolean;
|
|
13
|
+
plan: string;
|
|
14
|
+
}
|
|
15
|
+
export interface TogglProject {
|
|
16
|
+
id: number;
|
|
17
|
+
name: string;
|
|
18
|
+
workspace_id: number;
|
|
19
|
+
color: string;
|
|
20
|
+
active: boolean;
|
|
21
|
+
billable: boolean | null;
|
|
22
|
+
client_id: number | null;
|
|
23
|
+
}
|
|
24
|
+
export interface TogglTag {
|
|
25
|
+
id: number;
|
|
26
|
+
name: string;
|
|
27
|
+
workspace_id: number;
|
|
28
|
+
}
|
|
29
|
+
export interface TogglTimeEntry {
|
|
30
|
+
id: number;
|
|
31
|
+
workspace_id: number;
|
|
32
|
+
project_id: number | null;
|
|
33
|
+
task_id: number | null;
|
|
34
|
+
billable: boolean;
|
|
35
|
+
start: string;
|
|
36
|
+
stop: string | null;
|
|
37
|
+
duration: number;
|
|
38
|
+
description: string | null;
|
|
39
|
+
tag_ids: number[];
|
|
40
|
+
tags: string[];
|
|
41
|
+
at: string;
|
|
42
|
+
}
|
|
43
|
+
export interface TogglClient {
|
|
44
|
+
id: number;
|
|
45
|
+
name: string;
|
|
46
|
+
workspace_id: number;
|
|
47
|
+
}
|
|
48
|
+
export declare function formatDuration(seconds: number): string;
|
|
49
|
+
export declare function formatDate(iso: string): string;
|
|
50
|
+
export declare function isRunning(entry: TogglTimeEntry): boolean;
|
|
51
|
+
export declare function getActualDuration(entry: TogglTimeEntry): number;
|
|
52
|
+
export declare function formatTimeEntry(entry: TogglTimeEntry, projects: Map<number, string>): string;
|
|
53
|
+
export declare class TogglClient {
|
|
54
|
+
private authHeader;
|
|
55
|
+
private _workspaceId;
|
|
56
|
+
constructor(apiToken: string);
|
|
57
|
+
private request;
|
|
58
|
+
getMe(): Promise<TogglUser>;
|
|
59
|
+
getWorkspaces(): Promise<TogglWorkspace[]>;
|
|
60
|
+
getDefaultWorkspaceId(): Promise<number>;
|
|
61
|
+
getProjects(workspaceId: number): Promise<TogglProject[]>;
|
|
62
|
+
getProjectMap(workspaceId: number): Promise<Map<number, string>>;
|
|
63
|
+
getTags(workspaceId: number): Promise<TogglTag[]>;
|
|
64
|
+
getCurrentTimeEntry(): Promise<TogglTimeEntry | null>;
|
|
65
|
+
getTimeEntries(startDate?: string, endDate?: string): Promise<TogglTimeEntry[]>;
|
|
66
|
+
getRecentTimeEntries(days?: number): Promise<TogglTimeEntry[]>;
|
|
67
|
+
startTimer(workspaceId: number, description: string, projectId?: number, tags?: string[]): Promise<TogglTimeEntry>;
|
|
68
|
+
stopTimer(workspaceId: number, entryId: number): Promise<TogglTimeEntry>;
|
|
69
|
+
getSummary(workspaceId: number, startDate: string, endDate: string): Promise<{
|
|
70
|
+
totalSeconds: number;
|
|
71
|
+
byProject: {
|
|
72
|
+
name: string;
|
|
73
|
+
seconds: number;
|
|
74
|
+
}[];
|
|
75
|
+
}>;
|
|
76
|
+
}
|
|
77
|
+
//# sourceMappingURL=toggl.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"toggl.d.ts","sourceRoot":"","sources":["../src/toggl.ts"],"names":[],"mappings":"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"}
|
package/dist/toggl.js
ADDED
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
// =============================================================================
|
|
2
|
+
// toggl.ts — Toggl Track API v9 client
|
|
3
|
+
//
|
|
4
|
+
// Auth: HTTP Basic — API token as username, "api_token" as password
|
|
5
|
+
// Base URL: https://api.track.toggl.com/api/v9
|
|
6
|
+
//
|
|
7
|
+
// API docs: https://engineering.toggl.com/docs/track/
|
|
8
|
+
// =============================================================================
|
|
9
|
+
const BASE_URL = 'https://api.track.toggl.com/api/v9';
|
|
10
|
+
const REPORTS_URL = 'https://api.track.toggl.com/reports/api/v3';
|
|
11
|
+
// ---- Helpers ----------------------------------------------------------------
|
|
12
|
+
export function formatDuration(seconds) {
|
|
13
|
+
if (seconds < 0)
|
|
14
|
+
return 'Running...';
|
|
15
|
+
const h = Math.floor(seconds / 3600);
|
|
16
|
+
const m = Math.floor((seconds % 3600) / 60);
|
|
17
|
+
const s = seconds % 60;
|
|
18
|
+
if (h > 0)
|
|
19
|
+
return `${h}h ${m}m`;
|
|
20
|
+
if (m > 0)
|
|
21
|
+
return `${m}m ${s}s`;
|
|
22
|
+
return `${s}s`;
|
|
23
|
+
}
|
|
24
|
+
export function formatDate(iso) {
|
|
25
|
+
return new Date(iso).toLocaleString();
|
|
26
|
+
}
|
|
27
|
+
export function isRunning(entry) {
|
|
28
|
+
return entry.duration < 0;
|
|
29
|
+
}
|
|
30
|
+
export function getActualDuration(entry) {
|
|
31
|
+
if (entry.duration >= 0)
|
|
32
|
+
return entry.duration;
|
|
33
|
+
// Running entry: duration = -(start time in epoch seconds)
|
|
34
|
+
return Math.floor(Date.now() / 1000) + entry.duration;
|
|
35
|
+
}
|
|
36
|
+
export function formatTimeEntry(entry, projects) {
|
|
37
|
+
const running = isRunning(entry);
|
|
38
|
+
const duration = getActualDuration(entry);
|
|
39
|
+
const projectName = entry.project_id
|
|
40
|
+
? (projects.get(entry.project_id) ?? `Project #${entry.project_id}`)
|
|
41
|
+
: 'No project';
|
|
42
|
+
return [
|
|
43
|
+
`${running ? '▶ [RUNNING] ' : ''}${entry.description ?? '(no description)'}`,
|
|
44
|
+
`Project: ${projectName}`,
|
|
45
|
+
`Duration: ${formatDuration(duration)}${running ? ' (so far)' : ''}`,
|
|
46
|
+
`Started: ${formatDate(entry.start)}`,
|
|
47
|
+
entry.stop ? `Stopped: ${formatDate(entry.stop)}` : null,
|
|
48
|
+
entry.tags.length > 0 ? `Tags: ${entry.tags.join(', ')}` : null,
|
|
49
|
+
entry.billable ? `Billable: Yes` : null,
|
|
50
|
+
].filter(Boolean).join('\n');
|
|
51
|
+
}
|
|
52
|
+
// ---- API Client -------------------------------------------------------------
|
|
53
|
+
export class TogglClient {
|
|
54
|
+
authHeader;
|
|
55
|
+
_workspaceId = null;
|
|
56
|
+
constructor(apiToken) {
|
|
57
|
+
// Toggl auth: base64(token:api_token)
|
|
58
|
+
this.authHeader = 'Basic ' + Buffer.from(`${apiToken}:api_token`).toString('base64');
|
|
59
|
+
}
|
|
60
|
+
async request(path, options = {}, baseUrl = BASE_URL) {
|
|
61
|
+
const url = `${baseUrl}${path}`;
|
|
62
|
+
const response = await fetch(url, {
|
|
63
|
+
...options,
|
|
64
|
+
headers: {
|
|
65
|
+
Authorization: this.authHeader,
|
|
66
|
+
'Content-Type': 'application/json',
|
|
67
|
+
...options.headers,
|
|
68
|
+
},
|
|
69
|
+
});
|
|
70
|
+
if (!response.ok) {
|
|
71
|
+
const body = await response.text();
|
|
72
|
+
throw new Error(`Toggl API error ${response.status} on ${path}: ${body}`);
|
|
73
|
+
}
|
|
74
|
+
// 204 No Content
|
|
75
|
+
if (response.status === 204)
|
|
76
|
+
return null;
|
|
77
|
+
return response.json();
|
|
78
|
+
}
|
|
79
|
+
// ---- User & Workspace ----
|
|
80
|
+
async getMe() {
|
|
81
|
+
return this.request('/me');
|
|
82
|
+
}
|
|
83
|
+
async getWorkspaces() {
|
|
84
|
+
return this.request('/workspaces');
|
|
85
|
+
}
|
|
86
|
+
// Get default workspace ID (cached)
|
|
87
|
+
async getDefaultWorkspaceId() {
|
|
88
|
+
if (this._workspaceId)
|
|
89
|
+
return this._workspaceId;
|
|
90
|
+
const me = await this.getMe();
|
|
91
|
+
this._workspaceId = me.default_workspace_id;
|
|
92
|
+
return this._workspaceId;
|
|
93
|
+
}
|
|
94
|
+
// ---- Projects ----
|
|
95
|
+
async getProjects(workspaceId) {
|
|
96
|
+
const projects = await this.request(`/workspaces/${workspaceId}/projects`);
|
|
97
|
+
return projects ?? [];
|
|
98
|
+
}
|
|
99
|
+
async getProjectMap(workspaceId) {
|
|
100
|
+
const projects = await this.getProjects(workspaceId);
|
|
101
|
+
return new Map(projects.map(p => [p.id, p.name]));
|
|
102
|
+
}
|
|
103
|
+
// ---- Tags ----
|
|
104
|
+
async getTags(workspaceId) {
|
|
105
|
+
const tags = await this.request(`/workspaces/${workspaceId}/tags`);
|
|
106
|
+
return tags ?? [];
|
|
107
|
+
}
|
|
108
|
+
// ---- Time Entries ----
|
|
109
|
+
async getCurrentTimeEntry() {
|
|
110
|
+
try {
|
|
111
|
+
return await this.request('/me/time_entries/current');
|
|
112
|
+
}
|
|
113
|
+
catch {
|
|
114
|
+
return null;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
async getTimeEntries(startDate, endDate) {
|
|
118
|
+
const params = new URLSearchParams();
|
|
119
|
+
if (startDate)
|
|
120
|
+
params.set('start_date', startDate);
|
|
121
|
+
if (endDate)
|
|
122
|
+
params.set('end_date', endDate);
|
|
123
|
+
const query = params.toString() ? `?${params}` : '';
|
|
124
|
+
const entries = await this.request(`/me/time_entries${query}`);
|
|
125
|
+
return entries ?? [];
|
|
126
|
+
}
|
|
127
|
+
async getRecentTimeEntries(days = 7) {
|
|
128
|
+
const start = new Date();
|
|
129
|
+
start.setDate(start.getDate() - days);
|
|
130
|
+
return this.getTimeEntries(start.toISOString());
|
|
131
|
+
}
|
|
132
|
+
// ---- Start / Stop ----
|
|
133
|
+
async startTimer(workspaceId, description, projectId, tags) {
|
|
134
|
+
return this.request(`/workspaces/${workspaceId}/time_entries`, {
|
|
135
|
+
method: 'POST',
|
|
136
|
+
body: JSON.stringify({
|
|
137
|
+
created_with: 'toggl-mcp',
|
|
138
|
+
description,
|
|
139
|
+
project_id: projectId ?? null,
|
|
140
|
+
tags: tags ?? [],
|
|
141
|
+
start: new Date().toISOString(),
|
|
142
|
+
duration: -1, // -1 means running
|
|
143
|
+
workspace_id: workspaceId,
|
|
144
|
+
}),
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
async stopTimer(workspaceId, entryId) {
|
|
148
|
+
return this.request(`/workspaces/${workspaceId}/time_entries/${entryId}/stop`, { method: 'PATCH' });
|
|
149
|
+
}
|
|
150
|
+
// ---- Summary / Reports ----
|
|
151
|
+
async getSummary(workspaceId, startDate, endDate) {
|
|
152
|
+
// Use the reports API for aggregated data
|
|
153
|
+
const body = await this.request(`/workspace/${workspaceId}/summary/time_entries`, {
|
|
154
|
+
method: 'POST',
|
|
155
|
+
body: JSON.stringify({
|
|
156
|
+
start_date: startDate.split('T')[0], // reports API wants YYYY-MM-DD
|
|
157
|
+
end_date: endDate.split('T')[0],
|
|
158
|
+
grouping: 'projects',
|
|
159
|
+
sub_grouping: 'time_entries',
|
|
160
|
+
}),
|
|
161
|
+
}, REPORTS_URL);
|
|
162
|
+
const byProject = (body.groups ?? []).map(g => ({
|
|
163
|
+
name: g.title.project ?? 'No project',
|
|
164
|
+
seconds: g.sub_groups.reduce((sum, sg) => sum + sg.seconds, 0),
|
|
165
|
+
}));
|
|
166
|
+
const totalSeconds = byProject.reduce((sum, p) => sum + p.seconds, 0);
|
|
167
|
+
return { totalSeconds, byProject };
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
//# sourceMappingURL=toggl.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"toggl.js","sourceRoot":"","sources":["../src/toggl.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@souravpn/toggl-mcp",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "MCP server for Toggl Track — gives Claude access to your time tracking data",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"mcp",
|
|
7
|
+
"toggl",
|
|
8
|
+
"time-tracking",
|
|
9
|
+
"productivity",
|
|
10
|
+
"claude",
|
|
11
|
+
"ai"
|
|
12
|
+
],
|
|
13
|
+
"author": "Sourav Nayak",
|
|
14
|
+
"license": "MIT",
|
|
15
|
+
"type": "module",
|
|
16
|
+
"bin": {
|
|
17
|
+
"toggl-mcp": "./dist/index.js"
|
|
18
|
+
},
|
|
19
|
+
"main": "./dist/index.js",
|
|
20
|
+
"files": [
|
|
21
|
+
"dist"
|
|
22
|
+
],
|
|
23
|
+
"scripts": {
|
|
24
|
+
"build": "tsc",
|
|
25
|
+
"dev": "tsc --watch",
|
|
26
|
+
"start": "node dist/index.js",
|
|
27
|
+
"prepublishOnly": "npm run build"
|
|
28
|
+
},
|
|
29
|
+
"dependencies": {
|
|
30
|
+
"@modelcontextprotocol/sdk": "^1.10.0",
|
|
31
|
+
"zod": "^3.23.0"
|
|
32
|
+
},
|
|
33
|
+
"devDependencies": {
|
|
34
|
+
"@types/node": "^20.0.0",
|
|
35
|
+
"typescript": "^5.4.0"
|
|
36
|
+
},
|
|
37
|
+
"engines": {
|
|
38
|
+
"node": ">=18"
|
|
39
|
+
},
|
|
40
|
+
"mcpName": "io.github.souravpn/toggl-mcp",
|
|
41
|
+
"repository": {
|
|
42
|
+
"type": "git",
|
|
43
|
+
"url": "https://github.com/souravpn/toggl-mcp.git"
|
|
44
|
+
}
|
|
45
|
+
}
|