Unicum.gg World of Tanks Stats README

The full upstream README, mirrored for reference. Install config, tool schemas, adoption signals and our own overview live on the Unicum.gg World of Tanks Stats listing page.

unicum.gg

Free, open-source World of Tanks stats tracker. Player profiles, clan pages, leaderboards. WN7, WN8, WNX. No ads.

Live at unicum.gg.

Use it

MCP server

Every API endpoint is also a tool on a remote MCP server, no key needed. It is listed in the official MCP Registry as gg.unicum/wot-stats.

config.json
{
  "mcpServers": {
    "unicum": { "url": "https://unicum.gg/api/mcp" }
  }
}

Stack

Next.js 16, React 19, TypeScript, PostgreSQL via Drizzle, Tailwind v4, shadcn/ui, Recharts.

Monorepo

pnpm workspace. Dependencies flow one way, no cycles:

Code
@unicum.gg/wargaming ──▶ @unicum.gg/shared ──▶ @unicum.gg/core ──▶ apps/web (server) + apps/worker
                                                       │ HTTP API
                                @unicum.gg/sdk ◀───────┘
                                       └──▶ web front + apps/bot
Package / appRole
packages/wargamingNeutral Wargaming API SDK (client, rate limiting, full response types)
packages/sharedClient-safe foundations: env, constants, db schema, pure domain math and types
packages/coreServer-only: db pool, redis, crons, repositories, WG fetchers, auth
packages/sdkFluent client for our own public API, types generated from the OpenAPI spec
apps/webThe Next.js site and public API
apps/workerStandalone cron runner
apps/botDiscord bot (/player, /clan)

wargaming, shared and sdk are imported from their package barrel (import { Region } from "@unicum.gg/wargaming"). core is deliberately not a barrel: its modules have import-time side effects (db pool, auth secret assert), so server code imports the specific subpath it needs (@unicum.gg/core/db, ...). The front end and the Discord bot never import core; they consume the API through @unicum.gg/sdk and types through @unicum.gg/shared.

Run locally

bash
pnpm install
pnpm env:init   # generates .env.local from env.ts; fill in the values
pnpm dev

pnpm env:init reads env.ts and writes a .env.local with every required key. If a .env.local already exists it is backed up to .env.local.<timestamp>.bak first, so nothing is lost.

Get the three WG application IDs at developers.wargaming.net (one ID can be reused across regions).

Database

bash
for f in apps/web/drizzle/0*.sql; do psql "$DATABASE_URL" -f "$f"; done

Contributing

Issues and PRs welcome. Read AGENTS.md first. It is the project's contributing guide and covers the non-obvious foot-guns (schema factory pattern, migration workflow, cron loop, WG fetch and rate limits).

License

AGPL v3. Copyright (C) 2026 Antoine Kingue.

Not affiliated with Wargaming.net.