headlo-mcp
v1.0.3
Published
Headlo MCP server — use standalone or extend with your own tools and middleware
Downloads
403
Maintainers
Readme
Headlo MCP Server
MCP server for Headlo — gives Claude Desktop and Claude Code access to your Headlo collections, records, pages, and components.
Use it as a standalone server, or install as a library to add your own tools and intercept built-in ones.
Quickstart
Claude Desktop
Edit claude_desktop_config.json (Mac: ~/Library/Application Support/Claude/, Windows: %APPDATA%\Claude\):
{
"mcpServers": {
"headlo": {
"command": "npx",
"args": ["headlo-mcp"],
"env": {
"HEADLO_API_TOKEN": "hl_pat_your_token_here"
}
}
}
}Restart Claude Desktop. You should see the Headlo tools available.
Claude Code
claude mcp add headlo -e HEADLO_API_TOKEN=hl_pat_your_token_here -- npx headlo-mcpRemote MCP (no install)
If you don't need to extend the server, point Claude directly at the Headlo API:
claude mcp add headlo https://api.headlo.com/v1/mcp --header "Authorization: Bearer hl_pat_your_token_here"Extending the server
Install as a library to add your own tools or intercept built-in ones:
npm install headlo-mcp @modelcontextprotocol/sdkAdd custom tools
import { createHeadloServer } from 'headlo-mcp'
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'
import { z } from 'zod'
const server = createHeadloServer()
// your own tool alongside the built-ins
server.tool('my_crm_lookup', 'Look up a contact in my CRM', { email: z.string() }, async ({ email }) => {
const contact = await myCRM.find(email)
return { content: [{ type: 'text', text: JSON.stringify(contact) }] }
})
await server.connect(new StdioServerTransport())Intercept built-in tool calls
Pass a wrap map to run code before or after any built-in tool:
import { createHeadloServer } from 'headlo-mcp'
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'
const server = createHeadloServer({
wrap: {
// validate before creating a record, sync to CRM after
create_record: async (args, next) => {
await mySchema.validate(args)
const result = await next(args)
await myCRM.push(result)
return result
},
// log every CAP session to your analytics
cap_capture_expert: async (args, next) => {
const result = await next(args)
await myAnalytics.track(args.cap_id, result)
return result
},
}
})
await server.connect(new StdioServerTransport())next(args) calls the original Headlo handler. You can modify args before passing them, or modify the result before returning it.
Environment variables
| Variable | Required | Description |
|---|---|---|
| HEADLO_API_TOKEN | Yes | Your Headlo API token (hl_pat_...) |
| HEADLO_API_URL | No | API base URL (default: https://api.headlo.com) |
| HEADLO_ANON_KEY | No | Anon key for public tool calls |
Built-in tools
Context
| Tool | Description |
|---|---|
| get_context | List all sites and workspaces — call this first |
Collections
| Tool | Description |
|---|---|
| list_collections | List all collections in a workspace |
| create_collection | Create a new collection with a schema |
| update_collection | Update a collection label or schema |
Records
| Tool | Description |
|---|---|
| list_records | List records in a collection (includes drafts) |
| get_record | Get a single record by ID |
| create_record | Create a new record |
| update_record | Update a record (partial — only provided fields change) |
| delete_record | Delete a record |
Pages
| Tool | Description |
|---|---|
| list_pages | List all pages for a site |
| create_page | Create a new page |
| update_page | Update a page title, layout, or status |
Modules
| Tool | Description |
|---|---|
| list_modules_editor | List all modules on a page |
| create_module | Add a module to a page slot |
| update_module | Update a module's record, options, or template |
| delete_module | Remove a module from a page |
Public
| Tool | Description |
|---|---|
| list_page_modules | List modules on a page (anon auth) |
| get_module | Get a single module (anon auth) |
CAP (Context Accumulation Protocol)
CAP is Headlo's expert intake system — structured question flows backed by pre-researched knowledge that produce better AI answers than generic prompts.
| Tool | Description |
|---|---|
| create_expert_protocol | Create a new CAP with intake questions and knowledge probes for a question on the Ask network |
| cap_capture_expert | Run a CAP as a live multi-turn intake session — call with empty message to start, pass answers in subsequent calls |
| cap_edit_expert | Conversationally edit an existing CAP — add/remove questions, edit options |
Running a CAP session (multi-turn):
// Turn 1 — load the CAP (empty message)
const t1 = await cap_capture_expert({ cap_id: 'abc123def456', message: '' })
// → { response: "Question 1 of 3: ...", session_state: {...}, complete: false }
// Turn 2 — answer the first question, pass session_state back
const t2 = await cap_capture_expert({ cap_id: 'abc123def456', message: 'Downtown', session_state: t1.session_state })
// → { response: "Question 2 of 3: ...", session_state: {...}, complete: false }
// Turn 3 — final answer
const t3 = await cap_capture_expert({ cap_id: 'abc123def456', message: 'Coffee shops', session_state: t2.session_state })
// → { response: "...", complete: true, answer: "..." }Intercepting CAP calls with middleware:
const server = createHeadloServer({
wrap: {
cap_capture_expert: async (args, next) => {
const result = await next(args)
// log every completed session to your analytics
if (result.complete) await myAnalytics.track(args.cap_id, result)
return result
},
}
})Onboarding
| Tool | Description |
|---|---|
| setup_agency | Create a new agency/workspace |
| create_site | Create a new site |
| save_branding | Save logo and brand color |
| get_onboarding_progress | Get current onboarding step |
License
Elastic License 2.0 — © Headlo
Source available. Free for internal use. Production self-hosting requires a commercial license.
Built by Headlo.
