@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.
Files changed (55) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +123 -0
  3. package/build/src/config/cli.d.ts +9 -0
  4. package/build/src/config/cli.js +31 -0
  5. package/build/src/config/environment.d.ts +9 -0
  6. package/build/src/config/environment.js +13 -0
  7. package/build/src/config/index.d.ts +13 -0
  8. package/build/src/config/index.js +20 -0
  9. package/build/src/index.d.ts +2 -0
  10. package/build/src/index.js +21 -0
  11. package/build/src/server.d.ts +10 -0
  12. package/build/src/server.js +211 -0
  13. package/build/src/tools/handlers/analysis.d.ts +10 -0
  14. package/build/src/tools/handlers/analysis.js +127 -0
  15. package/build/src/tools/handlers/auth.d.ts +10 -0
  16. package/build/src/tools/handlers/auth.js +51 -0
  17. package/build/src/tools/handlers/collection.d.ts +22 -0
  18. package/build/src/tools/handlers/collection.js +82 -0
  19. package/build/src/tools/handlers/file.d.ts +5 -0
  20. package/build/src/tools/handlers/file.js +124 -0
  21. package/build/src/tools/handlers/generation.d.ts +10 -0
  22. package/build/src/tools/handlers/generation.js +201 -0
  23. package/build/src/tools/handlers/index.d.ts +10 -0
  24. package/build/src/tools/handlers/index.js +17 -0
  25. package/build/src/tools/handlers/migration.d.ts +18 -0
  26. package/build/src/tools/handlers/migration.js +219 -0
  27. package/build/src/tools/handlers/record.d.ts +18 -0
  28. package/build/src/tools/handlers/record.js +94 -0
  29. package/build/src/tools/index.d.ts +5 -0
  30. package/build/src/tools/index.js +7 -0
  31. package/build/src/tools/schemas/analysis.d.ts +56 -0
  32. package/build/src/tools/schemas/analysis.js +54 -0
  33. package/build/src/tools/schemas/auth.d.ts +59 -0
  34. package/build/src/tools/schemas/auth.js +59 -0
  35. package/build/src/tools/schemas/collection.d.ts +192 -0
  36. package/build/src/tools/schemas/collection.js +194 -0
  37. package/build/src/tools/schemas/file.d.ts +70 -0
  38. package/build/src/tools/schemas/file.js +70 -0
  39. package/build/src/tools/schemas/generation.d.ts +49 -0
  40. package/build/src/tools/schemas/generation.js +49 -0
  41. package/build/src/tools/schemas/index.d.ts +10 -0
  42. package/build/src/tools/schemas/index.js +17 -0
  43. package/build/src/tools/schemas/migration.d.ts +133 -0
  44. package/build/src/tools/schemas/migration.js +146 -0
  45. package/build/src/tools/schemas/record.d.ts +103 -0
  46. package/build/src/tools/schemas/record.js +103 -0
  47. package/build/src/types/index.d.ts +188 -0
  48. package/build/src/types/index.js +1 -0
  49. package/build/src/utils/errors.d.ts +17 -0
  50. package/build/src/utils/errors.js +35 -0
  51. package/build/src/utils/response.d.ts +23 -0
  52. package/build/src/utils/response.js +62 -0
  53. package/build/src/utils/typescript.d.ts +24 -0
  54. package/build/src/utils/typescript.js +130 -0
  55. 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
+ }