dav-mcp 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. package/CHANGELOG.md +45 -0
  2. package/LICENSE +21 -0
  3. package/README.md +260 -0
  4. package/package.json +80 -0
  5. package/src/error-handler.js +215 -0
  6. package/src/formatters.js +754 -0
  7. package/src/logger.js +144 -0
  8. package/src/server-http.js +402 -0
  9. package/src/server-stdio.js +225 -0
  10. package/src/tool-call-logger.js +148 -0
  11. package/src/tools/calendar/calendar-multi-get.js +38 -0
  12. package/src/tools/calendar/calendar-query.js +98 -0
  13. package/src/tools/calendar/create-event.js +79 -0
  14. package/src/tools/calendar/delete-calendar.js +36 -0
  15. package/src/tools/calendar/delete-event.js +38 -0
  16. package/src/tools/calendar/index.js +16 -0
  17. package/src/tools/calendar/list-calendars.js +21 -0
  18. package/src/tools/calendar/list-events.js +43 -0
  19. package/src/tools/calendar/make-calendar.js +80 -0
  20. package/src/tools/calendar/update-calendar.js +106 -0
  21. package/src/tools/calendar/update-event-fields.js +119 -0
  22. package/src/tools/calendar/update-event-raw.js +45 -0
  23. package/src/tools/contacts/addressbook-multi-get.js +38 -0
  24. package/src/tools/contacts/addressbook-query.js +85 -0
  25. package/src/tools/contacts/create-contact.js +84 -0
  26. package/src/tools/contacts/delete-contact.js +38 -0
  27. package/src/tools/contacts/index.js +13 -0
  28. package/src/tools/contacts/list-addressbooks.js +21 -0
  29. package/src/tools/contacts/list-contacts.js +32 -0
  30. package/src/tools/contacts/update-contact-fields.js +135 -0
  31. package/src/tools/contacts/update-contact-raw.js +45 -0
  32. package/src/tools/index.js +57 -0
  33. package/src/tools/shared/helpers.js +132 -0
  34. package/src/tools/todos/create-todo.js +101 -0
  35. package/src/tools/todos/delete-todo.js +38 -0
  36. package/src/tools/todos/index.js +12 -0
  37. package/src/tools/todos/list-todos.js +30 -0
  38. package/src/tools/todos/todo-multi-get.js +37 -0
  39. package/src/tools/todos/todo-query.js +112 -0
  40. package/src/tools/todos/update-todo-fields.js +119 -0
  41. package/src/tools/todos/update-todo-raw.js +46 -0
  42. package/src/tsdav-client.js +199 -0
  43. package/src/utils/tool-helpers.js +388 -0
  44. package/src/validation.js +245 -0
package/CHANGELOG.md ADDED
@@ -0,0 +1,45 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
8
+ ## [Unreleased]
9
+
10
+ ## [2.7.0] - 2025-10-30
11
+
12
+ ### Added
13
+ - **OAuth2 Authentication Support**: Full OAuth2 support for Google Calendar and other OAuth2-enabled CalDAV servers
14
+ - New `AUTH_METHOD` environment variable to switch between Basic Auth and OAuth2
15
+ - Support for Google Calendar via OAuth2 with automatic token refresh
16
+ - CalDAV discovery via RFC 4791 (no Google Calendar API required)
17
+ - Tested with Google Calendar (5 calendars discovered and fully functional)
18
+ - All CRUD operations (Create, Read, Update, Delete) working with OAuth2
19
+ - OAuth2 test suite with 10 comprehensive test cases
20
+ - OAuth2 configuration in `.env.example` with detailed setup instructions
21
+
22
+ ### Changed
23
+ - **Field-agnostic updates**: Integrated tsdav-utils for universal field update support
24
+ - `update_event` now supports all RFC 5545 iCalendar properties (SUMMARY, DESCRIPTION, LOCATION, DTSTART, DTEND, STATUS, etc.)
25
+ - `update_todo` now supports all RFC 5545 VTODO properties (SUMMARY, DESCRIPTION, STATUS, PRIORITY, DUE, PERCENT-COMPLETE, etc.)
26
+ - `update_contact` now supports all RFC 6350 vCard properties (FN, N, EMAIL, TEL, ORG, TITLE, NOTE, URL, ADR, BDAY, etc.)
27
+ - All update tools now accept custom X-* properties for extensions (e.g., X-ZOOM-LINK, X-MEETING-ROOM)
28
+ - Replaced manual iCal/vCard string manipulation with structured field updates via tsdav-utils
29
+ - Simplified update tool implementations (reduced code by 40-45% per tool)
30
+ - Updated input schemas to accept any RFC property name (field-agnostic validation)
31
+ - Enhanced `tsdav-client.js` to support both Basic Auth and OAuth2 authentication methods
32
+ - Updated `index.js` initialization logic to auto-detect authentication method
33
+
34
+ ### Dependencies
35
+ - Added: tsdav-utils (v0.1.0) - Field-agnostic utility layer for RFC-compliant updates
36
+
37
+ ### Compatibility
38
+ - Fully backward compatible with existing Basic Auth setup
39
+ - No breaking changes - existing configurations continue to work
40
+ - Google Calendar tested and verified with OAuth2
41
+
42
+ ## [2.6.0] - Previous Release
43
+
44
+ Initial release with 26 MCP tools for CalDAV, CardDAV, and VTODO operations.
45
+
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 tsdav-mcp-server contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,260 @@
1
+ # dav-mcp
2
+
3
+ **Give your AI agents the power of organization** — Transform them into orchestrating assistants managing calendars, contacts, and tasks.
4
+
5
+ Built on 26 production-ready tools spanning CalDAV, CardDAV, and VTODO protocols.
6
+
7
+ Built for n8n, Claude Desktop, and any MCP client.
8
+
9
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
10
+ [![npm version](https://badge.fury.io/js/dav-mcp.svg)](https://www.npmjs.com/package/dav-mcp)
11
+
12
+ ---
13
+
14
+ ### The Orchestration
15
+
16
+ When partial tools force your AI to improvise, complete tools let it **execute precise operations across all components**.
17
+
18
+ | Capability | dav-mcp | Most MCPs |
19
+ |------------|---------|-------------------|
20
+ | **Calendar Management** | ✅ Full CRUD (11 tools) | ⚠️ Create + list only (2-3 tools) |
21
+ | **Contact Management** | ✅ Complete CardDAV (8 tools) | ❌ Often missing entirely |
22
+ | **Task Management** | ✅ Full VTODO support (7 tools) | ❌ Rarely included |
23
+ | **Field-Based Updates** | ✅ All RFC properties + custom fields | ❌ Rarely available |
24
+ | **Server-Side Filtering** | ✅ Efficient queries | ❌ Dumps all data |
25
+ | **Multi-Provider** | ✅ Any CalDAV/CardDAV server | ⚠️ Limited provider support |
26
+ | **Total Tools** | **26 tools** | **2-6 tools** |
27
+
28
+
29
+ ---
30
+
31
+ ## 🚀 Full Feature Set
32
+
33
+ ### Protocol Support
34
+ - **26 MCP Tools**: Full CRUD operations for calendars, contacts, and tasks
35
+ - **CalDAV Integration**: ~88% tsdav coverage (11 tools)
36
+ - **CardDAV Integration**: 100% tsdav coverage (8 tools)
37
+ - **VTODO Support**: Full task management with status, priorities, due dates (7 tools)
38
+ - **Field-Based Updates**: Field-agnostic updates via tsdav-utils - supports all RFC 5545/6350 properties + custom X-* fields
39
+ - **RFC-Compliant**: ical.js for RFC 5545 (iCalendar) and RFC 6350 (vCard) support
40
+
41
+ ### Production-Ready Infrastructure
42
+ - **MCP Protocol**: STDIO transport for local clients, Stateless HTTP for remote
43
+ - **Multi-Server Tested**: Works with Radicale, Baikal, Nextcloud, iCloud
44
+ - **Bearer Auth**: Token authentication for HTTP transport
45
+ - **Structured Logging**: Custom JSON logger with millisecond precision
46
+
47
+ ### Efficiency Features
48
+ - **Server-Side Filtering**: calendar_query, addressbook_query, todo_query with smart filters reduce data transfer
49
+ - **LLM-Optimized Tool Design**: PREFERRED/WARNING labels guide AI to efficient choices
50
+ - **Batch Operations**: multi_get tools fetch multiple specific items without loading entire collections
51
+
52
+ ---
53
+
54
+ ## 📋 Available Tools (26 Total)
55
+
56
+
57
+ ### CalDAV Tools (11 tools)
58
+
59
+ 1. **list_calendars** - List all available calendars
60
+ 2. **list_events** - List ALL events (⚠️ WARNING: use calendar_query for filtered searches)
61
+ 3. **create_event** - Create a new calendar event
62
+ 4. **update_event** - ⭐ PREFERRED: Update any event field (SUMMARY, LOCATION, DTSTART, STATUS, custom X-* properties)
63
+ 5. **update_event_raw** - Update event with raw iCal data (advanced)
64
+ 6. **delete_event** - Delete an event permanently
65
+ 7. **calendar_query** - ⭐ PREFERRED: Search and filter events efficiently by text, date range, or location
66
+ 8. **make_calendar** - Create a new calendar collection
67
+ 9. **update_calendar** - Update calendar properties (display name, description, color, timezone)
68
+ 10. **delete_calendar** - Permanently delete a calendar and all its events
69
+ 11. **calendar_multi_get** - Batch fetch multiple specific events by URLs
70
+
71
+ ### CardDAV Tools (8 tools)
72
+
73
+ 12. **list_addressbooks** - List all available address books
74
+ 13. **list_contacts** - List ALL contacts (⚠️ WARNING: use addressbook_query for filtered searches)
75
+ 14. **create_contact** - Create a new contact (vCard)
76
+ 15. **update_contact** - ⭐ PREFERRED: Update any contact field (FN, EMAIL, TEL, ORG, ADR, custom X-* properties)
77
+ 16. **update_contact_raw** - Update contact with raw vCard data (advanced)
78
+ 17. **delete_contact** - Delete a contact permanently
79
+ 18. **addressbook_query** - ⭐ PREFERRED: Search and filter contacts efficiently by name, email, or organization
80
+ 19. **addressbook_multi_get** - Batch fetch multiple specific contacts by URLs
81
+
82
+ ### VTODO Tools (7 tools)
83
+
84
+ 20. **list_todos** - List ALL todos/tasks (⚠️ WARNING: use todo_query for filtered searches)
85
+ 21. **create_todo** - Create a new todo/task with optional due date, priority, status
86
+ 22. **update_todo** - ⭐ PREFERRED: Update any todo field (SUMMARY, STATUS, PRIORITY, DUE, PERCENT-COMPLETE, custom X-* properties)
87
+ 23. **update_todo_raw** - Update todo with raw VTODO iCal data (advanced)
88
+ 24. **delete_todo** - Delete a todo/task permanently
89
+ 25. **todo_query** - ⭐ PREFERRED: Search and filter todos efficiently by status/due date
90
+ 26. **todo_multi_get** - Batch fetch multiple specific todos by URLs
91
+
92
+ ---
93
+
94
+ ## 💡 Real-World Applications
95
+
96
+ See how complete tool coverage transforms basic operations into powerful workflows.
97
+
98
+ ### n8n Automation Workflows
99
+ - **Meeting Management**: "Show me all Friday meetings" → calendar_query with date filter returns only relevant events
100
+ - **Contact Search**: "Find everyone at Google" → addressbook_query with org filter finds matches efficiently
101
+ - **Task Reporting**: "Show overdue high-priority tasks" → todo_query with filters returns specific results
102
+ - **Scheduled Cleanup**: Daily cron job deletes completed tasks using targeted queries
103
+
104
+ ### Claude Desktop Integration
105
+ - **Quick Event Creation**: "Create team meeting tomorrow 2 PM" → create_event executes immediately
106
+ - **Contact Lookup**: "What's Sarah's email?" → addressbook_query with name filter finds contact
107
+ - **Calendar Overview**: "What's on my calendar next week?" → calendar_query with date range shows events
108
+ - **Calendar Management**: "Create a new calendar called Project Luna" → make_calendar creates collection
109
+
110
+ ---
111
+
112
+ ## 🛠️ Start Orchestrating in 5 Minutes
113
+
114
+ ### Installation
115
+
116
+ ```bash
117
+ git clone https://github.com/PhilflowIO/dav-mcp.git
118
+ cd dav-mcp
119
+ npm install
120
+ cp .env.example .env
121
+ ```
122
+
123
+ ### Configuration
124
+
125
+ Edit `.env`:
126
+
127
+ ```env
128
+ # CalDAV/CardDAV Server
129
+ CALDAV_SERVER_URL=https://dav.example.com
130
+ CALDAV_USERNAME=your_username
131
+ CALDAV_PASSWORD=your_password
132
+
133
+ # MCP Server
134
+ PORT=3000
135
+ MCP_SERVER_NAME=dav-mcp
136
+ MCP_SERVER_VERSION=2.6.0
137
+
138
+ # Authentication (optional)
139
+ BEARER_TOKEN=your-secure-token-here
140
+ ```
141
+
142
+ ### Start Server
143
+
144
+ ```bash
145
+ npm start
146
+ # Server runs on: http://localhost:3000
147
+ ```
148
+
149
+ ---
150
+
151
+ ## 🔗 Integration
152
+
153
+ ### n8n Workflow
154
+
155
+ 1. **Start HTTP server**: `BEARER_TOKEN=your-token npm run start:http`
156
+ 2. **Add "AI Agent" node**
157
+ 3. **Add "MCP Client Tool" node** and connect to AI Agent
158
+ 4. **Configure the connection:**
159
+ - **MCP Endpoint**: `http://localhost:3000/mcp`
160
+ - **Authentication Method**: `Bearer`
161
+ - **Bearer Token**: Your token
162
+
163
+ 5. **Example prompts:**
164
+
165
+ ```
166
+ "List all my calendars"
167
+ "Create a meeting tomorrow at 2 PM"
168
+ "Show me all events in October"
169
+ "Find all contacts at Google"
170
+ "Create a new contact for Jane Smith"
171
+ "Show overdue tasks with high priority"
172
+ ```
173
+
174
+ ### Claude Desktop
175
+
176
+ Add to `claude_desktop_config.json`:
177
+
178
+ ```json
179
+ {
180
+ "mcpServers": {
181
+ "dav-mcp": {
182
+ "command": "node",
183
+ "args": ["/absolute/path/to/dav-mcp/src/server-stdio.js"],
184
+ "env": {
185
+ "CALDAV_SERVER_URL": "https://dav.example.com",
186
+ "CALDAV_USERNAME": "your_username",
187
+ "CALDAV_PASSWORD": "your_password"
188
+ }
189
+ }
190
+ }
191
+ }
192
+ ```
193
+
194
+ **Config file locations:**
195
+ - **macOS**: `~/Library/Application Support/Claude/claude_desktop_config.json`
196
+ - **Windows**: `%APPDATA%\Claude\claude_desktop_config.json`
197
+ - **Linux**: `~/.config/Claude/claude_desktop_config.json`
198
+
199
+ **Restart Claude Desktop** after adding the configuration.
200
+
201
+ ---
202
+
203
+ ## 🌐 Works Across All Major Providers
204
+
205
+ Works with any CalDAV/CardDAV server that follows RFC 4791 and RFC 6352:
206
+
207
+ - ✅ **Nextcloud** - Full support
208
+ - ✅ **Baikal** - Full support
209
+ - ✅ **Radicale** - Full support
210
+ - ✅ **iCloud** - Works with app-specific password
211
+ - ✅ **Any RFC-compliant server** - Standard protocol support
212
+
213
+
214
+ ## 🔒 Security
215
+
216
+ - **Input Validation**: All inputs validated with Zod schemas before execution
217
+ - **Rate Limiting**: 100 requests/minute per session
218
+ - **Bearer Auth**: Optional token authentication
219
+ - **No Credential Storage**: Pass-through only, never logged or cached
220
+ - **Structured Logging**: Audit trail with request IDs, no PII exposure
221
+ - **CORS Protection**: Whitelist origins, block cross-site attacks
222
+
223
+
224
+
225
+ ## 📚 Documentation
226
+
227
+ - **[MCP Specification](https://modelcontextprotocol.io/specification/2025-03-26)** - Model Context Protocol docs
228
+ - **[tsdav Docs](https://tsdav.vercel.app/docs/intro)** - CalDAV/CardDAV library reference
229
+ - **[CalDAV RFC 4791](https://datatracker.ietf.org/doc/html/rfc4791)** - CalDAV protocol specification
230
+ - **[CardDAV RFC 6352](https://datatracker.ietf.org/doc/html/rfc6352)** - CardDAV protocol specification
231
+
232
+ ---
233
+
234
+ ## 🤝 Contributing
235
+
236
+ Pull requests are welcome! Please read [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines.
237
+
238
+ ---
239
+
240
+ ## 📄 License
241
+
242
+ MIT License - see [LICENSE](LICENSE) for details
243
+
244
+ ---
245
+
246
+ ## 🙏 Acknowledgments
247
+
248
+ Built with:
249
+ - **[tsdav](https://github.com/natelindev/tsdav)** - Excellent TypeScript CalDAV/CardDAV library
250
+ - **[tsdav-utils](https://github.com/PhilflowIO/tsdav-utils)** - Field-agnostic utility layer for RFC-compliant field updates
251
+ - **[MCP SDK](https://modelcontextprotocol.io)** - Model Context Protocol by Anthropic
252
+ - **[ical.js](https://github.com/kewisch/ical.js)** - RFC-compliant iCalendar parser
253
+
254
+ ---
255
+
256
+ **Questions? Issues?** Create a [GitHub issue](https://github.com/PhilflowIO/dav-mcp/issues)
257
+
258
+ ---
259
+
260
+ *Built for AI agents managing calendars, contacts, and tasks*
package/package.json ADDED
@@ -0,0 +1,80 @@
1
+ {
2
+ "name": "dav-mcp",
3
+ "version": "3.0.0",
4
+ "description": "Complete DAV integration for AI - Calendar (CalDAV), Contacts (CardDAV), and Tasks (VTODO) management via MCP protocol",
5
+ "type": "module",
6
+ "main": "src/server-stdio.js",
7
+ "bin": {
8
+ "dav-mcp": "src/server-stdio.js"
9
+ },
10
+ "scripts": {
11
+ "start": "MCP_TRANSPORT=stdio node src/server-stdio.js",
12
+ "start:stdio": "MCP_TRANSPORT=stdio node src/server-stdio.js",
13
+ "start:http": "node src/server-http.js",
14
+ "dev": "MCP_TRANSPORT=stdio node --watch src/server-stdio.js",
15
+ "dev:http": "node --watch src/server-http.js",
16
+ "install:fresh": "rm -rf node_modules package-lock.json && npm cache clean --force && npm install",
17
+ "update:tsdav": "npm cache clean --force && npm install tsdav@github:PhilflowIO/tsdav#master",
18
+ "test": "NODE_ENV=test NODE_OPTIONS='--experimental-vm-modules' jest",
19
+ "test:watch": "NODE_ENV=test NODE_OPTIONS='--experimental-vm-modules' jest --watch",
20
+ "test:coverage": "NODE_ENV=test NODE_OPTIONS='--experimental-vm-modules' jest --coverage",
21
+ "test:integration": "node tests/integration/mcp-test-runner.js",
22
+ "test:setup-data": "node tests/integration/setup-test-data.js"
23
+ },
24
+ "author": "dav-mcp contributors",
25
+ "license": "MIT",
26
+ "repository": {
27
+ "type": "git",
28
+ "url": "git+https://github.com/PhilflowIO/dav-mcp.git"
29
+ },
30
+ "bugs": {
31
+ "url": "https://github.com/PhilflowIO/dav-mcp/issues"
32
+ },
33
+ "homepage": "https://github.com/PhilflowIO/dav-mcp#readme",
34
+ "keywords": [
35
+ "mcp",
36
+ "model-context-protocol",
37
+ "caldav",
38
+ "carddav",
39
+ "vtodo",
40
+ "dav",
41
+ "calendar",
42
+ "contacts",
43
+ "tasks",
44
+ "todos",
45
+ "n8n",
46
+ "ai",
47
+ "llm",
48
+ "automation",
49
+ "nextcloud",
50
+ "baikal",
51
+ "radicale"
52
+ ],
53
+ "engines": {
54
+ "node": ">=18.0.0"
55
+ },
56
+ "files": [
57
+ "src/**/*",
58
+ "README.md",
59
+ "LICENSE",
60
+ "CHANGELOG.md"
61
+ ],
62
+ "dependencies": {
63
+ "@modelcontextprotocol/sdk": "^1.18.2",
64
+ "cors": "^2.8.5",
65
+ "dotenv": "^16.4.7",
66
+ "express": "^4.21.2",
67
+ "express-rate-limit": "^8.1.0",
68
+ "ical.js": "^2.2.1",
69
+ "tsdav": "github:PhilflowIO/tsdav#master",
70
+ "tsdav-utils": "github:PhilflowIO/tsdav-utils#main",
71
+ "zod": "^3.25.76"
72
+ },
73
+ "devDependencies": {
74
+ "@types/cors": "^2.8.17",
75
+ "@types/express": "^5.0.0",
76
+ "@types/jest": "^30.0.0",
77
+ "jest": "^30.2.0",
78
+ "pnpm": "^10.19.0"
79
+ }
80
+ }
@@ -0,0 +1,215 @@
1
+ /**
2
+ * MCP Standard Error Codes
3
+ * Following JSON-RPC 2.0 error code specification
4
+ */
5
+ export const MCP_ERROR_CODES = {
6
+ // JSON-RPC standard errors
7
+ PARSE_ERROR: -32700,
8
+ INVALID_REQUEST: -32600,
9
+ METHOD_NOT_FOUND: -32601,
10
+ INVALID_PARAMS: -32602,
11
+ INTERNAL_ERROR: -32603,
12
+
13
+ // Custom application errors (range -32000 to -32099)
14
+ CALDAV_ERROR: -32000,
15
+ CARDDAV_ERROR: -32001,
16
+ VALIDATION_ERROR: -32002,
17
+ AUTH_ERROR: -32003,
18
+ NETWORK_ERROR: -32004,
19
+ TIMEOUT_ERROR: -32005,
20
+ NOT_FOUND_ERROR: -32006,
21
+ CONFLICT_ERROR: -32007,
22
+ };
23
+
24
+ /**
25
+ * Error type to code mapping
26
+ */
27
+ const ERROR_TYPE_MAP = {
28
+ 'TypeError': MCP_ERROR_CODES.INVALID_PARAMS,
29
+ 'ValidationError': MCP_ERROR_CODES.VALIDATION_ERROR,
30
+ 'AuthenticationError': MCP_ERROR_CODES.AUTH_ERROR,
31
+ 'NetworkError': MCP_ERROR_CODES.NETWORK_ERROR,
32
+ 'TimeoutError': MCP_ERROR_CODES.TIMEOUT_ERROR,
33
+ 'NotFoundError': MCP_ERROR_CODES.NOT_FOUND_ERROR,
34
+ 'ConflictError': MCP_ERROR_CODES.CONFLICT_ERROR,
35
+ };
36
+
37
+ /**
38
+ * Get error code based on error type or message
39
+ */
40
+ function getErrorCode(error) {
41
+ // Check if error has explicit code
42
+ if (error.code && typeof error.code === 'number') {
43
+ return error.code;
44
+ }
45
+
46
+ // Map by error type
47
+ if (error.name && ERROR_TYPE_MAP[error.name]) {
48
+ return ERROR_TYPE_MAP[error.name];
49
+ }
50
+
51
+ // Check error message for CalDAV/CardDAV specific errors
52
+ const message = error.message?.toLowerCase() || '';
53
+ if (message.includes('caldav')) {
54
+ return MCP_ERROR_CODES.CALDAV_ERROR;
55
+ }
56
+ if (message.includes('carddav')) {
57
+ return MCP_ERROR_CODES.CARDDAV_ERROR;
58
+ }
59
+ if (message.includes('auth') || message.includes('unauthorized') || message.includes('forbidden')) {
60
+ return MCP_ERROR_CODES.AUTH_ERROR;
61
+ }
62
+ if (message.includes('not found') || message.includes('404')) {
63
+ return MCP_ERROR_CODES.NOT_FOUND_ERROR;
64
+ }
65
+ if (message.includes('timeout')) {
66
+ return MCP_ERROR_CODES.TIMEOUT_ERROR;
67
+ }
68
+ if (message.includes('network') || message.includes('connection')) {
69
+ return MCP_ERROR_CODES.NETWORK_ERROR;
70
+ }
71
+ if (message.includes('validation') || message.includes('invalid')) {
72
+ return MCP_ERROR_CODES.VALIDATION_ERROR;
73
+ }
74
+
75
+ // Default to internal error
76
+ return MCP_ERROR_CODES.INTERNAL_ERROR;
77
+ }
78
+
79
+ /**
80
+ * Format error into MCP-compliant structure
81
+ */
82
+ export function formatMCPError(error, includeStack = false) {
83
+ const code = getErrorCode(error);
84
+
85
+ const errorResponse = {
86
+ code,
87
+ message: error.message || 'An error occurred',
88
+ data: {
89
+ type: error.name || 'Error',
90
+ ...(error.details && { details: error.details }),
91
+ ...(includeStack && error.stack && { stack: error.stack }),
92
+ },
93
+ };
94
+
95
+ return errorResponse;
96
+ }
97
+
98
+ /**
99
+ * Create MCP tool error response
100
+ */
101
+ export function createToolErrorResponse(error, includeStack = false) {
102
+ const mcpError = formatMCPError(error, includeStack);
103
+
104
+ return {
105
+ content: [
106
+ {
107
+ type: 'text',
108
+ text: JSON.stringify(mcpError, null, 2),
109
+ },
110
+ ],
111
+ isError: true,
112
+ };
113
+ }
114
+
115
+ /**
116
+ * Create HTTP error response
117
+ */
118
+ export function createHTTPErrorResponse(error, statusCode = null) {
119
+ const mcpError = formatMCPError(error, process.env.NODE_ENV === 'development');
120
+
121
+ // Map MCP error codes to HTTP status codes
122
+ const defaultStatusCode = statusCode || mapMCPCodeToHTTPStatus(mcpError.code);
123
+
124
+ return {
125
+ statusCode: defaultStatusCode,
126
+ body: {
127
+ error: mcpError.message,
128
+ code: mcpError.code,
129
+ ...mcpError.data,
130
+ },
131
+ };
132
+ }
133
+
134
+ /**
135
+ * Map MCP error codes to HTTP status codes
136
+ */
137
+ function mapMCPCodeToHTTPStatus(code) {
138
+ switch (code) {
139
+ case MCP_ERROR_CODES.PARSE_ERROR:
140
+ case MCP_ERROR_CODES.INVALID_REQUEST:
141
+ case MCP_ERROR_CODES.INVALID_PARAMS:
142
+ case MCP_ERROR_CODES.VALIDATION_ERROR:
143
+ return 400; // Bad Request
144
+
145
+ case MCP_ERROR_CODES.METHOD_NOT_FOUND:
146
+ case MCP_ERROR_CODES.NOT_FOUND_ERROR:
147
+ return 404; // Not Found
148
+
149
+ case MCP_ERROR_CODES.AUTH_ERROR:
150
+ return 401; // Unauthorized
151
+
152
+ case MCP_ERROR_CODES.CONFLICT_ERROR:
153
+ return 409; // Conflict
154
+
155
+ case MCP_ERROR_CODES.TIMEOUT_ERROR:
156
+ return 408; // Request Timeout
157
+
158
+ case MCP_ERROR_CODES.NETWORK_ERROR:
159
+ return 502; // Bad Gateway
160
+
161
+ case MCP_ERROR_CODES.CALDAV_ERROR:
162
+ case MCP_ERROR_CODES.CARDDAV_ERROR:
163
+ case MCP_ERROR_CODES.INTERNAL_ERROR:
164
+ default:
165
+ return 500; // Internal Server Error
166
+ }
167
+ }
168
+
169
+ /**
170
+ * Custom error classes
171
+ */
172
+ export class ValidationError extends Error {
173
+ constructor(message, details = null) {
174
+ super(message);
175
+ this.name = 'ValidationError';
176
+ this.code = MCP_ERROR_CODES.VALIDATION_ERROR;
177
+ this.details = details;
178
+ }
179
+ }
180
+
181
+ export class AuthenticationError extends Error {
182
+ constructor(message, details = null) {
183
+ super(message);
184
+ this.name = 'AuthenticationError';
185
+ this.code = MCP_ERROR_CODES.AUTH_ERROR;
186
+ this.details = details;
187
+ }
188
+ }
189
+
190
+ export class NotFoundError extends Error {
191
+ constructor(message, details = null) {
192
+ super(message);
193
+ this.name = 'NotFoundError';
194
+ this.code = MCP_ERROR_CODES.NOT_FOUND_ERROR;
195
+ this.details = details;
196
+ }
197
+ }
198
+
199
+ export class CalDAVError extends Error {
200
+ constructor(message, details = null) {
201
+ super(message);
202
+ this.name = 'CalDAVError';
203
+ this.code = MCP_ERROR_CODES.CALDAV_ERROR;
204
+ this.details = details;
205
+ }
206
+ }
207
+
208
+ export class CardDAVError extends Error {
209
+ constructor(message, details = null) {
210
+ super(message);
211
+ this.name = 'CardDAVError';
212
+ this.code = MCP_ERROR_CODES.CARDDAV_ERROR;
213
+ this.details = details;
214
+ }
215
+ }