bear-notes-mcp-xq7k 2.0.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.
package/LICENSE.md ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Serhii Vasylenko
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,109 @@
1
+ # Bear Notes MCP Server
2
+
3
+ Search, read, and update your Bear Notes
4
+
5
+ Want to use this Bear Notes MCP server with Claude Code, Cursor, Codex, or other AI assistants? You can run it as a standalone MCP server.
6
+
7
+
8
+ **Requirements**: Node.js 22.13.0+
9
+
10
+ ### Quick Start - Claude Code (One Command)
11
+
12
+ **For Node.js 22.13.0+ / 23.4.0+ / 24.x+ / 25.x+ (recommended):**
13
+ ```bash
14
+ claude mcp add bear-notes --transport stdio -- npx -y bear-notes-mcp
15
+ ```
16
+
17
+ Read more here -- [README.npm.md](./README.npm.md)
18
+
19
+ **For Node.js 22.5.0-22.12.x or 23.0.0-23.3.x (older versions):**
20
+ ```bash
21
+ claude mcp add bear-notes --transport stdio --env NODE_OPTIONS="--experimental-sqlite" -- npx -y bear-notes-mcp
22
+ ```
23
+
24
+ That's it! The server will be downloaded from npm and configured automatically.
25
+
26
+ ### Quick Start - Other AI Assistants
27
+
28
+ **For Node.js 22.13.0+ / 23.4.0+ / 24.x+ / 25.x+ (recommended):**
29
+ ```json
30
+ {
31
+ "mcpServers": {
32
+ "bear-notes": {
33
+ "command": "npx",
34
+ "args": ["-y", "bear-notes-mcp"]
35
+ }
36
+ }
37
+ }
38
+ ```
39
+
40
+ **For Node.js 22.5.0-22.12.x or 23.0.0-23.3.x (older versions):**
41
+ ```json
42
+ {
43
+ "mcpServers": {
44
+ "bear-notes": {
45
+ "command": "npx",
46
+ "args": ["-y", "bear-notes-mcp"],
47
+ "env": {
48
+ "NODE_OPTIONS": "--experimental-sqlite"
49
+ }
50
+ }
51
+ }
52
+ }
53
+ ```
54
+
55
+ **Config file locations:**
56
+ - **Claude Desktop**: `~/Library/Application Support/Claude/claude_desktop_config.json`
57
+ - **Cline**: VS Code Settings → Extensions → Cline → MCP Settings
58
+ - **Continue**: `~/.continue/config.json`
59
+ - **Cursor**: Settings → Cursor Settings → MCP
60
+
61
+ **Check your Node.js version:** `node --version`
62
+
63
+ ### Advanced: Local Development Build
64
+
65
+ If you want to contribute or modify the code:
66
+
67
+ **Step 1: Clone and build**
68
+ ```bash
69
+ git clone https://github.com/vasylenko/claude-desktop-extension-bear-notes.git
70
+ cd claude-desktop-extension-bear-notes
71
+ npm install
72
+ npm run build
73
+ ```
74
+
75
+ **Step 2: Configure with local path**
76
+
77
+ For Claude Code (Node.js 22.13.0+):
78
+ ```bash
79
+ claude mcp add bear-notes --transport stdio -- node /absolute/path/to/dist/main.js
80
+ ```
81
+
82
+ For Claude Code (Node.js 22.5.0-22.12.x):
83
+ ```bash
84
+ claude mcp add bear-notes --transport stdio -- node --experimental-sqlite /absolute/path/to/dist/main.js
85
+ ```
86
+
87
+ For other AI assistants (Node.js 22.13.0+):
88
+ ```json
89
+ {
90
+ "mcpServers": {
91
+ "bear-notes": {
92
+ "command": "node",
93
+ "args": ["/absolute/path/to/dist/main.js"]
94
+ }
95
+ }
96
+ }
97
+ ```
98
+
99
+ For other AI assistants (Node.js 22.5.0-22.12.x):
100
+ ```json
101
+ {
102
+ "mcpServers": {
103
+ "bear-notes": {
104
+ "command": "node",
105
+ "args": ["--experimental-sqlite", "/absolute/path/to/dist/main.js"]
106
+ }
107
+ }
108
+ }
109
+ ```
package/README.npm.md ADDED
@@ -0,0 +1,109 @@
1
+ # Bear Notes MCP Server
2
+
3
+ Search, read, and update your Bear Notes
4
+
5
+ Want to use this Bear Notes MCP server with Claude Code, Cursor, Codex, or other AI assistants? You can run it as a standalone MCP server.
6
+
7
+
8
+ **Requirements**: Node.js 22.13.0+
9
+
10
+ ### Quick Start - Claude Code (One Command)
11
+
12
+ **For Node.js 22.13.0+ / 23.4.0+ / 24.x+ / 25.x+ (recommended):**
13
+ ```bash
14
+ claude mcp add bear-notes --transport stdio -- npx -y bear-notes-mcp
15
+ ```
16
+
17
+ Read more here -- [README.npm.md](./README.npm.md)
18
+
19
+ **For Node.js 22.5.0-22.12.x or 23.0.0-23.3.x (older versions):**
20
+ ```bash
21
+ claude mcp add bear-notes --transport stdio --env NODE_OPTIONS="--experimental-sqlite" -- npx -y bear-notes-mcp
22
+ ```
23
+
24
+ That's it! The server will be downloaded from npm and configured automatically.
25
+
26
+ ### Quick Start - Other AI Assistants
27
+
28
+ **For Node.js 22.13.0+ / 23.4.0+ / 24.x+ / 25.x+ (recommended):**
29
+ ```json
30
+ {
31
+ "mcpServers": {
32
+ "bear-notes": {
33
+ "command": "npx",
34
+ "args": ["-y", "bear-notes-mcp"]
35
+ }
36
+ }
37
+ }
38
+ ```
39
+
40
+ **For Node.js 22.5.0-22.12.x or 23.0.0-23.3.x (older versions):**
41
+ ```json
42
+ {
43
+ "mcpServers": {
44
+ "bear-notes": {
45
+ "command": "npx",
46
+ "args": ["-y", "bear-notes-mcp"],
47
+ "env": {
48
+ "NODE_OPTIONS": "--experimental-sqlite"
49
+ }
50
+ }
51
+ }
52
+ }
53
+ ```
54
+
55
+ **Config file locations:**
56
+ - **Claude Desktop**: `~/Library/Application Support/Claude/claude_desktop_config.json`
57
+ - **Cline**: VS Code Settings → Extensions → Cline → MCP Settings
58
+ - **Continue**: `~/.continue/config.json`
59
+ - **Cursor**: Settings → Cursor Settings → MCP
60
+
61
+ **Check your Node.js version:** `node --version`
62
+
63
+ ### Advanced: Local Development Build
64
+
65
+ If you want to contribute or modify the code:
66
+
67
+ **Step 1: Clone and build**
68
+ ```bash
69
+ git clone https://github.com/vasylenko/claude-desktop-extension-bear-notes.git
70
+ cd claude-desktop-extension-bear-notes
71
+ npm install
72
+ npm run build
73
+ ```
74
+
75
+ **Step 2: Configure with local path**
76
+
77
+ For Claude Code (Node.js 22.13.0+):
78
+ ```bash
79
+ claude mcp add bear-notes --transport stdio -- node /absolute/path/to/dist/main.js
80
+ ```
81
+
82
+ For Claude Code (Node.js 22.5.0-22.12.x):
83
+ ```bash
84
+ claude mcp add bear-notes --transport stdio -- node --experimental-sqlite /absolute/path/to/dist/main.js
85
+ ```
86
+
87
+ For other AI assistants (Node.js 22.13.0+):
88
+ ```json
89
+ {
90
+ "mcpServers": {
91
+ "bear-notes": {
92
+ "command": "node",
93
+ "args": ["/absolute/path/to/dist/main.js"]
94
+ }
95
+ }
96
+ }
97
+ ```
98
+
99
+ For other AI assistants (Node.js 22.5.0-22.12.x):
100
+ ```json
101
+ {
102
+ "mcpServers": {
103
+ "bear-notes": {
104
+ "command": "node",
105
+ "args": ["--experimental-sqlite", "/absolute/path/to/dist/main.js"]
106
+ }
107
+ }
108
+ }
109
+ ```
@@ -0,0 +1,87 @@
1
+ import { spawn } from 'node:child_process';
2
+ import { BEAR_URL_SCHEME } from './config.js';
3
+ import { logAndThrow, logger } from './utils.js';
4
+ /**
5
+ * Builds a Bear x-callback-url for various actions with proper parameter encoding.
6
+ * Includes required UX parameters for optimal user experience.
7
+ *
8
+ * @param action - Bear API action (e.g., 'create', 'add-text')
9
+ * @param params - Parameters for the specific action
10
+ * @returns Properly encoded x-callback-url string
11
+ */
12
+ export function buildBearUrl(action, params = {}) {
13
+ logger.debug(`Building Bear URL for action: ${action}`);
14
+ if (!action || typeof action !== 'string' || !action.trim()) {
15
+ logAndThrow('Bear URL error: Action parameter is required and must be a non-empty string');
16
+ }
17
+ const baseUrl = `${BEAR_URL_SCHEME}${action.trim()}`;
18
+ const urlParams = new URLSearchParams();
19
+ // Add provided parameters with proper encoding
20
+ const stringParams = ['title', 'text', 'tags', 'id', 'header', 'file', 'filename'];
21
+ for (const key of stringParams) {
22
+ const value = params[key];
23
+ if (value !== undefined && value.trim()) {
24
+ urlParams.set(key, value.trim());
25
+ }
26
+ }
27
+ if (params.mode !== undefined) {
28
+ urlParams.set('mode', params.mode);
29
+ }
30
+ // UX params with defaults
31
+ urlParams.set('open_note', params.open_note ?? 'yes');
32
+ urlParams.set('new_window', params.new_window ?? 'no');
33
+ urlParams.set('show_window', params.show_window ?? 'yes');
34
+ // Add required Bear API parameters for add-text action
35
+ if (action === 'add-text') {
36
+ urlParams.set('new_line', 'yes'); // Ensures text appears on new line
37
+ }
38
+ // Convert URLSearchParams to proper URL encoding (Bear expects %20 not +)
39
+ const queryString = urlParams.toString().replace(/\+/g, '%20');
40
+ const finalUrl = `${baseUrl}?${queryString}`;
41
+ logger.debug(`Built Bear URL: ${finalUrl}`);
42
+ return finalUrl;
43
+ }
44
+ /**
45
+ * Executes a Bear x-callback-url using macOS subprocess execution.
46
+ * Platform-specific function that requires macOS with Bear Notes installed.
47
+ *
48
+ * @param url - The x-callback-url to execute
49
+ * @returns Promise that resolves when the command completes successfully
50
+ * @throws Error if platform is not macOS or subprocess execution fails
51
+ */
52
+ export function executeBearXCallbackApi(url) {
53
+ logger.debug('Executing Bear x-callback-url');
54
+ if (!url || typeof url !== 'string' || !url.trim()) {
55
+ logAndThrow('Bear URL error: URL parameter is required and must be a non-empty string');
56
+ }
57
+ return new Promise((resolve, reject) => {
58
+ logger.debug('Launching Bear Notes via x-callback-url');
59
+ const child = spawn('open', ['-g', url.trim()], {
60
+ stdio: 'pipe',
61
+ detached: false,
62
+ });
63
+ let errorOutput = '';
64
+ if (child.stderr) {
65
+ child.stderr.on('data', (data) => {
66
+ errorOutput += data.toString();
67
+ });
68
+ }
69
+ child.on('close', (code) => {
70
+ if (code === 0) {
71
+ logger.debug('Bear x-callback-url executed successfully');
72
+ resolve();
73
+ }
74
+ else {
75
+ const errorMessage = `Bear URL error: Failed to execute x-callback-url (exit code: ${code})`;
76
+ const fullError = errorOutput ? `${errorMessage}. Error: ${errorOutput}` : errorMessage;
77
+ logger.error(fullError);
78
+ reject(new Error(fullError));
79
+ }
80
+ });
81
+ child.on('error', (error) => {
82
+ const errorMessage = `Bear URL error: Failed to spawn subprocess: ${error.message}`;
83
+ logger.error(errorMessage);
84
+ reject(new Error(errorMessage));
85
+ });
86
+ });
87
+ }
package/dist/config.js ADDED
@@ -0,0 +1,11 @@
1
+ export const APP_VERSION = '2.0.1';
2
+ export const BEAR_URL_SCHEME = 'bear://x-callback-url/';
3
+ export const CORE_DATA_EPOCH_OFFSET = 978307200; // 2001-01-01 to Unix epoch
4
+ export const DEFAULT_SEARCH_LIMIT = 50;
5
+ export const BEAR_DATABASE_PATH = 'Library/Group Containers/9K33E3U3T4.net.shinyfrog.bear/Application Data/database.sqlite';
6
+ export const ERROR_MESSAGES = {
7
+ BEAR_DATABASE_NOT_FOUND: 'Bear database not found. Please ensure Bear Notes is installed and has been opened at least once.',
8
+ MISSING_SEARCH_PARAM: 'Please provide either a search term or a tag to search for notes.',
9
+ MISSING_NOTE_ID: 'Please provide a note identifier. Use bear-search-notes first to find the note ID.',
10
+ MISSING_TEXT_PARAM: 'Text input parameter is required and must be a non-empty string',
11
+ };
@@ -0,0 +1,40 @@
1
+ import { DatabaseSync } from 'node:sqlite';
2
+ import { homedir } from 'node:os';
3
+ import { join } from 'node:path';
4
+ import { existsSync } from 'node:fs';
5
+ import { BEAR_DATABASE_PATH, ERROR_MESSAGES } from './config.js';
6
+ import { logAndThrow, logger } from './utils.js';
7
+ function getBearDatabasePath() {
8
+ // Environment override for testing
9
+ const envPath = process.env.BEAR_DB_PATH;
10
+ if (envPath) {
11
+ logger.debug(`Using environment override database path: ${envPath}`);
12
+ return envPath;
13
+ }
14
+ const defaultPath = join(homedir(), BEAR_DATABASE_PATH);
15
+ if (!existsSync(defaultPath)) {
16
+ logger.error(`Bear database not found at: ${defaultPath}`);
17
+ logAndThrow(`Database error: ${ERROR_MESSAGES.BEAR_DATABASE_NOT_FOUND}`);
18
+ }
19
+ logger.debug(`Using default Bear database path: ${defaultPath}`);
20
+ return defaultPath;
21
+ }
22
+ /**
23
+ * Opens a read-only connection to Bear's SQLite database.
24
+ *
25
+ * @returns DatabaseSync instance for querying Bear notes
26
+ * @throws Error if Bear database is not found or cannot be opened
27
+ */
28
+ export function openBearDatabase() {
29
+ const databasePath = getBearDatabasePath();
30
+ logger.info(`Opening Bear database at: ${databasePath}`);
31
+ try {
32
+ const db = new DatabaseSync(databasePath);
33
+ logger.debug('Bear database opened successfully');
34
+ return db;
35
+ }
36
+ catch (error) {
37
+ logger.error(`Failed to open Bear database: ${error}`);
38
+ logAndThrow(`Database error: Failed to open Bear database: ${error instanceof Error ? error.message : String(error)}`);
39
+ }
40
+ }