Architecture
This document describes the technical architecture of AgentPlaybooks.
System Overview
┌─────────────────────────────────────────────────────────────────┐
│ AI Consumers │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────────────┐ │
│ │ ChatGPT │ │ Claude │ │ Custom │ │ Enterprise AI │ │
│ │ (GPTs) │ │ (MCP) │ │ Agents │ │ Systems │ │
│ └────┬─────┘ └────┬─────┘ └────┬─────┘ └────────┬─────────┘ │
│ │ │ │ │ │
│ │ OpenAPI │ MCP │ REST/JSON/ │ │
│ ▼ ▼ ▼ Markdown ▼ │
└───────┴─────────────┴─────────────┴─────────────────┴───────────┘
│
▼
┌─────────────────────────────────────────────────────────────────┐
│ Cloudflare Edge Network │
│ ┌───────────────────────────────────────────────────────────┐ │
│ │ Cloudflare Workers │ │
│ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────────┐ │ │
│ │ │ REST API │ │ OpenAPI │ │ MCP Server │ │ │
│ │ │ (Hono) │ │ Generator │ │ Endpoint │ │ │
│ │ └─────────────┘ └─────────────┘ └─────────────────┘ │ │
│ └───────────────────────────────────────────────────────────┘ │
│ ┌───────────────────────────────────────────────────────────┐ │
│ │ Cloudflare Pages │ │
│ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────────┐ │ │
│ │ │ Landing │ │ Dashboard │ │ Docs │ │ │
│ │ │ Page │ │ (React) │ │ (MDX) │ │ │
│ │ └─────────────┘ └─────────────┘ └─────────────────┘ │ │
│ └───────────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────┐
│ Supabase │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────────────────┐ │
│ │ Auth │ │ PostgreSQL │ │ Row Level Security │ │
│ │ (JWT/OAuth)│ │ (Database) │ │ (RLS Policies) │ │
│ └─────────────┘ └─────────────┘ └─────────────────────────┘ │
└─────────────────────────────────────────────────────────────────┘Technology Stack
| Layer | Technology | Purpose |
| Frontend | Next.js 16 + React 19 | Server-side rendering, App Router |
| Styling | Tailwind CSS 4 | Utility-first CSS |
| Animation | Framer Motion | Smooth animations |
| UI Components | Aceternity UI | Modern, accessible components |
| i18n | next-intl | Multi-language support (EN/HU/DE/ES) |
| API | Hono | Fast, lightweight API framework |
| Database | Supabase PostgreSQL | Relational data with RLS |
| Auth | Supabase Auth | JWT, OAuth (Google, GitHub) |
| Hosting | Cloudflare Pages/Workers | Edge computing, global CDN |
| Docs | MDX | Markdown + React components |
Unified Operation Plane
MCP, OpenAPI/REST, and the dashboard are projections over the same playbook operation model. Playbook business rules do not belong to a protocol adapter.
- User control plane:
POST /api/mcp/managecan create/list playbooks and
playbook_id argument.
- Direct playbook plane:
POST /api/mcp/:guidexposes the same playbook
- OpenAPI/REST projections:
POST /api/control/:operationmirrors the user
POST /api/playbooks/:guid/operations/:operation mirrors the
direct playbook plane.
- Dashboard: dashboard-facing REST routes use the same shared auth and
StorageAdapter contract.The canonical tool catalog generates both MCP schemas and OpenAPI operation
paths. Adding a playbook operation therefore makes it available in both scopes
without copying its implementation. Dynamic tools from connected MCP servers
remain namespaced on the direct endpoint; the stable call_connected_tool
operation lets the user control plane call them after creating a playbook.
shared playbook operation catalog
│
┌────────────────────┼────────────────────┐
▼ ▼ ▼
user MCP + playbook_id direct MCP + :guid OpenAPI/REST paths
│ │ │
└────────────────────┴────────────────────┘
│
shared auth + repositories
│
SupabaseDatabase Schema
┌─────────────────┐ ┌─────────────────┐
│ users │ │ playbooks │
│ (auth.users) │◄──────│ │
├─────────────────┤ 1:N ├─────────────────┤
│ id (UUID) │ │ id (UUID) │
│ email │ │ user_id (FK) │
│ ... │ │ guid (unique) │
└─────────────────┘ │ name │
│ is_public │
└────────┬────────┘
│
┌────────────────────┼────────────────────┐
│ │ │
▼ ▼ ▼
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ personas │ │ skills │ │ mcp_servers │
├─────────────────┤ ├─────────────────┤ ├─────────────────┤
│ id │ │ id │ │ id │
│ playbook_id(FK) │ │ playbook_id(FK) │ │ playbook_id(FK) │
│ name │ │ name │ │ name │
│ system_prompt │ │ content │ │ tools (JSONB) │
│ metadata │ │ licence/priority│ │ transport config│
└─────────────────┘ └─────────────────┘ └─────────────────┘
┌────────────────────┼────────────────────┐
│ │ │
▼ ▼ ▼
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ memories │ │ api_keys │ │ playbook_public │
├─────────────────┤ ├─────────────────┤ │ _items │
│ id │ │ id │ ├─────────────────┤
│ playbook_id(FK) │ │ playbook_id(FK) │ │ playbook_id │
│ key │ │ key_hash │ │ item_type │
│ value (JSONB) │ │ permissions[] │ │ item_id │
└─────────────────┘ └─────────────────┘ └─────────────────┘
┌─────────────────┐ ┌─────────────────┐
│ public_skills │ │ public_mcp_ │
│ │ │ servers │
├─────────────────┤ ├─────────────────┤
│ id │ │ id │
│ author_id │ │ author_id │
│ name │ │ name │
│ tags[] │ │ tags[] │
│ usage_count │ │ usage_count │
│ is_verified │ │ is_verified │
└─────────────────┘ └─────────────────┘Request Flow
Public Playbook Read
1. Client → GET /api/playbooks/:guid?format=mcp
2. Cloudflare Worker receives request
3. Hono router matches route
4. Query Supabase (uses anon key, RLS allows public playbooks)
5. Format response based on ?format parameter
6. Return to clientAuthenticated Write-Back
1. AI Agent → PUT /api/playbooks/:guid/memory/:key
Headers: Authorization: Bearer apb_live_xxx
2. Cloudflare Worker receives request
3. Extract API key from header
4. Hash key, query api_keys table (service role, bypass RLS)
5. Verify key exists, is active, has permissions
6. Check key belongs to requested playbook
7. Perform write operation
8. Update last_used_at
9. Return successSecurity Model
Row Level Security (RLS)
All tables have RLS enabled. Key policies:
-- Playbooks: owner can do everything, public playbooks readable by all
CREATE POLICY "Users can manage own playbooks" ON playbooks
FOR ALL USING (auth.uid() = user_id);
CREATE POLICY "Public playbooks are readable" ON playbooks
FOR SELECT USING (is_public = true);
-- Memories: owner only (API key access handled at API level)
CREATE POLICY "Owner access memories" ON memories
FOR ALL USING (
EXISTS (SELECT 1 FROM playbooks
WHERE playbooks.id = memories.playbook_id
AND playbooks.user_id = auth.uid())
);API Key Security
- Keys are hashed with SHA-256 before storage
- Plain key shown only once at generation
- Keys can be revoked instantly
- Optional expiration dates
- Granular permissions (
memory:write,skills:write, etc.)
Human Collaboration Security
- Human editor membership is stored separately from bearer API keys in
playbook_collaborators - Invite links contain 256 bits of randomness; only their SHA-256 digests are stored
- Links are single-use, expire after 72 hours, and are atomically bound to the accepting account
- Editors may change content, while secrets, API keys, visibility, sharing, ownership, and deletion remain owner-only
- Removing a membership immediately revokes account-based access without rotating integration keys
Secrets Encryption
- Master key stored as
SECRETS_ENCRYPTION_KEYenvironment variable - Per-user encryption keys derived via HKDF (HMAC-based Key Derivation Function)
- AES-256-GCM with random IVs — ciphertext, IV, and auth tag stored separately
- Proxy pattern: agents call
use_secret(reads) oruse_secret_write(writes) → server decrypts → injects into HTTP request → returns only the response - RLS policies restrict secret access to playbook owner and service role
Deployment
GitHub Repository
│
▼
GitHub Actions (CI/CD)
│
├──► Build Next.js ──► Cloudflare Pages
│
└──► Build Workers ──► Cloudflare WorkersThe entire application could be deployed to Cloudflare's edge network.