Skip to content

Commit ad95fa5

Browse files
ktamas77claude
andcommitted
feat: initial Timebook CLI + MCP server
A single binary that works as a CLI for tracking time on Timebook (usetimebook.com) and as an MCP stdio server for AI agents like Claude, Codex, and Cursor. Highlights: - timebook login: browser-based auth via short-lived loopback listener; token saved 0600 in env-paths config dir - core CLI: whoami, status, start, stop, log, projects, clients, entries - timebook mcp: stdio MCP server exposing 8 tools (start_timer, stop_timer, log_time, list_*, etc.) - TypeScript, ESLint, Prettier, husky pre-commit, GitHub Actions CI + npm release workflow with provenance Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
0 parents  commit ad95fa5

30 files changed

Lines changed: 5734 additions & 0 deletions

.editorconfig

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
root = true
2+
3+
[*]
4+
charset = utf-8
5+
end_of_line = lf
6+
indent_style = space
7+
indent_size = 2
8+
insert_final_newline = true
9+
trim_trailing_whitespace = true

.github/workflows/ci.yml

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
name: CI
2+
3+
on:
4+
push:
5+
branches: [main]
6+
pull_request:
7+
8+
jobs:
9+
build:
10+
runs-on: ubuntu-latest
11+
strategy:
12+
matrix:
13+
node: ['18.x', '20.x', '22.x']
14+
steps:
15+
- uses: actions/checkout@v4
16+
- uses: actions/setup-node@v4
17+
with:
18+
node-version: ${{ matrix.node }}
19+
cache: npm
20+
- run: npm ci
21+
- run: npm run lint
22+
- run: npm run format:check
23+
- run: npm run typecheck
24+
- run: npm run build

.github/workflows/release.yml

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
name: Release to npm
2+
3+
on:
4+
release:
5+
types: [published]
6+
7+
jobs:
8+
publish:
9+
runs-on: ubuntu-latest
10+
permissions:
11+
contents: read
12+
id-token: write
13+
steps:
14+
- uses: actions/checkout@v4
15+
- uses: actions/setup-node@v4
16+
with:
17+
node-version: '20.x'
18+
registry-url: 'https://registry.npmjs.org'
19+
cache: npm
20+
- run: npm ci
21+
- run: npm publish --provenance --access public
22+
env:
23+
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}

.gitignore

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
node_modules
2+
dist
3+
*.log
4+
.DS_Store
5+
.env
6+
.env.local
7+
.env.*.local
8+
coverage
9+
.idea
10+
.vscode
11+
*.tsbuildinfo

.husky/pre-commit

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
npx lint-staged

.npmignore

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
src
2+
node_modules
3+
.husky
4+
.github
5+
scripts
6+
tsconfig.json
7+
eslint.config.js
8+
.prettierrc
9+
.prettierignore
10+
.editorconfig
11+
.eslintignore
12+
*.tsbuildinfo
13+
.gitignore

.prettierignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
node_modules
2+
dist
3+
package-lock.json
4+
*.tsbuildinfo

.prettierrc

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
{
2+
"semi": true,
3+
"singleQuote": true,
4+
"trailingComma": "all",
5+
"printWidth": 100,
6+
"tabWidth": 2,
7+
"arrowParens": "always",
8+
"endOfLine": "lf"
9+
}

LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2026 Squidcode LLC
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

README.md

Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
# Timebook CLI
2+
3+
Command-line client and **MCP server** for [Timebook](https://usetimebook.com) — track time, manage timers, and expose your Timebook account to AI agents (Claude, Codex, Cursor, …) over the [Model Context Protocol](https://modelcontextprotocol.io).
4+
5+
[![npm](https://img.shields.io/npm/v/%40squidcode%2Ftimebook-cli.svg)](https://www.npmjs.com/package/@squidcode/timebook-cli)
6+
[![license](https://img.shields.io/npm/l/%40squidcode%2Ftimebook-cli.svg)](./LICENSE)
7+
8+
## Install
9+
10+
```bash
11+
# one-off
12+
npx @squidcode/timebook-cli login
13+
14+
# globally
15+
npm install -g @squidcode/timebook-cli
16+
timebook --help
17+
```
18+
19+
Requires Node.js **18.17+**.
20+
21+
## Authenticate
22+
23+
`timebook login` opens your browser, you log into Timebook (or use an existing session) and pick a scope (which clients/projects this token can touch). The browser delivers the token back to a short-lived loopback HTTP listener, which the CLI then writes to a config file with `0600` permissions.
24+
25+
```bash
26+
timebook login
27+
```
28+
29+
The token is stored at:
30+
31+
- macOS: `~/Library/Preferences/timebook/config.json`
32+
- Linux: `~/.config/timebook/config.json`
33+
- Windows: `%APPDATA%\timebook\Config\config.json`
34+
35+
The token never leaves your machine after login. To revoke it server-side, visit `https://usetimebook.com/settings/api-tokens`.
36+
37+
## Use it as a CLI
38+
39+
```bash
40+
timebook whoami
41+
timebook projects # list projects
42+
timebook clients # list clients
43+
44+
timebook start -p "Acme website" -d "Wireframes"
45+
timebook status # show running timer
46+
timebook stop
47+
48+
# manual entries
49+
timebook log -p "Acme website" -t 1h30m -d "Code review"
50+
timebook log -p PROJ_ID --start 2026-05-04T09:00 --end 2026-05-04T10:30
51+
52+
timebook entries --project "Acme website" -n 10
53+
```
54+
55+
Duration formats accepted: `1h`, `45m`, `1h30m`, `1.5h`, `1:30`, or a bare number (interpreted as minutes — e.g. `90` → 1h 30m).
56+
57+
## Use it as an MCP server
58+
59+
The same binary speaks MCP over stdio when invoked with `timebook mcp`. Drop it into any MCP-aware host (Claude Code, Claude Desktop, Codex, Cursor, …):
60+
61+
### Claude Code / Claude Desktop
62+
63+
```json
64+
{
65+
"mcpServers": {
66+
"timebook": {
67+
"command": "npx",
68+
"args": ["-y", "@squidcode/timebook-cli", "mcp"]
69+
}
70+
}
71+
}
72+
```
73+
74+
Or, if installed globally:
75+
76+
```json
77+
{
78+
"mcpServers": {
79+
"timebook": {
80+
"command": "timebook",
81+
"args": ["mcp"]
82+
}
83+
}
84+
}
85+
```
86+
87+
The MCP server reuses the token saved by `timebook login` — run `timebook login` once in a terminal before starting the agent.
88+
89+
### Tools exposed to the model
90+
91+
| Tool | What it does |
92+
| ------------------ | ------------------------------------------------ |
93+
| `whoami` | Current authenticated user |
94+
| `list_projects` | All projects in scope |
95+
| `list_clients` | All clients in scope |
96+
| `get_active_timer` | The running timer, or `null` |
97+
| `start_timer` | Start a timer on a project |
98+
| `stop_timer` | Stop the running timer |
99+
| `log_time` | Log a manual entry (`duration` OR `start`+`end`) |
100+
| `list_entries` | Recent entries, optional project + date filters |
101+
102+
## Configuration
103+
104+
Override the API/web hosts (useful for self-hosted Timebook or local dev):
105+
106+
```bash
107+
TIMEBOOK_API_URL=https://api.example.com \
108+
TIMEBOOK_WEB_URL=https://example.com \
109+
timebook login
110+
```
111+
112+
You can also pass `--api-url` and `--web-url` to `timebook login` once; subsequent commands re-use the saved values.
113+
114+
## Develop
115+
116+
```bash
117+
git clone https://github.com/squidcode/timebook-cli
118+
cd timebook-cli
119+
npm install
120+
npm run dev -- --help # tsx-powered hot-loop
121+
npm run build # emits dist/
122+
npm run lint && npm run typecheck
123+
```
124+
125+
Pre-commit hooks (ESLint + Prettier via `lint-staged`) are wired up by `husky` on `npm install`.
126+
127+
## Release
128+
129+
`prepublishOnly` runs lint + typecheck + build, then:
130+
131+
```bash
132+
npm publish --access public
133+
```
134+
135+
## License
136+
137+
MIT © Squidcode LLC. See [LICENSE](./LICENSE).

0 commit comments

Comments
 (0)