mcp-quickbase 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/CHANGELOG.md +82 -0
- package/LICENSE +21 -0
- package/README.md +301 -0
- package/dist/client/quickbase.d.ts +28 -0
- package/dist/client/quickbase.js +235 -0
- package/dist/client/quickbase.js.map +1 -0
- package/dist/mcp/index.d.ts +4 -0
- package/dist/mcp/index.js +21 -0
- package/dist/mcp/index.js.map +1 -0
- package/dist/mcp/server.d.ts +19 -0
- package/dist/mcp/server.js +102 -0
- package/dist/mcp/server.js.map +1 -0
- package/dist/mcp-stdio-server.d.ts +2 -0
- package/dist/mcp-stdio-server.js +168 -0
- package/dist/mcp-stdio-server.js.map +1 -0
- package/dist/server.d.ts +2 -0
- package/dist/server.js +318 -0
- package/dist/server.js.map +1 -0
- package/dist/tools/apps/create_app.d.ts +87 -0
- package/dist/tools/apps/create_app.js +87 -0
- package/dist/tools/apps/create_app.js.map +1 -0
- package/dist/tools/apps/index.d.ts +9 -0
- package/dist/tools/apps/index.js +40 -0
- package/dist/tools/apps/index.js.map +1 -0
- package/dist/tools/apps/list_tables.d.ts +108 -0
- package/dist/tools/apps/list_tables.js +100 -0
- package/dist/tools/apps/list_tables.js.map +1 -0
- package/dist/tools/apps/update_app.d.ts +91 -0
- package/dist/tools/apps/update_app.js +99 -0
- package/dist/tools/apps/update_app.js.map +1 -0
- package/dist/tools/base.d.ts +47 -0
- package/dist/tools/base.js +63 -0
- package/dist/tools/base.js.map +1 -0
- package/dist/tools/configure_cache.d.ts +81 -0
- package/dist/tools/configure_cache.js +77 -0
- package/dist/tools/configure_cache.js.map +1 -0
- package/dist/tools/fields/create_field.d.ts +121 -0
- package/dist/tools/fields/create_field.js +102 -0
- package/dist/tools/fields/create_field.js.map +1 -0
- package/dist/tools/fields/index.d.ts +8 -0
- package/dist/tools/fields/index.js +37 -0
- package/dist/tools/fields/index.js.map +1 -0
- package/dist/tools/fields/update_field.d.ts +112 -0
- package/dist/tools/fields/update_field.js +114 -0
- package/dist/tools/fields/update_field.js.map +1 -0
- package/dist/tools/files/download_file.d.ts +111 -0
- package/dist/tools/files/download_file.js +173 -0
- package/dist/tools/files/download_file.js.map +1 -0
- package/dist/tools/files/index.d.ts +8 -0
- package/dist/tools/files/index.js +37 -0
- package/dist/tools/files/index.js.map +1 -0
- package/dist/tools/files/upload_file.d.ts +107 -0
- package/dist/tools/files/upload_file.js +211 -0
- package/dist/tools/files/upload_file.js.map +1 -0
- package/dist/tools/index.d.ts +18 -0
- package/dist/tools/index.js +65 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/tools/records/bulk_create_records.d.ts +75 -0
- package/dist/tools/records/bulk_create_records.js +104 -0
- package/dist/tools/records/bulk_create_records.js.map +1 -0
- package/dist/tools/records/bulk_update_records.d.ts +77 -0
- package/dist/tools/records/bulk_update_records.js +102 -0
- package/dist/tools/records/bulk_update_records.js.map +1 -0
- package/dist/tools/records/create_record.d.ts +68 -0
- package/dist/tools/records/create_record.js +123 -0
- package/dist/tools/records/create_record.js.map +1 -0
- package/dist/tools/records/index.d.ts +11 -0
- package/dist/tools/records/index.js +46 -0
- package/dist/tools/records/index.js.map +1 -0
- package/dist/tools/records/query_records.d.ts +164 -0
- package/dist/tools/records/query_records.js +261 -0
- package/dist/tools/records/query_records.js.map +1 -0
- package/dist/tools/records/update_record.d.ts +81 -0
- package/dist/tools/records/update_record.js +99 -0
- package/dist/tools/records/update_record.js.map +1 -0
- package/dist/tools/registry.d.ts +41 -0
- package/dist/tools/registry.js +66 -0
- package/dist/tools/registry.js.map +1 -0
- package/dist/tools/reports/index.d.ts +6 -0
- package/dist/tools/reports/index.js +31 -0
- package/dist/tools/reports/index.js.map +1 -0
- package/dist/tools/reports/run_report.d.ts +70 -0
- package/dist/tools/reports/run_report.js +72 -0
- package/dist/tools/reports/run_report.js.map +1 -0
- package/dist/tools/tables/create_table.d.ts +142 -0
- package/dist/tools/tables/create_table.js +119 -0
- package/dist/tools/tables/create_table.js.map +1 -0
- package/dist/tools/tables/get_table_fields.d.ts +108 -0
- package/dist/tools/tables/get_table_fields.js +96 -0
- package/dist/tools/tables/get_table_fields.js.map +1 -0
- package/dist/tools/tables/index.d.ts +9 -0
- package/dist/tools/tables/index.js +40 -0
- package/dist/tools/tables/index.js.map +1 -0
- package/dist/tools/tables/update_table.d.ts +91 -0
- package/dist/tools/tables/update_table.js +99 -0
- package/dist/tools/tables/update_table.js.map +1 -0
- package/dist/tools/test_connection.d.ts +51 -0
- package/dist/tools/test_connection.js +101 -0
- package/dist/tools/test_connection.js.map +1 -0
- package/dist/types/api.d.ts +70 -0
- package/dist/types/api.js +6 -0
- package/dist/types/api.js.map +1 -0
- package/dist/types/config.d.ts +49 -0
- package/dist/types/config.js +3 -0
- package/dist/types/config.js.map +1 -0
- package/dist/types/mcp.d.ts +55 -0
- package/dist/types/mcp.js +3 -0
- package/dist/types/mcp.js.map +1 -0
- package/dist/utils/cache.d.ts +87 -0
- package/dist/utils/cache.js +211 -0
- package/dist/utils/cache.js.map +1 -0
- package/dist/utils/file.d.ts +40 -0
- package/dist/utils/file.js +167 -0
- package/dist/utils/file.js.map +1 -0
- package/dist/utils/logger.d.ts +37 -0
- package/dist/utils/logger.js +144 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/utils/retry.d.ts +39 -0
- package/dist/utils/retry.js +88 -0
- package/dist/utils/retry.js.map +1 -0
- package/dist/utils/validation.d.ts +32 -0
- package/dist/utils/validation.js +227 -0
- package/dist/utils/validation.js.map +1 -0
- package/docs/README.md +41 -0
- package/docs/architecture.md +94 -0
- package/docs/claude-prompts.md +218 -0
- package/docs/deployment.md +244 -0
- package/docs/developer-guide.md +537 -0
- package/docs/final-qa-report.md +243 -0
- package/docs/performance-benchmarks.md +306 -0
- package/docs/quick-reference.md +109 -0
- package/docs/quickstart.md +183 -0
- package/docs/security-review.md +263 -0
- package/docs/tools.md +269 -0
- package/package.json +68 -0
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.calculateBackoff = calculateBackoff;
|
|
4
|
+
exports.withRetry = withRetry;
|
|
5
|
+
const logger_1 = require("./logger");
|
|
6
|
+
const logger = (0, logger_1.createLogger)('RetryUtil');
|
|
7
|
+
/**
|
|
8
|
+
* Default retry options
|
|
9
|
+
*/
|
|
10
|
+
const DEFAULT_RETRY_OPTIONS = {
|
|
11
|
+
maxRetries: 3,
|
|
12
|
+
baseDelay: 1000,
|
|
13
|
+
maxDelay: 10000,
|
|
14
|
+
backoffFactor: 2,
|
|
15
|
+
isRetryable: (error) => {
|
|
16
|
+
// Default logic for determining if an error is retryable
|
|
17
|
+
if (!error)
|
|
18
|
+
return false;
|
|
19
|
+
// Handle fetch response errors
|
|
20
|
+
if (typeof error === 'object' && error !== null && 'status' in error) {
|
|
21
|
+
const httpError = error;
|
|
22
|
+
// Retry 429 (Too Many Requests), 408 (Request Timeout), and 5xx errors
|
|
23
|
+
return httpError.status === 429 ||
|
|
24
|
+
httpError.status === 408 ||
|
|
25
|
+
(httpError.status >= 500 && httpError.status < 600);
|
|
26
|
+
}
|
|
27
|
+
// Handle network errors
|
|
28
|
+
if (error instanceof Error) {
|
|
29
|
+
return error.message.includes('network') ||
|
|
30
|
+
error.message.includes('timeout') ||
|
|
31
|
+
error.message.includes('connection');
|
|
32
|
+
}
|
|
33
|
+
return false;
|
|
34
|
+
}
|
|
35
|
+
};
|
|
36
|
+
/**
|
|
37
|
+
* Calculates the delay time for a retry attempt with exponential backoff
|
|
38
|
+
* @param attempt Retry attempt number (0-based)
|
|
39
|
+
* @param options Retry options
|
|
40
|
+
* @returns Delay time in milliseconds
|
|
41
|
+
*/
|
|
42
|
+
function calculateBackoff(attempt, options) {
|
|
43
|
+
const { baseDelay, backoffFactor = 2, maxDelay = 10000 } = options;
|
|
44
|
+
// Use exponential backoff with jitter
|
|
45
|
+
const exponentialDelay = baseDelay * Math.pow(backoffFactor, attempt);
|
|
46
|
+
const jitter = Math.random() * 0.2 * exponentialDelay; // 20% jitter
|
|
47
|
+
const delay = exponentialDelay + jitter;
|
|
48
|
+
// Ensure delay doesn't exceed maximum
|
|
49
|
+
return Math.min(delay, maxDelay);
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Wrapper function that adds retry logic to any async function
|
|
53
|
+
* @param fn Function to add retry logic to
|
|
54
|
+
* @param options Retry options
|
|
55
|
+
* @returns Function with retry logic
|
|
56
|
+
*/
|
|
57
|
+
function withRetry(fn, options = {}) {
|
|
58
|
+
const fullOptions = { ...DEFAULT_RETRY_OPTIONS, ...options };
|
|
59
|
+
return async function retryWrapper(...args) {
|
|
60
|
+
let lastError;
|
|
61
|
+
for (let attempt = 0; attempt <= fullOptions.maxRetries; attempt++) {
|
|
62
|
+
try {
|
|
63
|
+
if (attempt > 0) {
|
|
64
|
+
logger.info(`Retry attempt ${attempt} of ${fullOptions.maxRetries}`);
|
|
65
|
+
}
|
|
66
|
+
return await fn(...args);
|
|
67
|
+
}
|
|
68
|
+
catch (error) {
|
|
69
|
+
lastError = error;
|
|
70
|
+
const shouldRetry = attempt < fullOptions.maxRetries &&
|
|
71
|
+
fullOptions.isRetryable &&
|
|
72
|
+
fullOptions.isRetryable(error);
|
|
73
|
+
if (!shouldRetry) {
|
|
74
|
+
logger.debug('Error not retryable or max retries reached', { error });
|
|
75
|
+
throw error;
|
|
76
|
+
}
|
|
77
|
+
const delay = calculateBackoff(attempt, fullOptions);
|
|
78
|
+
logger.debug(`Retrying after ${delay}ms due to error`, { error });
|
|
79
|
+
// Wait before retrying
|
|
80
|
+
await new Promise(resolve => setTimeout(resolve, delay));
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
// This should never be reached due to the loop structure,
|
|
84
|
+
// but TypeScript requires it for type safety
|
|
85
|
+
throw lastError;
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
//# sourceMappingURL=retry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"retry.js","sourceRoot":"","sources":["../../src/utils/retry.ts"],"names":[],"mappings":";;AAwEA,4CAUC;AAQD,8BAwCC;AAlID,qCAAwC;AAExC,MAAM,MAAM,GAAG,IAAA,qBAAY,EAAC,WAAW,CAAC,CAAC;AAgCzC;;GAEG;AACH,MAAM,qBAAqB,GAAiB;IAC1C,UAAU,EAAE,CAAC;IACb,SAAS,EAAE,IAAI;IACf,QAAQ,EAAE,KAAK;IACf,aAAa,EAAE,CAAC;IAChB,WAAW,EAAE,CAAC,KAAc,EAAE,EAAE;QAC9B,yDAAyD;QACzD,IAAI,CAAC,KAAK;YAAE,OAAO,KAAK,CAAC;QAEzB,+BAA+B;QAC/B,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAI,QAAQ,IAAI,KAAK,EAAE,CAAC;YACrE,MAAM,SAAS,GAAG,KAA2B,CAAC;YAC9C,uEAAuE;YACvE,OAAO,SAAS,CAAC,MAAM,KAAK,GAAG;gBACxB,SAAS,CAAC,MAAM,KAAK,GAAG;gBACxB,CAAC,SAAS,CAAC,MAAM,IAAI,GAAG,IAAI,SAAS,CAAC,MAAM,GAAG,GAAG,CAAC,CAAC;QAC7D,CAAC;QAED,wBAAwB;QACxB,IAAI,KAAK,YAAY,KAAK,EAAE,CAAC;YAC3B,OAAO,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAC;gBACjC,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAC;gBACjC,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAC;QAC9C,CAAC;QAED,OAAO,KAAK,CAAC;IACf,CAAC;CACF,CAAC;AAEF;;;;;GAKG;AACH,SAAgB,gBAAgB,CAAC,OAAe,EAAE,OAAqB;IACrE,MAAM,EAAE,SAAS,EAAE,aAAa,GAAG,CAAC,EAAE,QAAQ,GAAG,KAAK,EAAE,GAAG,OAAO,CAAC;IAEnE,sCAAsC;IACtC,MAAM,gBAAgB,GAAG,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,aAAa,EAAE,OAAO,CAAC,CAAC;IACtE,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,EAAE,GAAG,GAAG,GAAG,gBAAgB,CAAC,CAAC,aAAa;IACpE,MAAM,KAAK,GAAG,gBAAgB,GAAG,MAAM,CAAC;IAExC,sCAAsC;IACtC,OAAO,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;AACnC,CAAC;AAED;;;;;GAKG;AACH,SAAgB,SAAS,CACvB,EAAiC,EACjC,UAAiC,EAAE;IAEnC,MAAM,WAAW,GAAiB,EAAE,GAAG,qBAAqB,EAAE,GAAG,OAAO,EAAE,CAAC;IAE3E,OAAO,KAAK,UAAU,YAAY,CAAC,GAAG,IAAU;QAC9C,IAAI,SAAkB,CAAC;QAEvB,KAAK,IAAI,OAAO,GAAG,CAAC,EAAE,OAAO,IAAI,WAAW,CAAC,UAAU,EAAE,OAAO,EAAE,EAAE,CAAC;YACnE,IAAI,CAAC;gBACH,IAAI,OAAO,GAAG,CAAC,EAAE,CAAC;oBAChB,MAAM,CAAC,IAAI,CAAC,iBAAiB,OAAO,OAAO,WAAW,CAAC,UAAU,EAAE,CAAC,CAAC;gBACvE,CAAC;gBAED,OAAO,MAAM,EAAE,CAAC,GAAG,IAAI,CAAC,CAAC;YAC3B,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,SAAS,GAAG,KAAK,CAAC;gBAElB,MAAM,WAAW,GAAG,OAAO,GAAG,WAAW,CAAC,UAAU;oBAChC,WAAW,CAAC,WAAW;oBACvB,WAAW,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;gBAEnD,IAAI,CAAC,WAAW,EAAE,CAAC;oBACjB,MAAM,CAAC,KAAK,CAAC,4CAA4C,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC;oBACtE,MAAM,KAAK,CAAC;gBACd,CAAC;gBAED,MAAM,KAAK,GAAG,gBAAgB,CAAC,OAAO,EAAE,WAAW,CAAC,CAAC;gBACrD,MAAM,CAAC,KAAK,CAAC,kBAAkB,KAAK,iBAAiB,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC;gBAElE,uBAAuB;gBACvB,MAAM,IAAI,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC,CAAC;YAC3D,CAAC;QACH,CAAC;QAED,0DAA0D;QAC1D,6CAA6C;QAC7C,MAAM,SAAS,CAAC;IAClB,CAAC,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
/**
|
|
3
|
+
* Custom validation error with additional context
|
|
4
|
+
*/
|
|
5
|
+
export declare class ValidationError extends Error {
|
|
6
|
+
readonly context?: {
|
|
7
|
+
toolName?: string;
|
|
8
|
+
issues?: z.ZodIssue[];
|
|
9
|
+
originalParams?: unknown;
|
|
10
|
+
} | undefined;
|
|
11
|
+
constructor(message: string, context?: {
|
|
12
|
+
toolName?: string;
|
|
13
|
+
issues?: z.ZodIssue[];
|
|
14
|
+
originalParams?: unknown;
|
|
15
|
+
} | undefined);
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Create Zod schema for MCP server tool registration
|
|
19
|
+
* Returns object with property schemas for MCP server
|
|
20
|
+
*/
|
|
21
|
+
export declare function createMcpZodSchema(schema: Record<string, unknown>): Record<string, z.ZodTypeAny>;
|
|
22
|
+
/**
|
|
23
|
+
* Create Zod object schema for parameter validation
|
|
24
|
+
* Returns complete Zod schema for validation
|
|
25
|
+
*/
|
|
26
|
+
export declare function createValidationSchema(schema: Record<string, unknown>): z.ZodSchema;
|
|
27
|
+
/**
|
|
28
|
+
* Validate parameters using JSON Schema with comprehensive error handling
|
|
29
|
+
*/
|
|
30
|
+
export declare function validateParams<T>(params: unknown, schema: Record<string, unknown>, toolName?: string): T;
|
|
31
|
+
export declare const createZodSchema: typeof createMcpZodSchema;
|
|
32
|
+
export declare const createZodObjectSchema: typeof createValidationSchema;
|
|
@@ -0,0 +1,227 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createZodObjectSchema = exports.createZodSchema = exports.ValidationError = void 0;
|
|
4
|
+
exports.createMcpZodSchema = createMcpZodSchema;
|
|
5
|
+
exports.createValidationSchema = createValidationSchema;
|
|
6
|
+
exports.validateParams = validateParams;
|
|
7
|
+
const zod_1 = require("zod");
|
|
8
|
+
const logger_1 = require("./logger");
|
|
9
|
+
const logger = (0, logger_1.createLogger)('Validation');
|
|
10
|
+
/**
|
|
11
|
+
* Custom validation error with additional context
|
|
12
|
+
*/
|
|
13
|
+
class ValidationError extends Error {
|
|
14
|
+
constructor(message, context) {
|
|
15
|
+
super(message);
|
|
16
|
+
this.context = context;
|
|
17
|
+
this.name = 'ValidationError';
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
exports.ValidationError = ValidationError;
|
|
21
|
+
/**
|
|
22
|
+
* Type guard for valid JSON Schema objects
|
|
23
|
+
*/
|
|
24
|
+
function isValidJSONSchema(schema) {
|
|
25
|
+
return typeof schema === 'object' &&
|
|
26
|
+
schema !== null &&
|
|
27
|
+
'type' in schema;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Schema cache for performance optimization
|
|
31
|
+
*/
|
|
32
|
+
class SchemaCache {
|
|
33
|
+
static get(key) {
|
|
34
|
+
const value = this.cache.get(key);
|
|
35
|
+
if (value !== undefined) {
|
|
36
|
+
// Move to end for LRU behavior
|
|
37
|
+
this.cache.delete(key);
|
|
38
|
+
this.cache.set(key, value);
|
|
39
|
+
}
|
|
40
|
+
return value;
|
|
41
|
+
}
|
|
42
|
+
static set(key, schema) {
|
|
43
|
+
// Remove existing key if present (for LRU update)
|
|
44
|
+
if (this.cache.has(key)) {
|
|
45
|
+
this.cache.delete(key);
|
|
46
|
+
}
|
|
47
|
+
// Evict oldest entries if cache is full (proper LRU eviction)
|
|
48
|
+
while (this.cache.size >= this.MAX_SIZE) {
|
|
49
|
+
const firstKey = this.cache.keys().next().value;
|
|
50
|
+
if (firstKey !== undefined) {
|
|
51
|
+
this.cache.delete(firstKey);
|
|
52
|
+
}
|
|
53
|
+
else {
|
|
54
|
+
break; // Safety check
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
this.cache.set(key, schema);
|
|
58
|
+
}
|
|
59
|
+
static clear() {
|
|
60
|
+
this.cache.clear();
|
|
61
|
+
}
|
|
62
|
+
static getStats() {
|
|
63
|
+
return { size: this.cache.size, maxSize: this.MAX_SIZE };
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
SchemaCache.cache = new Map();
|
|
67
|
+
SchemaCache.MAX_SIZE = 100;
|
|
68
|
+
/**
|
|
69
|
+
* Convert JSON Schema property to Zod type
|
|
70
|
+
*/
|
|
71
|
+
function convertPropertyToZod(prop) {
|
|
72
|
+
if (!prop || typeof prop !== 'object') {
|
|
73
|
+
logger.warn('Invalid property schema, defaulting to unknown', { prop });
|
|
74
|
+
return zod_1.z.unknown();
|
|
75
|
+
}
|
|
76
|
+
const { type, enum: enumValues, items, format } = prop;
|
|
77
|
+
// Handle enum constraints
|
|
78
|
+
if (enumValues && Array.isArray(enumValues) && enumValues.length > 0) {
|
|
79
|
+
if (enumValues.every(v => typeof v === 'string')) {
|
|
80
|
+
return zod_1.z.enum(enumValues);
|
|
81
|
+
}
|
|
82
|
+
const literals = enumValues.map(v => zod_1.z.literal(v));
|
|
83
|
+
if (literals.length === 1) {
|
|
84
|
+
return literals[0];
|
|
85
|
+
}
|
|
86
|
+
return zod_1.z.union([literals[0], literals[1], ...literals.slice(2)]);
|
|
87
|
+
}
|
|
88
|
+
// Handle primitive types
|
|
89
|
+
switch (type) {
|
|
90
|
+
case 'string': {
|
|
91
|
+
let stringSchema = zod_1.z.string();
|
|
92
|
+
if (format === 'email')
|
|
93
|
+
stringSchema = stringSchema.email();
|
|
94
|
+
if (format === 'uri')
|
|
95
|
+
stringSchema = stringSchema.url();
|
|
96
|
+
return stringSchema;
|
|
97
|
+
}
|
|
98
|
+
case 'number':
|
|
99
|
+
return zod_1.z.number();
|
|
100
|
+
case 'integer':
|
|
101
|
+
return zod_1.z.number().int();
|
|
102
|
+
case 'boolean':
|
|
103
|
+
return zod_1.z.boolean();
|
|
104
|
+
case 'array':
|
|
105
|
+
if (items && typeof items === 'object') {
|
|
106
|
+
const itemSchema = convertPropertyToZod(items);
|
|
107
|
+
return zod_1.z.array(itemSchema);
|
|
108
|
+
}
|
|
109
|
+
return zod_1.z.array(zod_1.z.unknown());
|
|
110
|
+
case 'object':
|
|
111
|
+
// For nested objects, we'd need recursive handling
|
|
112
|
+
// For now, treat as record of unknown values
|
|
113
|
+
return zod_1.z.record(zod_1.z.unknown());
|
|
114
|
+
default:
|
|
115
|
+
logger.warn('Unsupported schema type, defaulting to unknown', { type, prop });
|
|
116
|
+
return zod_1.z.unknown();
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Create Zod schema for MCP server tool registration
|
|
121
|
+
* Returns object with property schemas for MCP server
|
|
122
|
+
*/
|
|
123
|
+
function createMcpZodSchema(schema) {
|
|
124
|
+
if (!isValidJSONSchema(schema)) {
|
|
125
|
+
logger.warn('Invalid schema provided to createMcpZodSchema', { schema });
|
|
126
|
+
return {};
|
|
127
|
+
}
|
|
128
|
+
if (schema.type !== 'object' || !schema.properties) {
|
|
129
|
+
return {};
|
|
130
|
+
}
|
|
131
|
+
const properties = schema.properties;
|
|
132
|
+
const required = schema.required || [];
|
|
133
|
+
const zodSchemaObj = {};
|
|
134
|
+
try {
|
|
135
|
+
Object.entries(properties).forEach(([key, prop]) => {
|
|
136
|
+
let zodType = convertPropertyToZod(prop);
|
|
137
|
+
// Make optional if not in required array
|
|
138
|
+
if (!required.includes(key)) {
|
|
139
|
+
zodType = zodType.optional();
|
|
140
|
+
}
|
|
141
|
+
zodSchemaObj[key] = zodType;
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
catch (error) {
|
|
145
|
+
logger.error('Error creating MCP Zod schema', { error, schema });
|
|
146
|
+
return {};
|
|
147
|
+
}
|
|
148
|
+
return zodSchemaObj;
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* Create Zod object schema for parameter validation
|
|
152
|
+
* Returns complete Zod schema for validation
|
|
153
|
+
*/
|
|
154
|
+
function createValidationSchema(schema) {
|
|
155
|
+
if (!isValidJSONSchema(schema)) {
|
|
156
|
+
logger.warn('Invalid schema provided to createValidationSchema', { schema });
|
|
157
|
+
return zod_1.z.object({});
|
|
158
|
+
}
|
|
159
|
+
// Create cache key
|
|
160
|
+
const cacheKey = JSON.stringify(schema);
|
|
161
|
+
// Check cache first
|
|
162
|
+
const cached = SchemaCache.get(cacheKey);
|
|
163
|
+
if (cached) {
|
|
164
|
+
return cached;
|
|
165
|
+
}
|
|
166
|
+
let zodSchema;
|
|
167
|
+
try {
|
|
168
|
+
if (schema.type === 'object' && schema.properties) {
|
|
169
|
+
const mcpSchema = createMcpZodSchema(schema);
|
|
170
|
+
zodSchema = zod_1.z.object(mcpSchema);
|
|
171
|
+
}
|
|
172
|
+
else {
|
|
173
|
+
// Non-object schemas (rare but possible)
|
|
174
|
+
zodSchema = zod_1.z.object({});
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
catch (error) {
|
|
178
|
+
logger.error('Error creating validation schema', { error, schema });
|
|
179
|
+
zodSchema = zod_1.z.object({});
|
|
180
|
+
}
|
|
181
|
+
// Cache the result
|
|
182
|
+
SchemaCache.set(cacheKey, zodSchema);
|
|
183
|
+
return zodSchema;
|
|
184
|
+
}
|
|
185
|
+
/**
|
|
186
|
+
* Validate parameters using JSON Schema with comprehensive error handling
|
|
187
|
+
*/
|
|
188
|
+
function validateParams(params, schema, toolName) {
|
|
189
|
+
try {
|
|
190
|
+
const zodSchema = createValidationSchema(schema);
|
|
191
|
+
logger.debug('Validating parameters', {
|
|
192
|
+
toolName,
|
|
193
|
+
paramsType: typeof params,
|
|
194
|
+
schemaType: schema.type
|
|
195
|
+
});
|
|
196
|
+
const result = zodSchema.parse(params);
|
|
197
|
+
logger.debug('Parameter validation successful', { toolName });
|
|
198
|
+
return result;
|
|
199
|
+
}
|
|
200
|
+
catch (error) {
|
|
201
|
+
if (error instanceof zod_1.z.ZodError) {
|
|
202
|
+
const context = toolName ? ` in tool "${toolName}"` : '';
|
|
203
|
+
const issues = error.errors.map(err => {
|
|
204
|
+
const path = err.path.length > 0 ? err.path.join('.') : 'root';
|
|
205
|
+
return `${path}: ${err.message}`;
|
|
206
|
+
});
|
|
207
|
+
const validationError = new ValidationError(`Parameter validation failed${context}: ${issues.join(', ')}`, {
|
|
208
|
+
toolName,
|
|
209
|
+
issues: error.errors,
|
|
210
|
+
originalParams: params
|
|
211
|
+
});
|
|
212
|
+
logger.error('Parameter validation failed', {
|
|
213
|
+
toolName,
|
|
214
|
+
error: validationError.message,
|
|
215
|
+
issues: error.errors,
|
|
216
|
+
params: typeof params === 'object' ? 'object' : params
|
|
217
|
+
});
|
|
218
|
+
throw validationError;
|
|
219
|
+
}
|
|
220
|
+
logger.error('Unexpected validation error', { error, toolName });
|
|
221
|
+
throw error;
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
// Legacy exports for backward compatibility
|
|
225
|
+
exports.createZodSchema = createMcpZodSchema;
|
|
226
|
+
exports.createZodObjectSchema = createValidationSchema;
|
|
227
|
+
//# sourceMappingURL=validation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validation.js","sourceRoot":"","sources":["../../src/utils/validation.ts"],"names":[],"mappings":"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"}
|
package/docs/README.md
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# ๐ Quickbase MCP Server Documentation
|
|
2
|
+
|
|
3
|
+
This directory contains comprehensive documentation for Quickbase MCP Server v2.
|
|
4
|
+
|
|
5
|
+
## ๐ Documentation Index
|
|
6
|
+
|
|
7
|
+
### Getting Started
|
|
8
|
+
- **[Quick Start Guide](quickstart.md)** - Get up and running in 5 minutes
|
|
9
|
+
- **[Quick Reference](quick-reference.md)** - Common commands and troubleshooting
|
|
10
|
+
|
|
11
|
+
### Development
|
|
12
|
+
- **[Developer Guide](developer-guide.md)** - Comprehensive guide for developers
|
|
13
|
+
- **[Architecture Overview](architecture.md)** - System design and components
|
|
14
|
+
- **[Tools Reference](tools.md)** - Complete list of all 18 MCP tools
|
|
15
|
+
|
|
16
|
+
### Operations
|
|
17
|
+
- **[Deployment Guide](deployment.md)** - Production deployment instructions
|
|
18
|
+
- **[Claude Prompts](claude-prompts.md)** - Example prompts for Claude interactions
|
|
19
|
+
|
|
20
|
+
### Quality & Performance
|
|
21
|
+
- **[Security Review](security-review.md)** - Security considerations and best practices
|
|
22
|
+
- **[Performance Benchmarks](performance-benchmarks.md)** - Performance metrics and optimization
|
|
23
|
+
- **[QA Report](final-qa-report.md)** - Quality assurance testing results
|
|
24
|
+
|
|
25
|
+
## ๐ฏ Quick Links
|
|
26
|
+
|
|
27
|
+
- **New users**: Start with [Quick Start Guide](quickstart.md)
|
|
28
|
+
- **Developers**: See [Developer Guide](developer-guide.md)
|
|
29
|
+
- **Tool usage**: Check [Tools Reference](tools.md)
|
|
30
|
+
- **Production**: Review [Deployment Guide](deployment.md)
|
|
31
|
+
|
|
32
|
+
## ๐ Documentation Standards
|
|
33
|
+
|
|
34
|
+
All documentation follows these principles:
|
|
35
|
+
- Clear, concise language
|
|
36
|
+
- Practical examples
|
|
37
|
+
- Up-to-date with v2.0.0
|
|
38
|
+
- No redundancy between files
|
|
39
|
+
- Consistent formatting
|
|
40
|
+
|
|
41
|
+
Last updated: January 2025
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
# ๐๏ธ Quickbase MCP Server Architecture
|
|
2
|
+
|
|
3
|
+
## ๐ Architecture Overview
|
|
4
|
+
|
|
5
|
+
The Quickbase MCP Server follows a layered architecture:
|
|
6
|
+
|
|
7
|
+
```
|
|
8
|
+
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
|
9
|
+
โ MCP Interface โ
|
|
10
|
+
โโโโโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโ
|
|
11
|
+
โ
|
|
12
|
+
โโโโโโโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโ
|
|
13
|
+
โ Quickbase Client โ
|
|
14
|
+
โ โ
|
|
15
|
+
โ โโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโ โ
|
|
16
|
+
โ โ Cache โ โ Error Handler โ โ
|
|
17
|
+
โ โโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโ โ
|
|
18
|
+
โ โ
|
|
19
|
+
โ โโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโ โ
|
|
20
|
+
โ โ Logger โ โ Retry Logic โ โ
|
|
21
|
+
โ โโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโ โ
|
|
22
|
+
โโโโโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโ
|
|
23
|
+
โ
|
|
24
|
+
โโโโโโโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโ
|
|
25
|
+
โ Quickbase REST API โ
|
|
26
|
+
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## ๐ Components
|
|
30
|
+
|
|
31
|
+
### ๐ MCP Interface
|
|
32
|
+
- Exposes MCP-compliant tools
|
|
33
|
+
- Handles parameter validation with JSON Schema
|
|
34
|
+
- Formats responses according to MCP standards
|
|
35
|
+
- Supports both stdio and HTTP transports
|
|
36
|
+
|
|
37
|
+
### ๐ Quickbase Client
|
|
38
|
+
- Core client for interacting with Quickbase REST API
|
|
39
|
+
- Manages authentication and HTTP requests
|
|
40
|
+
- Implements TypeScript-first API wrappers
|
|
41
|
+
- Provides structured error handling
|
|
42
|
+
|
|
43
|
+
### ๐ ๏ธ Supporting Services
|
|
44
|
+
|
|
45
|
+
#### ๐ Cache Service
|
|
46
|
+
- Stores frequently accessed data (table schemas, field definitions)
|
|
47
|
+
- Implements intelligent cache invalidation
|
|
48
|
+
- Configurable TTL settings (default: 1 hour)
|
|
49
|
+
- LRU eviction policy for memory management
|
|
50
|
+
|
|
51
|
+
#### โ ๏ธ Error Handler
|
|
52
|
+
- Classifies and formats API errors
|
|
53
|
+
- Provides detailed error context for debugging
|
|
54
|
+
- Handles error recovery with exponential backoff
|
|
55
|
+
- Redacts sensitive information from error logs
|
|
56
|
+
|
|
57
|
+
#### ๐ Logger
|
|
58
|
+
- Structured logging with configurable levels
|
|
59
|
+
- Automatic PII and sensitive data redaction
|
|
60
|
+
- JSON-formatted logs for machine processing
|
|
61
|
+
- Context-aware logging with request tracing
|
|
62
|
+
|
|
63
|
+
#### ๐ Retry Logic
|
|
64
|
+
- Handles transient HTTP and network errors
|
|
65
|
+
- Implements exponential backoff with jitter
|
|
66
|
+
- Configurable retry limits and timeouts
|
|
67
|
+
- Circuit breaker pattern for failing services
|
|
68
|
+
|
|
69
|
+
## ๐ข Separation of Concerns
|
|
70
|
+
|
|
71
|
+
The architecture follows clean separation principles:
|
|
72
|
+
|
|
73
|
+
### 1. ๐ Interface Layer (MCP Tools)
|
|
74
|
+
- **Responsibility**: Expose Quickbase functionality via MCP protocol
|
|
75
|
+
- **Components**: Tool registry, parameter validation, response formatting
|
|
76
|
+
- **Benefits**: Protocol-agnostic business logic, easy testing
|
|
77
|
+
|
|
78
|
+
### 2. ๐ผ Business Logic Layer (Quickbase Client)
|
|
79
|
+
- **Responsibility**: Core Quickbase operations and data transformations
|
|
80
|
+
- **Components**: API client, data models, business rules
|
|
81
|
+
- **Benefits**: Reusable across different interfaces, focused testing
|
|
82
|
+
|
|
83
|
+
### 3. ๐ ๏ธ Infrastructure Layer
|
|
84
|
+
- **Responsibility**: Cross-cutting concerns and external dependencies
|
|
85
|
+
- **Components**: Cache, logging, error handling, retry logic
|
|
86
|
+
- **Benefits**: Centralized infrastructure management, easy configuration
|
|
87
|
+
|
|
88
|
+
### ๐ Benefits of This Architecture
|
|
89
|
+
|
|
90
|
+
- **๐งช Testability**: Each layer can be tested in isolation
|
|
91
|
+
- **๐ Maintainability**: Changes are isolated to specific layers
|
|
92
|
+
- **๐ Scalability**: Infrastructure components can be optimized independently
|
|
93
|
+
- **๐ Flexibility**: Interface layer can be swapped without affecting business logic
|
|
94
|
+
- **๐ Security**: Centralized handling of authentication and data protection
|