Skip to content

CAAL Tool API

Corey McCallum edited this page Jan 31, 2026 · 1 revision

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.

Architecture Overview

┌─────────────────────────────────────────────────────────────────────┐
│                         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)    │  │
│  └─────────────┘   └──────────────┘   └──────────────────────────┘  │
└─────────────────────────────────────────────────────────────────────┘

Tool Spec

Every CAAL tool is an n8n workflow exposed via MCP. The spec defines how tools are structured so CAAL can discover and call them.

Required Elements

  1. Webhook trigger with httpMethod: POST
  2. Webhook notes describing the tool for the LLM (see How Tool Calling Works)
  3. MCP enabled via settings.availableInMCP: true
  4. Voice-friendly response with message (spoken aloud) + structured data (for follow-ups)

Tool Types

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 action parameter - 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

Webhook Description

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 - query not "search term"
  • Disambiguate similar params - explain when to use days vs target_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)

Response Format

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.


Registry

The CAAL Tool Registry is where community tools are published. Think of it as an app store for CAAL capabilities.

Tool Package Structure

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

manifest.json

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

Registry Index

Tools are cataloged in index.json, auto-generated on every merge to main. CAAL's frontend fetches this to display the tool browser.

Install Flow

  1. User browses tools in CAAL web UI (Tools panel)
  2. Clicks "Install" on a tool
  3. 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)
  4. CAAL imports the workflow into n8n, substitutes variables, links credentials, activates it
  5. Tool is immediately available via voice

Submission Pipeline

The submission pipeline handles how tools go from a user's n8n instance to the public registry.

Submission Flow

┌────────────────────────────────────────────────────────────────┐
│  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                        │
└────────────────────────────────────────────────────────────────┘

Alternative Submission: CLI

For bulk submissions or users not running CAAL:

cd caal-tools
node scripts/intake.js ~/Downloads/my-workflow.json

The intake script handles sanitization, prompts for metadata, and generates the tool package locally. Then submit a PR manually.

Client-Side Sanitization

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)

OAuth & Attribution

Tool submissions use GitHub OAuth so PRs show the submitting user as author:

  1. User clicks "Submit with GitHub" on the form
  2. OAuth flow grants public_repo,workflow scope
  3. VPS pre-creates a fork of caal-tools on user's GitHub
  4. PR is opened from user's fork, attributed to them
  5. Fallback: if fork fails, bot creates PR with user attribution in commit metadata

Automated Review

Every PR triggers a review bot that checks:

  • Critical (blocks merge): No hardcoded secrets, credential IDs null, webhook description exists, settings whitelist (availableInMCP + callerPolicy only), voice triggers present, valid category, POST method, MCP enabled
  • Warnings (non-blocking): Description quality, voice-friendly responses, error handling, response latency, code node syntax

API Endpoints

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

Workflow Settings

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.

Parameterization

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=...)

Quality Tiers

Tier Badge Meaning
CoreWorxLab Gold Official tools maintained by CoreWorxLab
Community Silver Community-contributed tools

Related Pages