bugtracker-mcp
by SUKARDADDY
README.md
# bugtracker-mcp
Public, no-authentication MCP server over a bilingual (Hebrew / English) issue tracker.
Built as a portfolio demo: anyone can add the URL to Claude or ChatGPT and use it immediately.
**Live:** https://mcp.raceus.co.il/mcp · landing page at https://raceus.co.il
```
Worker bugtracker-mcp (Cloudflare Workers, free plan)
Storage D1 "bugtracker" (SQLite, FTS5)
Cron 0 21,22 * * * guarded to local midnight, Asia/Jerusalem
```
### Running your own
```bash
cp wrangler.toml.example wrangler.toml
npx wrangler d1 create bugtracker # put the returned id in wrangler.toml
npm install --legacy-peer-deps
npm run schema # applies src/db/schema.sql (destructive)
npx wrangler secret put RESEED_TOKEN
npm run deploy
curl -X POST https://<your-worker>/admin/reseed -H "x-reseed-token: $TOKEN"
./verify.sh https://<your-worker>
```
`wrangler.toml` is gitignored so deployments stay bound to whoever cloned it.
## Surface
All three MCP primitives, where most public servers implement only tools.
**Tools (11)**
| Tool | Notes |
|---|---|
| `list_bugs` | filter by status/origin/lang, cursor pagination |
| `get_bug` | full report + photo metadata + comment count |
| `get_bug_photo` | returns **binary image data inline** over MCP |
| `set_bug_status` | write, enum-validated, emits an audit event |
| `create_bug` | write, auto-detects Hebrew vs English |
| `search_bugs` | FTS5, bilingual (see below) |
| `add_comment` / `list_comments` | second entity |
| `bug_stats` | aggregation: status, origin, language, top reporters, busiest days |
| `bug_timeline` | audit trail from `bug_events` |
| `export_bugs` | CSV generation |
**Resources** — `bug://{id}` (templated, with listing) and `bug://recent`
**Prompts** — `triage_bug`, `weekly_summary`
## Hebrew search
The interesting part. Hebrew attaches grammatical particles as *prefixes*
(ה, ו, ב, ל, מ, כ, ש), so "export" appears in text as **הייצוא** and a user searching
**ייצוא** gets nothing. FTS5 prefix matching (`token*`) only extends rightward and
FTS5 ships no Hebrew stemmer, so neither helps.
Fix, in `src/mcp/hebrew.js`: normalise at **index** time by also indexing a
particle-stripped variant of every Hebrew token, and OR-expand query tokens the same
way. Matching becomes symmetric — `ייצוא` and `הייצוא` return identical results.
Deliberately shallow morphology: handles prefix particles, not roots, plurals or
possessive suffixes. That covers the overwhelming majority of real misses.
## Nightly reset
Cloudflare cron fires in **UTC only**. Israeli midnight is 21:00 or 22:00 UTC
depending on DST, so both are registered and `isLocalMidnight()` guards the handler
to fire on exactly one of them. Verified against summer and winter dates.
The reseed runs in `scheduled()`, never in a request path: the free plan allows
~10ms CPU per `fetch()` and rebuilding ~275 rows exceeds that comfortably.
## Data
70 synthetic reports (38 Hebrew / 32 English) about a fictional generic SaaS app,
plus 36 comments, 155 events and 14 photo attachments. Nothing real, no company
named anywhere. Timestamps are stored as day offsets and materialised at reseed
time, so the data always reads as recent.
Screenshots are drawn PNGs bundled with the Worker (`src/data/photos.js`) rather
than object storage — R2 is not enabled on this account and the demo does not need it.
## Commands
```bash
npm install --legacy-peer-deps # agents@0.16.0 has a peer conflict; this is required
npm run schema # apply schema.sql to remote D1 (destructive)
npm run deploy
./verify.sh # 28 assertions against the live endpoint
python3 scripts/gen_seed.py # regenerate seed data
python3 scripts/gen_photos.py # regenerate bundled screenshots
```
Manual reseed (needs the `RESEED_TOKEN` secret):
```bash
curl -X POST https://mcp.raceus.co.il/admin/reseed -H "x-reseed-token: $TOKEN"
```
## Gotchas
- **`npm install` fails without `--legacy-peer-deps`.** `agents@0.16.0` declares a peer
on `ai@^6` while its optional `@cloudflare/ai-chat` peer wants `^6 || ^7`.
- **Reseed immediately after deploy can race propagation.** A reseed run seconds after
`wrangler deploy` executed the *previous* bundle and silently wrote unexpanded search
rows. Wait, or verify `SELECT MAX(length(explanation)) FROM bug_search` is ~268 not ~198.
- **`raceus.co.il` also hosts `chat.` (claude-chat-bridge) and `tasks.` (sukartask).**
The apex is a Pages project named `raceus`, not this Worker.
This server cannot be deployed
Maintenance
ActivitySlowing
ResponsivenessNo issues