Real-time AI agent catalog — discover, track, and inspect A2A and MCP agents across Kubernetes clusters and static endpoints.
AgentLens automatically discovers AI agents running in Kubernetes (via Service annotations), polls static endpoints, and accepts push registrations. It exposes a REST API and a web dashboard for browsing the catalog, filtering by protocol/status, and inspecting agent cards and capabilities.
- Discovery — Automatically discover agents in Kubernetes (via Service annotations), static configuration, or push registration
- Multi-protocol support — A2A and MCP agent protocols; A2UI agents can be push-registered via the API
- Real-time catalog — Browse, filter, and inspect agent capabilities via REST API and web dashboard
- Health Monitoring — AgentLens continuously probes registered endpoints and shows real-time status on the dashboard. Entries transition through lifecycle states (
registered → active → degraded → offline) based on HTTP response codes and latency. Admins can manually deprecate entries and trigger on-demand probes from the UI. - Authentication & Authorization — JWT-based auth with role-based access control (admin, editor, viewer)
- Groups & Projects — Party archetype for managing users, hierarchical groups, and project namespaces with per-project RBAC (owner/developer/viewer roles). Catalog entries are scoped to projects; new entries auto-assigned to the
defaultproject. - Multi-database support — SQLite (single-instance) or PostgreSQL (production)
git clone https://github.com/PawelHaracz/agentlens
cd agentlens/examples
docker compose upOpen http://localhost:8080 in your browser.
helm install agentlens ./deploy/helm/agentlens \
--namespace agentlens --create-namespaceAgentLens will start watching Services across all namespaces for agent annotations.
Annotate your Services to register agents automatically:
| Annotation | Required | Description |
|---|---|---|
agentlens.io/type |
✓ | One of a2a, mcp |
agentlens.io/card-path |
Custom card path (defaults: /.well-known/agent-card.json for A2A, /.well-known/mcp/server.json for MCP) |
|
agentlens.io/team |
Owning team label | |
agentlens.io/tags |
Comma-separated categories |
Example:
apiVersion: v1
kind: Service
metadata:
name: my-agent
annotations:
agentlens.io/type: "a2a"
agentlens.io/team: "platform"
agentlens.io/tags: "nlp,support"
spec:
selector:
app: my-agent
ports:
- port: 8080# agentlens.yaml
port: 8080
data_dir: ./data
log_level: info
poll_interval: 5m
sources:
- name: my-a2a-agent
type: a2a
url: http://agent.internal:8080
- name: my-mcp-server
type: mcp
url: http://mcp.internal:9000
health_check:
enabled: true
interval: 30s
timeout: 5s
concurrency: 8
degraded_latency: 1500ms
failure_threshold: 3Run with:
agentlens --config agentlens.yamlBefore registering an A2A agent card, validate it using the validation endpoint:
curl -X POST http://localhost:8080/api/v1/catalog/validate \
-H "Content-Type: application/json" \
-d @agent-card.jsonThe validation endpoint:
- Auto-detects A2A specification version (v0.3 vs v1.0)
- Returns structured errors and warnings if validation fails
- Returns a preview of the agent details if valid
- Requires authentication —
catalog:writepermission needed
Example response for a valid card:
{
"valid": true,
"spec_version": "1.0",
"errors": [],
"warnings": [],
"preview": {
"display_name": "Example Chat Agent",
"description": "A sample agent demonstrating A2A v1.0 features",
"protocol": "a2a",
"spec_version": "1.0",
"skills_count": 0,
"extensions_count": 1,
"security_schemes": ["oauth2"],
"interfaces": ["https://api.example.com/v1"]
}
}Register an agent by providing the URL of its card — AgentLens fetches, validates, and imports it automatically:
curl -X POST http://localhost:8080/api/v1/catalog/import \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{"url": "https://my-agent.example.com/.well-known/agent.json"}'The import endpoint:
- Fetches the card from the provided URL (10 s timeout, 1 MB cap)
- Auto-detects the protocol from the URL path and card content
- Validates the card and returns structured errors if validation fails
- Rejects requests to private/internal network addresses (SSRF protection)
- Requires authentication —
catalog:writepermission needed
Optional "protocol" field to override auto-detection:
curl -X POST http://localhost:8080/api/v1/catalog/import \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{"url": "https://mcp.example.com/card", "protocol": "mcp"}'The web dashboard also exposes this feature via the Import from URL tab in the Register Agent dialog — see docs/end-user-guide.md for a step-by-step walkthrough.
Register a catalog entry via HTTP POST:
curl -X POST http://localhost:8080/api/v1/catalog \
-H "Content-Type: application/json" \
-d '{
"display_name": "my-agent",
"description": "Does amazing things",
"protocol": "a2a",
"endpoint": "http://my-agent.internal:8080",
"version": "1.2.3"
}'To register with full agent capabilities (skills, interfaces, security schemes), use POST /api/v1/catalog/register with a raw A2A or MCP agent card JSON instead.
| Method | Path | Description |
|---|---|---|
GET |
/healthz |
Health check |
GET |
/api/v1/catalog |
List catalog entries (?protocol=, ?status=, ?q=, ?team=, ?categories=, ?limit=, ?offset=) |
POST |
/api/v1/catalog/validate |
Validate A2A agent card (dry-run, does not persist) |
POST |
/api/v1/catalog/register |
Register an A2A agent from a raw agent card JSON |
POST |
/api/v1/catalog/import |
Fetch and import an agent card from a URL |
POST |
/api/v1/catalog |
Push-register a catalog entry |
GET |
/api/v1/catalog/{id} |
Get entry by ID |
DELETE |
/api/v1/catalog/{id} |
Delete entry |
GET |
/api/v1/catalog/{id}/card |
Get raw protocol card JSON |
PATCH |
/api/v1/catalog/{id}/lifecycle |
Change entry lifecycle state |
POST |
/api/v1/catalog/{id}/probe |
Trigger on-demand health probe |
GET |
/api/v1/capabilities |
List capabilities across all agents |
GET |
/api/v1/capabilities/{key} |
Get agents by capability key |
GET |
/api/v1/stats |
Aggregate stats |
POST |
/api/v1/auth/login |
Login and obtain JWT token |
POST |
/api/v1/auth/logout |
Logout (invalidate token) |
POST |
/api/v1/auth/refresh |
Refresh JWT token |
GET |
/api/v1/auth/me |
Get current user info |
PUT |
/api/v1/auth/password |
Change current user password |
GET |
/api/v1/users |
List users |
POST |
/api/v1/users |
Create user |
GET |
/api/v1/users/{id} |
Get user by ID |
PUT |
/api/v1/users/{id} |
Update user |
DELETE |
/api/v1/users/{id} |
Delete user |
GET |
/api/v1/roles |
List roles |
POST |
/api/v1/roles |
Create role |
PUT |
/api/v1/roles/{id} |
Update role |
DELETE |
/api/v1/roles/{id} |
Delete role |
GET |
/api/v1/settings |
List settings |
GET |
/api/v1/settings/{category} |
List settings in a category |
PUT |
/api/v1/settings |
Bulk update settings |
GET |
/api/v1/groups |
List groups |
POST |
/api/v1/groups |
Create group |
GET |
/api/v1/groups/{id} |
Get group by ID |
DELETE |
/api/v1/groups/{id} |
Delete group |
GET |
/api/v1/groups/{id}/members |
List group members |
POST |
/api/v1/groups/{id}/members |
Add member to group |
DELETE |
/api/v1/groups/{id}/members/{memberID} |
Remove member from group |
GET |
/api/v1/projects |
List projects |
POST |
/api/v1/projects |
Create project |
GET |
/api/v1/projects/{id} |
Get project by ID |
DELETE |
/api/v1/projects/{id} |
Delete project |
GET |
/api/v1/projects/{id}/members |
List project members |
POST |
/api/v1/projects/{id}/members |
Add member to project (with role) |
DELETE |
/api/v1/projects/{id}/members/{memberID} |
Remove member from project |
GET |
/api/v1/catalog/{id}/projects |
List projects a catalog entry belongs to |
POST |
/api/v1/catalog/{id}/projects |
Assign catalog entry to project |
DELETE |
/api/v1/catalog/{id}/projects/{projectID} |
Remove catalog entry from project |
See docs/api.md for full API documentation.
AgentLens uses a microkernel plugin architecture:
- Core kernel — manages store, config, logger, and plugin lifecycle
- Parser plugins — A2A and MCP card parsers (extensible)
- Source plugins — static config, Kubernetes discovery (extensible)
- Enterprise plugins — SSO, RBAC, audit, PostgreSQL (license-gated)
The domain model follows the Product Archetype Pattern where each discovered agent is an AgentType (protocol + endpoint + capabilities) wrapped by a CatalogEntry (display metadata, lifecycle state, health).
Access control uses a Party Archetype — users, groups, and projects are all Party records connected by named relationship edges. Hierarchical group membership is pre-computed into a closure table for O(1) permission checks. Catalog entries are scoped to projects; a default project is seeded on first run and all new entries are auto-assigned to it.
AgentLens supports two database backends:
- SQLite (default) — zero-config, file-based, ideal for single-instance deployments
- PostgreSQL — recommended for production, multi-instance, and high-availability setups
Configure via database.dialect in the config file or AGENTLENS_DB_DIALECT env var.
database:
dialect: sqlite
sqlite:
path: ./data/agentlens.dbdatabase:
dialect: postgres
postgres:
host: localhost
port: 5432
user: agentlens
password: secret
dbname: agentlens
sslmode: disableSee docs/database.md for full database documentation.
AgentLens includes built-in authentication with JWT tokens and role-based access control.
On first startup, AgentLens creates an admin user with a randomly generated password printed to stdout:
============================================
INITIAL ADMIN CREDENTIALS
Username: admin
Password: <generated>
CHANGE THIS PASSWORD IMMEDIATELY
============================================
curl -X POST http://localhost:8080/api/v1/auth/login \
-H "Content-Type: application/json" \
-d '{"username": "admin", "password": "<your-password>"}'The response includes a JWT token. Use it in subsequent requests:
curl http://localhost:8080/api/v1/catalog \
-H "Authorization: Bearer <token>"See docs/auth.md for full authentication documentation.
Three default roles are created on first run:
| Role | Permissions |
|---|---|
| admin | Full access: catalog, users, roles, settings (read/write/delete) |
| editor | catalog:read/write, users:read, roles:read, settings:read |
| viewer | catalog:read, users:read, roles:read, settings:read |
All permissions follow the resource:action format (e.g., catalog:read, users:write).
| Environment Variable | Default | Description |
|---|---|---|
AGENTLENS_PORT |
8080 |
HTTP server port |
AGENTLENS_DATA_DIR |
./data |
Data directory for SQLite |
AGENTLENS_LOG_LEVEL |
info |
Log level (debug/info/warn/error) |
AGENTLENS_POLL_INTERVAL |
5m |
Discovery poll interval |
AGENTLENS_DB_DIALECT |
sqlite |
Database backend (sqlite/postgres) |
AGENTLENS_DB_SQLITE_PATH |
./data/agentlens.db |
SQLite database file path |
AGENTLENS_DB_POSTGRES_HOST |
localhost |
PostgreSQL host |
AGENTLENS_DB_POSTGRES_PORT |
5432 |
PostgreSQL port |
AGENTLENS_DB_POSTGRES_USER |
agentlens |
PostgreSQL user |
AGENTLENS_DB_POSTGRES_PASSWORD |
PostgreSQL password | |
AGENTLENS_DB_POSTGRES_DBNAME |
agentlens |
PostgreSQL database name |
AGENTLENS_DB_POSTGRES_SSLMODE |
disable |
PostgreSQL SSL mode |
AGENTLENS_JWT_SECRET |
(auto-generated) | JWT signing secret |
AGENTLENS_SESSION_DURATION |
24h |
JWT token expiration |
AGENTLENS_KUBERNETES_ENABLED |
false |
Enable Kubernetes discovery |
AGENTLENS_HEALTH_CHECK_ENABLED |
true |
Enable health checking |
AGENTLENS_HEALTH_CHECK_INTERVAL |
30s |
Health check interval |
AGENTLENS_HEALTH_CHECK_TIMEOUT |
5s |
Health check timeout |
AGENTLENS_HEALTH_CHECK_CONCURRENCY |
8 |
Health check parallelism |
AGENTLENS_HEALTH_CHECK_DEGRADED_LATENCY |
1500ms |
Latency threshold for degraded status |
AGENTLENS_HEALTH_CHECK_FAILURE_THRESHOLD |
3 |
Consecutive failures before offline |
AGENTLENS_LICENSE_KEY |
(none) | Enterprise license key |
| Document | Description |
|---|---|
| API Reference | Full REST API documentation — endpoints, request/response schemas, error codes |
| Architecture | Microkernel design, plugin system, data flow diagrams |
| Authentication | JWT auth, RBAC, roles & permissions, account lockout |
| Database | SQLite & PostgreSQL setup, migrations, dialect differences |
| Settings | Application settings, categories, configuration store |
| Developer Guide | Build, test, lint, write plugins, frontend development |
| DevOps Guide | Docker, Helm, CI/CD, release pipeline, versioning, troubleshooting |
| End-User Guide | UI walkthrough with screenshots — catalog, agents, filtering |
| User Guide | Configuration, deployment modes, Kubernetes annotations |
| Architecture Decision Records | ADRs covering plugin architecture, product catalog, auth, database, frontend, and discovery |
| Contributing | How to contribute, project structure, code style |
See CONTRIBUTING.md.
AgentLens is licensed under the Business Source License 1.1.
What this means in plain language:
- ✅ You can use AgentLens freely for any purpose, including production and internal business use
- ✅ You can modify, fork, and create derivative works
- ✅ You can redistribute the source code
- ❌ You may not offer AgentLens as a commercial hosted or managed service competing with AgentLens commercial offerings
- 🔄 Each release automatically converts to Apache License 2.0 after four years
For commercial hosting/managed service licensing, contact the Licensor.