Skip to content

Commit dad13f7

Browse files
plcclaude
andcommitted
MCP overhaul: 24 tools, remote endpoint, agent guide
- Expand MCP from 8 to 24 tools matching every REST endpoint (agent management, SMTP config, full calendar/event CRUD, debugging, discovery) - Add missing parameters to existing tools (metadata, attendees, status, webhook config, welcome_event) - Add remote MCP endpoint at /mcp via Streamable HTTP transport — agents connect with just a URL and API key, no local install needed - Extract shared tool registration into src/lib/mcp-tools.mjs, used by both STDIO and HTTP transports - Rewrite MCP instructions as structured agent-facing quick-start guide - Add caldave://guide MCP resource with comprehensive getting-started docs (setup checklist, workflow examples, field reference, tool catalog) - Update CALDAVE_SPEC.md, README.md, CHANGELOG.md, and /changelog route Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 93d87fe commit dad13f7

File tree

8 files changed

+955
-188
lines changed

8 files changed

+955
-188
lines changed

CALDAVE_SPEC.md

Lines changed: 71 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -520,20 +520,81 @@ For AgentMail, set the `agentmail_api_key` on the calendar via `POST /calendars`
520520

521521
For agents using MCP, CalDave exposes these tools:
522522

523+
**Agent Management**
524+
525+
| Tool | Description |
526+
|------|-------------|
527+
| `caldave_get_agent` | Get the authenticated agent profile (name, description, created_at). |
528+
| `caldave_update_agent` | Update agent name or description. Name appears in outbound email From headers. |
529+
530+
**SMTP Configuration**
531+
532+
| Tool | Description |
533+
|------|-------------|
534+
| `caldave_set_smtp` | Configure SMTP for outbound invite/RSVP emails. |
535+
| `caldave_get_smtp` | View SMTP configuration (password excluded). |
536+
| `caldave_delete_smtp` | Remove SMTP configuration. Reverts to CalDave built-in delivery. |
537+
| `caldave_test_smtp` | Send a test email to verify SMTP configuration. |
538+
539+
**Calendars**
540+
523541
| Tool | Description |
524542
|------|-------------|
525-
| `caldave_create_calendar` | Create a new calendar. Returns calendar ID, email, and feed URL. |
526543
| `caldave_list_calendars` | List all calendars for this agent. |
527-
| `caldave_get_upcoming` | Get next N events from a calendar. |
528-
| `caldave_create_event` | Create an event on a calendar. |
529-
| `caldave_update_event` | Update an existing event. |
544+
| `caldave_get_calendar` | Get a single calendar by ID with full details. |
545+
| `caldave_create_calendar` | Create a new calendar. Returns calendar ID, email, and feed URL. |
546+
| `caldave_update_calendar` | Update calendar settings (name, timezone, webhook config). |
547+
| `caldave_delete_calendar` | Delete a calendar and all its events. |
548+
| `caldave_test_webhook` | Send a test payload to the calendar webhook URL. |
549+
550+
**Events**
551+
552+
| Tool | Description |
553+
|------|-------------|
554+
| `caldave_get_upcoming` | Get next N events from a calendar. Designed for agent polling. |
555+
| `caldave_list_events` | List events with optional date range and status filters. |
556+
| `caldave_get_event` | Get a single event by ID. |
557+
| `caldave_view_calendar` | Plain text table of upcoming events for quick inspection. |
558+
| `caldave_create_event` | Create an event. Supports recurring (RRULE), metadata, and attendees. |
559+
| `caldave_update_event` | Update an existing event. Supports metadata, attendees, and recurrence changes. |
530560
| `caldave_delete_event` | Delete an event. |
531561
| `caldave_respond_to_invite` | Accept/decline an inbound invite. |
532-
| `caldave_list_events` | List events with optional date range and status filters. |
562+
563+
**Debugging & Discovery**
564+
565+
| Tool | Description |
566+
|------|-------------|
567+
| `caldave_list_errors` | Query recent API errors for your agent. |
568+
| `caldave_get_error` | Get a single error with full stack trace. |
569+
| `caldave_get_changelog` | API changelog with personalized recommendations. |
570+
| `caldave_get_manual` | Machine-readable API manual with all endpoints and curl examples. |
533571

534572
### Configuration
535573

536-
The MCP server (`src/mcp.mjs`) uses STDIO transport. Configure it in your MCP client:
574+
CalDave supports two MCP transports:
575+
576+
#### Option 1: Remote URL (Recommended)
577+
578+
No installation needed. Point your MCP client at the CalDave server URL:
579+
580+
```json
581+
{
582+
"mcpServers": {
583+
"caldave": {
584+
"url": "https://caldave.ai/mcp",
585+
"headers": {
586+
"Authorization": "Bearer sk_live_..."
587+
}
588+
}
589+
}
590+
}
591+
```
592+
593+
The remote endpoint uses Streamable HTTP transport with session management. Auth is via your API key in the `Authorization` header.
594+
595+
#### Option 2: Local STDIO
596+
597+
For local development or offline use, run the STDIO server directly:
537598

538599
**Claude Desktop** (`~/Library/Application Support/Claude/claude_desktop_config.json`):
539600
```json
@@ -543,7 +604,8 @@ The MCP server (`src/mcp.mjs`) uses STDIO transport. Configure it in your MCP cl
543604
"command": "node",
544605
"args": ["/path/to/caldave/src/mcp.mjs"],
545606
"env": {
546-
"CALDAVE_API_KEY": "sk_live_..."
607+
"CALDAVE_API_KEY": "sk_live_...",
608+
"CALDAVE_URL": "https://caldave.ai"
547609
}
548610
}
549611
}
@@ -558,7 +620,8 @@ The MCP server (`src/mcp.mjs`) uses STDIO transport. Configure it in your MCP cl
558620
"command": "node",
559621
"args": ["/path/to/caldave/src/mcp.mjs"],
560622
"env": {
561-
"CALDAVE_API_KEY": "sk_live_..."
623+
"CALDAVE_API_KEY": "sk_live_...",
624+
"CALDAVE_URL": "https://caldave.ai"
562625
}
563626
}
564627
}

CHANGELOG.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,18 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
66

77
## [Unreleased]
88

9+
### Added
10+
- **MCP server at full parity with API** — Added 16 new MCP tools covering all documented API endpoints. Previously the MCP server only had 8 core tools; it now exposes 24 tools matching every REST endpoint:
11+
- **Agent management**: `caldave_get_agent`, `caldave_update_agent`
12+
- **SMTP configuration**: `caldave_set_smtp`, `caldave_get_smtp`, `caldave_delete_smtp`, `caldave_test_smtp`
13+
- **Calendar management**: `caldave_get_calendar`, `caldave_update_calendar`, `caldave_delete_calendar`, `caldave_test_webhook`
14+
- **Event tools**: `caldave_get_event`, `caldave_view_calendar`
15+
- **Debugging**: `caldave_list_errors`, `caldave_get_error`
16+
- **Discovery**: `caldave_get_changelog`, `caldave_get_manual`
17+
- **Missing parameters on existing MCP tools**`caldave_create_event` now supports `metadata`, `attendees`, and `status`. `caldave_update_event` now supports `metadata`, `attendees`, and `recurrence`. `caldave_create_calendar` now supports `webhook_url`, `webhook_secret`, `webhook_offsets`, `agentmail_api_key`, and `welcome_event`.
18+
- **Remote MCP endpoint at `/mcp`** — CalDave now serves an MCP endpoint via Streamable HTTP transport. Agents can connect with just a URL and API key (`{ "url": "https://caldave.ai/mcp", "headers": { "Authorization": "Bearer sk_live_..." } }`) — no local installation required. Sessions are stateful with automatic 30-minute TTL cleanup.
19+
- **MCP agent guide** — Enhanced MCP instructions with structured quick-start, workflow descriptions, and tool selection guide. Added `caldave://guide` MCP resource with a comprehensive getting-started guide for agents (setup checklist, code examples, event fields reference, webhook/SMTP config, debugging).
20+
921
### Improved
1022
- **Auth performance** — Added missing database index on `agents.api_key_hash`. Auth lookups now use an index scan instead of a full table scan on every authenticated request.
1123
- **`/docs` caching** — Static HTML documentation is pre-computed at startup and served with `Cache-Control: public, max-age=86400`. Eliminates ~30KB of string construction per request.

README.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ A calendar-as-a-service API for AI agents. Agents own calendars, create and mana
2020
- **PostgreSQL** database with auto-initializing schema
2121
- **Docker** setup for local development
2222
- **Fly.io** configuration for production deployment
23-
- **MCP server** for AI agents using the Model Context Protocol
23+
- **MCP server** — remote endpoint at `/mcp` (Streamable HTTP) and local STDIO transport
2424
- **Status page** at `/` showing server and database health
2525

2626
## Prerequisites
@@ -88,6 +88,7 @@ curl -s "http://127.0.0.1:3720/calendars/CAL_ID/upcoming" \
8888
| `POST /calendars/:id/events/:eid/respond` | Yes | Accept/decline invite |
8989
| `GET /feeds/:id.ics?token=TOKEN` | Feed token | iCal feed (subscribable) |
9090
| `POST /inbound/:token` | Token in URL | Inbound email webhook (per-calendar) |
91+
| `POST\|GET\|DELETE /mcp` | Yes | Remote MCP endpoint (Streamable HTTP transport) |
9192

9293
Auth = `Authorization: Bearer <api_key>` (except feeds and inbound webhook)
9394

@@ -103,6 +104,7 @@ See [CALDAVE_SPEC.md](CALDAVE_SPEC.md) for full request/response examples.
103104
│ ├── lib/
104105
│ │ ├── ids.js # nanoid-based ID generation (agt_, cal_, evt_, inb_)
105106
│ │ ├── keys.js # SHA-256 API key hashing
107+
│ │ ├── mcp-tools.mjs # Shared MCP tool registration (24 tools)
106108
│ │ └── recurrence.js # RRULE parsing + instance materialization
107109
│ ├── middleware/
108110
│ │ ├── auth.js # Bearer token auth
@@ -113,7 +115,7 @@ See [CALDAVE_SPEC.md](CALDAVE_SPEC.md) for full request/response examples.
113115
│ ├── events.js # Event CRUD + upcoming + respond
114116
│ ├── feeds.js # iCal feed generation
115117
│ └── inbound.js # Inbound email webhook (per-calendar token URL)
116-
│ └── mcp.mjs # MCP server (STDIO transport, 8 tools)
118+
│ └── mcp.mjs # MCP server (STDIO transport, 24 tools)
117119
├── scripts/
118120
│ ├── init-db.sh # Creates database if it doesn't exist
119121
│ └── get-port.sh # Generates deterministic port from project name

src/index.js

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,12 @@ curl -s "https://${DOMAIN}/man?guide"</code></pre>
165165
res.send(html);
166166
});
167167

168+
// Remote MCP endpoint (Streamable HTTP transport, auth handled internally)
169+
// Mounted via dynamic import in start() since route file is ESM
170+
app.post('/mcp', (req, res, next) => { if (app._mcpHandlers) app._mcpHandlers.handlePost(req, res).catch(next); else res.status(503).json({ error: 'MCP endpoint loading' }); });
171+
app.get('/mcp', (req, res, next) => { if (app._mcpHandlers) app._mcpHandlers.handleGet(req, res).catch(next); else res.status(503).json({ error: 'MCP endpoint loading' }); });
172+
app.delete('/mcp', (req, res, next) => { if (app._mcpHandlers) app._mcpHandlers.handleDelete(req, res).catch(next); else res.status(503).json({ error: 'MCP endpoint loading' }); });
173+
168174
// API documentation, quick start, and legal pages (no auth)
169175
app.use('/docs', docsRouter);
170176
app.use('/quickstart', quickstartRouter);
@@ -281,6 +287,15 @@ async function start() {
281287
console.error('Server starting without schema — DB may not be ready yet');
282288
}
283289

290+
// Load ESM MCP route handlers
291+
try {
292+
const mcpHandlers = await import('./routes/mcp.mjs');
293+
app._mcpHandlers = mcpHandlers;
294+
console.log('MCP HTTP endpoint loaded at /mcp');
295+
} catch (err) {
296+
console.error('Failed to load MCP HTTP route:', err.message);
297+
}
298+
284299
// Extend materialization horizons for recurring events
285300
extendAllHorizons(pool).catch(err => {
286301
console.error('Failed to extend horizons on startup:', err.message);

0 commit comments

Comments
 (0)