mcp-macos 2.1.4 → 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.
package/README.md CHANGED
@@ -2,9 +2,7 @@
2
2
 
3
3
  > Based on [FradSer/mcp-server-apple-events](https://github.com/FradSer/mcp-server-apple-events)
4
4
 
5
- A Model Context Protocol (MCP) server that gives Claude genuine access to your macOS personal data — **Reminders**, **Calendar**, **Notes**, **Mail**, **Messages**, and **Contacts**. Six apps, working together: ask Claude about tomorrow's meeting and it pulls the calendar event, finds related emails, and creates a prep note — from your phone, your desktop, or the web.
6
-
7
- Use with Claude Desktop locally, or Claude iOS/web remotely via Cloudflare Tunnel. **Requires a Mac** — for always-on remote access, a Mac Mini or Mac Studio is recommended.
5
+ MCP server for Reminders, Calendar, Notes, Mail, Messages, and Contacts on macOS. Local stdio transport for Claude Desktop, Claude Code, and Cursor.
8
6
 
9
7
  ## Quick Start
10
8
 
@@ -26,14 +24,12 @@ pnpm build
26
24
  ### Verify setup
27
25
 
28
26
  ```bash
29
- node dist/index.js --check # or: macos-mcp --check (if installed globally)
27
+ macos-mcp --check # or: node dist/index.js --check
30
28
  ```
31
29
 
32
- The preflight check validates macOS version, Node.js, EventKit binary, Full Disk Access, and JXA automation permissions.
33
-
34
- **Next step:** [Using Claude Desktop?](#local-setup-stdio) | [Using Claude iOS/web remotely?](#remote-setup-claude-iosweb)
30
+ Checks macOS version, Node.js, EventKit binary, Full Disk Access, and JXA automation permissions.
35
31
 
36
- ## Available MCP Tools
32
+ ## Tools
37
33
 
38
34
  | Tool | App | Bridge | Actions |
39
35
  |------|-----|--------|---------|
@@ -47,22 +43,19 @@ The preflight check validates macOS version, Node.js, EventKit binary, Full Disk
47
43
  | `messages_chat` | Messages | SQLite + JXA | read, create |
48
44
  | `contacts_people` | Contacts | JXA | read, search, create, update, delete |
49
45
 
50
- All tools support both underscore (`reminders_tasks`) and dot (`reminders.tasks`) notation.
46
+ Both underscore (`reminders_tasks`) and dot (`reminders.tasks`) notation work.
51
47
 
52
- ## Local Setup (stdio)
48
+ ## Setup
53
49
 
54
50
  ### Prerequisites
55
51
 
56
- - **Node.js 20 or later**
57
- - **macOS** (required for EventKit and JXA)
58
- - **Xcode Command Line Tools** (required for compiling Swift code)
59
- - **pnpm** (recommended for package management)
60
-
61
- ### Configure Your Client
52
+ - **Node.js 20+**
53
+ - **macOS**
54
+ - **Xcode Command Line Tools** (Swift compilation)
62
55
 
63
- #### Claude Desktop
56
+ ### Client Configuration
64
57
 
65
- Add to your `claude_desktop_config.json`:
58
+ The JSON config is the same for all clients — just the location differs.
66
59
 
67
60
  ```json
68
61
  {
@@ -75,115 +68,15 @@ Add to your `claude_desktop_config.json`:
75
68
  }
76
69
  ```
77
70
 
78
- #### Cursor
79
-
80
- 1. Open Cursor Settings > MCP > Add new global MCP server
81
- 2. Configure:
82
- ```json
83
- {
84
- "mcpServers": {
85
- "macos-mcp": {
86
- "command": "npx",
87
- "args": ["mcp-macos"]
88
- }
89
- }
90
- }
91
- ```
92
-
93
- #### Claude Code
94
-
95
- Add a `.mcp.json` to your project root:
96
-
97
- ```json
98
- {
99
- "mcpServers": {
100
- "macos-mcp": {
101
- "command": "npx",
102
- "args": ["mcp-macos"]
103
- }
104
- }
105
- }
106
- ```
71
+ | Client | Config location |
72
+ |--------|----------------|
73
+ | Claude Desktop | `claude_desktop_config.json` |
74
+ | Cursor | Settings > MCP > Add new global MCP server |
75
+ | Claude Code | `.mcp.json` in project root |
107
76
 
108
77
  ### Permissions
109
78
 
110
- On first use, macOS will prompt you to allow access for each app. Click **Allow** when prompted.
111
-
112
- - **Reminders & Calendar** — EventKit permission dialogs appear automatically.
113
- - **Notes, Mail, Contacts** — Automation permission dialogs appear when `osascript` first controls each app. Grant access via **System Settings > Privacy & Security > Automation**.
114
- - **Messages & Mail** — Require **Full Disk Access** for your terminal app (Terminal, iTerm2, etc.) since both read SQLite databases directly.
115
-
116
- Run `node dist/index.js --check` to verify all permissions are granted. See [Troubleshooting](#troubleshooting) if anything fails.
117
-
118
- ## Remote Setup (Claude iOS/web)
119
-
120
- Use this path to access your Mac's apps from Claude iOS or Claude web via a secure Cloudflare Tunnel.
121
-
122
- ```
123
- ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
124
- │ Claude iOS │──────│ Cloudflare │──────│ Your Mac │
125
- │ or Web │ HTTPS│ Edge + Access │tunnel│ macos-mcp │
126
- └─────────────────┘ └─────────────────┘ └─────────────────┘
127
- ```
128
-
129
- ### What you'll set up
130
-
131
- 1. **Cloudflare Tunnel** — Secure outbound connection from your Mac to Cloudflare's edge
132
- 2. **Cloudflare Access** — Email OTP authentication so only you can connect
133
- 3. **LaunchAgents** — Auto-start on boot for both the server and tunnel
134
- 4. **Permissions** — Automation + Full Disk Access granted to the node binary
135
-
136
- ### Prerequisites
137
-
138
- - **Cloudflare account** (free tier works)
139
- - **Custom domain** in Cloudflare (or use `.cfargotunnel.com` subdomain)
140
- - **Always-on Mac** (Mac Mini/Studio recommended)
141
- - **macos-mcp built and working locally** (`pnpm build && node dist/index.js --check`)
142
-
143
- ### Full Setup Guide
144
-
145
- Follow the step-by-step instructions in **[`docs/CLOUDFLARE_SETUP.md`](docs/CLOUDFLARE_SETUP.md)** — covers tunnel creation, Cloudflare Access configuration, LaunchAgent setup, permission granting, and registering in Claude iOS.
146
-
147
- ## Usage Examples
148
-
149
- ### Reminders
150
- ```
151
- Create a reminder to "Buy groceries" for tomorrow at 5 PM.
152
- Show all reminders in my "Work" list.
153
- Organize my reminders by priority.
154
- ```
155
-
156
- ### Calendar
157
- ```
158
- Create a meeting "Team Standup" tomorrow from 10 AM to 10:30 AM.
159
- Show my calendar events for this week.
160
- ```
161
-
162
- ### Notes
163
- ```
164
- Create a note titled "Meeting Notes" in the Work folder.
165
- Search my notes for "project plan".
166
- List all note folders.
167
- ```
168
-
169
- ### Mail
170
- ```
171
- Show my inbox.
172
- Read the email from John about the project.
173
- Draft an email to alice@example.com about the meeting.
174
- Reply to the last email from Bob.
175
- ```
176
-
177
- ### Messages
178
- ```
179
- Show my recent iMessage chats.
180
- Read messages from the chat with John.
181
- Send "On my way!" to the group chat.
182
- ```
183
-
184
- ## Troubleshooting
185
-
186
- ### Permission Quick Reference
79
+ macOS prompts for access on first use. Click **Allow** when prompted.
187
80
 
188
81
  | App | Permission | System Settings Path |
189
82
  |-----|------------|---------------------|
@@ -194,6 +87,12 @@ Send "On my way!" to the group chat.
194
87
  | Messages | Automation + Full Disk Access | Both locations |
195
88
  | Contacts | Automation | Privacy & Security > Automation > Contacts |
196
89
 
90
+ Messages and Mail read SQLite databases directly, so your terminal app (Terminal, iTerm2, etc.) needs **Full Disk Access**.
91
+
92
+ Run `macos-mcp --check` to verify. See [Troubleshooting](#troubleshooting) if anything fails.
93
+
94
+ ## Troubleshooting
95
+
197
96
  ### Quick-Fix Commands
198
97
 
199
98
  ```bash
@@ -202,154 +101,78 @@ open "x-apple.systempreferences:com.apple.preference.security?Privacy_Reminders"
202
101
  open "x-apple.systempreferences:com.apple.preference.security?Privacy_Calendars"
203
102
  open "x-apple.systempreferences:com.apple.preference.security?Privacy_Automation"
204
103
  open "x-apple.systempreferences:com.apple.preference.security?Privacy_AllFiles"
205
-
206
- # Run preflight check
207
- node dist/index.js --check
208
- ```
209
-
210
- ### EventKit (Reminders & Calendar)
211
-
212
- Apple separates Reminders and Calendar permissions into *write-only* and *full-access* scopes. The Swift bridge declares the following privacy keys:
213
-
214
- - `NSRemindersUsageDescription` / `NSRemindersFullAccessUsageDescription` / `NSRemindersWriteOnlyAccessUsageDescription`
215
- - `NSCalendarsUsageDescription` / `NSCalendarsFullAccessUsageDescription` / `NSCalendarsWriteOnlyAccessUsageDescription`
216
-
217
- If a permission failure occurs, the Node.js layer automatically runs a minimal AppleScript to surface the dialog and retries.
218
-
219
- ### JXA Automation (Notes, Mail, Contacts)
220
-
221
- JXA-based tools require macOS Automation permissions. On first use, macOS will prompt you to allow `osascript` to control each app.
222
-
223
- > **Headless / LaunchAgent:** Automation permission dialogs **cannot appear** through a LaunchAgent, SSH session, or any non-GUI context. You must grant them once from a local graphical Terminal session (physical access or Screen Sharing). See [`docs/CLOUDFLARE_SETUP.md`](docs/CLOUDFLARE_SETUP.md) Step 10 for the full procedure. Once granted, permissions persist across reboots.
224
-
225
- **Verify all Automation permissions:**
226
-
227
- ```bash
228
- /usr/bin/osascript -l JavaScript -e 'Application("Contacts").people().length'
229
- /usr/bin/osascript -l JavaScript -e 'Application("Calendar").calendars().length'
230
- /usr/bin/osascript -l JavaScript -e 'Application("Reminders").defaultList().name()'
231
- /usr/bin/osascript -l JavaScript -e 'Application("Mail").inbox().messages().length'
232
- /usr/bin/osascript -l JavaScript -e 'Application("Notes").notes().length'
233
104
  ```
234
105
 
235
- Each command should return a value without errors or hanging. A hang means the permission dialog is trying (and failing) to appear.
236
-
237
106
  ### Full Disk Access (Messages & Mail)
238
107
 
239
- The Messages and Mail tools read SQLite databases directly (`~/Library/Messages/chat.db` and `~/Library/Mail/V10/MailData/Envelope Index`). These databases are protected by **Full Disk Access (FDA)**.
240
-
241
- - **stdio transport**: Grant FDA to your terminal app (Terminal, iTerm2, etc.)
242
- - **HTTP transport / LaunchAgent**: Grant FDA to the **actual node binary**, not a version manager shim
243
-
244
- To find and grant access to the correct binary:
108
+ Messages and Mail read SQLite databases (`~/Library/Messages/chat.db` and `~/Library/Mail/V10/MailData/Envelope Index`). These require Full Disk Access on your terminal app.
245
109
 
246
110
  ```bash
247
- # Find the actual node binary path
111
+ # Find your real node binary (version managers use shims)
248
112
  node -e "console.log(process.execPath)"
249
113
 
250
- # Reveal it in Finder (drag-and-drop into FDA settings)
114
+ # Reveal it in Finder for drag-and-drop into FDA settings
251
115
  open -R "$(node -e "console.log(process.execPath)")"
252
116
 
253
117
  # Open Full Disk Access settings
254
118
  open "x-apple.systempreferences:com.apple.preference.security?Privacy_AllFiles"
255
119
  ```
256
120
 
257
- > **Note:** Version managers (Volta, nvm, fnm) use shims that point to a launcher, not the real binary. The System Settings file picker may not show binaries in hidden directories — use the drag-and-drop method above instead. See [`docs/CLOUDFLARE_SETUP.md`](docs/CLOUDFLARE_SETUP.md) Step 11 for detailed instructions and troubleshooting.
258
-
259
- ### Version Manager Shim Resolution
260
-
261
- If you use **Volta**, **nvm**, or **fnm**, the `node` command is a shim/launcher. System Settings needs the real binary:
121
+ **Version manager users** (Volta, nvm, fnm): the `node` command is a shim. System Settings needs the real binary:
262
122
 
263
123
  | Manager | Find real binary |
264
124
  |---------|-----------------|
265
- | Volta | `volta which node` or `node -e "console.log(process.execPath)"` |
125
+ | Volta | `volta which node` |
266
126
  | nvm | `nvm which current` |
267
127
  | fnm | `fnm exec -- node -e "console.log(process.execPath)"` |
268
128
 
269
- The System Settings file picker may not show binaries in hidden directories — use the `open -R` command above to reveal the binary in Finder, then drag-and-drop it into the FDA list.
270
-
271
- ### Gmail Labels / Missing Inbox Messages
129
+ System Settings may not show binaries in hidden directories — use `open -R` above to reveal it in Finder, then drag into the FDA list.
272
130
 
273
- Gmail stores all messages in `[Gmail]/All Mail` and uses **labels** for folder membership. The server checks both the direct mailbox and the labels join table for inbox queries. If you're not seeing Gmail inbox messages, verify the Mail app has fully synced your account.
131
+ ### JXA Automation (Notes, Mail, Contacts)
274
132
 
275
- ### Server Restart (LaunchAgent)
133
+ On first use, macOS prompts for Automation access. Grant via **System Settings > Privacy & Security > Automation**.
276
134
 
277
- If running as a LaunchAgent with Cloudflare Tunnel, restart **both** services:
135
+ Verify permissions:
278
136
 
279
137
  ```bash
280
- launchctl kickstart -k gui/$(id -u)/com.macos-mcp.server
281
- launchctl kickstart -k gui/$(id -u)/com.cloudflare.macos-mcp-tunnel
138
+ osascript -l JavaScript -e 'Application("Contacts").people().length'
139
+ osascript -l JavaScript -e 'Application("Calendar").calendars().length'
140
+ osascript -l JavaScript -e 'Application("Reminders").defaultList().name()'
141
+ osascript -l JavaScript -e 'Application("Mail").inbox().messages().length'
142
+ osascript -l JavaScript -e 'Application("Notes").notes().length'
282
143
  ```
283
144
 
145
+ Each command should return a value. A hang means the permission dialog is trying (and failing) to appear.
146
+
147
+ ### Gmail Labels / Missing Inbox Messages
148
+
149
+ Gmail stores all messages in `[Gmail]/All Mail` and uses labels for folder membership. The server checks both the direct mailbox and labels join table. If Gmail inbox messages are missing, verify the Mail app has fully synced.
150
+
284
151
  ## Development
285
152
 
286
153
  ```bash
287
154
  pnpm install # Install dependencies
288
155
  pnpm build # Build TypeScript + Swift binary
289
156
  pnpm test # Run full test suite
290
- pnpm lint # Lint and format with Biome + TypeScript check
291
- pnpm dev # Run from source via tsx (stdio only, no build needed)
157
+ pnpm lint # Lint and format (Biome + TypeScript)
158
+ pnpm dev # Run from source via tsx
292
159
  ```
293
160
 
294
- > **Note:** The production entry point (`bin/run.cjs`) requires `pnpm build` first. Use `pnpm dev` for quick local development with stdio transport.
295
-
296
- ### End-to-End Testing
297
-
298
- For HTTP transport testing, an E2E script is available:
299
-
300
- ```bash
301
- ./scripts/test-e2e.sh
302
- ```
303
-
304
- This script:
305
- - Starts the server in HTTP mode
306
- - Tests health endpoints
307
- - Verifies CORS headers and OPTIONS preflight
308
- - Tests MCP endpoint availability
309
- - Tests rate limit headers
310
- - Verifies graceful shutdown
311
-
312
- Requirements: `jq` (install with `brew install jq`)
161
+ Production entry point (`bin/run.cjs`) requires `pnpm build`. Use `pnpm dev` for local development.
313
162
 
314
163
  ### Architecture
315
164
 
316
- The server uses two bridging strategies to communicate with Apple apps:
317
-
318
- - **EventKit (Swift binary)** — Reminders and Calendar. A compiled Swift CLI binary performs EventKit operations and returns JSON.
319
- - **JXA (JavaScript for Automation)** — Notes, Mail, Contacts. Scripts run via `osascript -l JavaScript` with template-based parameter interpolation.
320
- - **SQLite** — Messages reads (`~/Library/Messages/chat.db`) and Mail reads (`~/Library/Mail/V10/MailData/Envelope Index`). JXA message reading is broken on macOS Sonoma+; JXA mail reading is too slow for real inboxes. Writes still use JXA.
321
-
322
- ### HTTP Transport Configuration
323
-
324
- The server supports HTTP transport for remote access. Set via environment variables or `macos-mcp.config.json`:
325
-
326
- | Variable | Default | Description |
327
- |----------|---------|-------------|
328
- | `MCP_TRANSPORT` | `stdio` | Transport mode: `stdio`, `http`, or `both` |
329
- | `MCP_HTTP_ENABLED` | `false` | Enable HTTP transport |
330
- | `MCP_HTTP_PORT` | `3847` | HTTP server port |
331
-
332
- Key design decisions:
333
- - **Stateless mode** — required for multi-client support (Claude.ai serves multiple users)
334
- - **Root endpoint** — MCP handler at `/` (Claude expects this, not `/mcp`)
335
- - **JSON fallback** — `enableJsonResponse: true` for clients without SSE support
336
-
337
- ### Structured Prompt Library
338
-
339
- The server ships with prompt templates exposed via MCP `ListPrompts` and `GetPrompt` endpoints:
340
-
341
- - **daily-task-organizer** — optional `today_focus` input produces a same-day execution blueprint
342
- - **smart-reminder-creator** — optional `task_idea` generates an optimally scheduled reminder
343
- - **reminder-review-assistant** — optional `review_focus` to audit and optimize existing reminders
344
- - **weekly-planning-workflow** — optional `user_ideas` guides a Monday-through-Sunday reset
165
+ Three bridges to Apple apps:
345
166
 
346
- Run `pnpm test -- src/server/prompts.test.ts` to validate prompt metadata and schema compatibility.
167
+ - **EventKit (Swift binary)** Reminders, Calendar. Compiled Swift CLI, returns JSON.
168
+ - **JXA** — Notes, Mail writes, Contacts. Scripts run via `osascript -l JavaScript`.
169
+ - **SQLite** — Messages reads (`~/Library/Messages/chat.db`), Mail reads (`~/Library/Mail/V10/MailData/Envelope Index`). JXA message reading is broken on Sonoma+; JXA mail reading is too slow for real inboxes.
347
170
 
348
171
  ### Dependencies
349
172
 
350
- **Runtime:** `@modelcontextprotocol/sdk`, `express`, `jose`, `zod`
173
+ **Runtime:** `@modelcontextprotocol/sdk`, `zod`
351
174
 
352
- **Dev:** `typescript`, `tsx`, `jest`, `ts-jest`, `babel-jest`, `@biomejs/biome`
175
+ **Dev:** `typescript`, `tsx`, `jest`, `@biomejs/biome`
353
176
 
354
177
  ## License
355
178
 
@@ -357,4 +180,4 @@ MIT
357
180
 
358
181
  ## Contributing
359
182
 
360
- Contributions welcome! Please read the [contributing guidelines](CONTRIBUTING.md) first.
183
+ See [CONTRIBUTING.md](CONTRIBUTING.md).
@@ -1,36 +1,9 @@
1
1
  /**
2
- * @fileoverview Configuration loading and management for macos-mcp server
2
+ * @fileoverview Configuration loader for macos-mcp server
3
3
  * @module config
4
- * @description Loads configuration from file and environment variables with auto-injection of package.json metadata
5
- */
6
- import { type CloudflareAccessConfig, type FullServerConfig, type HttpConfig } from './schema.js';
7
- /**
8
- * Loads server configuration from file and environment variables
9
- *
10
- * Configuration is loaded in the following priority (highest to lowest):
11
- * 1. Environment variables (MCP_TRANSPORT, MCP_HTTP_*, CF_ACCESS_*)
12
- * 2. Configuration file (macos-mcp.config.json in project root)
13
- * 3. Default values from schema
14
- *
15
- * Name and version are always auto-injected from package.json
16
- *
17
- * @returns Validated server configuration
18
- * @throws Error if configuration is invalid
19
- *
20
- * @example
21
- * // Basic usage
22
- * const config = loadConfig();
23
- * console.log(config.transport); // 'stdio' (default)
24
- *
25
- * @example
26
- * // With environment variables
27
- * // MCP_TRANSPORT=http
28
- * // MCP_HTTP_ENABLED=true
29
- * // MCP_HTTP_PORT=8080
30
- * const config = loadConfig();
31
- * console.log(config.transport); // 'http'
32
- * console.log(config.http?.port); // 8080
4
+ * @description Auto-injects name + version from package.json
33
5
  */
6
+ import { type FullServerConfig } from './schema.js';
34
7
  export declare function loadConfig(): FullServerConfig;
35
- export type { CloudflareAccessConfig, FullServerConfig, HttpConfig };
36
- export { CloudflareAccessConfigSchema, HttpConfigSchema, ServerConfigSchema, } from './schema.js';
8
+ export type { FullServerConfig };
9
+ export { ServerConfigSchema } from './schema.js';
@@ -1,127 +1,20 @@
1
1
  /**
2
- * @fileoverview Configuration loading and management for macos-mcp server
2
+ * @fileoverview Configuration loader for macos-mcp server
3
3
  * @module config
4
- * @description Loads configuration from file and environment variables with auto-injection of package.json metadata
4
+ * @description Auto-injects name + version from package.json
5
5
  */
6
- import { existsSync, readFileSync } from 'node:fs';
6
+ import { readFileSync } from 'node:fs';
7
7
  import { join } from 'node:path';
8
8
  import { findProjectRoot } from '../utils/projectUtils.js';
9
- import { ServerConfigSchema, } from './schema.js';
10
- /** Configuration file name */
11
- const CONFIG_FILENAME = 'macos-mcp.config.json';
12
- /**
13
- * Loads server configuration from file and environment variables
14
- *
15
- * Configuration is loaded in the following priority (highest to lowest):
16
- * 1. Environment variables (MCP_TRANSPORT, MCP_HTTP_*, CF_ACCESS_*)
17
- * 2. Configuration file (macos-mcp.config.json in project root)
18
- * 3. Default values from schema
19
- *
20
- * Name and version are always auto-injected from package.json
21
- *
22
- * @returns Validated server configuration
23
- * @throws Error if configuration is invalid
24
- *
25
- * @example
26
- * // Basic usage
27
- * const config = loadConfig();
28
- * console.log(config.transport); // 'stdio' (default)
29
- *
30
- * @example
31
- * // With environment variables
32
- * // MCP_TRANSPORT=http
33
- * // MCP_HTTP_ENABLED=true
34
- * // MCP_HTTP_PORT=8080
35
- * const config = loadConfig();
36
- * console.log(config.transport); // 'http'
37
- * console.log(config.http?.port); // 8080
38
- */
9
+ import { ServerConfigSchema } from './schema.js';
39
10
  export function loadConfig() {
40
11
  const projectRoot = findProjectRoot();
41
- const configPath = join(projectRoot, CONFIG_FILENAME);
42
- // Load file configuration if it exists
43
- let fileConfig = {};
44
- if (existsSync(configPath)) {
45
- const fileContent = readFileSync(configPath, 'utf-8');
46
- fileConfig = JSON.parse(fileContent);
47
- }
48
- // Build environment variable configuration
49
- const envConfig = buildEnvConfig();
50
- // Deep merge file config with env config (env takes precedence)
51
- const merged = deepMerge(fileConfig, envConfig);
52
- // Load package.json for name and version
53
12
  const packageJsonPath = join(projectRoot, 'package.json');
54
13
  const packageJson = JSON.parse(readFileSync(packageJsonPath, 'utf-8'));
55
- // Parse and validate configuration
56
14
  return ServerConfigSchema.parse({
57
15
  name: packageJson.name,
58
16
  version: packageJson.version,
59
- ...merged,
60
17
  });
61
18
  }
62
- /**
63
- * Builds configuration object from environment variables
64
- * @returns Partial configuration from environment variables
65
- */
66
- function buildEnvConfig() {
67
- const config = {};
68
- // Transport mode
69
- if (process.env.MCP_TRANSPORT) {
70
- config.transport = process.env.MCP_TRANSPORT;
71
- }
72
- // HTTP configuration (only if explicitly enabled)
73
- if (process.env.MCP_HTTP_ENABLED === 'true') {
74
- const httpConfig = {
75
- enabled: true,
76
- };
77
- if (process.env.MCP_HTTP_HOST) {
78
- httpConfig.host = process.env.MCP_HTTP_HOST;
79
- }
80
- if (process.env.MCP_HTTP_PORT) {
81
- const port = Number.parseInt(process.env.MCP_HTTP_PORT, 10);
82
- if (!Number.isNaN(port)) {
83
- httpConfig.port = port;
84
- }
85
- }
86
- // Cloudflare Access configuration
87
- if (process.env.CF_ACCESS_TEAM_DOMAIN && process.env.CF_ACCESS_POLICY_AUD) {
88
- const cfConfig = {
89
- teamDomain: process.env.CF_ACCESS_TEAM_DOMAIN,
90
- policyAUD: process.env.CF_ACCESS_POLICY_AUD,
91
- };
92
- if (process.env.CF_ACCESS_ALLOWED_EMAILS) {
93
- cfConfig.allowedEmails = process.env.CF_ACCESS_ALLOWED_EMAILS.split(',').map((e) => e.trim());
94
- }
95
- httpConfig.cloudflareAccess = cfConfig;
96
- }
97
- config.http = httpConfig;
98
- }
99
- return config;
100
- }
101
- /**
102
- * Deep merges two objects, with source taking precedence
103
- * @param target - Base object
104
- * @param source - Object to merge in (takes precedence)
105
- * @returns Merged object
106
- */
107
- function deepMerge(target, source) {
108
- const result = { ...target };
109
- for (const key of Object.keys(source)) {
110
- const sourceValue = source[key];
111
- const targetValue = result[key];
112
- if (sourceValue !== null &&
113
- typeof sourceValue === 'object' &&
114
- !Array.isArray(sourceValue) &&
115
- targetValue !== null &&
116
- typeof targetValue === 'object' &&
117
- !Array.isArray(targetValue)) {
118
- result[key] = deepMerge(targetValue, sourceValue);
119
- }
120
- else if (sourceValue !== undefined) {
121
- result[key] = sourceValue;
122
- }
123
- }
124
- return result;
125
- }
126
- export { CloudflareAccessConfigSchema, HttpConfigSchema, ServerConfigSchema, } from './schema.js';
19
+ export { ServerConfigSchema } from './schema.js';
127
20
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/config/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/config/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAC3D,OAAO,EAAyB,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAExE,MAAM,UAAU,UAAU;IACxB,MAAM,WAAW,GAAG,eAAe,EAAE,CAAC;IACtC,MAAM,eAAe,GAAG,IAAI,CAAC,WAAW,EAAE,cAAc,CAAC,CAAC;IAC1D,MAAM,WAAW,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,eAAe,EAAE,OAAO,CAAC,CAGpE,CAAC;IAEF,OAAO,kBAAkB,CAAC,KAAK,CAAC;QAC9B,IAAI,EAAE,WAAW,CAAC,IAAI;QACtB,OAAO,EAAE,WAAW,CAAC,OAAO;KAC7B,CAAC,CAAC;AACL,CAAC;AAGD,OAAO,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC"}