Skip to main content

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.
TechnologyRole
Astro (SSR)Web portal, API routes, Astro Actions for backend operations
TypeScriptAll BFF application logic
ZodRequest/response validation at every API boundary
Tailwind CSSOnly 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.
TechnologyRole
Astro (SSR server-capable)Dynamic internal views — paginated listings, live approval queues
Tailwind CSSOnly CSS standard, same rules as the BFF
auth-sdkConsumes 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.
TechnologyRole
FastAPIOptional internal API endpoints for private communication
RQ + RedisBackground worker queue and task broker
LangGraphComplex stateful workflows only (multi-step, decisions, retries, human-in-the-loop)
Pydantic v2Contracts and validation for all internal data models
SQLAlchemy async / asyncpgAsync PostgreSQL access
Watchdog / watchfilesDirectory 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

Layer 4 — Dynamic Tools

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 typetype valuetransport valueExamples
MCP over HTTPmcp_httpoauthmcp-readonly-sql, mcp-identity-connector, mcp-document-registry, mcp-expedientes, mcp-reportes, mcp-notificaciones
MCP over stdiomcp_stdiocommandLocal stdio-based MCP servers
CLI wrapperclicommandcli-pdf-tools, cli-ocr-tools, cli-office-converter
HTTP / API adapterhttp_apiapiExternal REST integrations
Inbound webhookwebhook_inwebhookEvent triggers from external systems
Outbound webhookwebhook_outwebhookNotifications 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.
StorePurpose
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.
RedisWorker queue broker (RQ) and operational cache
NAS / MinIORaw 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.
ComponentLocationRole
mcp-auth-serviceapps/mcp-auth-serviceOAuth 2.1-compatible. Issues and validates Bearer tokens via Client Credentials. Exposes /oauth/token, JWKS endpoint, and introspection. Manages clients, scopes, and policies.
auth-sdkpackages/auth-sdkShared 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

ComponentRole
vLLMLocal model server. The primary and initial model backend.
Model GatewayInternal 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

TechnologyRole
DockerContainer runtime for all services
Docker ComposeLocal and production service orchestration
DokployReproducible production deployment management
GitHub ActionsCI/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:
ToolMinimum version
Docker24+
Docker Composev2
Node.js20+
Python3.12+
pnpm9+

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.

Build docs developers (and LLMs) love