obsidian-mcp-server 1.3.0 → 1.4.1

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 (79) hide show
  1. package/LICENSE +2 -1
  2. package/README.md +36 -77
  3. package/build/index.js +12 -3
  4. package/build/mcp/handlers.js +138 -0
  5. package/build/mcp/index.js +7 -0
  6. package/build/mcp/server.js +131 -0
  7. package/build/mcp/types.js +7 -0
  8. package/build/{obsidian.js → obsidian/client.js} +116 -96
  9. package/build/obsidian/errors.js +75 -0
  10. package/build/obsidian/index.js +7 -0
  11. package/build/obsidian/types.js +12 -0
  12. package/build/resources/index.js +15 -0
  13. package/build/{resources.js → resources/tags.js} +31 -5
  14. package/build/resources/types.js +5 -0
  15. package/build/tools/base.js +78 -0
  16. package/build/tools/files/content.js +171 -0
  17. package/build/tools/files/index.js +22 -0
  18. package/build/tools/files/list.js +133 -0
  19. package/build/tools/index.js +31 -0
  20. package/build/tools/properties/index.js +19 -0
  21. package/build/{properties.js → tools/properties/manager.js} +40 -8
  22. package/build/{propertyTools.js → tools/properties/tools.js} +22 -6
  23. package/build/{propertyTypes.js → tools/properties/types.js} +17 -5
  24. package/build/tools/search/complex.js +203 -0
  25. package/build/tools/search/index.js +20 -0
  26. package/build/tools/search/simple.js +127 -0
  27. package/build/utils/errors.js +59 -0
  28. package/build/utils/index.js +9 -0
  29. package/build/utils/logging.js +119 -0
  30. package/build/utils/rate-limiting.js +94 -0
  31. package/build/utils/tokenization.js +62 -0
  32. package/build/utils/validation.js +88 -0
  33. package/examples/README.md +48 -0
  34. package/examples/append-content.md +63 -0
  35. package/examples/complex-search.md +117 -0
  36. package/examples/find-in-file.md +94 -0
  37. package/examples/get-file-contents.md +72 -0
  38. package/examples/get-properties.md +89 -0
  39. package/examples/list-files-in-dir.md +55 -0
  40. package/examples/list-files-in-vault.md +53 -0
  41. package/examples/patch-content.md +60 -0
  42. package/examples/update-properties.md +126 -0
  43. package/package.json +12 -14
  44. package/src/index.ts +13 -3
  45. package/src/mcp/handlers.ts +183 -0
  46. package/src/mcp/index.ts +6 -0
  47. package/src/mcp/server.ts +162 -0
  48. package/src/mcp/types.ts +46 -0
  49. package/src/{obsidian.ts → obsidian/client.ts} +132 -125
  50. package/src/obsidian/errors.ts +105 -0
  51. package/src/obsidian/index.ts +6 -0
  52. package/src/obsidian/types.ts +124 -0
  53. package/src/resources/index.ts +17 -0
  54. package/src/{resources.ts → resources/tags.ts} +38 -6
  55. package/src/resources/types.ts +30 -0
  56. package/src/tools/base.ts +112 -0
  57. package/src/tools/files/content.ts +206 -0
  58. package/src/tools/files/index.ts +31 -0
  59. package/src/tools/files/list.ts +150 -0
  60. package/src/tools/index.ts +38 -0
  61. package/src/tools/properties/index.ts +21 -0
  62. package/src/{properties.ts → tools/properties/manager.ts} +41 -8
  63. package/src/{propertyTools.ts → tools/properties/tools.ts} +33 -7
  64. package/src/{propertyTypes.ts → tools/properties/types.ts} +29 -5
  65. package/src/tools/search/complex.ts +231 -0
  66. package/src/tools/search/index.ts +22 -0
  67. package/src/tools/search/simple.ts +147 -0
  68. package/src/utils/errors.ts +69 -0
  69. package/src/utils/index.ts +8 -0
  70. package/src/utils/logging.ts +146 -0
  71. package/src/utils/rate-limiting.ts +114 -0
  72. package/src/utils/tokenization.ts +71 -0
  73. package/src/utils/validation.ts +95 -0
  74. package/build/server.js +0 -263
  75. package/build/tools.js +0 -845
  76. package/build/types.js +0 -37
  77. package/src/server.ts +0 -335
  78. package/src/tools.ts +0 -926
  79. package/src/types.ts +0 -184
package/LICENSE CHANGED
@@ -1,7 +1,8 @@
1
1
 
2
2
  Apache License
3
3
  Version 2.0, January 2004
4
- http://www.apache.org/licenses/
4
+ Copyright 2025 Casey Hand @cyanheads
5
+ http://www.apache.org/licenses/
5
6
 
6
7
  TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
7
8
 
package/README.md CHANGED
@@ -1,8 +1,8 @@
1
1
  # Obsidian MCP Server
2
2
 
3
- [![TypeScript](https://img.shields.io/badge/TypeScript-5.3-blue.svg)](https://www.typescriptlang.org/)
4
- [![Model Context Protocol](https://img.shields.io/badge/MCP-1.4.0-green.svg)](https://modelcontextprotocol.io/)
5
- [![Version](https://img.shields.io/badge/Version-1.2.3-blue.svg)]()
3
+ [![TypeScript](https://img.shields.io/badge/TypeScript-5.7-blue.svg)](https://www.typescriptlang.org/)
4
+ [![Model Context Protocol](https://img.shields.io/badge/MCP-1.6.1-green.svg)](https://modelcontextprotocol.io/)
5
+ [![Version](https://img.shields.io/badge/Version-1.4.1-blue.svg)]()
6
6
  [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0)
7
7
  [![Status](https://img.shields.io/badge/Status-Stable-blue.svg)]()
8
8
  [![GitHub](https://img.shields.io/github/stars/cyanheads/obsidian-mcp-server?style=social)](https://github.com/cyanheads/obsidian-mcp-server)
@@ -18,6 +18,7 @@ Requires the Local REST API plugin in Obsidian.
18
18
  ### File Operations
19
19
  - Atomic file/directory operations with validation
20
20
  - Resource monitoring and cleanup
21
+ - Error handling and graceful failure
21
22
 
22
23
  ### Search System
23
24
  - Full-text search with configurable context
@@ -32,12 +33,14 @@ Requires the Local REST API plugin in Obsidian.
32
33
  ### Security & Performance
33
34
  - API key auth with rate limiting and SSL options
34
35
  - Resource monitoring and health checks
36
+ - Graceful shutdown handling
35
37
 
36
38
  ## Installation
37
39
 
38
- 1. Install Node.js (LTS recommended)
39
- 2. Enable Local REST API plugin in Obsidian
40
- 3. Clone and build:
40
+ Note: Requires Node.js
41
+
42
+ 1. Enable Local REST API plugin in Obsidian
43
+ 2. Clone and build:
41
44
  ```bash
42
45
  git clone git@github.com:cyanheads/obsidian-mcp-server.git
43
46
  cd obsidian-mcp-server
@@ -84,7 +87,7 @@ Required:
84
87
  - `OBSIDIAN_API_KEY`: Your API key from Obsidian's Local REST API plugin settings
85
88
 
86
89
  Connection Settings:
87
- - `VERIFY_SSL`: Enable SSL certificate verification (default: false in development)
90
+ - `VERIFY_SSL`: Enable SSL certificate verification (default: false) # This must be set to false for self-signed certificates. If you are running locally or don't understand what this means, this should be set to false.
88
91
  - `OBSIDIAN_PROTOCOL`: Protocol to use (default: "https")
89
92
  - `OBSIDIAN_HOST`: Host address (default: "127.0.0.1")
90
93
  - `OBSIDIAN_PORT`: Port number (default: 27124)
@@ -101,46 +104,22 @@ Rate Limiting:
101
104
  Tool Execution:
102
105
  - `TOOL_TIMEOUT_MS`: Tool execution timeout in milliseconds (default: 60000 [1 minute])
103
106
 
104
- SSL Certificate Setup:
105
-
106
- For Windows Users:
107
- 1. Development Setup (Not Recommended for Production):
108
- - Set `VERIFY_SSL` to "false"
109
- - Set `OBSIDIAN_PROTOCOL` to "http"
110
- - Enable "Non-encrypted (HTTP) Server" in Obsidian's Local REST API settings
111
-
112
- 2. Production Setup (Recommended):
113
- - Set `VERIFY_SSL` to "true"
114
- - Get the certificate from Obsidian Settings > Local REST API > 'How to Access'
115
- - Open Windows Certificate Manager (certmgr.msc)
116
- - Navigate to "Trusted Root Certification Authorities" > "Certificates"
117
- - Right-click > "All Tasks" > "Import" and select the certificate file
107
+ ## Project Structure
118
108
 
119
- For Other Systems:
120
- - macOS: Add certificate to Keychain Access
121
- - Linux: Add to ca-certificates
109
+ The project follows a modular architecture with clear separation of concerns:
122
110
 
123
- Additional configuration options:
124
- ```typescript
125
- interface ObsidianConfig {
126
- apiKey: string; // Required: API key for authentication
127
- verifySSL?: boolean; // Optional: Enable SSL verification
128
- timeout?: number; // Optional: Request timeout in ms
129
- maxContentLength?: number;// Optional: Max response content length
130
- maxBodyLength?: number; // Optional: Max request body length
131
- }
132
-
133
- interface RateLimitConfig {
134
- windowMs: number; // Time window for rate limiting
135
- maxRequests: number; // Max requests per window
136
- }
137
111
  ```
138
-
139
- Error Handling:
140
- - All errors include a 5-digit error code
141
- - HTTP status codes are automatically converted (e.g., 404 -> 40400)
142
- - Default server error code: 50000
143
- - Detailed error messages include original error stack traces in development
112
+ src/
113
+ ├── index.ts # Main entry point
114
+ ├── mcp/ # MCP server implementation
115
+ ├── obsidian/ # Obsidian API client and types
116
+ ├── resources/ # MCP resource implementations
117
+ ├── tools/ # MCP tool implementations
118
+ │ ├── files/ # File operations tools
119
+ │ ├── search/ # Search tools
120
+ │ └── properties/ # Property management tools
121
+ └── utils/ # Shared utilities
122
+ ```
144
123
 
145
124
  ## Tools
146
125
 
@@ -184,6 +163,11 @@ obsidian_complex_search: {
184
163
  // {"in": ["#mytag", {"var": "frontmatter.tags"}]}
185
164
  // ]}
186
165
  }
166
+
167
+ // Get all tags in vault or directory
168
+ obsidian_get_tags: {
169
+ path?: string // Optional: limit to specific directory
170
+ }
187
171
  ```
188
172
 
189
173
  ### Content Modification
@@ -201,41 +185,8 @@ obsidian_patch_content: {
201
185
  }
202
186
  ```
203
187
 
204
- ### Command Management
205
- ```typescript
206
- // List available commands
207
- obsidian_list_commands: {}
208
-
209
- // Execute a command
210
- obsidian_execute_command: {
211
- commandId: string // Command ID to execute
212
- }
213
- ```
214
-
215
- ### File Navigation
216
- ```typescript
217
- // Open a file in Obsidian
218
- obsidian_open_file: {
219
- filepath: string, // Path relative to vault root
220
- newLeaf?: boolean // Open in new leaf (default: false)
221
- }
222
-
223
- // Get active file content
224
- obsidian_get_active_file: {}
225
-
226
- // Get periodic note content
227
- obsidian_get_periodic_note: {
228
- period: "daily" | "weekly" | "monthly" | "quarterly" | "yearly"
229
- }
230
- ```
231
-
232
188
  ### Property Management
233
189
  ```typescript
234
- // Get all tags in vault or directory
235
- obsidian_get_tags: {
236
- path?: string // Optional: limit to specific directory
237
- }
238
-
239
190
  // Get note properties
240
191
  obsidian_get_properties: {
241
192
  filepath: string // Path relative to vault root
@@ -286,6 +237,14 @@ obsidian_update_properties: {
286
237
  - Validate inputs and handle errors gracefully
287
238
  - Monitor patterns and respect rate limits
288
239
 
240
+ ## Resources
241
+
242
+ The MCP server exposes the following resources:
243
+
244
+ ```
245
+ obsidian://tags # List of all tags used across the vault
246
+ ```
247
+
289
248
  ## Contributing
290
249
 
291
250
  1. Fork the repository
package/build/index.js CHANGED
@@ -1,11 +1,20 @@
1
1
  #!/usr/bin/env node
2
- import { run } from "./server.js";
2
+ import { run } from "./mcp/server.js";
3
+ import { createLogger } from "./utils/logging.js";
4
+ // Create a logger for the main entry point
5
+ const logger = createLogger('Main');
3
6
  // Main entry point
4
7
  if (import.meta.url === `file://${process.argv[1]}`) {
8
+ logger.info("Starting Obsidian MCP Server");
5
9
  run().catch((error) => {
6
- console.error("Failed to start server:", error);
10
+ logger.error("Failed to start server:", error);
7
11
  process.exit(1);
8
12
  });
9
13
  }
10
- export { run };
14
+ // Export the run function and other important modules
15
+ export { run } from "./mcp/server.js";
16
+ export * from "./obsidian/index.js";
17
+ export * from "./tools/index.js";
18
+ export * from "./resources/index.js";
19
+ export * from "./utils/index.js";
11
20
  //# sourceMappingURL=index.js.map
@@ -0,0 +1,138 @@
1
+ /**
2
+ * MCP server request handlers
3
+ */
4
+ import { ListToolsRequestSchema, CallToolRequestSchema, ListResourcesRequestSchema, ReadResourceRequestSchema } from "@modelcontextprotocol/sdk/types.js";
5
+ import { ObsidianError } from "../utils/errors.js";
6
+ import { validateToolArguments } from "../utils/validation.js";
7
+ import { rateLimiter } from "../utils/rate-limiting.js";
8
+ import { createLogger } from "../utils/logging.js";
9
+ import { DEFAULT_TIMEOUT_CONFIG } from "./types.js";
10
+ // Create a logger for request handlers
11
+ const logger = createLogger('McpHandlers');
12
+ /**
13
+ * Set up tool listing handler
14
+ * @param server The MCP server instance
15
+ * @param toolHandlers The tool handlers to register
16
+ */
17
+ export function setupToolListingHandler(server, toolHandlers) {
18
+ server.setRequestHandler(ListToolsRequestSchema, async () => {
19
+ logger.debug('Handling ListToolsRequest');
20
+ const tools = [];
21
+ for (const handler of toolHandlers.values()) {
22
+ tools.push(handler.getToolDescription());
23
+ }
24
+ return { tools };
25
+ });
26
+ }
27
+ /**
28
+ * Set up tool calling handler
29
+ * @param server The MCP server instance
30
+ * @param toolHandlers The tool handlers to register
31
+ */
32
+ export function setupToolCallingHandler(server, toolHandlers) {
33
+ server.setRequestHandler(CallToolRequestSchema, async (request) => {
34
+ const { name, arguments: args } = request.params;
35
+ logger.debug(`Handling CallToolRequest for tool: ${name}`);
36
+ const handler = toolHandlers.get(name);
37
+ if (!handler) {
38
+ logger.error(`Unknown tool requested: ${name}`);
39
+ throw new ObsidianError(`Unknown tool: ${name}`, 40400); // 40400 = Not found
40
+ }
41
+ // Check rate limit
42
+ try {
43
+ rateLimiter.enforceRateLimit(name);
44
+ }
45
+ catch (error) {
46
+ // If rate limit is exceeded, log and rethrow the error
47
+ logger.warn(`Rate limit exceeded for tool: ${name}`);
48
+ throw error;
49
+ }
50
+ // Add timeout handling
51
+ const timeoutMs = DEFAULT_TIMEOUT_CONFIG.toolExecutionMs;
52
+ const timeoutPromise = new Promise((_, reject) => {
53
+ setTimeout(() => {
54
+ reject(new ObsidianError(`Tool execution timed out after ${timeoutMs}ms`, 40800)); // 40800 = Request timeout
55
+ }, timeoutMs);
56
+ });
57
+ try {
58
+ // Validate arguments against tool's schema
59
+ const toolDescription = handler.getToolDescription();
60
+ const validationResult = validateToolArguments(args, toolDescription.inputSchema);
61
+ if (!validationResult.valid) {
62
+ logger.error(`Invalid tool arguments for ${name}:`, validationResult.errors);
63
+ throw new ObsidianError(`Invalid tool arguments: ${validationResult.errors.join(', ')}`, 40000 // 40000 = Bad request
64
+ );
65
+ }
66
+ // Log the tool execution
67
+ logger.info(`Executing tool: ${name}`);
68
+ // Race between tool execution and timeout
69
+ const content = await Promise.race([
70
+ handler.runTool(args),
71
+ timeoutPromise
72
+ ]);
73
+ logger.debug(`Tool execution completed successfully: ${name}`);
74
+ return { content };
75
+ }
76
+ catch (error) {
77
+ if (error instanceof ObsidianError) {
78
+ // Check if the operation actually succeeded despite the error
79
+ if (error.errorCode === 20400) { // 20400 = Success with no content
80
+ return {
81
+ content: [{
82
+ type: "text",
83
+ text: "Operation completed successfully"
84
+ }]
85
+ };
86
+ }
87
+ throw error;
88
+ }
89
+ // Enhanced error logging
90
+ logger.error("Tool execution error:", {
91
+ name: error instanceof Error ? error.name : 'Unknown',
92
+ message: error instanceof Error ? error.message : String(error),
93
+ stack: error instanceof Error ? error.stack : undefined,
94
+ toolName: name
95
+ });
96
+ if (error instanceof Error) {
97
+ throw new ObsidianError(`Tool '${name}' execution failed: ${error.message}`, 50000, // 50000 = Internal server error
98
+ { originalError: error.stack });
99
+ }
100
+ throw new ObsidianError("Tool execution failed with unknown error", 50000, // 50000 = Internal server error
101
+ { error });
102
+ }
103
+ });
104
+ }
105
+ /**
106
+ * Set up resource listing handler
107
+ * @param server The MCP server instance
108
+ * @param resources The resources to register
109
+ */
110
+ export function setupResourceListingHandler(server, resources) {
111
+ server.setRequestHandler(ListResourcesRequestSchema, async () => {
112
+ logger.debug('Handling ListResourcesRequest');
113
+ return {
114
+ resources: Object.values(resources).map(resource => resource.getResourceDescription())
115
+ };
116
+ });
117
+ }
118
+ /**
119
+ * Set up resource reading handler
120
+ * @param server The MCP server instance
121
+ * @param resources The resources to register
122
+ */
123
+ export function setupResourceReadingHandler(server, resources) {
124
+ server.setRequestHandler(ReadResourceRequestSchema, async (request) => {
125
+ const uri = request.params.uri;
126
+ logger.debug(`Handling ReadResourceRequest for URI: ${uri}`);
127
+ const resource = resources[uri];
128
+ if (resource) {
129
+ logger.debug(`Found resource for URI: ${uri}`);
130
+ return {
131
+ contents: await resource.getContent()
132
+ };
133
+ }
134
+ logger.error(`Resource not found: ${uri}`);
135
+ throw new ObsidianError(`Resource not found: ${uri}`, 40400); // 40400 = Not found
136
+ });
137
+ }
138
+ //# sourceMappingURL=handlers.js.map
@@ -0,0 +1,7 @@
1
+ /**
2
+ * MCP module exports
3
+ */
4
+ export * from './types.js';
5
+ export * from './handlers.js';
6
+ export * from './server.js';
7
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1,131 @@
1
+ /**
2
+ * MCP server implementation
3
+ */
4
+ import { config } from "dotenv";
5
+ import { Server } from "@modelcontextprotocol/sdk/server/index.js";
6
+ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
7
+ import { createLogger } from "../utils/logging.js";
8
+ import { rateLimiter } from "../utils/rate-limiting.js";
9
+ import { createTagResource } from "../resources/index.js";
10
+ import { createToolHandlers, createToolHandlerMap } from "../tools/index.js";
11
+ import { ObsidianClient } from "../obsidian/client.js";
12
+ import { setupToolListingHandler, setupToolCallingHandler, setupResourceListingHandler, setupResourceReadingHandler } from "./handlers.js";
13
+ // Create a logger for the server
14
+ const logger = createLogger('McpServer');
15
+ // Load environment variables
16
+ config();
17
+ /**
18
+ * Initialize MCP server components
19
+ */
20
+ export async function initializeServer() {
21
+ // Verify API key exists
22
+ const API_KEY = process.env.OBSIDIAN_API_KEY;
23
+ if (!API_KEY) {
24
+ throw new Error("OBSIDIAN_API_KEY environment variable is required");
25
+ }
26
+ // Initialize Obsidian client with environment configuration
27
+ logger.info('Initializing Obsidian client');
28
+ const client = new ObsidianClient({
29
+ apiKey: API_KEY,
30
+ verifySSL: process.env.VERIFY_SSL === 'true',
31
+ timeout: parseInt(process.env.REQUEST_TIMEOUT || '5000'),
32
+ maxContentLength: parseInt(process.env.MAX_CONTENT_LENGTH || String(50 * 1024 * 1024)),
33
+ maxBodyLength: parseInt(process.env.MAX_BODY_LENGTH || String(50 * 1024 * 1024))
34
+ });
35
+ // Initialize tool handlers
36
+ logger.info('Initializing tool handlers');
37
+ const toolHandlers = createToolHandlers(client);
38
+ const toolHandlerMap = createToolHandlerMap(toolHandlers);
39
+ // Initialize resources
40
+ logger.info('Initializing resources');
41
+ const tagResource = createTagResource(client);
42
+ const resources = {
43
+ [tagResource.getResourceDescription().uri]: tagResource
44
+ };
45
+ // Create MCP server
46
+ const serverConfig = {
47
+ name: "obsidian-mcp-server",
48
+ version: process.env.npm_package_version ?? "1.1.0" // Use version from package.json
49
+ };
50
+ logger.info(`Creating MCP server: ${serverConfig.name} v${serverConfig.version}`);
51
+ const server = new Server(serverConfig, {
52
+ capabilities: {
53
+ tools: {},
54
+ resources
55
+ }
56
+ });
57
+ // Set up request handlers
58
+ setupToolListingHandler(server, toolHandlerMap);
59
+ setupToolCallingHandler(server, toolHandlerMap);
60
+ setupResourceListingHandler(server, resources);
61
+ setupResourceReadingHandler(server, resources);
62
+ // Set up error handler
63
+ server.onerror = (error) => {
64
+ logger.error("[MCP Error]", error);
65
+ };
66
+ return server;
67
+ }
68
+ /**
69
+ * Set up graceful shutdown handling
70
+ * @param server The MCP server instance
71
+ * @param cleanupHandlers Additional cleanup handlers to run on shutdown
72
+ */
73
+ export function setupShutdownHandling(server, cleanupHandlers = []) {
74
+ // Cleanup function for graceful shutdown
75
+ const cleanup = async () => {
76
+ logger.info('Shutting down server...');
77
+ // Run cleanup handlers
78
+ for (const handler of cleanupHandlers) {
79
+ try {
80
+ await handler();
81
+ }
82
+ catch (error) {
83
+ logger.error('Error during cleanup:', error);
84
+ }
85
+ }
86
+ // Dispose rate limiter
87
+ rateLimiter.dispose();
88
+ // Close server
89
+ await server.close();
90
+ process.exit(0);
91
+ };
92
+ // Handle various termination signals
93
+ process.on('SIGINT', cleanup); // Ctrl+C on all platforms
94
+ process.on('SIGTERM', cleanup); // Termination request
95
+ if (process.platform === 'win32') {
96
+ // Windows-specific handling
97
+ process.on('SIGHUP', cleanup); // Terminal closed
98
+ }
99
+ else {
100
+ // Unix-specific signals
101
+ process.on('SIGUSR1', cleanup);
102
+ process.on('SIGUSR2', cleanup);
103
+ }
104
+ // Handle uncaught errors
105
+ process.on('uncaughtException', async (error) => {
106
+ logger.error('Uncaught exception:', error);
107
+ await cleanup();
108
+ });
109
+ process.on('unhandledRejection', async (error) => {
110
+ logger.error('Unhandled rejection:', error);
111
+ await cleanup();
112
+ });
113
+ }
114
+ /**
115
+ * Run the MCP server
116
+ */
117
+ export async function run() {
118
+ try {
119
+ const server = await initializeServer();
120
+ setupShutdownHandling(server, []);
121
+ // Connect to transport
122
+ const transport = new StdioServerTransport();
123
+ await server.connect(transport);
124
+ logger.info("Obsidian MCP server running on stdio");
125
+ }
126
+ catch (error) {
127
+ logger.error("Failed to start server:", error);
128
+ process.exit(1);
129
+ }
130
+ }
131
+ //# sourceMappingURL=server.js.map
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Default timeout configuration
3
+ */
4
+ export const DEFAULT_TIMEOUT_CONFIG = {
5
+ toolExecutionMs: parseInt(process.env.TOOL_TIMEOUT_MS ?? '60000') // 60 second default timeout
6
+ };
7
+ //# sourceMappingURL=types.js.map