Atlas / MCP servers / trebeljahr / trackyourtime

trackyourtimeBLOCK

mcp/trebeljahr/trackyourtime

Self-hostable time tracker for freelancers. Track time from the web app, your browser or Raycast, then turn the hours into reports and invoices.

Verdict
BLOCK
Grade
F
Trust score
31 /100
Exposed tools
29 21r · 8w · 0d
Transport
stdio
License
AGPL-3.0
Stars
2
01

Overview

From the repository's own README, as read at the audited commit. Badges and raw HTML are left out.

Free, open-source time tracking for freelancers and small teams who bill by the hour.

Start a timer in the web app, the Chrome extension, Raycast on your Mac, or the iPhone and Android apps. Each one keeps counting without a connection and sends your changes when the connection comes back. Stop the timer on your phone, and your laptop shows it stopped.

At the end of the month, the hours become a report, a PDF invoice, or a ZUGFeRD or XRechnung e-invoice. Invite colleagues, and each person sees only their own time until you let them see more. Import a CSV from another tracker, take everything out as JSON or CSV, or connect other tools through the REST API.

There's no paid plan, now or later. Use the hosted version at , or run the same app on your own server from one compose file. The extensions and the phone apps work with either, because each one asks for a server address.

The Chrome extension is in the Chrome Web Store. Self-host images are published through v0.1.2. Desktop downloads remain in draft releases, and the phone apps are in testing channels. Release readiness records the remaining distribution checks.

[](LICENSE) [](https://github.com/trebeljahr/trackyourtime/actions/workflows/build-and-deploy.yml?query=branch%3Amain)

The product was called tracktime until September 2026. The repository, images, bundle ids and every other identifier were renamed to trackyourtime before the first release.

The hosted web app is at , with the API on its own host at . The API reference and OpenAPI document describe its public routes. [`do

Read from source at commit 132b7c032fb9OBSERVED · 2026-10-11
Advertisement
02

Connect

Built from this server's own package name, version and transport as found in its source — not copied from anyone's documentation, so it cannot drift against a page we do not control. Replace the environment placeholders with a token scoped to the least it needs.

claude-code
claude mcp add shared --env CRON_SECRET=${CRON_SECRET} --env E2E_DISABLE_AUTH_RATE_LIMIT=${E2E_DISABLE_AUTH_RATE_LIMIT} --env GH_TOKEN=${GH_TOKEN} --env LISTMONK_API_TOKEN=${LISTMONK_API_TOKEN} -- npx -y @starter/[email protected]
claude-desktop
{
  "mcpServers": {
    "shared": {
      "command": "npx",
      "args": [
        "-y",
        "@starter/[email protected]"
      ],
      "env": {
        "CRON_SECRET": "${CRON_SECRET}",
        "E2E_DISABLE_AUTH_RATE_LIMIT": "${E2E_DISABLE_AUTH_RATE_LIMIT}",
        "GH_TOKEN": "${GH_TOKEN}",
        "LISTMONK_API_TOKEN": "${LISTMONK_API_TOKEN}"
      }
    }
  }
}
03

Exposed tools (29)

21 read · 8 write · 0 destructive.

ToolRiskDescription
blankreadA blank invoice: no billed range, so no BillingSpecifiedPeriod, and delivery on the issue date; two manual lines at 19 %.
create_clientwriteCreate a client. A colour is assigned when none is given.
create_projectwriteCreate a project, optionally under a client (clientId from list_clients), with an hourly rate, a billable default, estimated hours or a budget.
create_tagwriteCreate a tag. Entries can carry several tags, and reports can group by them.
create_taskwriteCreate a workspace-wide task, a name for a kind of work that any project
escapingreadMarkup characters, non-Latin-1 text, an emoji, CR/LF, a tab and a control character.
get_running_timerreadReturn the timer currently running in this token
get_token_inforeadConfirm the MCP server can reach Track Your Time, and show the token
legacy-attachedreadAn invoice created before e-invoicing, filled from the current business profile and client billing details.
list_clientsreadList the workspace
list_entriesreadList time entries that overlap a date range, newest first, with project, client and task names. Filter by project, client, task, tag, billable flag, or a text
list_projectsreadList projects with their client, hourly rate, total tracked time and budget progress. Narrow to one client with clientId. Archived projects are left out unless includeArchived is true.
list_tagsreadList tags with how many entries carry each one and their total time.
list_tasksreadList tasks. A task is a workspace-wide kind of work (for example \
log_time_entrywriteCreate a finished time entry with an explicit start and end, for work that was not timed.
long-500read500 lines: multi-page PDF and performance. No goldens (too large to review).
manual-linesreadTracked hours (HUR) beside a workshop billed by the day (DAY) and a licence by the piece (C62), all at 19 %.
mixed-19-7read19 % and 7 % on one invoice: two breakdown rows, VAT ties rounded away from zero, a 6-dp quantity.
not-subject-chfwriteThe Swiss category O service invoiced in CHF: a plain credit transfer (BT-81 \
not-subject-oreadService not subject to VAT for a Swiss buyer: category O, no VAT ids emitted (BR-O-02), no line rate (BR-O-05).
reduced-7readOne line at the reduced 7 % rate.
reverse-charge-aereadReverse charge to an Austrian business: category AE, buyer VAT id (BR-AE-02), VATEX-EU-AE.
small-business-eread§ 19 UStG small business: category E, no VAT id, tax number plus seller identifier (BR-CO-26), German texts.
standard-19readTwo hourly lines at 19 %: the business content of the validated research sample.
start_timerwriteStart a timer now (or at
stop_timerwriteStop the timer running in this workspace, now or at
summary_reportreadTotal, billable time and amount for a date range, broken down by project, client, task or tag (or by day, week or month), plus a daily series. Grouped by tag, each entry counts fully toward every tag it carries, so tag rows can add up to more than the total. Refused when the token
xrechnung-leitwegreadA public buyer: Leitweg-ID as buyer reference and as electronic address (scheme 0204).
zero-ratedreadCategory Z at 0 %: no exemption reason (BR-Z-10).
04

Trust audit

BLOCKgrade F · trust 31/100 Do not install this without reading the findings. The audit found something that could harm you or your machine.

LayerWhat it checksResult
L0Provenance & inventoryWARN
L1Static analysis of the codeFAIL
L2Instruction surface (what it tells the agent)PASS
L3Class-specific surfacePASS
L4Behavioural (sandbox)SKIPPED

What the source does

Filesystem
declared (11 observation(s))
Network
declared (5 observation(s))
Shell
declared (3 observation(s))
Dependencies
not all pinned
Secrets in source
found

Findings (25)

CRITICALObfuscation / stealth · obf.decode_then_exec · CWE-506, CWE-94
scripts/ops/test-mongo-replica-maintenance.py:49
b64decode( ... subprocess.
Why it matters. decodes a payload and executes it
HIGHCode injection · code.deserialize · CWE-78, CWE-94, CWE-95
scripts/desktop-release-draft.mjs:86
return { name: basename(file), text, feed: yaml.load(text) };
Why it matters. deserialises untrusted bytes into live objects
Fix. use json or yaml.safe_load
HIGHCode injection · code.deserialize · CWE-78, CWE-94, CWE-95
scripts/desktop-release-draft.mjs:97
staged.push({ name, text: next, feed: yaml.load(next) });
Why it matters. deserialises untrusted bytes into live objects
Fix. use json or yaml.safe_load
HIGHCode injection · code.eval_exec · CWE-78, CWE-94, CWE-95
packages/client/next.config.ts:177
const esmImport = new Function(
Why it matters. evaluates text as code
Fix. remove; use a parser or a dispatch table
HIGHNetwork egress · net.tls_off · CWE-200, CWE-319
scripts/selfhost-check.sh:55
--insecure | -k)
Why it matters. certificate verification is disabled
Fix. leave verification on
HIGHNetwork egress · net.tls_off · CWE-200, CWE-319
scripts/selfhost-check.sh:119
echo "Usage: scripts/selfhost-check.sh <domain> [--token tt_...] [--insecure]" >&2
Why it matters. certificate verification is disabled
Fix. leave verification on
HIGHNetwork egress · net.tls_off · CWE-200, CWE-319
scripts/selfhost-check.sh:418
skip "HTTPS certificate is not trusted, accepted because of --insecure"
Why it matters. certificate verification is disabled
Fix. leave verification on
MEDIUMInventory / provenance · inv.binary · CWE-1104
android/gradle/wrapper/gradle-wrapper.jar
gradle-wrapper.jar
Why it matters. a compiled or binary member cannot be reviewed from source
Fix. ship source, or explain the binary in the README
MEDIUMInformation disclosure · disclose.log_secret · CWE-209, CWE-532
scripts/marketing/seed-demo.mjs:217
console.log(JSON.stringify({ email: EMAIL, password: PASSWORD, entries: created, invoice: invoice.number }, null, 2));
MEDIUMNetwork egress · net.raw_ip · CWE-200, CWE-319
.env.selfhost.example:70
# http://localhost and http://127.0.0.1 are two different deployments as far
MEDIUMObfuscation / stealth · obf.base64_blob · CWE-506, CWE-94
packages/shared/src/store-clients.ts:31
"MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxUtsVmu2FXo99hXcLk0ot48DeRuxmTV1+K8sVul2GjdQEy0gxAUNtiRcd/+/4/wZSqwyRqQVia65AVavVfKtJNXqCd3yUxNrVrrdEEOxOedXuQb7RZ/ZIWeU2f6nhyNxJaKXYwrKvE9DvdgSxXmLvQccXLp
MEDIUMObfuscation / stealth · obf.zero_width · CWE-506, CWE-94
packages/server/src/services/import/delimited.ts:130
text.replace(/^[]+/, "");
MEDIUMHard-coded secrets · secret.generic · CWE-798, CWE-321
e2e/desktop/support.ts:113
password: "desktop-e2e-password-1",
MEDIUMHard-coded secrets · secret.generic · CWE-798, CWE-321
packages/mcp/src/tests/integration/local-server.ts:162
body: JSON.stringify({ name: "MCP Test", email, password: "correct-horse-battery" }),
MEDIUMHard-coded secrets · secret.generic · CWE-798, CWE-321
packages/server/src/tests/account-deletion-integration.test.ts:89
secret: "account-deletion-integration-secret-0123456789",
MEDIUMHard-coded secrets · secret.generic · CWE-798, CWE-321
packages/server/src/tests/admin-cli.test.ts:190
secret: "admin-cli-integration-secret-0123456789abcdef",
MEDIUMHard-coded secrets · secret.generic · CWE-798, CWE-321
packages/server/src/tests/email-link.test.ts:63
secret: "email-link-test-secret-0123456789abcdef",
MEDIUMHard-coded secrets · secret.private_key · CWE-798, CWE-321
scripts/lib/chrome-web-store.test.mjs:144
assert.equal(containsPrivateKey("-----BEGIN PRIVATE KEY-----\nabc"), true);
MEDIUMHard-coded secrets · secret.private_key · CWE-798, CWE-321
scripts/lib/chrome-web-store.test.mjs:145
assert.equal(containsPrivateKey("-----BEGIN RSA PRIVATE KEY-----"), true);
LOWInventory / provenance · inv.binary · CWE-1104
packages/server/src/tests/invitations.test.ts
invitations.test.ts
Why it matters. a compiled or binary member cannot be reviewed from source
Fix. ship source, or explain the binary in the README
LOWInventory / provenance · inv.hidden_file · CWE-1104
.env.selfhost.example
.env.selfhost.example
Why it matters. hidden member outside the usual dotfiles
Fix. review its purpose
LOWInventory / provenance · inv.hidden_file · CWE-1104
.hatchkit.json
.hatchkit.json
Why it matters. hidden member outside the usual dotfiles
Fix. review its purpose
LOWInventory / provenance · inv.hidden_file · CWE-1104
packages/raycast/.prettierignore
.prettierignore
Why it matters. hidden member outside the usual dotfiles
Fix. review its purpose
LOWCode injection · code.deserialize · CWE-78, CWE-94, CWE-95
scripts/lib/desktop-rollout.test.mjs:106
const feed = yaml.load(first.text);
Why it matters. deserialises untrusted bytes into live objects
Fix. use json or yaml.safe_load
LOWCode injection · code.deserialize · CWE-78, CWE-94, CWE-95
scripts/lib/desktop-rollout.test.mjs:108
assert.deepEqual(feed.files, yaml.load(FEED).files);
Why it matters. deserialises untrusted bytes into live objects
Fix. use json or yaml.safe_load

Gates applied: critical_finding, no_behavioural_pass.

Audited 2026-10-11 · audit v0.4.1 · source sha 132b7c032fb9full audit observations/trust-audit/mcp-server/trebeljahr__trackyourtime.json · Report an issue / request a re-scan
05

Audit history

Every audit this server has had. A grade with a past is a grade somebody is still checking.

DateSourceVerdictGradeScoreChange
2026-10-11132b7c032fb9BLOCKF31first audit
06

Questions

What is the trackyourtime MCP server?

Self-hostable time tracker for freelancers. Track time from the web app, your browser or Raycast, then turn the hours into reports and invoices.

What tools does trackyourtime expose?

29 in total: 21 read-only, 8 that write, and 0 that can delete or overwrite. Every one is listed on this page with its risk.

Is trackyourtime safe to connect to an agent?

No — not without reading the findings first. The audit graded it F (31/100) and found 7 critical or high issues in the source. Each one is listed on this page with the file and line it is on.

What credentials does trackyourtime need?

It reads CRON_SECRET, E2E_DISABLE_AUTH_RATE_LIMIT, GH_TOKEN, LISTMONK_API_TOKEN, NEWSLETTER_TOKEN_SECRET and WINGET_PKGS_TOKEN from the environment. Give it a token scoped to the least it needs — an agent that can be talked into calling a tool can be talked into calling it with your credentials.

How does trackyourtime run?

It speaks stdio, so it runs as a local process your client starts. It is published on npm as @starter/shared at 0.3.0.

How current is this page?

The grade is for one exact copy of the source (132b7c032fb9), read on 2026-10-11. The repository is watched and re-audited when it changes.

Advertisement