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.
Files changed (135) hide show
  1. package/CHANGELOG.md +82 -0
  2. package/LICENSE +21 -0
  3. package/README.md +301 -0
  4. package/dist/client/quickbase.d.ts +28 -0
  5. package/dist/client/quickbase.js +235 -0
  6. package/dist/client/quickbase.js.map +1 -0
  7. package/dist/mcp/index.d.ts +4 -0
  8. package/dist/mcp/index.js +21 -0
  9. package/dist/mcp/index.js.map +1 -0
  10. package/dist/mcp/server.d.ts +19 -0
  11. package/dist/mcp/server.js +102 -0
  12. package/dist/mcp/server.js.map +1 -0
  13. package/dist/mcp-stdio-server.d.ts +2 -0
  14. package/dist/mcp-stdio-server.js +168 -0
  15. package/dist/mcp-stdio-server.js.map +1 -0
  16. package/dist/server.d.ts +2 -0
  17. package/dist/server.js +318 -0
  18. package/dist/server.js.map +1 -0
  19. package/dist/tools/apps/create_app.d.ts +87 -0
  20. package/dist/tools/apps/create_app.js +87 -0
  21. package/dist/tools/apps/create_app.js.map +1 -0
  22. package/dist/tools/apps/index.d.ts +9 -0
  23. package/dist/tools/apps/index.js +40 -0
  24. package/dist/tools/apps/index.js.map +1 -0
  25. package/dist/tools/apps/list_tables.d.ts +108 -0
  26. package/dist/tools/apps/list_tables.js +100 -0
  27. package/dist/tools/apps/list_tables.js.map +1 -0
  28. package/dist/tools/apps/update_app.d.ts +91 -0
  29. package/dist/tools/apps/update_app.js +99 -0
  30. package/dist/tools/apps/update_app.js.map +1 -0
  31. package/dist/tools/base.d.ts +47 -0
  32. package/dist/tools/base.js +63 -0
  33. package/dist/tools/base.js.map +1 -0
  34. package/dist/tools/configure_cache.d.ts +81 -0
  35. package/dist/tools/configure_cache.js +77 -0
  36. package/dist/tools/configure_cache.js.map +1 -0
  37. package/dist/tools/fields/create_field.d.ts +121 -0
  38. package/dist/tools/fields/create_field.js +102 -0
  39. package/dist/tools/fields/create_field.js.map +1 -0
  40. package/dist/tools/fields/index.d.ts +8 -0
  41. package/dist/tools/fields/index.js +37 -0
  42. package/dist/tools/fields/index.js.map +1 -0
  43. package/dist/tools/fields/update_field.d.ts +112 -0
  44. package/dist/tools/fields/update_field.js +114 -0
  45. package/dist/tools/fields/update_field.js.map +1 -0
  46. package/dist/tools/files/download_file.d.ts +111 -0
  47. package/dist/tools/files/download_file.js +173 -0
  48. package/dist/tools/files/download_file.js.map +1 -0
  49. package/dist/tools/files/index.d.ts +8 -0
  50. package/dist/tools/files/index.js +37 -0
  51. package/dist/tools/files/index.js.map +1 -0
  52. package/dist/tools/files/upload_file.d.ts +107 -0
  53. package/dist/tools/files/upload_file.js +211 -0
  54. package/dist/tools/files/upload_file.js.map +1 -0
  55. package/dist/tools/index.d.ts +18 -0
  56. package/dist/tools/index.js +65 -0
  57. package/dist/tools/index.js.map +1 -0
  58. package/dist/tools/records/bulk_create_records.d.ts +75 -0
  59. package/dist/tools/records/bulk_create_records.js +104 -0
  60. package/dist/tools/records/bulk_create_records.js.map +1 -0
  61. package/dist/tools/records/bulk_update_records.d.ts +77 -0
  62. package/dist/tools/records/bulk_update_records.js +102 -0
  63. package/dist/tools/records/bulk_update_records.js.map +1 -0
  64. package/dist/tools/records/create_record.d.ts +68 -0
  65. package/dist/tools/records/create_record.js +123 -0
  66. package/dist/tools/records/create_record.js.map +1 -0
  67. package/dist/tools/records/index.d.ts +11 -0
  68. package/dist/tools/records/index.js +46 -0
  69. package/dist/tools/records/index.js.map +1 -0
  70. package/dist/tools/records/query_records.d.ts +164 -0
  71. package/dist/tools/records/query_records.js +261 -0
  72. package/dist/tools/records/query_records.js.map +1 -0
  73. package/dist/tools/records/update_record.d.ts +81 -0
  74. package/dist/tools/records/update_record.js +99 -0
  75. package/dist/tools/records/update_record.js.map +1 -0
  76. package/dist/tools/registry.d.ts +41 -0
  77. package/dist/tools/registry.js +66 -0
  78. package/dist/tools/registry.js.map +1 -0
  79. package/dist/tools/reports/index.d.ts +6 -0
  80. package/dist/tools/reports/index.js +31 -0
  81. package/dist/tools/reports/index.js.map +1 -0
  82. package/dist/tools/reports/run_report.d.ts +70 -0
  83. package/dist/tools/reports/run_report.js +72 -0
  84. package/dist/tools/reports/run_report.js.map +1 -0
  85. package/dist/tools/tables/create_table.d.ts +142 -0
  86. package/dist/tools/tables/create_table.js +119 -0
  87. package/dist/tools/tables/create_table.js.map +1 -0
  88. package/dist/tools/tables/get_table_fields.d.ts +108 -0
  89. package/dist/tools/tables/get_table_fields.js +96 -0
  90. package/dist/tools/tables/get_table_fields.js.map +1 -0
  91. package/dist/tools/tables/index.d.ts +9 -0
  92. package/dist/tools/tables/index.js +40 -0
  93. package/dist/tools/tables/index.js.map +1 -0
  94. package/dist/tools/tables/update_table.d.ts +91 -0
  95. package/dist/tools/tables/update_table.js +99 -0
  96. package/dist/tools/tables/update_table.js.map +1 -0
  97. package/dist/tools/test_connection.d.ts +51 -0
  98. package/dist/tools/test_connection.js +101 -0
  99. package/dist/tools/test_connection.js.map +1 -0
  100. package/dist/types/api.d.ts +70 -0
  101. package/dist/types/api.js +6 -0
  102. package/dist/types/api.js.map +1 -0
  103. package/dist/types/config.d.ts +49 -0
  104. package/dist/types/config.js +3 -0
  105. package/dist/types/config.js.map +1 -0
  106. package/dist/types/mcp.d.ts +55 -0
  107. package/dist/types/mcp.js +3 -0
  108. package/dist/types/mcp.js.map +1 -0
  109. package/dist/utils/cache.d.ts +87 -0
  110. package/dist/utils/cache.js +211 -0
  111. package/dist/utils/cache.js.map +1 -0
  112. package/dist/utils/file.d.ts +40 -0
  113. package/dist/utils/file.js +167 -0
  114. package/dist/utils/file.js.map +1 -0
  115. package/dist/utils/logger.d.ts +37 -0
  116. package/dist/utils/logger.js +144 -0
  117. package/dist/utils/logger.js.map +1 -0
  118. package/dist/utils/retry.d.ts +39 -0
  119. package/dist/utils/retry.js +88 -0
  120. package/dist/utils/retry.js.map +1 -0
  121. package/dist/utils/validation.d.ts +32 -0
  122. package/dist/utils/validation.js +227 -0
  123. package/dist/utils/validation.js.map +1 -0
  124. package/docs/README.md +41 -0
  125. package/docs/architecture.md +94 -0
  126. package/docs/claude-prompts.md +218 -0
  127. package/docs/deployment.md +244 -0
  128. package/docs/developer-guide.md +537 -0
  129. package/docs/final-qa-report.md +243 -0
  130. package/docs/performance-benchmarks.md +306 -0
  131. package/docs/quick-reference.md +109 -0
  132. package/docs/quickstart.md +183 -0
  133. package/docs/security-review.md +263 -0
  134. package/docs/tools.md +269 -0
  135. package/package.json +68 -0
@@ -0,0 +1,211 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.UploadFileTool = void 0;
37
+ const base_1 = require("../base");
38
+ const logger_1 = require("../../utils/logger");
39
+ const file_1 = require("../../utils/file");
40
+ const logger = (0, logger_1.createLogger)('UploadFileTool');
41
+ /**
42
+ * Tool for uploading a file to a field in a Quickbase record
43
+ */
44
+ class UploadFileTool extends base_1.BaseTool {
45
+ /**
46
+ * Constructor
47
+ * @param client Quickbase client
48
+ */
49
+ constructor(client) {
50
+ super(client);
51
+ this.name = 'upload_file';
52
+ this.description = 'Uploads a file to a field in a Quickbase record';
53
+ /**
54
+ * Parameter schema for upload_file
55
+ */
56
+ this.paramSchema = {
57
+ type: 'object',
58
+ properties: {
59
+ table_id: {
60
+ type: 'string',
61
+ description: 'The ID of the table (must be a file attachment field)'
62
+ },
63
+ record_id: {
64
+ type: 'string',
65
+ description: 'The ID of the record'
66
+ },
67
+ field_id: {
68
+ type: 'string',
69
+ description: 'The ID of the field (must be a file attachment field)'
70
+ },
71
+ file_path: {
72
+ type: 'string',
73
+ description: 'Path to the file to upload'
74
+ },
75
+ file_name: {
76
+ type: 'string',
77
+ description: 'Custom file name (optional, defaults to the original filename)'
78
+ }
79
+ },
80
+ required: ['table_id', 'record_id', 'field_id', 'file_path']
81
+ };
82
+ }
83
+ /**
84
+ * Run the upload_file tool
85
+ * @param params Tool parameters
86
+ * @returns Upload result
87
+ */
88
+ async run(params) {
89
+ const { table_id, record_id, field_id, file_path, file_name } = params;
90
+ logger.info('Uploading file to Quickbase record', {
91
+ tableId: table_id,
92
+ recordId: record_id,
93
+ fieldId: field_id,
94
+ filePath: file_path
95
+ });
96
+ // Check if the file exists
97
+ if (!(0, file_1.fileExists)(file_path)) {
98
+ throw new Error(`File not found: ${file_path}`);
99
+ }
100
+ // Get file information
101
+ const fileInfo = (0, file_1.getFileInfo)(file_path);
102
+ if (!fileInfo) {
103
+ throw new Error(`Unable to get file information: ${file_path}`);
104
+ }
105
+ // Validate file size (max 100MB)
106
+ const MAX_FILE_SIZE = 100 * 1024 * 1024; // 100MB
107
+ if (fileInfo.size > MAX_FILE_SIZE) {
108
+ throw new Error(`File size ${fileInfo.size} bytes exceeds maximum allowed size of ${MAX_FILE_SIZE} bytes`);
109
+ }
110
+ // Secure file path validation - prevent directory traversal attacks
111
+ const path = await Promise.resolve().then(() => __importStar(require('path')));
112
+ const fs = await Promise.resolve().then(() => __importStar(require('fs')));
113
+ // First, validate the input path before any resolution
114
+ if (!file_path || typeof file_path !== 'string') {
115
+ throw new Error('Invalid file path: must be a non-empty string');
116
+ }
117
+ // Reject obvious traversal attempts immediately
118
+ if (file_path.includes('..') || file_path.startsWith('/') || file_path.includes('\\')) {
119
+ throw new Error('Invalid file path: directory traversal detected');
120
+ }
121
+ // Define allowed working directory (current directory only)
122
+ const workingDir = process.cwd();
123
+ let resolvedPath;
124
+ try {
125
+ // Resolve the path relative to working directory
126
+ resolvedPath = path.resolve(workingDir, file_path);
127
+ }
128
+ catch (error) {
129
+ throw new Error('Invalid file path format');
130
+ }
131
+ // Critical security check: ensure resolved path is within working directory
132
+ if (!resolvedPath.startsWith(workingDir + path.sep) && resolvedPath !== workingDir) {
133
+ throw new Error('Invalid file path: access outside working directory denied');
134
+ }
135
+ // Verify file exists and is readable
136
+ try {
137
+ await fs.promises.access(resolvedPath, fs.constants.R_OK);
138
+ }
139
+ catch (error) {
140
+ throw new Error(`File access denied or file does not exist: ${file_path}`);
141
+ }
142
+ // Memory-efficient file reading with size validation
143
+ const CHUNK_SIZE = 1024 * 1024; // 1MB chunks
144
+ let fileBase64;
145
+ try {
146
+ if (fileInfo.size > 10 * 1024 * 1024) { // > 10MB, use streaming
147
+ logger.debug('Using streaming read for large file', { size: fileInfo.size });
148
+ // Stream the file in chunks to prevent memory overflow
149
+ const chunks = [];
150
+ const readStream = fs.createReadStream(resolvedPath, { highWaterMark: CHUNK_SIZE });
151
+ for await (const chunk of readStream) {
152
+ chunks.push(chunk.toString('base64'));
153
+ }
154
+ fileBase64 = chunks.join('');
155
+ }
156
+ else {
157
+ // Small files can be read directly
158
+ const fileBuffer = (0, file_1.readFileAsBuffer)(file_path);
159
+ if (!fileBuffer) {
160
+ throw new Error(`Unable to read file: ${file_path}`);
161
+ }
162
+ fileBase64 = fileBuffer.toString('base64');
163
+ }
164
+ }
165
+ catch (error) {
166
+ throw new Error(`Failed to read file: ${error instanceof Error ? error.message : 'Unknown error'}`);
167
+ }
168
+ // Prepare the file upload request
169
+ const body = {
170
+ tableId: table_id,
171
+ recordId: record_id,
172
+ fieldId: field_id,
173
+ fileName: file_name || fileInfo.name,
174
+ contentType: fileInfo.mimeType,
175
+ fileData: fileBase64
176
+ };
177
+ // Upload the file
178
+ const response = await this.client.request({
179
+ method: 'POST',
180
+ path: '/files',
181
+ body
182
+ });
183
+ if (!response.success || !response.data) {
184
+ logger.error('Failed to upload file', {
185
+ error: response.error,
186
+ tableId: table_id,
187
+ recordId: record_id,
188
+ fieldId: field_id
189
+ });
190
+ throw new Error(response.error?.message || 'Failed to upload file');
191
+ }
192
+ const fileData = response.data;
193
+ logger.info('Successfully uploaded file', {
194
+ tableId: table_id,
195
+ recordId: record_id,
196
+ fieldId: field_id,
197
+ fileName: file_name || fileInfo.name
198
+ });
199
+ return {
200
+ recordId: record_id,
201
+ fieldId: field_id,
202
+ tableId: table_id,
203
+ fileName: file_name || fileInfo.name,
204
+ fileSize: fileInfo.size,
205
+ version: fileData.version || 1,
206
+ uploadTime: new Date().toISOString()
207
+ };
208
+ }
209
+ }
210
+ exports.UploadFileTool = UploadFileTool;
211
+ //# sourceMappingURL=upload_file.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"upload_file.js","sourceRoot":"","sources":["../../../src/tools/files/upload_file.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,18 @@
1
+ import { QuickbaseClient } from '../client/quickbase';
2
+ import { CacheService } from '../utils/cache';
3
+ /**
4
+ * Initialize all MCP tools and register them with the registry
5
+ * @param client Quickbase client
6
+ * @param cacheService Cache service
7
+ */
8
+ export declare function initializeTools(client: QuickbaseClient, cacheService: CacheService): void;
9
+ export * from './registry';
10
+ export * from './base';
11
+ export * from './test_connection';
12
+ export * from './configure_cache';
13
+ export * from './apps';
14
+ export * from './tables';
15
+ export * from './fields';
16
+ export * from './records';
17
+ export * from './files';
18
+ export * from './reports';
@@ -0,0 +1,65 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ exports.initializeTools = initializeTools;
18
+ const registry_1 = require("./registry");
19
+ const test_connection_1 = require("./test_connection");
20
+ const configure_cache_1 = require("./configure_cache");
21
+ const apps_1 = require("./apps");
22
+ const tables_1 = require("./tables");
23
+ const fields_1 = require("./fields");
24
+ const records_1 = require("./records");
25
+ const files_1 = require("./files");
26
+ const reports_1 = require("./reports");
27
+ const logger_1 = require("../utils/logger");
28
+ const logger = (0, logger_1.createLogger)('ToolsInit');
29
+ /**
30
+ * Initialize all MCP tools and register them with the registry
31
+ * @param client Quickbase client
32
+ * @param cacheService Cache service
33
+ */
34
+ function initializeTools(client, cacheService) {
35
+ logger.info('Initializing MCP tools');
36
+ // Register connection tools
37
+ registry_1.toolRegistry.registerTool(new test_connection_1.TestConnectionTool(client));
38
+ registry_1.toolRegistry.registerTool(new configure_cache_1.ConfigureCacheTool(client, cacheService));
39
+ // Register app management tools
40
+ (0, apps_1.registerAppTools)(client);
41
+ // Register table operation tools
42
+ (0, tables_1.registerTableTools)(client);
43
+ // Register field management tools
44
+ (0, fields_1.registerFieldTools)(client);
45
+ // Register record operation tools
46
+ (0, records_1.registerRecordTools)(client);
47
+ // Register file operation tools
48
+ (0, files_1.registerFileTools)(client);
49
+ // Register report operation tools
50
+ (0, reports_1.registerReportTools)(client);
51
+ // Additional tools will be registered here
52
+ logger.info(`Registered ${registry_1.toolRegistry.getToolCount()} tools`);
53
+ }
54
+ // Export all tools and related types
55
+ __exportStar(require("./registry"), exports);
56
+ __exportStar(require("./base"), exports);
57
+ __exportStar(require("./test_connection"), exports);
58
+ __exportStar(require("./configure_cache"), exports);
59
+ __exportStar(require("./apps"), exports);
60
+ __exportStar(require("./tables"), exports);
61
+ __exportStar(require("./fields"), exports);
62
+ __exportStar(require("./records"), exports);
63
+ __exportStar(require("./files"), exports);
64
+ __exportStar(require("./reports"), exports);
65
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAoBA,0CA+BC;AAjDD,yCAA0C;AAC1C,uDAAuD;AACvD,uDAAuD;AACvD,iCAA0C;AAC1C,qCAA8C;AAC9C,qCAA8C;AAC9C,uCAAgD;AAChD,mCAA4C;AAC5C,uCAAgD;AAChD,4CAA+C;AAE/C,MAAM,MAAM,GAAG,IAAA,qBAAY,EAAC,WAAW,CAAC,CAAC;AAEzC;;;;GAIG;AACH,SAAgB,eAAe,CAC7B,MAAuB,EACvB,YAA0B;IAE1B,MAAM,CAAC,IAAI,CAAC,wBAAwB,CAAC,CAAC;IAEtC,4BAA4B;IAC5B,uBAAY,CAAC,YAAY,CAAC,IAAI,oCAAkB,CAAC,MAAM,CAAC,CAAC,CAAC;IAC1D,uBAAY,CAAC,YAAY,CAAC,IAAI,oCAAkB,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC,CAAC;IAExE,gCAAgC;IAChC,IAAA,uBAAgB,EAAC,MAAM,CAAC,CAAC;IAEzB,iCAAiC;IACjC,IAAA,2BAAkB,EAAC,MAAM,CAAC,CAAC;IAE3B,kCAAkC;IAClC,IAAA,2BAAkB,EAAC,MAAM,CAAC,CAAC;IAE3B,kCAAkC;IAClC,IAAA,6BAAmB,EAAC,MAAM,CAAC,CAAC;IAE5B,gCAAgC;IAChC,IAAA,yBAAiB,EAAC,MAAM,CAAC,CAAC;IAE1B,kCAAkC;IAClC,IAAA,6BAAmB,EAAC,MAAM,CAAC,CAAC;IAE5B,2CAA2C;IAE3C,MAAM,CAAC,IAAI,CAAC,cAAc,uBAAY,CAAC,YAAY,EAAE,QAAQ,CAAC,CAAC;AACjE,CAAC;AAED,qCAAqC;AACrC,6CAA2B;AAC3B,yCAAuB;AACvB,oDAAkC;AAClC,oDAAkC;AAClC,yCAAuB;AACvB,2CAAyB;AACzB,2CAAyB;AACzB,4CAA0B;AAC1B,0CAAwB;AACxB,4CAA0B"}
@@ -0,0 +1,75 @@
1
+ import { BaseTool } from '../base';
2
+ import { QuickbaseClient } from '../../client/quickbase';
3
+ /**
4
+ * Parameters for bulk_create_records tool
5
+ */
6
+ export interface BulkCreateRecordsParams {
7
+ /**
8
+ * The ID of the table to create records in
9
+ */
10
+ table_id: string;
11
+ /**
12
+ * Array of record data to insert
13
+ */
14
+ records: Record<string, any>[];
15
+ }
16
+ /**
17
+ * Response from bulk creating records
18
+ */
19
+ export interface BulkCreateRecordsResult {
20
+ /**
21
+ * Array of created record IDs
22
+ */
23
+ recordIds: string[];
24
+ /**
25
+ * The ID of the table the records were created in
26
+ */
27
+ tableId: string;
28
+ /**
29
+ * Number of records created
30
+ */
31
+ createdCount: number;
32
+ /**
33
+ * Creation timestamp
34
+ */
35
+ createdTime?: string;
36
+ }
37
+ /**
38
+ * Tool for creating multiple records in a Quickbase table
39
+ */
40
+ export declare class BulkCreateRecordsTool extends BaseTool<BulkCreateRecordsParams, BulkCreateRecordsResult> {
41
+ name: string;
42
+ description: string;
43
+ /**
44
+ * Parameter schema for bulk_create_records
45
+ */
46
+ paramSchema: {
47
+ type: string;
48
+ properties: {
49
+ table_id: {
50
+ type: string;
51
+ description: string;
52
+ };
53
+ records: {
54
+ type: string;
55
+ description: string;
56
+ items: {
57
+ type: string;
58
+ additionalProperties: boolean;
59
+ };
60
+ };
61
+ };
62
+ required: string[];
63
+ };
64
+ /**
65
+ * Constructor
66
+ * @param client Quickbase client
67
+ */
68
+ constructor(client: QuickbaseClient);
69
+ /**
70
+ * Run the bulk_create_records tool
71
+ * @param params Tool parameters
72
+ * @returns Bulk create result
73
+ */
74
+ protected run(params: BulkCreateRecordsParams): Promise<BulkCreateRecordsResult>;
75
+ }
@@ -0,0 +1,104 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.BulkCreateRecordsTool = void 0;
4
+ const base_1 = require("../base");
5
+ const logger_1 = require("../../utils/logger");
6
+ const logger = (0, logger_1.createLogger)('BulkCreateRecordsTool');
7
+ /**
8
+ * Tool for creating multiple records in a Quickbase table
9
+ */
10
+ class BulkCreateRecordsTool extends base_1.BaseTool {
11
+ /**
12
+ * Constructor
13
+ * @param client Quickbase client
14
+ */
15
+ constructor(client) {
16
+ super(client);
17
+ this.name = 'bulk_create_records';
18
+ this.description = 'Creates multiple records in a Quickbase table';
19
+ /**
20
+ * Parameter schema for bulk_create_records
21
+ */
22
+ this.paramSchema = {
23
+ type: 'object',
24
+ properties: {
25
+ table_id: {
26
+ type: 'string',
27
+ description: 'The ID of the Quickbase table'
28
+ },
29
+ records: {
30
+ type: 'array',
31
+ description: 'Array of record data to insert',
32
+ items: {
33
+ type: 'object',
34
+ additionalProperties: true
35
+ }
36
+ }
37
+ },
38
+ required: ['table_id', 'records']
39
+ };
40
+ }
41
+ /**
42
+ * Run the bulk_create_records tool
43
+ * @param params Tool parameters
44
+ * @returns Bulk create result
45
+ */
46
+ async run(params) {
47
+ const { table_id, records } = params;
48
+ logger.info(`Bulk creating ${records.length} records in Quickbase table`, {
49
+ tableId: table_id,
50
+ recordCount: records.length
51
+ });
52
+ // Validate records
53
+ if (!records || !Array.isArray(records) || records.length === 0) {
54
+ throw new Error('Records array is required and must not be empty');
55
+ }
56
+ // Prepare record data
57
+ const formattedRecords = records.map(record => {
58
+ const recordData = {};
59
+ for (const [field, value] of Object.entries(record)) {
60
+ recordData[field] = { value };
61
+ }
62
+ return recordData;
63
+ });
64
+ // Prepare request body
65
+ const body = {
66
+ to: table_id,
67
+ data: formattedRecords
68
+ };
69
+ // Create the records
70
+ const response = await this.client.request({
71
+ method: 'POST',
72
+ path: '/records',
73
+ body
74
+ });
75
+ if (!response.success || !response.data) {
76
+ logger.error('Failed to bulk create records', {
77
+ error: response.error,
78
+ tableId: table_id
79
+ });
80
+ throw new Error(response.error?.message || 'Failed to bulk create records');
81
+ }
82
+ const result = response.data;
83
+ const metadata = result.metadata || {};
84
+ if (!metadata.createdRecordIds || metadata.createdRecordIds.length === 0) {
85
+ logger.error('Bulk record creation response missing record IDs', {
86
+ response: result
87
+ });
88
+ throw new Error('Records created but no record IDs were returned');
89
+ }
90
+ const recordIds = metadata.createdRecordIds;
91
+ logger.info(`Successfully created ${recordIds.length} records`, {
92
+ recordCount: recordIds.length,
93
+ tableId: table_id
94
+ });
95
+ return {
96
+ recordIds,
97
+ tableId: table_id,
98
+ createdCount: recordIds.length,
99
+ createdTime: new Date().toISOString()
100
+ };
101
+ }
102
+ }
103
+ exports.BulkCreateRecordsTool = BulkCreateRecordsTool;
104
+ //# sourceMappingURL=bulk_create_records.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bulk_create_records.js","sourceRoot":"","sources":["../../../src/tools/records/bulk_create_records.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,77 @@
1
+ import { BaseTool } from '../base';
2
+ import { QuickbaseClient } from '../../client/quickbase';
3
+ /**
4
+ * Parameters for bulk_update_records tool
5
+ */
6
+ export interface BulkUpdateRecordsParams {
7
+ /**
8
+ * The ID of the table containing the records
9
+ */
10
+ table_id: string;
11
+ /**
12
+ * Array of record data to update (must include record IDs)
13
+ */
14
+ records: Array<Record<string, any> & {
15
+ id: string;
16
+ }>;
17
+ }
18
+ /**
19
+ * Response from bulk updating records
20
+ */
21
+ export interface BulkUpdateRecordsResult {
22
+ /**
23
+ * Array of updated record IDs
24
+ */
25
+ recordIds: string[];
26
+ /**
27
+ * The ID of the table containing the records
28
+ */
29
+ tableId: string;
30
+ /**
31
+ * Number of records updated
32
+ */
33
+ updatedCount: number;
34
+ /**
35
+ * Update timestamp
36
+ */
37
+ updatedTime?: string;
38
+ }
39
+ /**
40
+ * Tool for updating multiple records in a Quickbase table
41
+ */
42
+ export declare class BulkUpdateRecordsTool extends BaseTool<BulkUpdateRecordsParams, BulkUpdateRecordsResult> {
43
+ name: string;
44
+ description: string;
45
+ /**
46
+ * Parameter schema for bulk_update_records
47
+ */
48
+ paramSchema: {
49
+ type: string;
50
+ properties: {
51
+ table_id: {
52
+ type: string;
53
+ description: string;
54
+ };
55
+ records: {
56
+ type: string;
57
+ description: string;
58
+ items: {
59
+ type: string;
60
+ additionalProperties: boolean;
61
+ };
62
+ };
63
+ };
64
+ required: string[];
65
+ };
66
+ /**
67
+ * Constructor
68
+ * @param client Quickbase client
69
+ */
70
+ constructor(client: QuickbaseClient);
71
+ /**
72
+ * Run the bulk_update_records tool
73
+ * @param params Tool parameters
74
+ * @returns Bulk update result
75
+ */
76
+ protected run(params: BulkUpdateRecordsParams): Promise<BulkUpdateRecordsResult>;
77
+ }
@@ -0,0 +1,102 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.BulkUpdateRecordsTool = void 0;
4
+ const base_1 = require("../base");
5
+ const logger_1 = require("../../utils/logger");
6
+ const logger = (0, logger_1.createLogger)('BulkUpdateRecordsTool');
7
+ /**
8
+ * Tool for updating multiple records in a Quickbase table
9
+ */
10
+ class BulkUpdateRecordsTool extends base_1.BaseTool {
11
+ /**
12
+ * Constructor
13
+ * @param client Quickbase client
14
+ */
15
+ constructor(client) {
16
+ super(client);
17
+ this.name = 'bulk_update_records';
18
+ this.description = 'Updates multiple records in a Quickbase table';
19
+ /**
20
+ * Parameter schema for bulk_update_records
21
+ */
22
+ this.paramSchema = {
23
+ type: 'object',
24
+ properties: {
25
+ table_id: {
26
+ type: 'string',
27
+ description: 'The ID of the Quickbase table'
28
+ },
29
+ records: {
30
+ type: 'array',
31
+ description: 'Array of record data to update (must include record IDs)',
32
+ items: {
33
+ type: 'object',
34
+ additionalProperties: true
35
+ }
36
+ }
37
+ },
38
+ required: ['table_id', 'records']
39
+ };
40
+ }
41
+ /**
42
+ * Run the bulk_update_records tool
43
+ * @param params Tool parameters
44
+ * @returns Bulk update result
45
+ */
46
+ async run(params) {
47
+ const { table_id, records } = params;
48
+ logger.info(`Bulk updating ${records.length} records in Quickbase table`, {
49
+ tableId: table_id,
50
+ recordCount: records.length
51
+ });
52
+ // Validate records
53
+ if (!records || !Array.isArray(records) || records.length === 0) {
54
+ throw new Error('Records array is required and must not be empty');
55
+ }
56
+ // Check if all records have IDs
57
+ const missingIds = records.some(record => !record.id);
58
+ if (missingIds) {
59
+ throw new Error('All records must include an "id" field for bulk updates');
60
+ }
61
+ // Prepare record data
62
+ const formattedRecords = records.map(record => {
63
+ const { id, ...fields } = record;
64
+ const recordData = { id };
65
+ for (const [field, value] of Object.entries(fields)) {
66
+ recordData[field] = { value };
67
+ }
68
+ return recordData;
69
+ });
70
+ // Prepare request body
71
+ const body = {
72
+ to: table_id,
73
+ data: formattedRecords
74
+ };
75
+ // Update the records
76
+ const response = await this.client.request({
77
+ method: 'POST',
78
+ path: '/records',
79
+ body
80
+ });
81
+ if (!response.success || !response.data) {
82
+ logger.error('Failed to bulk update records', {
83
+ error: response.error,
84
+ tableId: table_id
85
+ });
86
+ throw new Error(response.error?.message || 'Failed to bulk update records');
87
+ }
88
+ const recordIds = records.map(record => record.id);
89
+ logger.info(`Successfully updated ${recordIds.length} records`, {
90
+ recordCount: recordIds.length,
91
+ tableId: table_id
92
+ });
93
+ return {
94
+ recordIds,
95
+ tableId: table_id,
96
+ updatedCount: recordIds.length,
97
+ updatedTime: new Date().toISOString()
98
+ };
99
+ }
100
+ }
101
+ exports.BulkUpdateRecordsTool = BulkUpdateRecordsTool;
102
+ //# sourceMappingURL=bulk_update_records.js.map