A standalone HTTP microservice that parses raw TF2 match log files (as produced by the mge_logs SourceMod plugin) into structured JSON. Built for mge.tf, a competitive TF2 MGE duel league.
The parser is a pure function: same input text always produces the same output JSON. It performs no database writes and has no external runtime dependencies — any system that needs structured match data (the mge.tf website, historical re-processing, a future competitive plugin, etc.) can consume it independently of the rest of the mge.tf stack.
See docs/spec.md for the full specification, including the input log format, parsing rules, and output schema.
- Runtime: Bun
- Language: TypeScript (strict mode), executed natively by Bun
- HTTP framework: Fastify
- Worker pool: tinypool (parsing runs off the main event loop)
- Tests: Bun's built-in test runner (
bun test)
Install dependencies:
bun installRun the server:
bun run startRun in watch mode:
bun run devRun the test suite:
bun run test| Variable | Default | Description |
|---|---|---|
PORT |
3000 |
Port the HTTP server listens on |
Accepts a raw TF2 log file as the request body (Content-Type: text/plain) and returns the parsed match as JSON.
POST /parse
Content-Type: text/plain
<raw log file content>
| Status | Meaning |
|---|---|
200 |
Returns the parsed ParsedMatch JSON |
400 |
Empty body, or no meta_data line found |
413 |
Body exceeds 2 MB |
500 |
Unhandled parse error |
Returns { "ok": true }. Used for uptime/health checks.
Serves a small HTML UI (src/ui.html) for pasting a log and viewing the parsed result manually.
Full request/response shapes are documented in docs/spec.md.
This service has no authentication. It is designed to run on a private/internal network where the caller (the mge.tf backend) is the only client. If you deploy this service, put it behind a reverse proxy or network boundary that restricts access — do not expose /parse directly to the public internet. See SECURITY.md for how to report vulnerabilities.
docs/example-logs/contains real-shaped TF2 log files with all player identities, names, and IP addresses replaced by synthetic placeholders. They're useful for manually exercising the parser or the/UI.tests/fixtures/contains the golden log/JSON pairs used by the test suite, also fully synthetic.
src/
types.ts — shared TypeScript interfaces (ParsedMatch, PlayerRecord, etc.)
parser.ts — pure synchronous parse function; no side effects, no runtime imports
worker.ts — worker thread entry point; wraps parser.ts for the tinypool pool
server.ts — Fastify HTTP server; dispatches parse calls to the worker pool
ui.html — minimal manual-testing UI served at GET /
docs/
spec.md — full parser specification (input format, rules, output schema)
example-logs/ — sample synthetic log files
tests/
fixtures/ — golden log/JSON pairs
*.test.ts — parser and HTTP server tests