Skip to content
Allay

WikiAllay Server

Architecture

The backend is one Bun process with MongoDB and Redis beside it. A question goes through it like this.

#A question's way

  1. The plugin posts to /api/v2/chat. src/features/auth/caller.ts identifies the server by its license or PLUGIN_TOKEN and names its tenant; src/features/chat/ validates the body and opens the SSE stream.
  2. src/features/billing/gate.ts decides who pays: the plugin's own key, a license with money left, or the backend's key on a self-hosted backend. Limits count per tenant.
  3. src/agent/ assembles the prompt from src/prompts/*.md, the player's memories, and the session, then runs the Mastra agent.
  4. When the model calls a game tool, the bridge in src/features/chat/ sends a tool_call event and waits for the plugin's POST /api/v2/chat/{run}/tools/{call}.
  5. Server tools (search_web, exact_calculations, remember, forget) run in src/features/tools/.
  6. The answer streams back. Afterwards the session is saved to Redis, folded into a summary when it grows too long, and the run's numbers land in MongoDB.

The bridge keeps pending calls in memory, so the backend runs as one instance.

#The code

Path What it does
src/application/ Entrypoint, routes, shared dependencies
src/features/chat/ POST /api/v2/chat: the SSE stream and the tool bridge
src/features/ask, src/features/askx v1 endpoints; their request and response shapes stay
src/features/tools/ Client tool definitions (run by the plugin) and the server tools
src/features/users/ Sessions and memories for /allay new, /allay memory, /allay forget; a player's export and erasure
src/features/auth/ Who sent a request, and its tenant
src/infrastructure/database/migrations.ts What runs on start, and the migrate command
src/agent/ The agent runner, prompt assembly, the session summarizer, askx command validation
src/prompts/*.md The system prompts, bundled into the build
src/infrastructure/ Redis sessions, memories in MongoDB, the OpenRouter provider, traces
src/features/billing/, src/infrastructure/billing/ Who pays, plans, licenses, budget windows, payments
src/features/telegram/ The payment bot: Stars invoices, payments, renewals, refunds
src/features/settings/ Every setting with its type, bounds, and default (settings.definitions.ts)
src/features/admin/, src/infrastructure/admin/ The admin panel's API, accounts, sessions, the audit log
admin/ The panel: React, Vite, shadcn/ui, TanStack Router and Query
docs/protocol-v2.md The contract with the plugin

#Prompts

The prompts live in src/prompts: minecraft-ask.md, minecraft-askx.md, minecraft-task.md for automation agents, and telegram.md. They ship inside the build. Each run appends who asks, their language, and the server version.

#Settings

A setting is read through settings.get(...) where it's used: the environment first, then MongoDB, then the default. A save in the panel applies to the next run. Only what the backend needs to start reads process.env directly.

#Storage

  • MongoDB: memories (by tenant and player), licenses and payments, admin accounts and the audit log, stored settings, the runs collection with its rollups (players as pseudonyms), the player directory that names pseudonyms for the panel, and Mastra's traces.
  • Redis: chat sessions and their summaries, public and task threads, all keyed by tenant first, and admin panel sessions.

Next: Building from source