-
Notifications
You must be signed in to change notification settings - Fork 95
CAAL Tool API
The CAAL Tool API is the complete system for building, sharing, and installing voice-callable tools. It covers everything from how tools are structured, to how they're submitted to the registry, to how users install them.
┌─────────────────────────────────────────────────────────────────────┐
│ CAAL Tool API │
│ │
│ ┌─────────────┐ ┌──────────────┐ ┌──────────────────────────┐ │
│ │ Tool Spec │ │ Registry │ │ Submission Pipeline │ │
│ │ │ │ │ │ │ │
│ │ • Webhook │ │ • caal-tools │ │ 1. Sanitize (client) │ │
│ │ • Notes │ │ • manifest │ │ 2. Metadata (VPS LLM) │ │
│ │ • MCP │ │ • index.json │ │ 3. PR (GitHub fork) │ │
│ │ • Switch │ │ • Install UI │ │ 4. Review (automated) │ │
│ └─────────────┘ └──────────────┘ └──────────────────────────┘ │
└─────────────────────────────────────────────────────────────────────┘
Every CAAL tool is an n8n workflow exposed via MCP. The spec defines how tools are structured so CAAL can discover and call them.
-
Webhook trigger with
httpMethod: POST - Webhook notes describing the tool for the LLM (see How Tool Calling Works)
-
MCP enabled via
settings.availableInMCP: true -
Voice-friendly response with
message(spoken aloud) + structured data (for follow-ups)
Tool Suites (preferred) - A single workflow handling multiple related actions via a Switch node:
Webhook → Switch (action) → [get] → HTTP Request → Code → Respond
→ [add] → HTTP Request → Code → Respond
→ [delete] → HTTP Request → Code → Respond
-
Naming:
service(snake_case) - e.g.,google_tasks,truenas,espn_nhl -
Routes on
actionparameter - get, add, complete, delete, etc. - Shared credentials, error handling, and rate limiting across actions
Individual Tools - Single-purpose tools that don't fit a suite:
-
Naming:
service_action_object- e.g.,weather_get_forecast,date_calculate_days_until
The webhook node's notes field is how the LLM knows what your tool does and what parameters to send. CAAL passes this text directly as the tool description - there's no schema validation, the LLM interprets it.
Key principles:
- Start broad, then scope - "Weather tool - forecast and current conditions for Australia" not "Australian weather tool"
-
Use exact parameter names -
querynot "search term" -
Disambiguate similar params - explain when to use
daysvstarget_day - Include examples mapping natural language to parameters
Example:
Weather tool - forecast and current conditions for Australia.
Parameters:
- action (required): 'forecast' or 'current'
- location (required): city, suburb, or postcode
- days (optional, default 7): forecast days ahead (1-7), use for 'next week' queries
- target_day (optional): specific weekday like 'Monday', use only for 'on Friday' style queries
Examples: 'Sydney weather', 'Melbourne next week' (days=7)
return {
message: "Brief voice response here", // Spoken aloud
games: [...] // Structured data for follow-up questions
};Always return both. The message is read aloud; the data is cached so follow-up questions don't need another API call.
The CAAL Tool Registry is where community tools are published. Think of it as an app store for CAAL capabilities.
Every registry tool has three files in tools/{category}/{tool-name}/:
tools/homelab/truenas-get-status/
├── workflow.json # n8n workflow (parameterized, no secrets)
├── manifest.json # Metadata (name, category, voice triggers, credentials, variables)
└── README.md # Setup instructions
Key fields:
| Field | Description |
|---|---|
name |
Tool identifier (kebab-case) |
version |
Semantic version (e.g., 1.0.0) |
category |
smart-home, media, homelab, productivity, developer, utilities, sports, social, other |
description |
Voice-friendly one-line description |
voice_triggers |
2+ natural phrases users might say |
toolSuite |
true if workflow uses Switch node for multiple actions |
actions |
Array of action names (if tool suite) |
required_credentials |
n8n credential types needed |
required_variables |
User-specific config (URLs, IDs) with descriptions and examples |
Tools are cataloged in index.json, auto-generated on every merge to main. CAAL's frontend fetches this to display the tool browser.
- User browses tools in CAAL web UI (Tools panel)
- Clicks "Install" on a tool
- Fill in required configuration:
-
Variables - Service URLs, IDs (e.g.,
TRUENAS_URL: http://192.168.1.100) -
Credentials - n8n credential names (e.g.,
truenas_api)
-
Variables - Service URLs, IDs (e.g.,
- CAAL imports the workflow into n8n, substitutes variables, links credentials, activates it
- Tool is immediately available via voice
The submission pipeline handles how tools go from a user's n8n instance to the public registry.
┌────────────────────────────────────────────────────────────────┐
│ 1. CAAL Frontend (Your Browser) │
│ │
│ User clicks "Share" on their workflow │
│ • Sanitizes workflow locally (secrets never sent) │
│ • Strips credential IDs, cached names, instance data │
│ • Shows security confirmation dialog │
│ • POSTs sanitized workflow to registry.caal.io │
└────────────────────────┬───────────────────────────────────────┘
│
▼
┌────────────────────────────────────────────────────────────────┐
│ 2. VPS Metadata Generation (registry.caal.io) │
│ │
│ • LLM analyzes workflow structure │
│ • Suggests name, category, description, voice triggers │
│ • Detects credentials from node types │
│ • Smart URL/IP parameterization (192.168.x.x → ${SERVICE_URL})│
│ • Returns suggested metadata to submission form │
└────────────────────────┬───────────────────────────────────────┘
│
▼
┌────────────────────────────────────────────────────────────────┐
│ 3. Submission Form │
│ │
│ • Pre-filled with LLM suggestions │
│ • User reviews/edits metadata │
│ • GitHub OAuth for attribution (PR shows as user's) │
│ • Click "Submit" │
└────────────────────────┬───────────────────────────────────────┘
│
▼
┌────────────────────────────────────────────────────────────────┐
│ 4. PR Creation │
│ │
│ • Forks caal-tools to user's GitHub (pre-created at OAuth) │
│ • Syncs fork with upstream │
│ • Pushes tool files to fork branch │
│ • Opens PR from user's fork → CoreWorxLab/caal-tools │
│ • PR attributed to the submitting user │
└────────────────────────┬───────────────────────────────────────┘
│
▼
┌────────────────────────────────────────────────────────────────┐
│ 5. Automated Review │
│ │
│ • GitHub webhook triggers review bot │
│ • Validates: secrets, credentials, settings, description, │
│ voice triggers, category, webhook method, MCP enabled │
│ • Posts review comment with verdict + feedback │
│ • Labels PR: ready-to-merge or needs-changes │
└────────────────────────┬───────────────────────────────────────┘
│
▼
┌────────────────────────────────────────────────────────────────┐
│ 6. Merge & Publish │
│ │
│ • Maintainer reviews and merges │
│ • Registry index regenerates │
│ • Tool available to all CAAL instances │
└────────────────────────────────────────────────────────────────┘
For bulk submissions or users not running CAAL:
cd caal-tools
node scripts/intake.js ~/Downloads/my-workflow.jsonThe intake script handles sanitization, prompts for metadata, and generates the tool package locally. Then submit a PR manually.
Your secrets never leave your network.
When you click "Share", sanitization runs entirely in your browser:
| What | Action |
|---|---|
| API keys, tokens, passwords | Blocked (submission fails if detected) |
| Credential IDs and names | Stripped (set to null) |
| Cached resource names (e.g., "Cor's Calendar") | Stripped (privacy) |
| Instance IDs, version IDs | Stripped |
| URLs and IPs | Sent to VPS for smart parameterization (not secrets) |
Tool submissions use GitHub OAuth so PRs show the submitting user as author:
- User clicks "Submit with GitHub" on the form
- OAuth flow grants
public_repo,workflowscope - VPS pre-creates a fork of caal-tools on user's GitHub
- PR is opened from user's fork, attributed to them
- Fallback: if fork fails, bot creates PR with user attribution in commit metadata
Every PR triggers a review bot that checks:
-
Critical (blocks merge): No hardcoded secrets, credential IDs null, webhook description exists, settings whitelist (
availableInMCP+callerPolicyonly), voice triggers present, valid category, POST method, MCP enabled - Warnings (non-blocking): Description quality, voice-friendly responses, error handling, response latency, code node syntax
The submission API runs at registry.caal.io:
| Endpoint | Method | Description |
|---|---|---|
/api/submit/intake |
POST | Receives sanitized workflow, generates metadata suggestions |
/api/submit/{session_id} |
GET | Retrieves session data for form pre-population |
/api/submit/create-pr |
POST | Creates GitHub PR with tool files |
/api/oauth/login |
GET | Initiates GitHub OAuth flow |
/api/oauth/callback |
GET | Handles OAuth callback, returns token |
/api/analytics/install |
POST | Tracks tool installation |
/api/analytics/counts |
GET | Returns install counts by tool |
/api/analytics/top |
GET | Returns most installed tools |
/api/icons/search |
GET | Search available tool icons |
Registry tools must use specific n8n workflow settings:
"settings": {
"availableInMCP": true,
"callerPolicy": "workflowsFromSameOwner"
}Only availableInMCP and callerPolicy are allowed. Other settings (e.g., executionOrder, timeSavedMode) cause the n8n API to reject the workflow during import.
All user-specific values use CAAL's variable syntax (${VARIABLE_NAME}), which is replaced before importing into n8n:
"url": "${TRUENAS_URL}/api/v2.0"This is NOT n8n's native expression syntax (={{ $vars.X }}). CAAL does simple string replacement before the workflow reaches n8n.
Tool authors can add PARAMETERIZE: blocks in node notes to provide "where to find" guidance that appears as helper text in the install modal:
PARAMETERIZE:
- databaseId: Your Notion task database
Find: In URL when viewing database (notion.so/{workspace}/{DATABASE_ID}?v=...)
| Tier | Badge | Meaning |
|---|---|---|
| CoreWorxLab | Gold | Official tools maintained by CoreWorxLab |
| Community | Silver | Community-contributed tools |
- How Tool Calling Works - How CAAL discovers and executes tools via MCP
- Tool Registry - Browsing, installing, and submitting tools (user guide)
- Contributing Guide - Step-by-step submission instructions
- n8n Integration - n8n MCP setup and configuration
Getting Started
Architecture
Tools
Integrations
Language Support
Deployment
Links