Freelancer time tracking for AI assistants: log time, timers, timesheets, sign-off links, invoices.
A simple timesheet for freelancers. Log your day in seconds: type 1.5, 1:30 or 90m, press Enter, done.
Live: https://usehourly.app · Free to use, no paywall, no ads.

UseHourly runs a remote Model Context Protocol server at https://usehourly.app/api/mcp (Streamable HTTP). It has 30 tools for projects, clients, time entries, timers, invoices and reports; each one runs as you, so it only sees your own data. Create a token on Account > AI assistants (read-only or read and write, with an expiry), then:
claude mcp add --transport http usehourly https://usehourly.app/api/mcp --header "Authorization: Bearer <your token>"
That example is for Claude Code. Other clients just need the URL and an Authorization: Bearer <token> header in their MCP settings.
Cursor (~/.cursor/mcp.json):
{ "mcpServers": { "usehourly": { "url": "https://usehourly.app/api/mcp", "headers": { "Authorization": "Bearer <your token>" } } } }
VS Code (.vscode/mcp.json):
{ "servers": { "usehourly": { "type": "http", "url": "https://usehourly.app/api/mcp", "headers": { "Authorization": "Bearer <your token>" } } } }
Then ask: "Log 2 hours on the Acme website for yesterday" or "Make an invoice for Acme for September."
Next.js 16 (App Router) · React 19 · Tailwind CSS v4 · shadcn/ui · NextAuth v5 (credentials) · tRPC v11 · Prisma 7 with Cloudflare D1 · Vitest · Biome · deployed to Cloudflare Workers with OpenNext.
You need Node 22+.
npm install # also runs `prisma generate`
cp wrangler.example.jsonc wrangler.jsonc # then set account_id and database_id (see Deploy)
# .env.local and .dev.vars (keep the two in sync):
# AUTH_SECRET=<a long random string, e.g. `openssl rand -base64 32`>
# AUTH_URL=http://localhost:3028
npm run d1:migrate:local # create the local D1 database
npm run dev # http://localhost:3028
Register an account on the sign-up page and you are in.
npm test # scenario tests (Vitest)
npx biome check # lint and format
npx tsc --noEmit # type check
It runs on Cloudflare Workers with a D1 database:
cp wrangler.example.jsonc wrangler.jsonc and fill in your Cloudflare account id and a D1 database
(npx wrangler d1 create usehourly-db). wrangler.jsonc is git-ignored, so your ids stay out of the repo..env.production.local: NEXT_PUBLIC_APP_URL=https://app.example.com
(it is baked into the build) and set the same value as AUTH_URL in wrangler.jsonc.npm run d1:migrate:remotenpx wrangler secret put AUTH_SECRETnpm run deployPassword reset and email confirmation need an email service. UseHourly sends through Resend: verify your sending domain there, then set two values on the Worker:
npx wrangler secret put RESEND_API_KEY
npx wrangler secret put EMAIL_FROM # for example: UseHourly <noreply@your-domain.com>
Without them the app works as before, and the forgot-password page says email isn't set up.
.circleci/config.yml runs the checks on every push and, on main, applies the D1 migrations and
deploys. In the CircleCI project settings add these environment variables:
| Variable | Value |
|---|---|
CLOUDFLARE_API_TOKEN | a token with Workers Scripts: Edit and D1: Edit |
CLOUDFLARE_ACCOUNT_ID | your Cloudflare account id |
D1_DATABASE_ID | the id of your D1 database |
APP_URL | your public address, for example https://app.example.com |
Optional: WORKER_NAME, D1_DATABASE_NAME, CUSTOM_DOMAIN. AUTH_SECRET stays a Worker secret
(npx wrangler secret put AUTH_SECRET, once); CI never sees it. scripts/ci-wrangler-config.mjs
writes wrangler.jsonc from these variables, so no account ids live in the repository.
UseHourly is free. If it saves you time you can sponsor it on GitHub.
Thank you to everyone who helps keep UseHourly free:
Be the first: sponsor UseHourly on GitHub.
Built on the excellent next-shadcn-admin-dashboard template by Mohammed Arham Khan.
Released under the MIT License. The code is open; the name "UseHourly" and its logo are not part of the license.
Source-derived launch command. Check the maintainer’s required arguments and credentials before running:
npx -y usehourly-mcpMerge this template into ~/Library/Application Support/Claude/claude_desktop_config.json. Keep existing servers. Add any arguments, credentials, and permissions required by the maintainer; this template has not been install-tested.
{
"mcpServers": {
"app-usehourly-usehourly": {
"command": "npx",
"args": [
"-y",
"usehourly-mcp"
]
}
}
}Restart Claude Desktop completely for changes to take effect. Confirm the server appears connected in the client’s tool list, then try a read-only example from its documentation.
Claude Desktop setup referenceusehourly-mcpnpmUseHourly works with any MCP-compatible client. Copy the config snippet from the Configuration section above and add it to the file shown for your client, then restart the application.
~/Library/Application Support/Claude/claude_desktop_config.jsonRestart Claude Desktop completely for changes to take effect.~/.cursor/mcp.jsonRestart Cursor for changes to take effect..vscode/mcp.jsonReload VS Code window for changes to take effect.~/.codeium/windsurf/mcp_config.jsonRestart Windsurf for changes to take effect..mcp.jsonSave at the project root, then start Claude Code in that project and review the MCP server approval prompt. Keep real credentials out of shared files.