Skip to content

Commit 3d99ff9

Browse files
thatsmeclaude
andcommitted
Update docs: add MCP to README, SECURITY, and ARCHITECTURE
README.md: - Added MCP Server to Core features - Updated architecture diagram with MCP client path - Updated health/metrics descriptions with MCP fields - Added MCP Bearer auth to Security section SECURITY.md: - New "MCP Server Authentication" section: Bearer token management, policy enforcement, resource filtering, audit logging, hardening ALEXCLAW_ARCHITECTURE.md: - Added mcp/ and plugs/mcp_*.ex to Project Structure - Added anubis_mcp and nostrum to Dependencies Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 1fa37b7 commit 3d99ff9

3 files changed

Lines changed: 41 additions & 3 deletions

File tree

ALEXCLAW_ARCHITECTURE.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -623,6 +623,10 @@ lib/
623623
scheduler.ex # Quantum cron scheduler
624624
skill.ex # Skill behaviour definition
625625
skill_supervisor.ex # DynamicSupervisor for skill workers
626+
mcp/
627+
server.ex # MCP server — Anubis callbacks, tool calls, resource reads
628+
tool_schema.ex # Maps skills/workflows to MCP tool definitions (Peri format)
629+
resource_provider.ex # Routes resource URIs to context modules
626630
alex_claw_web/
627631
controllers/
628632
auth_controller.ex # Login/logout with rate limiting
@@ -634,6 +638,8 @@ lib/
634638
live/admin_live/ # LiveView pages (12 pages, .ex logic + .html.heex templates)
635639
plugs/
636640
caching_body_reader.ex # Caches raw body for webhook HMAC verification
641+
mcp_auth.ex # Bearer token auth for /mcp endpoint
642+
mcp_forward.ex # Runtime forwarder to Anubis StreamableHTTP Plug
637643
rate_limit.ex # Plug for POST /login rate limiting
638644
require_auth.ex # Session-based auth guard
639645
router.ex
@@ -671,6 +677,8 @@ config/
671677
{:quantum, "~> 3.5"} # Cron scheduler
672678
{:nimble_totp, "~> 1.0"} # TOTP 2FA
673679
{:eqrcode, "~> 0.2"} # QR code generation for 2FA setup
680+
{:anubis_mcp, "~> 1.0"} # MCP server (Streamable HTTP transport)
681+
{:nostrum, "~> 0.10"} # Discord gateway
674682
{:jason, "~> 1.4"} # JSON
675683
{:telemetry_metrics, "~> 1.0"}
676684
{:telemetry_poller, "~> 1.0"}

README.md

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ AlexClaw monitors the world (RSS feeds, web sources, GitHub repositories, APIs),
2727
- **Knowledge Base RAG** — Separate `knowledge_entries` table for documentation and reference material, isolated from news/conversation memory. Scraper skills fetch, chunk, and embed documentation from hexdocs.pm, Erlang/OTP source (GitHub), Elixir stdlib source, Learn You Some Erlang, and existing skill code. Chat integrates both Knowledge and Memory search with a context source selector. ~7200 embeddings across 6 knowledge kinds.
2828
- **Cron Scheduler** — Quantum-based. Jobs defined in config or DB.
2929
- **Multi-Node BEAM Clustering** — Multiple AlexClaw instances connected via Erlang distribution. Each node runs its own executor independently; nodes exchange workflow outputs via `send_to_workflow` and `receive_from_workflow` skills. Auto-discovery, node status monitoring, and per-workflow node assignment from the admin UI. `docker-compose_swarm.yml` included for local multi-node testing.
30+
- **MCP Server** — Model Context Protocol server exposes all skills and workflows as MCP tools, and internal data (knowledge, memory, workflows, runs, config) as MCP resources. External AI clients (Claude Code, Cursor, Claude Desktop) can discover and invoke AlexClaw capabilities via the `/mcp` endpoint. Bearer token auth, policy-based tool restrictions, dynamic tool list refresh via PubSub. Built on `anubis_mcp` with Streamable HTTP transport.
3031

3132
### Skills
3233

@@ -107,8 +108,8 @@ AlexClaw can review pull requests and commits for security issues:
107108

108109
### Observability
109110

110-
- **Health endpoint**`GET /health` (unauthenticated) returns `{"status":"ok","version":"...","db":"connected"}` for load balancers and Docker healthchecks. Returns HTTP 503 when the database is unreachable.
111-
- **Metrics endpoint**`GET /metrics` (authenticated) returns a JSON payload with system stats (uptime, memory, BEAM processes), LLM provider usage, workflow run counts, skill and circuit breaker states, log severity counts, and knowledge/memory entry counts.
111+
- **Health endpoint**`GET /health` (unauthenticated) returns `{"status":"ok","version":"...","db":"connected","mcp":"running"}` for load balancers and Docker healthchecks. Returns HTTP 503 when the database is unreachable.
112+
- **Metrics endpoint**`GET /metrics` (authenticated) returns a JSON payload with system stats (uptime, memory, BEAM processes), LLM provider usage, workflow run counts, skill and circuit breaker states, MCP status and tool count, log severity counts, and knowledge/memory entry counts.
112113

113114
### Database Backups
114115

@@ -127,7 +128,8 @@ Automated PostgreSQL backups via the `db_backup` core skill. Backups are gzip-co
127128
- **HMAC-SHA256 webhook verification** — GitHub webhook endpoint uses `Plug.Crypto.secure_compare` for timing-safe signature validation
128129
- **Encryption at rest** — API keys and tokens are AES-256-GCM encrypted in PostgreSQL, decrypted transparently at runtime
129130
- **Sensitive key masking** — API keys and tokens show partial values in the admin UI
130-
- **Agent authorization layer** — Context-aware PolicyEngine with HMAC capability tokens, chain-depth enforcement, process isolation for dynamic skills, configurable policy rules (rate_limit, time_window, chain_restriction, permission_override), and persistent audit logging
131+
- **Agent authorization layer** — Context-aware PolicyEngine with HMAC capability tokens, chain-depth enforcement, process isolation for dynamic skills, configurable policy rules (rate_limit, time_window, chain_restriction, permission_override, mcp_restriction), and persistent audit logging
132+
- **MCP Bearer token auth** — MCP endpoint requires `Authorization: Bearer <token>` validated against `mcp.api_key` via constant-time comparison. Policy-based tool restrictions allow blocking specific tools for MCP clients. Sensitive config values are redacted in MCP resource responses
131133
- **Shell command security** — 5-layer defense: disabled by default, 2FA gate, whitelist with word-boundary check, blocklist for shell metacharacters, no shell interpretation (`System.cmd/3` with args as list), configurable timeout + output truncation
132134

133135
---
@@ -137,6 +139,7 @@ Automated PostgreSQL backups via the `db_backup` core skill. Backups are gzip-co
137139
```
138140
Telegram <──> TelegramGateway ──┐
139141
Discord <──> DiscordGateway ──┼──> Router ──> Dispatcher ──> Skills
142+
MCP Client <──> MCP.Server ────┘
140143
141144
Admin UI (Chat) ──────> SkillSupervisor ──> Dynamic Skills
142145
(DynamicSupervisor)

SECURITY.md

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,33 @@ Set `github.webhook_secret` in Admin > Config (GitHub category).
6666

6767
---
6868

69+
## MCP Server Authentication
70+
71+
The MCP endpoint (`/mcp`) exposes AlexClaw skills, workflows, and data to external AI clients (Claude Code, Cursor, Claude Desktop) via the Model Context Protocol.
72+
73+
**Bearer token auth:** Every MCP request must include `Authorization: Bearer <token>`. The token is validated against `mcp.api_key` stored in Admin > Config using `Plug.Crypto.secure_compare/2` (constant-time comparison, no timing attacks). Requests without a valid token receive 401.
74+
75+
**Token management:**
76+
- Store the API key encrypted in PostgreSQL (`sensitive: true` on the config setting)
77+
- No automatic expiration — treat MCP tokens like long-lived API keys
78+
- Rotate by updating `mcp.api_key` in Admin > Config — all previous tokens are immediately invalidated
79+
- If compromised: rotate immediately in Admin > Config
80+
81+
**Policy enforcement:** MCP tool calls pass through `PolicyEngine.evaluate/2` with `:mcp` caller type. The `mcp_restriction` policy rule type blocks tools by name pattern — insert a policy with `rule_type: "mcp_restriction"` and `config: {"tool_pattern": "shell", "action": "deny"}` to block any tool matching that pattern.
82+
83+
**Resource filtering:** Sensitive config values (API keys, OAuth tokens) are redacted in MCP resource responses — only `[REDACTED]` is returned for settings marked `sensitive: true`.
84+
85+
**Audit logging:** All MCP tool invocations are logged to `auth_audit_log` with caller `mcp:<tool_name>`, visible in Admin > Policies > Audit Log.
86+
87+
**Hardening recommendations:**
88+
- The `/mcp` endpoint must be behind TLS — never transmit Bearer tokens over plain HTTP
89+
- Store the MCP API key in your client's config securely (environment variable or encrypted config)
90+
- Monitor the Audit Log for unexpected MCP activity
91+
- Use `mcp_restriction` policies to limit which tools are available to MCP clients
92+
- If MCP is not needed, do not set `mcp.api_key` — the auth plug rejects all requests when the key is unconfigured
93+
94+
---
95+
6996
## Inter-Node Authentication (Clustering)
7097

7198
Multi-node clusters authenticate via BEAM's distributed Erlang protocol:

0 commit comments

Comments
 (0)