@fadlee/pocketbase-mcp 1.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/LICENSE +21 -0
- package/README.md +123 -0
- package/build/src/config/cli.d.ts +9 -0
- package/build/src/config/cli.js +31 -0
- package/build/src/config/environment.d.ts +9 -0
- package/build/src/config/environment.js +13 -0
- package/build/src/config/index.d.ts +13 -0
- package/build/src/config/index.js +20 -0
- package/build/src/index.d.ts +2 -0
- package/build/src/index.js +21 -0
- package/build/src/server.d.ts +10 -0
- package/build/src/server.js +211 -0
- package/build/src/tools/handlers/analysis.d.ts +10 -0
- package/build/src/tools/handlers/analysis.js +127 -0
- package/build/src/tools/handlers/auth.d.ts +10 -0
- package/build/src/tools/handlers/auth.js +51 -0
- package/build/src/tools/handlers/collection.d.ts +22 -0
- package/build/src/tools/handlers/collection.js +82 -0
- package/build/src/tools/handlers/file.d.ts +5 -0
- package/build/src/tools/handlers/file.js +124 -0
- package/build/src/tools/handlers/generation.d.ts +10 -0
- package/build/src/tools/handlers/generation.js +201 -0
- package/build/src/tools/handlers/index.d.ts +10 -0
- package/build/src/tools/handlers/index.js +17 -0
- package/build/src/tools/handlers/migration.d.ts +18 -0
- package/build/src/tools/handlers/migration.js +219 -0
- package/build/src/tools/handlers/record.d.ts +18 -0
- package/build/src/tools/handlers/record.js +94 -0
- package/build/src/tools/index.d.ts +5 -0
- package/build/src/tools/index.js +7 -0
- package/build/src/tools/schemas/analysis.d.ts +56 -0
- package/build/src/tools/schemas/analysis.js +54 -0
- package/build/src/tools/schemas/auth.d.ts +59 -0
- package/build/src/tools/schemas/auth.js +59 -0
- package/build/src/tools/schemas/collection.d.ts +192 -0
- package/build/src/tools/schemas/collection.js +194 -0
- package/build/src/tools/schemas/file.d.ts +70 -0
- package/build/src/tools/schemas/file.js +70 -0
- package/build/src/tools/schemas/generation.d.ts +49 -0
- package/build/src/tools/schemas/generation.js +49 -0
- package/build/src/tools/schemas/index.d.ts +10 -0
- package/build/src/tools/schemas/index.js +17 -0
- package/build/src/tools/schemas/migration.d.ts +133 -0
- package/build/src/tools/schemas/migration.js +146 -0
- package/build/src/tools/schemas/record.d.ts +103 -0
- package/build/src/tools/schemas/record.js +103 -0
- package/build/src/types/index.d.ts +188 -0
- package/build/src/types/index.js +1 -0
- package/build/src/utils/errors.d.ts +17 -0
- package/build/src/utils/errors.js +35 -0
- package/build/src/utils/response.d.ts +23 -0
- package/build/src/utils/response.js +62 -0
- package/build/src/utils/typescript.d.ts +24 -0
- package/build/src/utils/typescript.js +130 -0
- package/package.json +57 -0
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { McpError, ErrorCode } from "@modelcontextprotocol/sdk/types.js";
|
|
2
|
+
/**
|
|
3
|
+
* Create a standardized MCP error with proper error message formatting
|
|
4
|
+
*/
|
|
5
|
+
export function createMcpError(code, message, error) {
|
|
6
|
+
const errorMessage = error
|
|
7
|
+
? `${message}: ${error instanceof Error ? error.message : JSON.stringify(error)}`
|
|
8
|
+
: message;
|
|
9
|
+
return new McpError(code, errorMessage);
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Handle and format errors from PocketBase operations
|
|
13
|
+
*/
|
|
14
|
+
export function handlePocketBaseError(operation, error) {
|
|
15
|
+
const errorMessage = error instanceof Error ? error.message : JSON.stringify(error);
|
|
16
|
+
return new McpError(ErrorCode.InternalError, `Failed to ${operation}: ${errorMessage}`);
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Validate required parameters and throw appropriate errors
|
|
20
|
+
*/
|
|
21
|
+
export function validateRequiredParams(params, requiredFields) {
|
|
22
|
+
for (const field of requiredFields) {
|
|
23
|
+
if (params[field] === undefined || params[field] === null) {
|
|
24
|
+
throw new McpError(ErrorCode.InvalidParams, `Required parameter '${field}' is missing`);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Validate enum values
|
|
30
|
+
*/
|
|
31
|
+
export function validateEnumValue(value, allowedValues, fieldName) {
|
|
32
|
+
if (value && !allowedValues.includes(value)) {
|
|
33
|
+
throw new McpError(ErrorCode.InvalidParams, `Invalid value for ${fieldName}. Allowed values: ${allowedValues.join(", ")}`);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { ToolResponse } from "../types/index.js";
|
|
2
|
+
/**
|
|
3
|
+
* Create a standardized tool response with JSON content
|
|
4
|
+
*/
|
|
5
|
+
export declare function createJsonResponse(data: any): ToolResponse;
|
|
6
|
+
/**
|
|
7
|
+
* Create a standardized tool response with plain text content
|
|
8
|
+
*/
|
|
9
|
+
export declare function createTextResponse(text: string): ToolResponse;
|
|
10
|
+
/**
|
|
11
|
+
* Create a success response with a message and optional data
|
|
12
|
+
*/
|
|
13
|
+
export declare function createSuccessResponse(message: string, data?: any): ToolResponse;
|
|
14
|
+
/**
|
|
15
|
+
* Format CSV data for export responses
|
|
16
|
+
*/
|
|
17
|
+
export declare function formatCsvData(collections: Array<[
|
|
18
|
+
string,
|
|
19
|
+
{
|
|
20
|
+
schema: any[];
|
|
21
|
+
records: Record<string, any>[];
|
|
22
|
+
}
|
|
23
|
+
]>): ToolResponse;
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Create a standardized tool response with JSON content
|
|
3
|
+
*/
|
|
4
|
+
export function createJsonResponse(data) {
|
|
5
|
+
return {
|
|
6
|
+
content: [
|
|
7
|
+
{
|
|
8
|
+
type: "text",
|
|
9
|
+
text: JSON.stringify(data, null, 2),
|
|
10
|
+
},
|
|
11
|
+
],
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Create a standardized tool response with plain text content
|
|
16
|
+
*/
|
|
17
|
+
export function createTextResponse(text) {
|
|
18
|
+
return {
|
|
19
|
+
content: [
|
|
20
|
+
{
|
|
21
|
+
type: "text",
|
|
22
|
+
text,
|
|
23
|
+
},
|
|
24
|
+
],
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Create a success response with a message and optional data
|
|
29
|
+
*/
|
|
30
|
+
export function createSuccessResponse(message, data) {
|
|
31
|
+
const response = { message };
|
|
32
|
+
if (data !== undefined) {
|
|
33
|
+
Object.assign(response, { data });
|
|
34
|
+
}
|
|
35
|
+
return createJsonResponse(response);
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Format CSV data for export responses
|
|
39
|
+
*/
|
|
40
|
+
export function formatCsvData(collections) {
|
|
41
|
+
let csv = "";
|
|
42
|
+
for (const [collectionName, data] of collections) {
|
|
43
|
+
csv += `Collection: ${collectionName}\n`;
|
|
44
|
+
csv += `Schema:\n${JSON.stringify(data.schema, null, 2)}\n`;
|
|
45
|
+
csv += "Records:\n";
|
|
46
|
+
if (data.records.length > 0) {
|
|
47
|
+
const headers = Object.keys(data.records[0]);
|
|
48
|
+
csv += `${headers.join(",")}\n`;
|
|
49
|
+
data.records.forEach((record) => {
|
|
50
|
+
const values = headers.map((header) => {
|
|
51
|
+
const value = record[header];
|
|
52
|
+
return typeof value === "string" && value.includes(",")
|
|
53
|
+
? `"${value.replace(/"/g, '""')}"`
|
|
54
|
+
: String(value || "");
|
|
55
|
+
});
|
|
56
|
+
csv += `${values.join(",")}\n`;
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
csv += "\n";
|
|
60
|
+
}
|
|
61
|
+
return createTextResponse(csv);
|
|
62
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Utility functions for TypeScript code parsing and generation
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* Convert string to PascalCase
|
|
6
|
+
*/
|
|
7
|
+
export declare function toPascalCase(str: string): string;
|
|
8
|
+
/**
|
|
9
|
+
* Convert string to PascalCase (alias for backward compatibility)
|
|
10
|
+
*/
|
|
11
|
+
export declare function pascalCase(str: string): string;
|
|
12
|
+
/**
|
|
13
|
+
* Map PocketBase field types to TypeScript types
|
|
14
|
+
*/
|
|
15
|
+
export declare function mapPbTypeToTsType(pbType: string, options?: any): string;
|
|
16
|
+
/**
|
|
17
|
+
* Map PocketBase field types to TypeScript types (alias for backward compatibility)
|
|
18
|
+
*/
|
|
19
|
+
export declare function mapPocketBaseTypeToTypeScript(pbType: string, options?: any): string;
|
|
20
|
+
/**
|
|
21
|
+
* Analyze TypeScript source code to extract interface definitions
|
|
22
|
+
* This is a simplified parser for basic interface extraction
|
|
23
|
+
*/
|
|
24
|
+
export declare function analyzeTypeScriptForSchema(sourceCode: string, options: any): any;
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Utility functions for TypeScript code parsing and generation
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* Convert string to PascalCase
|
|
6
|
+
*/
|
|
7
|
+
export function toPascalCase(str) {
|
|
8
|
+
return str
|
|
9
|
+
.replace(/[^a-zA-Z0-9]/g, " ")
|
|
10
|
+
.split(" ")
|
|
11
|
+
.map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase())
|
|
12
|
+
.join("");
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Convert string to PascalCase (alias for backward compatibility)
|
|
16
|
+
*/
|
|
17
|
+
export function pascalCase(str) {
|
|
18
|
+
return str
|
|
19
|
+
.replace(/[^a-zA-Z0-9]/g, " ")
|
|
20
|
+
.split(" ")
|
|
21
|
+
.map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase())
|
|
22
|
+
.join("");
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Map PocketBase field types to TypeScript types
|
|
26
|
+
*/
|
|
27
|
+
export function mapPbTypeToTsType(pbType, options) {
|
|
28
|
+
switch (pbType) {
|
|
29
|
+
case "text":
|
|
30
|
+
case "email":
|
|
31
|
+
case "url":
|
|
32
|
+
case "editor":
|
|
33
|
+
case "select":
|
|
34
|
+
return "string";
|
|
35
|
+
case "number":
|
|
36
|
+
return "number";
|
|
37
|
+
case "bool":
|
|
38
|
+
return "boolean";
|
|
39
|
+
case "date":
|
|
40
|
+
case "autodate":
|
|
41
|
+
return "string"; // ISO date string
|
|
42
|
+
case "json":
|
|
43
|
+
return "any";
|
|
44
|
+
case "file":
|
|
45
|
+
return options?.multiple ? "string[]" : "string";
|
|
46
|
+
case "relation":
|
|
47
|
+
return options?.multiple ? "string[]" : "string";
|
|
48
|
+
default:
|
|
49
|
+
return "any";
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Map PocketBase field types to TypeScript types (alias for backward compatibility)
|
|
54
|
+
*/
|
|
55
|
+
export function mapPocketBaseTypeToTypeScript(pbType, options) {
|
|
56
|
+
return mapPbTypeToTsType(pbType, options);
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Analyze TypeScript source code to extract interface definitions
|
|
60
|
+
* This is a simplified parser for basic interface extraction
|
|
61
|
+
*/
|
|
62
|
+
export function analyzeTypeScriptForSchema(sourceCode, options) {
|
|
63
|
+
const collections = [];
|
|
64
|
+
// Simple regex-based parsing for interface definitions
|
|
65
|
+
const interfaceRegex = /interface\s+(\w+)\s*{([^}]*)}/g;
|
|
66
|
+
let match;
|
|
67
|
+
match = interfaceRegex.exec(sourceCode);
|
|
68
|
+
while (match !== null) {
|
|
69
|
+
const interfaceName = match[1];
|
|
70
|
+
const interfaceBody = match[2];
|
|
71
|
+
// Skip if not a collection-like interface
|
|
72
|
+
if (!interfaceName.toLowerCase().includes("collection") &&
|
|
73
|
+
!interfaceName.toLowerCase().includes("record") &&
|
|
74
|
+
!interfaceName.toLowerCase().includes("model")) {
|
|
75
|
+
continue;
|
|
76
|
+
}
|
|
77
|
+
const fields = [];
|
|
78
|
+
// Parse fields from interface body
|
|
79
|
+
const fieldRegex = /(\w+)\??:\s*([^;\n]+)/g;
|
|
80
|
+
let fieldMatch;
|
|
81
|
+
fieldMatch = fieldRegex.exec(interfaceBody);
|
|
82
|
+
while (fieldMatch !== null) {
|
|
83
|
+
const fieldName = fieldMatch[1];
|
|
84
|
+
const fieldType = fieldMatch[2].trim();
|
|
85
|
+
// Skip common metadata fields
|
|
86
|
+
if (["id", "created", "updated", "collectionId", "collectionName"].includes(fieldName)) {
|
|
87
|
+
continue;
|
|
88
|
+
}
|
|
89
|
+
fields.push({
|
|
90
|
+
name: fieldName,
|
|
91
|
+
type: mapTsTypeToPbType(fieldType),
|
|
92
|
+
required: !fieldMatch[0].includes("?"),
|
|
93
|
+
});
|
|
94
|
+
fieldMatch = fieldRegex.exec(interfaceBody);
|
|
95
|
+
}
|
|
96
|
+
if (fields.length > 0) {
|
|
97
|
+
collections.push({
|
|
98
|
+
name: interfaceName.toLowerCase().replace(/collection|record|model/gi, ""),
|
|
99
|
+
type: "base",
|
|
100
|
+
fields,
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
match = interfaceRegex.exec(sourceCode);
|
|
104
|
+
}
|
|
105
|
+
return collections;
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Map TypeScript types back to PocketBase field types
|
|
109
|
+
*/
|
|
110
|
+
function mapTsTypeToPbType(tsType) {
|
|
111
|
+
const cleanType = tsType.replace(/\[\]$/, "").trim();
|
|
112
|
+
switch (cleanType) {
|
|
113
|
+
case "string":
|
|
114
|
+
return "text";
|
|
115
|
+
case "number":
|
|
116
|
+
return "number";
|
|
117
|
+
case "boolean":
|
|
118
|
+
return "bool";
|
|
119
|
+
case "Date":
|
|
120
|
+
return "date";
|
|
121
|
+
case "any":
|
|
122
|
+
case "object":
|
|
123
|
+
return "json";
|
|
124
|
+
default:
|
|
125
|
+
if (tsType.includes("[]")) {
|
|
126
|
+
return "relation"; // Assume array types are relations
|
|
127
|
+
}
|
|
128
|
+
return "text";
|
|
129
|
+
}
|
|
130
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@fadlee/pocketbase-mcp",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"description": "PocketBase MCP Server for integration with MCP-compatible applications",
|
|
6
|
+
"main": "build/src/index.js",
|
|
7
|
+
"bin": "build/src/index.js",
|
|
8
|
+
"files": [ "build/",
|
|
9
|
+
"README.md",
|
|
10
|
+
"LICENSE"
|
|
11
|
+
],
|
|
12
|
+
"author": {
|
|
13
|
+
"name": "fadlee",
|
|
14
|
+
"email": "fad.lee@hotmail.com"
|
|
15
|
+
},
|
|
16
|
+
"repository": {
|
|
17
|
+
"type": "git",
|
|
18
|
+
"url": "git+https://github.com/fadlee/pocketbase-mcp.git"
|
|
19
|
+
},
|
|
20
|
+
"bugs": {
|
|
21
|
+
"url": "https://github.com/fadlee/pocketbase-mcp/issues"
|
|
22
|
+
},
|
|
23
|
+
"homepage": "https://github.com/fadlee/pocketbase-mcp#readme",
|
|
24
|
+
"license": "MIT",
|
|
25
|
+
"publishConfig": {
|
|
26
|
+
"access": "public"
|
|
27
|
+
},
|
|
28
|
+
"scripts": {
|
|
29
|
+
"build": "tsc && node -e \"require('fs').chmodSync('build/src/index.js', '755')\"",
|
|
30
|
+
"start": "node build/src/index.js",
|
|
31
|
+
"dev": "tsc -w",
|
|
32
|
+
"prepublishOnly": "npm run build",
|
|
33
|
+
"release": "npm version patch --no-git-tag-version && npm publish",
|
|
34
|
+
"release:minor": "npm version minor --no-git-tag-version && npm publish",
|
|
35
|
+
"release:major": "npm version major --no-git-tag-version && npm publish"
|
|
36
|
+
},
|
|
37
|
+
"keywords": [
|
|
38
|
+
"pocketbase",
|
|
39
|
+
"mcp",
|
|
40
|
+
"model-context-protocol",
|
|
41
|
+
"database",
|
|
42
|
+
"api",
|
|
43
|
+
"server"
|
|
44
|
+
],
|
|
45
|
+
"dependencies": {
|
|
46
|
+
"@modelcontextprotocol/sdk": "^1.15.1",
|
|
47
|
+
"dotenv": "^16.6.1",
|
|
48
|
+
"pocketbase": "^0.26.1",
|
|
49
|
+
"yargs": "^18.0.0"
|
|
50
|
+
},
|
|
51
|
+
"devDependencies": {
|
|
52
|
+
"@jest/globals": "^29.7.0",
|
|
53
|
+
"@types/node": "^20.19.7",
|
|
54
|
+
"@types/yargs": "^17.0.33",
|
|
55
|
+
"typescript": "^5.8.3"
|
|
56
|
+
}
|
|
57
|
+
}
|