An enterprise-grade multi-agent AI platform built on the Agent-to-Agent (A2A) protocol. Users interact through web or messaging clients; a central orchestrator plans tasks and delegates work to specialized sub-agents.
┌──────────────────────────────────────────────────────────────────────────────────┐
│ Clients │
│ ┌──────────────────┐ ┌──────────────┐ ┌───────────────┐ ┌───────────────┐ │
│ │ Console Frontend│ │ Client Slack │ │ Client Email │ │ Google Chat │ │
│ └────────┬─────────┘ └──────┬───────┘ └──────┬────────┘ └──────┬────────┘ │
└───────────┼────────────────────┼──────────────────┼──────────────────┼───────────┘
│ REST / WS │ A2A │ A2A │ A2A
▼ ▼ ▼ ▼
┌───────────────────┐A2A ┌────────────────────────────────────────────────┐
│ Console Backend │◄─--│ Orchestrator Agent │
│ (API + Scheduler)│ │ (LangGraph — plans & delegates) │
└───────────────────┘ └──────────────────────────┬─────────────────────┘
│ A2A
┌─────────▼───┐
│ Sub Agents │
└─────────────┘
export OPENAI_COMPATIBLE_BASE_URL=http://localhost:1234
just start-local| Scope | Components | External Dependencies |
| PoC | • Orchestrator (low capability) |
• OIDC Issuer • Orchestrator OIDC Client • LLM Provider (local or remote) • PostgresSQL (+pgvector) |
| Medium | • Orchestrator |
+ S3, DynamoDB (LangGraph Checkpointing) + S3 (binary file storage) + MCP Gateway (e.g. Gatana) |
| Full | • Orchestrator • Agent Runner • Console (Web admin app) |
+ PostgreSQL pgcrypto extension + Console OIDC Client + KeyCloak Admin Credentials |
| + Slack |
• Slack Client • Slack Client Admin GUI |
+ Slack Client OIDC Client |
| • Email Client |
+ Email Client OIDC Client + AWS SES |
|
| + Google Chat | • Google Chat Client |
+ Google Chat Client OIDC Client + GCP Service Account |
The following environment variables should be set on orchestrator, and on any agent which A2A agent using agent-common as a base.
| Provider | Configuration |
|---|---|
| Local/OpenAI Compatible API | OPENAI_COMPATIBLE_BASE_URL |
| AWS Bedrock | AWS SDK compatible environment variables |
| AzureAI | AZURE_OPENAI_API_KEY |
| GCP_KEY |
You can enable tracing by setting
- LANGSMITH_API_KEY
- LANGSMITH_TRACING = true
- LANGSMITH_ENDPOINT
- LANGSMITH_PROJECT
We recommend KeyCloak, as the Console has connector for managing users and groups in KeyCloak from within the Console frontend app.
Full scope extensions required: pgcrypto and pgvector.
The following components executes SQL DB migrations on start-up and we recommend to prepare an empty schema for each:
- Orchestrator (suggested username
docstoresince its used for semantic search over documents) - Console Backend
- Slack Client
- Email Client
- Google Chat Client
| Component | PG database/schema | Shared | Need Schema Owner |
|---|---|---|---|
| Orchestrator | docstore | ✅ | ✅ |
| Agent Runner | docstore | ✅ | |
| Any A2A Server based on agent-common | docstore | ✅ | |
| Console | console | ✅ | |
| Slack Client | slack client | ✅ | |
| Email Client | email client | ✅ | |
| Google Chat Client | google chat client | ✅ |
| Image | Purpose | Port |
|---|---|---|
ghcr.io/ringier-data/nannos-orchestrator-agent |
Required: entry-point for requests. A2A server powered by LangGraph. Receives tasks, plans execution, discovers sub-agents, and delegates work. | 10001 |
| Image | Purpose | Port |
|---|---|---|
ghcr.io/ringier-data/nannos-agent-runner |
Required for scheduled jobs A2A server that executes scheduled automated sub-agent jobs. | 5005 |
ghcr.io/ringier-data/nannos-console-backend |
Admin Management REST + WebSocket API. Manages agents, conversations, file uploads, and the background scheduler. The single backend all other services register against. | 5001 |
ghcr.io/ringier-data/nannos-console-frontend |
Admin Management React SPA served by nginx. The primary operator/user web interface. | 8081 |
| Image | Purpose | Port |
|---|---|---|
ghcr.io/ringier-data/nannos-client-slack |
Slack A2A Client | 3000 |
ghcr.io/ringier-data/nannos-client-slack-frontend |
Slack Admin Management Frontend (React SPA) | 8080 |
ghcr.io/ringier-data/nannos-client-email |
Email A2A Client | 3000 |
ghcr.io/ringier-data/nannos-client-google-chat |
Google Chat A2A Client | 3000 |
| Image | Purpose | Port |
|---|---|---|
ghcr.io/ringier-data/nannos-agent-creator |
A2A server for designing and generating new agents via LLM. | 8080 |
Full reference: packages/orchestrator-agent/
| Variable | Description |
|---|---|
OIDC_ISSUER |
OIDC issuer URL |
AGENT_BASE_URL |
Public URL of this service, used in the A2A agent card (default: http://localhost:10001) |
CONSOLE_BACKEND_URL |
URL of the console-backend service (default: http://localhost:5001) |
POSTGRES_HOST |
PostgreSQL hostname |
POSTGRES_DB |
PostgreSQL database |
POSTGRES_USER |
docstore user |
POSTGRES_PASSWORD |
Database password |
POSTGRES_SCHEMA |
Schema name (required for migrations to work) |
LLM provider — provide credentials for at least one:
| Variable | Provider |
|---|---|
OPENAI_COMPATIBLE_BASE_URL |
Any OpenAI-compatible server (Ollama, LM Studio, vLLM, etc.) |
AWS_ACCESS_KEY_ID + AWS_SECRET_ACCESS_KEY + AWS_BEDROCK_REGION |
Amazon Bedrock |
AZURE_OPENAI_API_KEY + AZURE_OPENAI_ENDPOINT + OPENAI_API_VERSION |
Azure OpenAI |
Full reference: packages/console-backend/.env.template
| Variable | Description |
|---|---|
OIDC_ISSUER |
OIDC issuer URL |
OIDC_CLIENT_ID |
Keycloak client ID for this service (e.g. agent-console) |
OIDC_CLIENT_SECRET |
Client secret |
BASE_DOMAIN |
Public domain used for CORS origin checks |
SECRET_KEY |
Secret used to sign sessions — change this in production |
ORCHESTRATOR_CLIENT_ID |
Keycloak client ID of the orchestrator (e.g. orchestrator) |
ORCHESTRATOR_BASE_DOMAIN |
e.g. orchestrator.nannos.mydomain.com |
POSTGRES_HOST |
PostgreSQL hostname |
POSTGRES_PORT |
PostgreSQL port (default: 5432) |
POSTGRES_DB |
Database name |
POSTGRES_USER |
Database user |
POSTGRES_PASSWORD |
Database password |
POSTGRES_SCHEMA |
Schema name (required for migrations to work) |
LANGSMITH_ORGANIZATION_ID |
LangSmith organization ID for frontend trace links (optional) |
LANGSMITH_PROJECT_ID |
LangSmith project ID for frontend trace links (optional) |
AUTO_APPROVE_MAX_SYSTEM_PROMPT_LENGTH |
Max chars for auto-approve system prompt (default: 500) |
AUTO_APPROVE_MAX_MCP_TOOLS_COUNT |
Max MCP tools for auto-approve (default: 3) |
Full reference: packages/agent-creator/.env.template
| Variable | Description |
|---|---|
OIDC_ISSUER |
OIDC issuer URL |
OIDC_CLIENT_ID |
Keycloak client ID (e.g. agent-creator) |
OIDC_CLIENT_SECRET |
Client secret |
ORCHESTRATOR_CLIENT_ID |
Keycloak client ID used to validate inbound tokens |
AGENT_ID |
Numeric identifier for this agent instance (e.g. 1) |
CONSOLE_BACKEND_URL |
URL of the console-backend service (default: http://localhost:5001) |
CONSOLE_FRONTEND_URL |
URL of the console-frontend (default: http://localhost:5173) |
LLM provider credentials — same options as the orchestrator.
Full reference: packages/agent-runner/.env.template
| Variable | Description |
|---|---|
OIDC_ISSUER |
OIDC issuer URL |
OIDC_CLIENT_ID |
Keycloak client ID (uses orchestrator client) |
AGENT_BASE_URL |
Public URL of this service (default: http://localhost:5005) |
CONSOLE_BACKEND_URL |
URL of the console-backend service (default: http://localhost:5001) |
POSTGRES_HOST |
PostgreSQL hostname (for document store) |
POSTGRES_PORT |
PostgreSQL port (default: 5432) |
POSTGRES_DB |
PostgreSQL database |
POSTGRES_USER |
docstore user |
POSTGRES_PASSWORD |
Database password |
POSTGRES_SCHEMA |
Schema name (required for migrations to work) |
LLM provider credentials — same options as the orchestrator.
Full reference: packages/client-slack/.env.example
All variables below are required — there are no fallback defaults.
| Variable | Description |
|---|---|
ENVIRONMENT |
Deployment environment: local, dev, stg, or prod |
OIDC_ISSUER_URL |
OIDC issuer URL |
OIDC_CLIENT_ID |
Keycloak client ID for this service |
OIDC_CLIENT_SECRET |
Client secret |
A2A_SERVER_URL |
Full URL of the orchestrator A2A endpoint, e.g. https://orchestrator.example.com/api |
ADMIN_GROUP |
Keycloak group name that grants admin access |
POSTGRES_HOST |
PostgreSQL hostname |
POSTGRES_PASSWORD |
Postgres password |
POSTGRES_USER |
Postgres user |
POSTGRES_DB |
Postgres database |
Full reference: packages/client-email/.env.example
| Variable | Description |
|---|---|
ENVIRONMENT |
Deployment environment: local, dev, stg, or prod |
OIDC_ISSUER_URL |
OIDC issuer URL |
OIDC_CLIENT_ID |
Keycloak client ID for this service |
OIDC_CLIENT_SECRET |
Client secret |
A2A_SERVER_URL |
Full URL of the orchestrator A2A endpoint |
Full reference: packages/client-google-chat/.env.example
| Variable | Description |
|---|---|
ENVIRONMENT |
Deployment environment: local, dev, stg, or prod |
BASE_URL |
Google chat serve url |
OIDC_ISSUER_URL |
OIDC issuer URL |
OIDC_CLIENT_ID |
Keycloak client ID for this service |
OIDC_CLIENT_SECRET |
Client secret |
A2A_SERVER_URL |
Full URL of the orchestrator A2A endpoint |
GCP_CHAT_PROJECTS |
JSON array of Google Chat project configs |
GCP_SA_JSON_KEY_* |
GCP service account key JSON (one per project) |
GOOGLE_CHAT_TOKEN_EXPECTED_AUDIENCE |
Google chat expected audience in events token |
POSTGRES_HOST |
PostgreSQL hostname |
POSTGRES_PASSWORD |
Postgres password |
POSTGRES_USER |
Postgres user |
POSTGRES_DB |
Postgres database |
The frontend is a static SPA served by nginx. It requires no build-time environment variables —
all configuration is loaded at runtime from the console-backend via GET /api/v1/config.
| Variable | Description |
|---|---|
OVERRIDE_OPENAPI_URL |
URL to the Slack backend's OpenAPI spec, used for client code generation at build time (e.g. http://client-slack:3001/api/v2/openapi.json) |