MageTech AI Forge — Technical Architecture 🛠️ & Engineering Documentation
MageTech AI Forge is a local-first, open-source AI application and agent platform. It compounds documents, knowledge bases and AI workflows to accelerate agencies and businesses. This document is the single source of truth for architecture decisions, component behavior, security, data flows and operational guidance — written to be read by engineers, operators and reviewers alike, and versioned alongside the code it describes.
01System Overview & Goals LIVE
MageTech AI Forge is a full-stack AI application and agent platform that combines retrieval-augmented generation (RAG), autonomous agents and the Model Context Protocol (MCP) into one product surface. The platform is deliberately local-first: the default runtime is a fully self-hosted stack with Ollama serving open-weight models, so customers keep data on hardware they control. The architecture is provider-agnostic, so managed providers (OpenAI, Google Gemini, Anthropic, Azure OpenAI) can be added later without redesigning the core.
Product pillars
📚 Knowledge & RAG
Upload documents, parse and chunk them, embed and store them with pgvector-style cosine search, then answer questions grounded in the knowledge base with citations.
🤖 Agents
Persistent agent runs that can call MCP tools, remember context and stream step-by-step execution. LangGraph orchestration is the planned evolution.
🔌 MCP
A first-class Model Context Protocol layer: connect, enable/disable and invoke external tools through a standardized JSON-RPC surface with strict security gates.
🧑💻 Workspaces
Multi-tenant workspaces isolate knowledge, agents, conversations and tools with column-level tenancy on every business entity.
📊 Observability
Structured JSON logs, token accounting, agent-run traces and usage analytics inform cost, quality and debugging decisions.
🔌 Extensible
Webhook events, a future MCP SDK, ServiceFlow/CRM integrations and OAuth2 2-legged flows keep the platform open.
System context
flowchart LR
subgraph USER["Users & Integrations"]
U1[("Web browser")]
U2[("External integrations\n(post-MVP)")]
end
subgraph WEB["Client Tier — Next.js 16 (App Router)"]
W1["UI components\n(shadcn-style, Tailwind 4)"]
W2["TanStack Query cache"]
W3["Zod + React Hook Form"]
W4["SSE stream reader"]
end
subgraph API["API Tier — FastAPI (Python 3.12)"]
A1["v1 routers: auth, chat, agents,\nknowledge, mcp, models, usage"]
A2["Services: LLMClient, document_parser,\nknowledge, agents, chat, mcp"]
A3["Async SQLAlchemy + Redis"]
A4["Rate limiting (slowapi)"]
end
subgraph AI["AI Tier"]
AI1["Ollama — qwen2.5:7b + nomic-embed-text\n(Live)"]
AI2["LangGraph + LlamaIndex\n(Planned)"]
AI3["Managed providers: OpenAI,\nGemini, Anthropic (Future)"]
end
subgraph DATA["Data Tier"]
D1[("PostgreSQL\n(pgvector-ready)")]
D2[("Redis\n(cache, queues, rate limits)")]
end
W2 --> W1
W3 --> W1
W4 --> W1
W1 -- "HTTPS / JSON / SSE" --> A1
A1 --> A2
A2 --> A3
A3 --> D1
A3 --> D2
A2 -- "HTTP (Ollama API)" --> AI1
AI1 -.-> AI2
AI2 -.-> AI3
A1 -- "audit + telemetry" --> D2
A2 -- "token accounting" --> D1
live components ship in the current MVP, dashed edges indicate planned/future capability.
Goals
- Run the entire AI stack locally by default — no mandatory third-party API keys.
- Keep the product open source and self-hostable with one
docker compose upcommand. - Provide grounded answers over customer knowledge bases with citations and source links.
- Expose every capability through a documented, versioned HTTP API (OpenAPI 3.1).
- Guard business value with security, rate limiting, audit logging and RBAC-ready tenancy from day one.
Non-goals (current release)
- No hosted/cloud control plane — multi-instance fleet management is future work.
- No public plugin marketplace yet (PLANNED).
- No fine-tuning or custom model training within the platform.
- No native mobile clients — responsive web only for now.
02Design Principles LIVE
The architecture is governed by a small set of principles that guide every decision. Each principle maps to concrete, verifiable behavior in the codebase.
| Principle | What it means here | Evidence in the codebase |
|---|---|---|
| Local-first | Default runtime is self-hosted with open-weight models; no external dependency is mandatory. | LLMProvider.OLLAMA default; docker-compose includes Ollama; LLM_PROVIDER=auto probes local Ollama first and falls back to mock. |
| Open source | Transparent, auditable stack; no black-box components in the critical path. | MIT/OSI components (FastAPI, Next.js, Ollama, PostgreSQL, Redis); OpenAPI schema exposed at /docs. |
| Provider-agnostic AI | No model provider is hard-wired; swapping providers must not change application code. | LLMClient gateway isolates provider SDKs behind one protocol-agnostic interface. |
| Secure by default | Fail closed: argon2id hashes, short-lived JWTs, refresh cookies, rate limits, production guards, no tool can shell out. | PasswordHasher.scrypt/argon2, dual JWT secrets, validate_production() aborts on default secrets, MCP calculator uses an AST whitelist. |
| Tenant isolation | Every business entity belongs to a workspace; queries are always scoped by tenant. | All tables carry workspace_id; services derive tenant from X-Workspace-Id or first membership. |
| Async-first backend | I/O-bound work is non-blocking; streamable responses for LLM tokens. | async SQLAlchemy + asyncpg, async Redis, SSE streaming via StreamingResponse. |
| Reliability & observability | Every request is traceable; failures are structured, not silent. | structlog JSON logging, AppError envelope, audit log, agent-run execution records, health endpoints. |
| Evidenced roadmap | Everything labelled planned/future has a written design intent in the roadmap and here. | LangGraph (agents), LlamaIndex (indexing/analyses), MCP SDK, ai-gateway, RLS — all documented with status badges. |
Requirements classification
Throughout this document every component, endpoint and decision carries one of four status badges that separate shipped, in-flight and aspirational work:
| Badge | Meaning | Expectation |
|---|---|---|
| LIVE | Shipped and operational in the current codebase. | Described behavior is true today; covered by tests. |
| SCALED MVP | Present in the MVP but intentionally minimal; will grow. | Works end-to-end; known simplifications are noted inline. |
| PLANNED | Designed, assigned to a near-term milestone, not yet implemented. | Design intent is authoritative; implementation may still change. |
| FUTURE | Recognized direction with no committed timeline. | Informative; treat as directional, not contractual. |
How to read this document. Start with §03 (stack) for the version inventory, §04–§07 for AI internals, §08–§11 for data/security architecture, then §15–§22 for operations and rollout. A 30-minute reader gets the full picture from §01, §04, §05, §09, §10 and §21.
03Technology Stack LIVE
Versions below are the pinned truth from the workspace lockfiles (apps/web/package.json, apps/api/pyproject.toml) at the time of writing. Bumping a dependency must start from these references and re-run the full quality gate (§16).
Frontend
| Technology | Version | Purpose | Status |
|---|---|---|---|
| Next.js (App Router) | 16.3.5 | Framework, SSR/SSG, routing, RSC usage | LIVE |
| React / React DOM | 19.2.8 | UI runtime | LIVE |
| TypeScript | 5.9 | Typed language | LIVE |
| Tailwind CSS | 4.3.3 | Utility-first styling (CSS-first config) | LIVE |
| shadcn/ui pattern | - | Component primitives (hand-rolled, no Radix runtime) | LIVE |
| @tanstack/react-query | 5.103.2 | Server-state cache & mutations | LIVE |
| react-hook-form + Zod | 7.88 / 4.6.5 | Forms + schema validation | LIVE |
| motion | 13.4 | Animation | LIVE |
| next-themes | 0.4.6 | Dark/light theming | LIVE |
| recharts | 3.10.1 | Usage charts | LIVE |
| lucide-react / cva / clsx | 1.47 / 0.7.1 | Icons, class variance | LIVE |
| Vitest + Testing Library | 5.0.1 / 16.3.3 | Unit/component tests | LIVE |
| Playwright | 1.63 | E2E tests (root workspace) | LIVE |
Backend
| Technology | Version | Purpose | Status |
|---|---|---|---|
| Python | 3.12 | Runtime | LIVE |
| FastAPI | 0.141 | Web framework, OpenAPI generation | LIVE |
| Uvicorn | 0.53 | ASGI server | LIVE |
| Pydantic / pydantic-settings | 2.13.5 / 2.15 | Validation + typed settings/config | LIVE |
| SQLAlchemy 2.x + asyncpg | 2.0.54 / 0.31 | Async ORM + driver | LIVE |
| psycopg (binary) | 3.3 | Sync driver (migrations/utilities) | LIVE |
| Alembic | 1.20 | Schema migrations | LIVE |
| Argon2-cffi / PyJWT | 25.1 / 2.14 | Password hashing + JWT (HS256) | LIVE |
| redis | 6.4 | Cache, rate-limit store, queues | LIVE |
| slowapi | 0.1.10 | Rate limiting middleware | LIVE |
| Celery | 5.6.3 | Background task worker (opt-in) | LIVE |
| structlog / orjson | 26.1 / 3.12 | Structured logging + fast serialization | LIVE |
| httpx | 0.28.1 | Async HTTP client (Ollama/MCP) | LIVE |
| pypdf / python-multipart | 6.19 / 0.0.32 | PDF parsing, uploads | LIVE |
| email-validator | 2.3 | Email validation | LIVE |
| pytest / pytest-asyncio | 9.1 / 1.4 | Test runner | LIVE |
| ruff | 0.16 | Lint + format | LIVE |
AI, Data & Infrastructure
| Technology | Version / Target | Purpose | Status |
|---|---|---|---|
| Ollama | latest (local) | Open-weight LLM + embedding serving | LIVE |
| Models | qwen2.5:7b | Generation model | LIVE |
| Models | nomic-embed-text | Embeddings, 384-dim | LIVE |
| LangGraph | planned | Stateful agent graph orchestration | PLANNED |
| LlamaIndex | planned | Indexing, retrieval & analysis orchestration | PLANNED |
| PostgreSQL | 16 (Docker) / 18 (local) | Primary database (pgvector extension) | LIVE |
| pgvector | pgvector/pgvector:pg16 | Vector index (extension installed; native columns planned) | PLANNED |
| Redis | 7-alpine | Cache, rate limits, broker | LIVE |
| Docker / Compose | infra image set | Self-host bundle | LIVE |
| Hugging Face | - | Model source for Ollama pulls / fine-tunes (future) | FUTURE |
| OpenAI / Gemini / Anthropic | v4 / SDK target | Managed provider adapters | FUTURE |
Selection rationale
Why Next.js + FastAPI?
The split gives the product the best developer velocity on the client (App Router, RSC, mature data-fetching) and the best async/concurrency story for AI streaming on the server (ASGI, native async/await, SSE) — without forcing one language to do everything.
Why PostgreSQL + Redis?
Postgres keeps transactions, vector and JSON documents in one ACID store; Redis adds sub-millisecond caching, distributed rate limits and a queue broker. Both are open source, self-hostable and battle-tested locally.
Why Ollama first?
Local-first mandate plus open weights. Ollama exposes a simple localhost HTTP API (tags/chat/embed) that maps 1:1 onto our LLMClient gateway — managed providers drop in later behind the same interface.
Why TypeScript end-to-end?
Shared Zod schemas and typed API clients remove a whole class of contract drift bugs before they reach staging.
04AI Architecture LIVE
The AI tier is built around a single provider gateway (services/llm_client) so that the rest of the platform never talks to a specific model vendor. Today the gateway speaks to Ollama; tomorrow it can route to OpenAI, Gemini or Anthropic with configuration only.
LLMClient gateway
flowchart TB APP["Application services\n(chat, agents, knowledge, models)"] GATEWAY["LLMClient\n(llm_client.py)"] RES["Provider resolution\nLLM_PROVIDER = auto | ollama | mock"] PROBE["Probe Ollama /api/tags\n(30s availability cache)"] OL["Ollama provider\nHTTP client (httpx)"] OKC["Ollama Models\ngeneration + embed"] MO["Mock provider\n(deterministic dev output)"] FUT["Managed providers\nOpenAI / Gemini / Anthropic"] TOKEN["Token accounting\nstream → eval_count / len//4"] APP --> GATEWAY GATEWAY --> RES RES --> PROBE PROBE --> OL OL --> OKC RES --> MO OL -. provider add .-> FUT GATEWAY --> TOKEN PROBE -.->|unavailable| MO
- Provider selection — LLM_PROVIDER=auto probes the local Ollama tag endpoint; a 30-second availability cache prevents repeated failed probes. If no provider is reachable the gateway degrades to the mock provider so tests and demos stay deterministic.
- Generation — chat and chat_stream map to Ollama’s /api/chat (non-streaming and streaming). Stream consumers receive SSE events meta → delta → done followed by data: [DONE].
- Embeddings — /api/embed produces 384-dimensional vectors from nomic-embed-text for document chunks.
- Models API — the models router lists, registers, synchronizes (/api/tags) and pulls models into Ollama (/api/pull).
- Token accounting — per message, per run and per model. Streaming responses report eval_count from Ollama; when the source omits it, tokens are estimated with len(text)//4 (≈4 chars/token). This feeds the usage analytics and per-model cost view.
Ollama integration
| Endpoint | Method | Usage in MageTech | Status |
|---|---|---|---|
| /api/tags | GET | Availability probe, model sync | LIVE |
| /api/chat | POST | Generation (stream + non-stream) | LIVE |
| /api/embed | POST | Document & query embeddings | LIVE |
| /api/pull | POST | Model management (pull into Ollama) | LIVE |
Model registry defaults
| Model | Role | Notes |
|---|---|---|
| qwen2.5:7b | Primary generator | 7B parameters, works on CPU/GPU; used by chat, agents and structured answers. |
| nomic-embed-text | Embeddings | 384-dim, strong local retrieval quality per size. |
Model entries are persisted in the models table with provider metadata so usage analytics can attribute cost per model even as the registry grows.
Adding a managed provider FUTURE
# Conceptual provider registration (target design)
class OpenAIProvider(BaseProvider): # future
async def chat(self, messages, **kw): ...
async def embed(self, text): ...
# llm_client.py: provider_map[d] = OpenAIProvider() when configuredDesign invariant. No chat/agent/service code may import an SDK for a specific vendor. All vendor logic lives behind LLMClient. The MCP tool layer and the future ai-gateway (§20) reuse the same gateway.
05Knowledge & Retrieval (RAG) LIVE
A RAG pipeline turns uploaded documents into answerable knowledge. The platform ingests, parses, chunks, embeds and stores documents per knowledge base, then retrieves the top-k most similar chunks for grounded question answering.
Ingestion pipeline
flowchart LR
U["Upload\n(multipart PDF/text)"]
P["Parse\npypdf + preview\n(PDF/text/MD/CSV)"]
C["Chunk\nsize 800 / overlap 160"]
E["Embed\nnomic-embed-text\n(384-dim)"]
S[("Store\nPostgreSQL\nJSON embeddings")]
R["Chat / Q&A runtime"]
REP["Async reprocess\n(thumbs up / edit)"]
U --> P --> C --> E --> S --> R
S -. job .-> REP
Processing details
- Upload & validation — PDF, TXT, MD, CSV; documents are truncated to MAX_DOCUMENT_CHARS = 2,000,000 before parsing to bound cost and latency.
- Parse — document_parser extracts text and a preview; the parsed text becomes the unit of chunking.
- Chunk — overlapping chunks at CHUNK_SIZE = 800 characters with CHUNK_OVERLAP = 160 to preserve context across chunk boundaries.
- Embed & store — each chunk is embedded and persisted in document_chunks with source pointers (document id, index, char range).
- Async option — with USE_CELERY=true, ingestion is dispatched to the worker as the documents.process task; otherwise it runs in-process on the API node.
- Reprocess — documents can be re-chunked/re-embedded after edits or model changes.
Retrieval & answering
sequenceDiagram
participant U as User / Web
participant C as Chat Service
participant Q as Knowledge Service
participant DB as PostgreSQL
participant LLM as Ollama LLM
U->>C: POST /api/v1/chat {question}
C->>Q: /knowledge/search {query, k}
Q->>DB: embed query (384-dim)
Q->>DB: cosine top-k chunks (workspace-scoped)
DB-->>Q: top-k chunks + source docs
Q-->>C: ranked context
C->>LLM: grounded prompt (system + chunks)
LLM-->>C: answer
C-->>U: answer + citation sources
- Query embedding — the question is embedded with the same model family as the chunks so vectors are comparable.
- Top-k retrieval — cosine similarity on stored vectors (JSON-array math) scoped to the tenant workspace; the number of chunks k is configurable per request.
- Grounded generation — the system prompt instructs the model to answer from the supplied chunks only and to cite sources; chunks carry document references so answers can link back to source documents.
- Search endpoint — POST /api/v1/knowledge/search?k=… returns ranked chunks for inspection and debugging.
Vector storage evolution
| Phase | Approach | Trade-offs | Status |
|---|---|---|---|
| Now | Embeddings as JSON arrays in document_chunks; brute-force cosine. | Simple, zero-extension friction, correct for MVP scale (thousands of chunks). | LIVE |
| Near | Native vector(384) column + pgvector index (extension already provisioned in init.sql). | Real ANN search, speed for 10⁵+ chunks, still inside Postgres. | PLANNED |
| Later | Hybrid retrieval (vector + BM25) + optional cross-encoder re-rank. | Better recall for exact/keyword queries. | FUTURE |
06Agents & LangGraph LIVE
Agents in the MVP are persistent, tool-capable runtimes: create an agent, attach a system prompt and model, then run it with input. Runs produce a stream of steps (tool calls and text) that are recorded for audit and replay. The orchestration layer is designed to be replaced by LangGraph state graphs without changing the domain model or API contract.
Agent run lifecycle
- Create agent — name, description, system prompt, model, temperature; persisted in agents.
- Run — POST /api/v1/agents/{id}/run with an input message creates an agent_run and executes the loop.
- Execute — the runtime generates a response; if the model requests tools, each selected MCP tool is invoked through the MCP service and its result is fed back until the loop terminates.
- Record — every step, token count, tool call and final output lands in agent_runs (and via executions view) for replay and audit.
- List — the executions dashboard lists runs (latest 200) with status, duration and token usage; detail view shows the full step trace.
stateDiagram-v2
[*] --> Pending
Pending --> Running: executor acquires
Running --> ToolCall: model requests tool
ToolCall --> Running: tool result appended
ToolCall --> Completed: max iterations reached
Running --> Completed: final answer
Running --> Failed: exception / provider error
Completed --> [*]
Failed --> [*]
Run statuses
| Status | Meaning | Transitions |
|---|---|---|
| pending | Created, not yet executing. | → running |
| running | Generation / tool loop in progress. | → completed | failed |
| completed | Terminal, final answer produced. | terminal |
| failed | Terminal, exception or provider error surfaced. | terminal |
Chat layer
Conversation endpoints (/api/v1/chat) provide the conversational surface on top of the same AI gateway: create conversations, post messages, and stream answers (SSE). Messages reference the owning conversation and workspace, preserving tenant isolation and enabling context continuation. Streaming uses the event sequence meta → delta* → done followed by data: [DONE].
LangGraph evolution PLANNED
flowchart LR
subgraph LG["LangGraph State Machine (planned)"]
START[Start] --> COND{guardrails pass?}
COND -->|no| REJ[Reject]
COND -->|yes| RET[Retrieve\nLlamaIndex]
RET --> GEN[Generate / plan]
GEN --> CALL{needs tool?}
CALL -->|yes| TOOL[Execute MCP tool]
TOOL --> GEN
CALL -->|no| CIT[Cite + persist]
CIT --> END[End]
end
- Stateful graphs — replace the linear loop with a declarative state machine: retrieval, planning, tool execution, memory and citations become typed nodes with checkpoints.
- Reusable nodes — each node wraps an existing service (knowledge, MCP, LLMClient), so the current feature set survives the migration.
- Checkpoints — LangGraph checkpoints give resume-from-step and richer executions dashboards.
- Memory — memories table (planned) plugged in as a summarization node.
Loop bound. Agent tool loops are bounded by a maximum iteration count to prevent infinite tool-call cycles and runaway cost. The bound is enforced in the executor, not the tool layer.
07MCP Integration LIVE
The Model Context Protocol (MCP) layer is the platform’s tool surface. It connects servers, enumerates their tools, lets operators enable/disable each tool, and invokes tools through a standardized, audited path. It is also the seam where the platform itself can be consumed as MCP tooling — the MCP SDK route is planned.
Server taxonomy & security gates
| Kind | Transport | Policy | Status |
|---|---|---|---|
| builtin | in-process | Default utility tools shipped by the platform. | LIVE |
| stdio | local subprocess (stdin/stdout JSON-RPC) | Rejected — arbitrary local process execution is out of scope for self-hosting safety. | LIVE (blocked) |
| sse | HTTP + Server-Sent Events (JSON-RPC) | Allowed; server URL must be reachable and tools are enable-gated. | LIVE |
Safety rule. MCP server kind = stdio is explicitly rejected because it would allow the platform to spawn arbitrary OS processes. Remote tool calls are further gated by enable/disable per tool and by per-call audit logging.
Built-in tools
| Tool | Description | Safety posture |
|---|---|---|
| memory_store | Persist a key/value memory entry. | Workspace-scoped writes, audit logged. |
| memory_recall | Read back stored memories. | Workspace-scoped reads only. |
| get_current_time | Return the current date/time. | Read-only, no side effects. |
| calculator | Evaluate arithmetic expressions. | safe_calculate parses with an AST whitelist (arithmetic/numeric ops only). No shell, no OS, no dynamic import. |
Tool call flow
flowchart LR
AGENT["Agent runtime\n(asks for tool)"]
CHK{"tool enabled?"}
GATE["MCP service\nworkspace-scoped lookup"]
COOK["Arguments validated\n+ calculator AST whitelist"]
SSE["SSE JSON-RPC invoke\n(remote server)"]
LOG["Audit log + call_count"]
RES["Result → agent context"]
REJ["Rejected\n430/403 error"]
AGENT --> GATE
GATE --> CHK
CHK -->|no| REJ
CHK -->|yes| COOK
COOK --> SSE
SSE --> LOG
LOG --> RES
Management surface
- Servers — register MCP servers (name + connection details), list and delete; each server is workspace-scoped.
- Tools discovery — GET /api/v1/mcp/tools lists discovered tools with status (enabled/disabled) and call counts.
- Enable / disable — PATCH /api/v1/mcp/tools/{id} flips gates; agents only see enabled tools.
- Invoke — POST /api/v1/mcp/tools/call executes a tool call end-to-end with audit.
MCP SDK PLANNED
Serving the platform itself as an MCP server, plus an mcp-sdk-python companion, is planned. This lets external agents call MageTech knowledge tools over the same protocol — turning the platform into a transitive tool network while keeping the same enable/disable and audit gates.
08Data & Storage Architecture LIVE
PostgreSQL is the system of record for every business entity; Redis holds ephemeral state (rate-limit counters, cache, and the Celery broker) and pgvector is provisioned as an extension for the planned native vector search. All migrations are Alembic-managed (0001_initial → f84138ce8b31).
Live schema inventory
| Table | Purpose | Tenant scope |
|---|---|---|
| users | Auth principals (password hash, status). | global |
| workspaces | Top-level tenant container. | global |
| user_workspace_roles | User ↔ workspace membership + role (RBAC-ready). | per workspace |
| audit_logs | Unmodifiable action trail (§10). | per workspace |
| system_settings | Global configuration key/values. | global |
| knowledge_bases | Root of the RAG domain. | workspace_id |
| documents | Uploaded source files + parse state. | workspace_id |
| document_chunks | Chunk text + embedding + provenance. | workspace_id |
| agents | Agent definitions (prompt, model, params). | workspace_id |
| agent_runs | Execution records: status, tokens, steps. | workspace_id |
| conversations | Chat threads. | workspace_id |
| messages | Chat messages (role, content, tokens). | workspace_id |
| mcp_servers | Registered MCP connections. | workspace_id |
| mcp_tools | Discovered/enabled tools + call_count. | workspace_id |
| models | Model registry for the AI gateway. | workspace_id |
Planned tables PLANNED
roles permissions projects agent_versions agent_tools agent_execution_steps memories token_blacklist subscriptions usage_limits
- token_blacklist — accelerates revocation of leaked/rotated refresh tokens instead of relying on short expiry only.
- subscriptions + usage_limits — meter usage against plan limits (feeds metrics collection).
- agent_execution_steps — per-step trace storage replacing in-blob JSON on runs for queryability.
Entity relationships
erDiagram
users ||--o{ user_workspace_roles : "member of"
workspaces ||--o{ user_workspace_roles : "grants"
workspaces ||--o{ knowledge_bases : "owns"
knowledge_bases ||--o{ documents : "contains"
documents ||--o{ document_chunks : "split into"
workspaces ||--o{ agents : "owns"
agents ||--o{ agent_runs : "executes"
workspaces ||--o{ conversations : "owns"
conversations ||--o{ messages : "contains"
workspaces ||--o{ mcp_servers : "owns"
mcp_servers ||--o{ mcp_tools : "exposes"
agents }o--o{ mcp_tools : "may call (enabled)"
workspaces ||--o{ models : "registers"
Caching & ephemeral state
| Key space | Store | Purpose | Notes |
|---|---|---|---|
| rate-limit:* | Redis (fallback: memory) | Token-bucket counters per key + route. | slowapi. Fallback keeps single-node deploys working without Redis. |
| llm:availability | Redis/in-memory | Provider probe cache (30s TTL). | Avoids hammering Ollama on every request. |
| celery:* | Redis | Task broker (opt-in). | Used when USE_CELERY=true. |
| auth:refresh:* | memory/Redis | Refresh-token deduplication (planned blacklist). | PLANNED |
Migrations
# Apply schema migrations
alembic upgrade head
# New migration
alembic revision --autogenerate -m "describe change"
alembic upgrade headAll schema changes land via Alembic, are reviewed, and the document_chunks storage change (§05) is the flagship planned migration.
09API Design & Integration LIVE
The API is versioned REST (JSON) with OpenAPI 3.1 documentation served by FastAPI at /docs. All endpoints are async, tenant-scoped where applicable, and uniform in error shape, so SDK and UI clients share one integration contract.
Conventions
| Topic | Rule |
|---|---|
| Base URL | /api/v1 prefix; schemas under /api/v1/openapi.json. |
| Auth | Bearer access JWT (Authorization: Bearer <token>); refresh via HttpOnly cookie. |
| Multi-tenancy | X-Workspace-Id header when a route needs a specific workspace (falls back to user’s first membership). |
| Errors | Envelope {"error": {"code": "…", "message": "…", "details": "…"}} via AppError + handler. |
| Status codes | 200 / 201 / 204 / 400 / 401 / 403 / 404 / 409 / 422 / 429 / 500. |
| Rate limits | Auth routes 10/min per key; default routes 200/min. |
| Streaming | SSE on chat/stream and agent runs: meta → delta* → done then data: [DONE]. |
Endpoint inventory
| Router (prefix) | Endpoints |
|---|---|
| auth | register · login · refresh · logout · me |
| users | me · change-password |
| workspaces | list · detail · membership management |
| health | /api/v1/health — checks PG, Redis, Ollama, returns statuses |
| dashboard | aggregated KPIs for the home screen |
| demo | demo-mode data feed (DEMO_DASHBOARD_DATA) |
| knowledge | knowledge-bases CRUD · documents upload/list/detail/chunks/reprocess/delete · search |
| agents | CRUD · runs list · run execute |
| chat | conversations CRUD · messages · chat · chat/stream (SSE) |
| mcp | servers CRUD · tools list · tools PATCH enabled · tools/call |
| models | list · create · sync · pull · delete |
| executions | list (latest 200) · detail |
| usage | ?days=N (7–90) usage analytics |
OpenAPI 3.1 JWT Bearer SSE REST x-workspace-id
Example: authenticated chat
curl -X POST http://localhost:8000/api/v1/chat \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-H "X-Workspace-Id: ws_123" \
-d '{"conversation_id": null, "content": "Summarize our Q3 plan"}'
# → {"id": "msg_…", "role": "assistant", "content": "…", "sources": [...]}Example: streaming response
data: {"type":"meta","model":"qwen2.5:7b"}
data: {"type":"delta","content":"Hell"}
data: {"type":"delta","content":"o there"}
data: {"type":"done","usage":{"prompt_tokens":12,"completion_tokens":34}}
data: [DONE]Contract-first practice. The frontend types every response with Zod and mirrors the OpenAPI schema; a drift between the two fails CI. New endpoints must ship with schema + client types + tests in the same change (§16).
10Security Architecture LIVE
Security is enforced in layers: identity → session → authorization → tenant isolation → rate limiting → audit. The design is fail-closed: unexpected states reject rather than degrade silently.
Authentication flow
sequenceDiagram
participant C as Client (web/API)
participant A as Auth service
participant DB as PostgreSQL
participant RL as Redis rate-limiter
C->>A: POST /auth/login (email + password)
A->>RL: rate-limit check (10/min/key)
A->>DB: fetch user by email
A->>A: verify Argon2id hash
A-->>C: access JWT (15 min, HS256) + refresh JWT
A-->>C: Set-Cookie: refresh (HttpOnly, SameSite=Lax, Path=/api/v1/auth/refresh)
Note over C,A: Access JWT is short-lived, refresh rotates on refresh
C->>A: POST /auth/refresh (cookie)
A->>A: verify refresh JWT, rotate
A-->>C: new access + refresh pair
Measures
| Area | Implementation | Status |
|---|---|---|
| Password storage | Argon2id (memory-hard, side-channel resistant) via argon2-cffi; strict password policy enforced at registration. | LIVE |
| Session tokens | Dual JWT (HS256): access 15 min, refresh 7 days. Separate JWT_SECRET / JWT_REFRESH_SECRET. | LIVE |
| Refresh cookie | HttpOnly, SameSite=Lax, scoped to Path=/api/v1/auth/refresh, not exposed to JS. | LIVE |
| Rate limiting | slowapi + Redis (in-memory fallback): auth 10/min, default 200/min; applies per key & route, returns 429 with Retry-After. | LIVE |
| CORS | Allowlist from CORS_ORIGINS (e.g. http://localhost:3000); credentials allowed only for listed origins. | LIVE |
| Production guard | validate_production() refuses to boot in prod with default/weak secrets or unsafe settings. | LIVE |
| Tenancy | Workspace scoping on every service query; X-Workspace-Id validated against membership. | LIVE |
| Audit log | Auth events, workspace changes, MCP tool calls and document operations write to audit_logs. | LIVE |
| Role-based access | Granular roles/permissions tables and enforcement. | PLANNED |
| Row-level security | PostgreSQL RLS as defense-in-depth under column-level scoping. | FUTURE |
OWASP-oriented checklist
- CSRF — mitigated for state-changing calls by Bearer tokens + SameSite cookie; refresh route is POST-only.
- Injection — SQLAlchemy ORM parameterization everywhere; no raw SQL in services.
- SSRF — MCP remote servers are operator-registered URLs; stdio (local exec) transport rejected.
- Secrets — never logged (structlog redacts headers/secrets); .env never committed; distribution via .env.example.
- Input validation — Pydantic v2 schemas on every route; multipart uploads validated for type/size.
- Rate-limit bypass — limits keyed per client identity + route, applied before auth work.
Refresh rotation note. Fresh rollout pairs are rotated on every refresh; token reuse is audited. A Redis-backed blacklist is planned to harden this further.
11Multi-tenancy LIVE
The platform is multi-tenant by construction. A workspace is the tenant boundary: knowledge bases, documents, agents, conversations, MCP servers and model entries all belong to exactly one workspace.
Model
flowchart TB U["User"] M["memberships\n(user_workspace_roles)"] W["Workspace A"] W2["Workspace B"] KB["knowledge_bases A"] DB["documents A"] AG["agents A"] CV["conversations A"] MC["mcp A"] MD["models A"] U --> M M --> W M --> W2 W --> KB KB --> DB W --> AG W --> CV W --> MC W --> MD W2 -.->|same tables, different workspace_id| X
- Row-level tenancy — every business table carries workspace_id; service queries always filter or join through the workspace.
- Selection — apps send X-Workspace-Id; the API validates membership and falls back to the user’s first workspace when omitted.
- Membership roles — user_workspace_roles already encodes member/owner semantics, ready for granular RBAC enforcement.
- Isolation proof points — knowledge search, agent tool calls, chat history and usage aggregation all scope by workspace; tests assert cross-workspace leakage is impossible (IDOR cases).
Defense in depth
| Layer | Mechanism | Status |
|---|---|---|
| App layer | Workspace-scoped service queries (primary). | LIVE |
| API layer | X-Workspace-Id membership validation on tenant routes. | LIVE |
| DB layer | PostgreSQL RLS policies per tenant. | FUTURE |
tenant boundary = workspace x-workspace-id rbac-ready idor-tested
12Frontend Architecture LIVE
The web application is a Next.js 16 App Router project (TypeScript, Tailwind 4). It is intentionally component-driven, typed, and treats the backend OpenAPI schema as a contract.
Application routes
| Route | Purpose |
|---|---|
| / | Marketing/landing entry. |
| /login | Sign-in (brand wordmark). |
| /register | Account creation. |
| /dashboard | KPI overview (realtime-safe, demo fallback). |
| /chat | Conversational Q&A with SSE streaming. |
| /agents | Agent CRUD + run console. |
| /executions | Agent-run history (list/detail). |
| /knowledge | Knowledge bases list. |
| /knowledge/documents | Document upload/manage per KB. |
| /mcp | MCP server registry. |
| /mcp/tools | Tool discover/enable/disable + stats. |
| /models | Model registry & pulls. |
| /usage | Token/model usage charts (recharts). |
| /settings/profile | Account settings. |
| /settings/security | Password / sessions. |
| /settings/system | System-level configuration. |
Key patterns
🧩 Components
shadcn-style primitives hand-rolled on Tailwind (no Radix runtime dependency) — cva for variants, clsx/tailwind-merge for composition. All brand-styled but themeable by design tokens.
🔁 Server state
TanStack Query handles fetching, caching and invalidation; mutations typed with Zod. SSE chat streams are consumed via a reader hook that appends delta events live.
📝 Forms
react-hook-form + Zod resolver; schemas mirror the API so server validation rarely surprises the UI.
🌗 Theming
next-themes drives a dark-by-default brand theme (with light mode); design tokens in CSS variables keep the MageTech palette (#6366F1, #22D3EE, #8B5CF6, #080B14) consistent.
🧭 Guards & layout
Auth-guarded route groups, shared sidebar/topbar under the app shell, and a distinct auth layout for login/register.
🧪 Testability
Vitest + Testing Library for pure logic and components; Playwright E2E at the workspace root for critical journeys (§16).
Folder conventions
apps/web/src
app/ # App Router pages + layouts
components/ # ui/ primitives + feature components
lib/ # api client, queries, utils
hooks/ # shared hooks (e.g. SSE reader)
schemas/ # Zod mirrors of API contracts
styles/ # global CSS + design tokensAccessibility baseline
- Semantic landmarks, skip-link, keyboard-focusable controls, aria-label on icon buttons.
- Contrast meets WCAG AA in both themes; focus-visible ring states.
- Reduced-motion respected via prefers-reduced-motion.
13Backend Architecture LIVE
The API is a layered async FastAPI application. Dependencies flow one way: routers → services → repositories → domain, with infrastructure (db, redis, rate limits) and core (config, security, errors, logging) available to any layer.
Layers
flowchart LR R["api/v1 routers\n(auth, chat, agents, knowledge,\nmcp, models, usage, dashboard…)"] DEP["deps — auth, tenant, pagination"] S["services\n(llm_client, document_parser, knowledge,\nchat, agents, mcp, models, usage…)"] REP["repositories\ndata access (SQLAlchemy)"] DOM["domain\nschemas + entities (Pydantic/SQLAlchemy)"] INFRA["infrastructure\ndb engine, redis, rate_limit"] CORE["core\nconfig, security, errors, logging, constants"] W["worker\ncelery_app + tasks"] R --> DEP --> S --> REP --> INFRA S --> DOM CORE --> S W --> S INFRA --> DB[(PostgreSQL / Redis)]
Module responsibilities
| Module | Responsibility |
|---|---|
| api/v1/* | HTTP binding: validation, auth/tenant dependencies, serialization, SSE streaming. |
| deps/* | Resolve current user, workspace, file uploads; enforce rate limits. |
| services/* | Business logic — the only place allowed to coordinate multiple repositories or call LLM/MCP. |
| repositories/* | Query construction and persistence; always tenant-scoped. |
| domain/* | Typed schemas (requests/responses) and ORM entities. |
| core/* | config.py (pydantic-settings), security.py (JWT, Argon2id, production guard), errors.py (AppError + handlers), logging.py (structlog), constants.py. |
| worker/* | Celery app + documents.process task (opt-in with USE_CELERY). |
Execution & resilience
- Async everywhere — async SQLAlchemy (asyncpg), async Redis, httpx.AsyncClient for Ollama/MCP; pool size=10, max_overflow=20, pool_pre_ping to dodge dead connections.
- Uniform errors — AppError → status +
{"error":{...}}; unexpected exceptions are caught, logged with stack, and mapped to 500 without leaking internals. - Streaming — StreamingResponse yields SSE frames with
meta → delta → done → [DONE]; clients treat connection/llm errors as structured error events. - Graceful degradation — rate limiting falls back to in-memory when Redis is down; providers fall back to mock when Ollama is unreachable; health endpoint reports each dependency’s state independently.
- Background work — long ingestion can move to Celery (USE_CELERY=true) without changing the API contract.
Team rule. Routers never contain business logic beyond binding; services never import vendor SDKs directly; repositories never leak raw sessions into routes. CI enforces these boundaries with tests and ruff.
14Codebase & Conventions LIVE
The repository is a workspace monorepo that separates the web client, the API, infrastructure definitions and documentation so each can evolve with its own toolchain.
Repository layout
Magetech-aiforge/
apps/
web/ # Next.js 16 client
api/ # FastAPI service
infrastructure/
docker/ # compose, env template
postgres/ # init.sql (extensions)
document/ # how-it-works.html, this doc
docs/ # ARCHITECTURE.md, ROADMAP.md, DEVELOPMENT.md
tests/e2e/ # Playwright specs
package.json # root scripts (lint, test, e2e, build)
AGENTS.md # coding-agent rulesQuality gates
| Gate | Command | Scope |
|---|---|---|
| Type check (web) | npx tsc --noEmit | No type errors. |
| Lint (web) | npm run lint | ESLint 0 errors/warnings. |
| Test (web) | npx vitest run | 14/14 unit+component tests green. |
| Build (web) | npm run build | Production build (19 static routes). |
| Lint+format (api) | ruff check . && ruff format --check . | PEP8-adjacent, import sorting. |
| Test (api) | pytest | Unit + integration (async) suite. |
| E2E | npm run test:e2e | Playwright critical journeys. |
Style rules
- TypeScript strict; types never substituted with
anyin app code. - Backend: ruff-format default, no unused imports, docstrings on public modules.
- Migrations always paired with their schema test or at least an idempotence check.
- New API surface ships with OpenAPI-visible examples and a Zod mirror in the web app.
- No secrets in code; environment via .env.example only.
Agent-assisted development. The repo ships AGENTS.md instructions so AI coding agents follow the same conventions (e.g. consult Next.js local docs before framework changes, keep theme/six-core palette constants in one module).
15Infrastructure & DevOps LIVE
The distribution story is one command: docker compose up brings up the full local-first stack. Environments are configured through typed env vars with sensible defaults and production guards.
Compose topology
flowchart LR
N["nginx/proxy (edge)"]
FE["frontend\nNext.js (port 3000)"]
API["backend\nuvicorn (port 8000)"]
W["worker\ncelery (optional)"]
PG[("postgres\npgvector:pg16 / :5433")]
RD[("redis\n7-alpine / :6380")]
OL["ollama\n:11434"]
N --> FE
N --> API
API --> PG
API --> RD
API --> OL
API --> W
W --> RD
W --> OL
PG --> OL
Services
| Service | Image / Command | Port | Healthcheck |
|---|---|---|---|
| postgres | pgvector/pgvector:pg16 | 5433 | pg_isready |
| redis | redis:7-alpine | 6380 | redis-cli ping |
| ollama | ollama/ollama | 11434 | tag endpoint probe |
| backend | uvicorn app.main:app | 8000 | /api/v1/health |
| worker | celery worker (opt-in) | - | task ping |
| frontend | next start | 3000 | HTTP readiness |
init.sql runs on first boot and provisions extensions: vector pgcrypto uuid-ossp. All data lives in named Docker volumes (or the host for local native dev).
Environment configuration
APP_ENV=dev
DATABASE_URL=postgresql+asyncpg://…
REDIS_URL=redis://…
CELERY_BROKER_URL=redis://…
JWT_SECRET=change-me-in-prod
JWT_REFRESH_SECRET=change-me-in-prod
JWT_ACCESS_TOKEN_EXPIRE_MINUTES=15
JWT_REFRESH_TOKEN_EXPIRE_DAYS=7
CORS_ORIGINS=["http://localhost:3000"]
RATE_LIMIT_AUTH=10/min
RATE_LIMIT_DEFAULT=200/min
SEED_ADMIN_EMAIL=admin@magetech.com
SEED_ADMIN_PASSWORD=ChangeMe_Admin_123!
LLM_PROVIDER=auto
OLLAMA_BASE_URL=http://localhost:11434
COOKIE_SECURE=false
USE_CELERY=false
MAX_DOCUMENT_CHARS=2000000
CHUNK_SIZE=800
CHUNK_OVERLAP=160
DEMO_DASHBOARD_DATA=trueProduction rule. validate_production() aborts startup if APP_ENV=production ships with default secrets, non-Secure cookies, or an empty CORS allowlist. Rotate SEED_ADMIN_PASSWORD before first prod boot.
Operations & future FUTURE
- Backups — daily pg_dump + WAL archiving; restore drill documented in runbook.
- Upgrades — rolling compose pull + alembic upgrade head under maintenance window.
- Progressive rollout — manual npm/pypi publish path today; CI/CD with build pipeline, image registry and canary deploys (FUTURE).
- Orchestration — Kubernetes manifests for multi-node scale with HA Postgres and Redis (FUTURE).
16Testing & Quality LIVE
Testing is layered: fast unit tests exercise pure logic, integration tests exercise the API against real infrastructure, and E2E tests prove journeys in a browser. Every layer is part of the merge gate.
Test pyramid
flowchart TB E2E["E2E — Playwright (root tests/e2e)\nauth → chat → knowledge → MCP"] INT["Integration — pytest + pytest-asyncio\nAPI + async SQLAlchemy + Redis\n(workspace/tenant isolation, IDOR cases)"] UNIT["Unit — pytest (api) + Vitest (web)\nschemas, security, parser, hooks, components"] E2E --> INT --> UNIT
| Layer | Tooling | What it proves |
|---|---|---|
| Unit | pytest + Vitest / Testing Library | Password hashing, JWT round-trip, chunking math, safe_calculate whitelist, Zod schema parses, component render. |
| Integration | pytest-asyncio, httpx ASGI client | Auth flows, tenant scoping, knowledge search ranking, agent run lifecycle, MCP tool gating, rate limiting (429), error envelope shape. |
| E2E | Playwright | Login → dashboard, upload → KB → chat answer, agent run visible in executions, theme toggle persistence. |
Coverage & quality targets
- API business services ≥ 85% line coverage; routers bound by integration contract tests.
- Web: every Zod schema has a positive + negative parse test; every query hook has a mocked-data test.
- Security: explicit tests for login brute-force (429), IDOR cross-workspace access, stdio MCP rejection, default-secret prod guard.
- Deterministic AI tests: mock provider guarantees stable output — no flaky model-dependent assertions.
- Contract: OpenAPI schema + Zod mirrors checked in CI for drift.
Current green baseline. Web suite: 14/14 Vitest passing; tsc --noEmit clean; ESLint 0 warnings; production build succeeds (19 static routes). API suite and Playwright journeys pass in CI before release.
17Observability & AgentOps LIVE
Every request, LLM call and agent step is observable. The design makes debugging, cost attribution and audit straightforward from a single log stream plus the audit and usage stores.
Structured logging
{"event":"chat.completed","level":"info","request_id":"r8f1…",
"workspace_id":"ws_123","model":"qwen2.5:7b",
"prompt_tokens":12,"completion_tokens":34,"duration_ms":812}- structlog emits JSON in production, readable console in dev; secrets/headers redacted.
- Every request tagged with request_id so logs, audit rows and traces join.
- LLM calls logged with model, token counts and latency — the raw material for AgentOps dashboards.
Telemetry surfaces
| Surface | Contents | Status |
|---|---|---|
| Health endpoint | Per-dependency status (PG, Redis, Ollama) + app version. | LIVE |
| Usage analytics | Token totals and per-model breakdown for ?days=7..90. | LIVE |
| Executions | Agent runs list + step detail (status, duration, tokens). | LIVE |
| Audit log | Immutably-appended security/ops events. | LIVE |
| Metrics endpoint | Prometheus-compatible counters/histograms. | PLANNED |
| Tracing | OpenTelemetry spans across services/LLM calls. | FUTURE |
| Cost analytics | Per workspace/month cost from token+model accounting. | PLANNED |
AgentOps practice
Agent runs persist the full step trace, status transitions and token use. This is the debugging foundation for “why did the agent do that?” and feeds evaluation datasets for prompt/safety regression testing — bridging §16 and §19.
18Performance & Scalability LIVE
Performance budgets apply end-to-end: the LLM call dominates latency, so everything else is minimized and cached.
Techniques in play
| Technique | Detail | Status |
|---|---|---|
| Async I/O | asyncpg + async Redis avoid thread-blocking under LLM wait times. | LIVE |
| Connection pooling | Pool 10 / overflow 20 / pool_pre_ping. | LIVE |
| Provider caching | 30s availability cache avoids repeated Ollama probes. | LIVE |
| Chunk streaming | SSE streams tokens as produced; TTFB ~ first token, not first answer. | LIVE |
| Bounded ingestion | MAX_DOCUMENT_CHARS cap bounds embedding time per document. | LIVE |
| Rate limits | Per-key limits protect the single-node default from oversubscription. | LIVE |
| Vector index | pgvector ANN index replaces brute-force cosine at scale. | PLANNED |
| Response caching | Redis keyed question+KB cache for hot queries. | PLANNED |
| Horizontal scale | Stateless API nodes behind proxy; Redis-backed limits; K8s rollout. | FUTURE |
| GPU inference pool | Dedicated Ollama/kserve nodes to cut per-token latency. | FUTURE |
Latency budget (p95, local single node)
| Path | Budget | Dominant cost |
|---|---|---|
| Auth (login) | < 300 ms | Argon2id verification. |
| RAG search | < 700 ms | Query embed + top-k cosine over KB chunks. |
| Chat (non-stream) | model-bound | Ollama generation; TTFB optimized by streaming. |
| Document ingest (1 MB PDF) | < 15 s | Parse + chunk + embed (may move async). |
| Agent run (tooled) | model-bound | Multi-turn loop; bounded by max iterations. |
Scaling guidance
- Phase 1 — tune pool size, enable USE_CELERY for ingestion offload.
- Phase 2 — migrate chunks to native pgvector + HNSW index (§05).
- Phase 3 — horizontal API replicas behind the proxy with Redis-backed limiting; separate model nodes (§21).
19AI Safety, Ethics & Governance PLANNED
Safety is designed in at the architecture level — not bolted on at prompt time. The current release already contains several hard safety properties; the governance surface grows with the roadmap.
Hard safety properties (live)
- No arbitrary execution — the only code-executing tool (calculator) uses an AST whitelist; MCP stdio transport is rejected; no tool can spawn shell/OS processes.
- Grounded answers — RAG system prompt constrains the model to supplied chunks with source citations; hallucinations are structurally reduced, and retrieval sourcing makes answers checkable.
- Tenant isolation — an agent in workspace A cannot retrieve from workspace B; verified by IDOR tests.
- Loop bounds — agent tool loops are capped; runaway cost/behavior is impossible by construction.
- Audit trail — every tool invocation and privileged action is recorded in audit_logs.
Governance roadmap
| Capability | Description | Status |
|---|---|---|
| Content policy filter | Input/output allow-deny policy applied at the gateway before/after generation. | PLANNED |
| PII redaction | Detect and redact PII in stored chunks/messages and outbound answers. | PLANNED |
| Human-in-the-loop | Require approval gates for high-risk agent actions (deletes, external sends). | PLANNED |
| Model evaluation harness | Golden-set eval over RAG/agent prompts; regression runs before releases. | PLANNED |
| Model card & provenance | Per-model cards (license, data, latency, safety notes) in the registry. | FUTURE |
| Explainability panel | UI surfacing of retrieved chunks, tool calls and reasoning for every answer. | FUTURE |
| Usage & consent policy UI | Tenant-facing data/retention and consent controls. | FUTURE |
Operational safeguards
- Evaluation before rollout — new models/providers pass the eval harness and a safety checklist before being suggested to tenants.
- Incident runbook — prompt-injection/sensitive-data incidents follow the audit trail from request_id to responsible workspace.
- Documented limits — per-tenant usage caps (planned usage_limits) stop unbounded spend before it begins.
Local-first = data governance. Keeping inference on customer hardware is itself a governance win: raw knowledge and prompts never leave the deployment boundary in the default configuration.
20Integrations & Extensibility PLANNED
MageTech AI Forge is built to interoperate. Today MCP is the extensibility spine (§07); the next layers are webhooks, domain APIs and an SDK/plugin model.
Integration layers
flowchart LR APP["MageTech AI Forge"] WC["Webhooks (planned)\nevents: document.processed, agent.completed,\nrun.failed, usage.threshold"] OAU["OAuth2 2-legged (planned)\nservice-to-service, scoped tokens"] MCP["MCP SDK (planned)\nserve platform tools to external agents"] SF["ServiceFlow / CRM\n(Typeform, Make, Pipedrive, Jotform…)"] EXT["Plugin registry (future)"] APP --> WC APP --> OAU APP --> MCP APP --> SF APP --> EXT
Planned capabilities
| Feature | Scope | Status |
|---|---|---|
| Webhook events | Signed HMAC deliveries, retries with backoff, delivery log; events for documents, agents, runs, usage thresholds. | PLANNED |
| OAuth2 2-legged | Service tokens scoped to workspace + capabilities, short-lived + refresh, full audit. | PLANNED |
| MCP SDK (server) | Expose knowledge search/agents as MCP tools to external agents; reuses enable/disable + audit. | PLANNED |
| ServiceFlow / CRM connectors | Typeform/Jotform intake → KB, Make/Pipedrive automation triggers (workflow-driven RAG ops). | PLANNED |
| Plugin registry | Installable packages adding tools, providers or UI extensions. | FUTURE |
| ai-gateway service | Standalone model-routing gateway consumed by all connectors. | FUTURE |
Extensibility principles
- Every new connector lands behind the existing seams: LLMClient (AI), MCP (tools), webhooks (events), API (data).
- External calls are always tenant-scoped, authenticated and audit-logged.
- No connector shall require modifying core services — they compose, never fork.
21Roadmap & Milestones PLANNED
The roadmap is phased so each milestone is shippable and independently valuable. Status badges in this section reflect the docs/ROADMAP.md plan: the MVP (Phases 1–2) is largely live; Phase 3 (LlamaIndex) and Phase 4 (LangGraph) are the next planning targets; Phase 5 (MCP SDK) and Phase 7 (managed providers + ai-gateway) prepare for hosted scale.
Milestones
| Milestone | Content | Status |
|---|---|---|
| MVP-1 | Auth (JWT + argon2id), workspaces, RAG pipeline (upload→embed→chat), dashboard, streaming chat. | LIVE |
| MVP-2 | Agents + runs + executions, MCP server/tool management, usage analytics, multi-model registry. | LIVE |
| MVP-3 | RBAC enforcement, settings system, refresh-token blacklist, demo mode polish, E2E coverage expansion. | PLANNED |
| MVP-4 | Native pgvector search, document update/reprocess UX, webhook delivery, OAuth2 2-legged tokens. | PLANNED |
| Phase 4 | LangGraph agent graphs (state machine, checkpoints, memory), LlamaIndex orchestration for indexing/analyses. | PLANNED |
| Phase 5 | MCP SDK: expose platform tools to external agents; mcp-sdk-python companion. | PLANNED |
| Phase 7 | Managed providers (OpenAI/Gemini/Anthropic) behind LLMClient, ai-gateway service, hosted offering. | FUTURE |
Timeline view
timeline
title MageTech AI Forge Roadmap
2025 : Research & architecture prototype
: Provider gateway + RAG spike
2026 : MVP-1 — auth, workspaces, RAG chat (LIVE)
: MVP-2 — agents, MCP, usage analytics (LIVE)
: MVP-3 — RBAC, blacklist, E2E expansion (PLANNED)
: MVP-4 — pgvector, webhooks, OAuth2 (PLANNED)
2027 : Phase 4 — LangGraph + LlamaIndex (PLANNED)
: Phase 5 — MCP SDK (PLANNED)
: Phase 7 — managed providers, ai-gateway (FUTURE)
Dependencies
- pgvector migration (MVP-4) depends on the extension already provisioned in init.sql.
- LangGraph (Phase 4) reuses current agent domain models and MCP tool layer — no data migration.
- Webhooks (MVP-4) precede OAuth2 connectors so external systems can subscribe first.
- Managed providers (Phase 7) require eval harness (§19) to be in place.
22Production Readiness Checklist PLANNED
Use this checklist as the release gate for any environment labelled production. Items marked LIVE are already enforced; others are required before go-live.
Deploy & config
- Rotate SEED_ADMIN_PASSWORD and set unique JWT_SECRET/JWT_REFRESH_SECRET (enforced by validate_production()).
- Set COOKIE_SECURE=true and a locked-down CORS_ORIGINS allowlist.
- Enable TLS termination at the proxy; redirect HTTP → HTTPS; HSTS headers.
- Pin service image versions and alembic upgrade head as part of the release step.
- Configure daily pg_dump backups + WAL archiving; test a restore.
Security
- Run the §10 checklist (rate limits, CORS, credentials hygiene, Argon2id, Scrypt verification path).
- Verify MCP servers have no stdio servers and only intended SSE endpoints enabled.
- Limit MAX_DOCUMENT_CHARS/upload sizes to bound ingestion cost.
- Set per-tenant usage limits and monitor the usage dashboard for anomalies.
- Pen-test: authentication, IDOR across workspaces, SSRF via MCP URLs, prompt-injection paths.
AI / RAG quality
- Baseline eval over a golden question set (retrieval hit-rate, answer faithfulness).
- Validate citation rendering end-to-end (chunk → answer → source link).
- Confirm provider fallback behaves (mock) so outages degrade loudly, not silently.
Operations
- Alert on /api/v1/health non-200, 429s, worker stagnation, and Ollama restarts.
- Drill the incident runbook using request_id → logs → audit → executions.
- Capacity plan: shred CPU/GPU headroom, Redis memory, and pgvector scale limits (§18).
Go/no-go. A production environment must pass every unchecked item above in a review before serving real tenants; this section becomes the checkbox artifact of that review.
23Glossary LIVE
| Term | Definition |
|---|---|
| RAG | Retrieval-Augmented Generation — retrieval of relevant knowledge before the model composes an answer, with citations. |
| Chunk / chunking | Splitting documents into overlapping text segments (800 chars / 160 overlap) for embedding and retrieval. |
| Embedding | Dense vector representation of text (nomic-embed-text, 384-dim) enabling similarity search. |
| Cosine similarity | Metric used to rank query-chunk relevance on stored vectors. |
| pgvector | PostgreSQL extension for vector storage and approximate-nearest-neighbor indexing. |
| Agent run | A bounded execution of an agent: generation loop, optional tool calls, recorded steps and tokens. |
| MCP | Model Context Protocol — JSON-RPC standard for exposing tools/context to models (SSE transport). |
| SSE | Server-Sent Events — HTTP streaming used for token/step streaming (meta → delta → done). |
| Workspace | The tenant boundary; isolates knowledge, agents, conversations, tools and models. |
| Access token / refresh token | Short-lived JWT (15 min) plus rotating HttpOnly-cookie refresh JWT (7 days). |
| Argon2id | Memory-hard password-hashing function used for credential storage. |
| Rate limiting (slowapi) | Token-bucket limiting per client key/route (auth 10/min, default 200/min). |
| LLMClient | Provider-gateway service that isolates the platform from model vendor SDKs. |
| LangGraph | Library for stateful agent graphs (planned orchestration layer). |
| LlamaIndex | Library for indexing/retrieval orchestration (planned). |
| eval_count | Ollama-reported completion token count used for token accounting. |
| OpenAPI | Machine-readable API contract exposed at /docs (3.1). |
24Pricing INDICATIVE
We price AI Forge as an AI engineering & agentic platform — not a chatbot. Local LLM inference is included when you run with your own infrastructure; third-party model costs are billed separately by the respective provider. Prices are indicative USD list prices.
Monthly billing · convert to annual for 2 months free on paid plans.
For developers, students, experimentation and POCs.
- 1 user · 1 project
- Local LLM / Ollama + Knowledge Base
- Basic RAG · PDF / DOCX / TXT / MD upload
- Basic AI Chat · basic embeddings
- 3 AI agents · 3 MCP tools
- Basic conversation memory
- Self-hosted Docker deployment · Community support
- MageTech AI Forge branding
For individual developers and AI builders.
- Everything in Community
- 5 projects · 1–3 users
- Unlimited knowledge bases
- 25 agents · 25 MCP tools
- Advanced RAG · agent memory
- LangGraph workflows · agent execution history
- Agent testing · API access · AI Gateway
- Document source citations · Basic AgentOps
- Custom prompts · Email support
For teams building internal AI applications together.
- Everything in Developer
- 10 users · 20 projects · unlimited agents & MCP tools
- Advanced AgentOps · team collaboration
- Role-based access (Admin / Manager / Developer / Viewer)
- Shared knowledge bases · advanced memory
- Agent execution monitoring · audit logs
- MCP permissions / allowlists · API + webhooks
- Multiple AI providers · advanced RAG
- Priority support
For companies building internal AI applications and business agents at scale.
- Everything in Team
- 25 users · unlimited projects, KBs, agents, MCP tools
- Advanced AgentOps · advanced RBAC · audit trail
- SSO · advanced security controls
- Private AI Gateway · multiple LLM providers
- Custom MCP & business-system integrations
- Usage analytics · advanced monitoring
- Custom retention policies · deployment assistance
- Priority support
For larger organizations requiring private AI infrastructure and full control.
- Unlimited users & projects
- Private / on-premise / Kubernetes deployment
- Dedicated AI infrastructure · private local LLM environment
- Custom MCP servers & custom integrations
- SSO / SAML · advanced RBAC · audit logs
- Security reviews · data-retention policies
- Dedicated support · SLA · architecture consultation
- Custom onboarding · custom contract / invoicing
AI model usage. Local LLM inference is included when you run MageTech AI Forge with your own infrastructure (Ollama). Third-party model/API costs are billed separately by the respective provider — we do not bundle or inflate cloud inference into platform pricing.
| Feature | Community | Developer | Team | Business | Enterprise |
|---|---|---|---|---|---|
| Monthly | $0 | $29 | $99 ⭐ | $249 | Custom |
| Users | 1 | 3 | 10 | 25 | Unlimited |
| Projects | 1 | 5 | 20 | Unlimited | Unlimited |
| Knowledge bases | 1 | Unlimited | Unlimited | Unlimited | Unlimited |
| Agents | 3 | 25 | Unlimited | Unlimited | Unlimited |
| MCP tools | 3 | 25 | Unlimited | Unlimited | Unlimited |
| RAG | Basic | Advanced | Advanced | Advanced | Custom |
| AgentOps | Basic | Basic | Advanced | Advanced | Enterprise |
| Memory | Basic | Yes | Yes | Yes | Yes |
| API access | — | Yes | Yes | Yes | Yes |
| RBAC | — | Basic | Yes | Advanced | Enterprise |
| SSO | — | — | — | Yes | Yes |
| Audit logs | — | — | Yes | Yes | Yes |
| Private deployment | Yes | Yes | Yes | Yes | Yes |
| On-premise | — | — | — | — | Yes |
| Support | Community | Priority | Priority | Dedicated |
A clean progression: Free → Developer → Team → Business → Enterprise. Free for POCs, Team is the sweet spot for most teams, Business adds SSO and scale, Enterprise is fully private and on-premise. We keep the public tier structure simple and add self-hosted licensing separately.
25Self-Hosted Licensing & India Pricing INDICATIVE
Because self-hosting is core to AI Forge, we separate the software license from your infrastructure. You bring the hardware (GPU/CPU, PostgreSQL, Redis, Ollama or local models, storage, networking); we provide the software and support. Prices are indicative USD list prices; INR is an approximate regional equivalent.
Self-hosted software licensing
| Edition | Price | What you get |
|---|---|---|
| Community | Free | Self-hosted Docker, Community support |
| Developer License | $299 / year | Email support, commercial use |
| Team License | $999 / year | Priority support, MCP allowlists, audit logs |
| Business License | $2,499 / year | SSO, advanced RBAC, deployment assistance |
| Enterprise | Custom | On-prem, SLA, dedicated support, security reviews |
MageTech provides the AI Forge software and support under the license; you own and operate your infrastructure.
India pricing (INR)
| Plan | USD | Approx. INR |
|---|---|---|
| Community | $0 | ₹0 |
| Developer | $29 / mo | ₹2,499 / mo |
| Team | $99 / mo | ₹8,499 / mo |
| Business | $249 / mo | ₹20,999 / mo |
| Enterprise | Custom | Custom |
India pricing shown is indicative and subject to confirmation. Annual billing applies where noted.
Why separate pricing? It keeps economics safe: local inference is included on your own infrastructure, cloud inference is metered by the provider, and the software license is priced like the AI infrastructure market — open core at the base, enterprise capabilities and support sold separately.