Documentation Index
Fetch the complete documentation index at: https://mintlify.com/joseluis-dev/harness-ai/llms.txt
Use this file to discover all available pages before exploring further.
Harness AI is organized into nine technology layers, each with a clearly bounded responsibility. No layer performs work that belongs to another — the BFF never runs heavy processing inside an HTTP request, the runtime never authenticates clients directly, and the auth service never carries business logic. This document describes each layer, its chosen technologies, and its operational constraints as implemented in the monorepo.
Layer 1 — BFF and Institutional Web Application
The public-facing web application and backend-for-frontend is built with Astro SSR running in server-capable mode. React islands are used only where true client-side interactivity is necessary; everything else is server-rendered.
| Technology | Role |
|---|
| Astro (SSR) | Web portal, API routes, Astro Actions for backend operations |
| TypeScript | All BFF application logic |
| Zod | Request/response validation at every API boundary |
| Tailwind CSS | Only CSS standard — integrated via official Astro plugin; global CSS imported from the layout |
Environment variable rule: PUBLIC_* variables may reach the client bundle. SERVER_* and API_* variables are server-only. No secret or key of any kind travels to the browser.
Responsibilities:
- Web portal and institutional chat interface
- Internal API endpoints consumed by the frontend
- Execution status and approval views
- Integration with n8n via signed webhooks
- Connection to the Python runtime via internal API or queue
- Delegation of all external authentication to
mcp-auth-service
The BFF is intentionally kept thin. No heavy processing (RAG, embeddings, document ingestion, agent execution) runs inside an Astro request handler. All such work is dispatched to the Python runtime.
Layer 2 — Admin Panel (Internal Network Only)
The admin panel is a separate Astro application (apps/admin-panel) that runs only on the internal network, never sharing a public port with the BFF.
| Technology | Role |
|---|
| Astro (SSR server-capable) | Dynamic internal views — paginated listings, live approval queues |
| Tailwind CSS | Only CSS standard, same rules as the BFF |
auth-sdk | Consumes mcp-auth-service and policy_library with admin-scoped tokens |
The same PUBLIC_* vs SERVER_*/API_* environment variable rule applies here. The admin panel never exposes secrets to the browser.
Responsibilities:
- CRUD for agents, tools, OAuth clients, scopes, prompts, and policies
- Activation, deactivation, and versioning of
tool_registry rows
- Full change history with audit trail
- OAuth client lifecycle (create, suspend, revoke, rotate secrets)
The admin panel is network-isolated with an IP/VPN allowlist. It must never be exposed on a public port. Static-only output is prohibited for any view that involves mutations or live state.
Layer 3 — Python Runtime
The internal execution engine runs in Python and handles all compute-intensive work that must stay off the HTTP request path.
| Technology | Role |
|---|
| FastAPI | Optional internal API endpoints for private communication |
| RQ + Redis | Background worker queue and task broker |
| LangGraph | Complex stateful workflows only (multi-step, decisions, retries, human-in-the-loop) |
| Pydantic v2 | Contracts and validation for all internal data models |
| SQLAlchemy async / asyncpg | Async PostgreSQL access |
| Watchdog / watchfiles | Directory watchers for document ingestion |
Responsibilities:
- Agent and workflow execution
- RAG pipeline and vector embedding generation
- Document processing (extraction, chunking, vectorization)
- Tool resolution by name from
tool_registry — no hardcoded lists
- CLI runner (parameterized, audited, sandboxed)
- File watchers for institutional document directories
- Communication with vLLM via the Model Gateway
- Detailed technical audit logging
Every tool — MCP server, CLI wrapper, HTTP adapter, or webhook — is described in tool_registry and resolved by name at runtime. The runtime and the gateway carry no hardcoded tool lists.
| Tool type | type value | transport value | Examples |
|---|
| MCP over HTTP | mcp_http | oauth | mcp-readonly-sql, mcp-identity-connector, mcp-document-registry, mcp-expedientes, mcp-reportes, mcp-notificaciones |
| MCP over stdio | mcp_stdio | command | Local stdio-based MCP servers |
| CLI wrapper | cli | command | cli-pdf-tools, cli-ocr-tools, cli-office-converter |
| HTTP / API adapter | http_api | api | External REST integrations |
| Inbound webhook | webhook_in | webhook | Event triggers from external systems |
| Outbound webhook | webhook_out | webhook | Notifications dispatched to external systems |
Seeds registered at Phase 0.b (inserted via Alembic migration 0002_tool_registry_seed):
mcp-readonly-sql — read-only SQL over allowlisted views
mcp-identity-connector — institutional identity/actor lookup
mcp-document-registry — document metadata catalog
mcp-expedientes — municipal case-file lookup
mcp-reportes — report runner
mcp-notificaciones — external notification dispatch
cli-pdf-tools — PDF processing utilities
cli-ocr-tools — OCR extraction utilities
cli-office-converter — Office document format conversion
Future integrations (cloud ERPs, external APIs, notification providers) are added as new rows in tool_registry without any change to harness-core.
Layer 5 — Data
Harness AI uses two isolated PostgreSQL databases, a Redis instance, and object storage. These four stores must never be cross-connected.
| Store | Purpose |
|---|
harness_db (PostgreSQL + pgvector) | Business data: executions, audit_events, embeddings, RAG, policy_library, model_prompts. Sole writer: Python runtime. |
harness_auth_db (PostgreSQL, separate instance) | Auth plane: oauth_clients, oauth_scopes, oauth_tokens, oauth_policies, tools (the tool_registry), tool_operations, permissions, agent_permissions, issued_tokens, revoked_tokens, audit_auth_events, tool_execution_logs, security_events. Sole writer: mcp-auth-service. |
| Redis | Worker queue broker (RQ) and operational cache |
| NAS / MinIO | Raw document storage for institutional files |
harness_db and harness_auth_db run on separate Compose services with separate volumes, separate credentials, and separate Alembic version tables (alembic_version and alembic_version_auth respectively). Migrations for each database live in separate directories and must never be merged.
Layer 6 — Centralized Authorization
Authorization is handled by a dedicated service and a shared SDK. No MCP, CLI wrapper, or integration implements its own auth logic.
| Component | Location | Role |
|---|
mcp-auth-service | apps/mcp-auth-service | OAuth 2.1-compatible. Issues and validates Bearer tokens via Client Credentials. Exposes /oauth/token, JWKS endpoint, and introspection. Manages clients, scopes, and policies. |
auth-sdk | packages/auth-sdk | Shared library in TypeScript and Python. Used by every MCP server, CLI wrapper, runtime service, webhook handler, and the admin panel to validate tokens, handle refresh, and report decisions. |
Key constraints:
- No auth by MCP — any component that implements its own OAuth flow instead of using
auth-sdk is a prohibited pattern.
- No public client self-registration — clients are created explicitly through the admin panel or via a versioned migration. There is no open registration endpoint.
- All token transmission uses
Authorization: Bearer. Tokens in query strings are unconditionally prohibited.
Layer 7 — AI Models
| Component | Role |
|---|
| vLLM | Local model server. The primary and initial model backend. |
| Model Gateway | Internal routing layer. Initially routes all requests to vLLM. External providers are added only in final phases under explicit policy. |
The Model Gateway is the only component that speaks to model backends. The runtime and agents call the gateway; they have no direct model connection.
Layer 8 — Deployment
| Technology | Role |
|---|
| Docker | Container runtime for all services |
| Docker Compose | Local and production service orchestration |
| Dokploy | Reproducible production deployment management |
| GitHub Actions | CI/CD pipeline |
Every service ships as a Docker-ready image. No hardcoded secrets in any image or Compose file — all sensitive values are injected via environment variables. Private inter-service networks are declared per service. Persistent volumes are attached for stateful services.
Minimum operator tooling requirements:
| Tool | Minimum version |
|---|
| Docker | 24+ |
| Docker Compose | v2 |
| Node.js | 20+ |
| Python | 3.12+ |
| pnpm | 9+ |
Layer 9 — External Automation (n8n)
n8n is integrated via signed webhooks only. It is not the system orchestrator and has no direct authority over the harness internals.
- n8n fires events, receives notifications, and coordinates simple external tasks.
- n8n authenticates to
mcp-auth-service as a standard technical client — not as a special case.
- n8n must not connect directly to any harness database.
- n8n must not invoke MCP servers or CLI tools without going through Harness Core.
Monorepo Structure
The entire system lives in a single monorepo with the following layout:
harness-ai/
apps/
harness-core/ # BFF + institutional control plane (Astro SSR)
admin-panel/ # Internal admin panel (Astro SSR + Tailwind)
mcp-auth-service/ # OAuth 2.1 authorization service
mcps/ # In-monorepo MCP servers (tool_registry seeds)
mcp-readonly-sql/
mcp-identity-connector/
mcp-document-registry/
mcp-expedientes/
mcp-reportes/
mcp-notificaciones/
packages/
auth-sdk/ # Shared Bearer token validation (TS + Python)
tool-registry/ # Data model, migrations, registry client
mcp-shared/ # HTTP/stdio server utilities + auth middleware
config/ # Typed per-environment configuration
logger/ # Structured logging
types/ # Shared TypeScript types (events, results, errors)
shared-schemas/ # JSON Schema / OpenAPI / Pydantic / Zod schemas
prompt-library/ # Versioned prompts
policy-library/ # Declarative policies
services/
runtime-python/ # Workers, RAG, embeddings, file watchers
model-gateway/ # Local-first model routing gateway
cli/
cli-pdf-tools/
cli-ocr-tools/
cli-office-converter/
allowed-tools.yaml
infra/
docker/ # Dockerfiles per service
compose/ # docker-compose.local.yml + docker-compose.prod.yml
dokploy/ # Reproducible deployment config + notes
postgres/
migrations/ # harness_db Alembic migrations
auth-migrations/ # harness_auth_db Alembic migrations (separate)
seed/
tool_registry_seed.yaml
auth_clients_seed.yaml
scopes_seed.yaml
docs/
openspec/
.github/
workflows/
README.md
Key monorepo conventions:
apps/harness-core and apps/admin-panel stay thin — no heavy work inside HTTP request handlers.
apps/admin-panel never shares a port with apps/harness-core; it lives on an internal network with IP/VPN allowlist.
- Every MCP in
mcps/* is a Docker-deployable entrypoint registered as a tool_registry row via seed migration. No apps/* enumerates them in code.
packages/auth-sdk is the only approved path for token validation across all services.
infra/postgres/migrations and infra/postgres/auth-migrations belong to different databases and must never be merged.