# Directory Structure
```
├── .gitignore
├── package-lock.json
├── package.json
├── README.md
├── src
│ ├── .prettierignore
│ └── index.ts
└── tsconfig.json
```
# Files
--------------------------------------------------------------------------------
/src/.prettierignore:
--------------------------------------------------------------------------------
```
1 | build
2 | pocketbase
3 |
```
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
```
1 | node_modules/
2 | build/
3 | pocketbase/
4 | *.log
5 | .env*
```
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
```markdown
1 | # pocketbase-mcp-server MCP Server
2 |
3 | Model Context Protocol Server for PocketBase
4 |
5 | This is a TypeScript-based MCP server that provides:
6 |
7 | - Tools for listing PocketBase collections
8 |
9 | ## Features
10 |
11 | ### Tools
12 |
13 | - `pocketbase_list_collections` - List all collections from a PocketBase instance
14 | - Requires server to be started with PocketBase configuration
15 | - Returns JSON representation of all collections
16 |
17 | ## Development
18 |
19 | Install dependencies:
20 |
21 | ```bash
22 | npm install
23 | ```
24 |
25 | Build the server:
26 |
27 | ```bash
28 | npm run build
29 | ```
30 |
31 | For development with auto-rebuild:
32 |
33 | ```bash
34 | npm run watch
35 | ```
36 |
37 | ## Installation
38 |
39 | To use with Claude Desktop, add the server config:
40 |
41 | On MacOS: `~/Library/Application Support/Claude/claude_desktop_config.json`
42 | On Windows: `%APPDATA%/Claude/claude_desktop_config.json`
43 |
44 | ```json
45 | {
46 | "mcpServers": {
47 | "pocketbase-mcp-server": {
48 | "command": "/path/to/pocketbase-mcp-server/build/index.js --pb-url=http://localhost:8090 [email protected] --pb-admin-password=your-secure-password"
49 | }
50 | }
51 | }
52 | ```
53 |
54 | ### PocketBase Configuration
55 |
56 | To enable the PocketBase collections tool, you must provide the following configuration either as command line arguments or environment variables:
57 |
58 | - `--pb-url=<url>` or `PB_URL` - The URL of your PocketBase instance (e.g., http://localhost:8090)
59 | - `--pb-admin-email=<email>` or `PB_ADMIN_EMAIL` - Admin email for authentication
60 | - `--pb-admin-password=<password>` or `PB_ADMIN_PASSWORD` - Admin password for authentication
61 |
62 | If using environment variables, you can set them like this:
63 |
64 | ```bash
65 | export PB_URL=http://localhost:8090
66 | export [email protected]
67 | export PB_ADMIN_PASSWORD=your-secure-password
68 | ```
69 |
70 | Example using command line arguments:
71 |
72 | ```bash
73 | node build/index.js --pb-url=http://localhost:8090 [email protected] --pb-admin-password=your-secure-password
74 | ```
75 |
76 | ### Debugging
77 |
78 | Since MCP servers communicate over stdio, debugging can be challenging. We recommend using the [MCP Inspector](https://github.com/modelcontextprotocol/inspector), which is available as a package script:
79 |
80 | ```bash
81 | npm run inspector
82 | ```
83 |
84 | The Inspector will provide a URL to access debugging tools in your browser.
85 |
```
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
```json
1 | {
2 | "compilerOptions": {
3 | "target": "ES2022",
4 | "module": "Node16",
5 | "moduleResolution": "Node16",
6 | "outDir": "./build",
7 | "rootDir": "./src",
8 | "strict": true,
9 | "esModuleInterop": true,
10 | "skipLibCheck": true,
11 | "forceConsistentCasingInFileNames": true
12 | },
13 | "include": ["src/**/*"],
14 | "exclude": ["node_modules"]
15 | }
16 |
```
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
```json
1 | {
2 | "name": "pocketbase-mcp-server",
3 | "version": "0.1.0",
4 | "description": "Model Context Protocol Server for PocketBase",
5 | "private": true,
6 | "type": "module",
7 | "bin": {
8 | "pocketbase-mcp-server": "./build/index.js"
9 | },
10 | "files": [
11 | "build"
12 | ],
13 | "scripts": {
14 | "build": "tsc && node -e \"require('fs').chmodSync('build/index.js', '755')\"",
15 | "prepare": "npm run build",
16 | "watch": "tsc --watch",
17 | "inspector": "npx @modelcontextprotocol/inspector build/index.js"
18 | },
19 | "dependencies": {
20 | "@modelcontextprotocol/sdk": "0.6.0",
21 | "pocketbase": "^0.25.2"
22 | },
23 | "devDependencies": {
24 | "@types/node": "^20.11.24",
25 | "prettier": "3.5.2",
26 | "typescript": "^5.3.3"
27 | },
28 | "prettier": {
29 | "printWidth": 120,
30 | "singleQuote": true
31 | }
32 | }
33 |
```
--------------------------------------------------------------------------------
/src/index.ts:
--------------------------------------------------------------------------------
```typescript
1 | #!/usr/bin/env node
2 |
3 | /**
4 | * This is an MCP server to manage PocketBase via LLMs.
5 | */
6 |
7 | import { Server } from '@modelcontextprotocol/sdk/server/index.js';
8 | import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
9 | import { CallToolRequestSchema, ListToolsRequestSchema } from '@modelcontextprotocol/sdk/types.js';
10 | import PocketBase from 'pocketbase';
11 |
12 | /**
13 | * PocketBase configuration options obtained from command line args.
14 | */
15 | interface PocketBaseConfig {
16 | url: string;
17 | adminEmail: string;
18 | adminPassword: string;
19 | }
20 |
21 | /**
22 | * Parse configuration from command line arguments and environment variables.
23 | * Command line arguments take precedence over environment variables.
24 | */
25 | function getPocketBaseConfig(): PocketBaseConfig {
26 | const args = process.argv.slice(2);
27 | const url = args.find((arg) => arg.startsWith('--pb-url='))?.split('=')[1] || process.env.PB_URL;
28 | const adminEmail =
29 | args.find((arg) => arg.startsWith('--pb-admin-email='))?.split('=')[1] || process.env.PB_ADMIN_EMAIL;
30 | const adminPassword =
31 | args.find((arg) => arg.startsWith('--pb-admin-password='))?.split('=')[1] || process.env.PB_ADMIN_PASSWORD;
32 |
33 | if (!url || !adminEmail || !adminPassword) {
34 | console.error(
35 | 'PocketBase configuration is required. Please provide --pb-url, --pb-admin-email, and --pb-admin-password as command line arguments or set PB_URL, PB_ADMIN_EMAIL, and PB_ADMIN_PASSWORD as environment variables.',
36 | );
37 | process.exit(1);
38 | }
39 |
40 | return { url, adminEmail, adminPassword };
41 | }
42 |
43 | // Load PocketBase configuration from command line args or environment variables
44 | const pocketBaseConfig = getPocketBaseConfig();
45 |
46 | /**
47 | * Create an MCP server with capabilities for resources,
48 | * tools, and prompts.
49 | */
50 | const server = new Server(
51 | {
52 | name: 'pocketbase-mcp-server',
53 | version: '0.1.0',
54 | },
55 | {
56 | capabilities: {
57 | resources: {},
58 | tools: {},
59 | prompts: {},
60 | },
61 | },
62 | );
63 |
64 | /**
65 | * Handler that lists available tools.
66 | * Exposes tools for creating notes and listing PocketBase collections (if configured).
67 | */
68 | server.setRequestHandler(ListToolsRequestSchema, async () => {
69 | return {
70 | tools: [
71 | {
72 | name: 'pocketbase_list_collections',
73 | description: 'List PocketBase Collections',
74 | inputSchema: {
75 | type: 'object',
76 | properties: {},
77 | required: [],
78 | },
79 | },
80 | ],
81 | };
82 | });
83 |
84 | /**
85 | * Handler for tool calls.
86 | * Handles:
87 | * - pocketbase_list_collections: Connects to PocketBase and lists all collections
88 | */
89 | server.setRequestHandler(CallToolRequestSchema, async (request) => {
90 | switch (request.params.name) {
91 | case 'pocketbase_list_collections': {
92 | if (!pocketBaseConfig) {
93 | throw new Error(
94 | 'PocketBase configuration is not available. Please start the server with --pb-url, --pb-admin-email, and --pb-admin-password arguments.',
95 | );
96 | }
97 |
98 | try {
99 | // Connect to PocketBase
100 | const pb = new PocketBase(pocketBaseConfig.url);
101 |
102 | // Authenticate as admin
103 | await pb
104 | .collection('_superusers')
105 | .authWithPassword(pocketBaseConfig.adminEmail, pocketBaseConfig.adminPassword);
106 |
107 | // Fetch all collections
108 | const collections = await pb.collections.getFullList();
109 |
110 | return {
111 | content: [
112 | {
113 | type: 'text',
114 | text: JSON.stringify(collections, null, 2),
115 | },
116 | ],
117 | };
118 | } catch (error) {
119 | throw new Error(
120 | `Failed to list PocketBase collections: ${error instanceof Error ? error.message : String(error)}`,
121 | );
122 | }
123 | }
124 |
125 | default:
126 | throw new Error('Unknown tool');
127 | }
128 | });
129 |
130 | /**
131 | * Start the server using stdio transport.
132 | * This allows the server to communicate via standard input/output streams.
133 | */
134 | async function main() {
135 | const transport = new StdioServerTransport();
136 | await server.connect(transport);
137 | }
138 |
139 | main().catch((error) => {
140 | console.error('Server error:', error);
141 | process.exit(1);
142 | });
143 |
```