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
package/CHANGELOG.md ADDED
@@ -0,0 +1,82 @@
1
+ # 📋 Changelog
2
+
3
+ All notable changes to Quickbase MCP Server will be documented in this file.
4
+
5
+ ## [2.0.0] - 2025-05-24
6
+
7
+ ### Added
8
+ - Complete TypeScript rewrite - removed Python dependency
9
+ - Full type safety with TypeScript strict mode
10
+ - Intelligent caching system with configurable TTL
11
+ - Built-in retry logic with exponential backoff
12
+ - Rate limiting to prevent API overload
13
+ - Comprehensive error handling with structured responses
14
+ - Jest-based test suite with 45%+ coverage
15
+ - ESLint and Prettier for code quality
16
+ - MCP server implementation for both stdio and HTTP modes
17
+ - Session management and proper lifecycle handling
18
+ - Migration guide for v1 users
19
+ - Performance benchmarking tests
20
+
21
+ ### Changed
22
+ - Minimum Node.js version increased to 18+ (from 14+)
23
+ - Entry point changed to `dist/mcp-stdio-server.js`
24
+ - Startup time reduced by 60% (~2s vs 5s+)
25
+ - Memory usage reduced by 40%
26
+ - All async operations now use modern async/await
27
+ - Improved validation for all tool parameters
28
+ - Better error messages with actionable context
29
+ - Reorganized project structure for better maintainability
30
+
31
+ ### Fixed
32
+ - Memory leaks in long-running sessions
33
+ - Race conditions in concurrent requests
34
+ - File upload issues with large files
35
+ - Pagination bugs in query_records
36
+ - Cache invalidation timing issues
37
+ - Proper cleanup on shutdown
38
+
39
+ ### Deprecated
40
+ - v1 implementation moved to v1-legacy/ for reference only
41
+
42
+ ## [1.0.0] - 2025-03-21
43
+
44
+ ### Added
45
+ - Added pagination support for query_records tool
46
+ - Added comprehensive test suite
47
+ - Added run_tests.sh script for easy testing
48
+ - Added TEST_RESULTS.md with detailed test results
49
+ - Added CHANGELOG.md file
50
+
51
+ ### Changed
52
+ - Fixed file upload and download operations
53
+ - Improved error handling across all operations
54
+ - Updated create_record to properly format field IDs
55
+ - Updated update_record to handle JSON string parsing
56
+ - Updated documentation in README.md and tools_tested.txt
57
+
58
+ ### Removed
59
+ - Removed all delete operations due to API limitations:
60
+ - delete_app
61
+ - delete_table
62
+ - delete_field
63
+ - delete_record
64
+ - bulk_delete_records
65
+ - delete_file
66
+ - Removed user operations due to API limitations:
67
+ - get_user
68
+ - get_current_user
69
+ - get_user_roles
70
+ - manage_users
71
+ - Removed form operations due to API limitations:
72
+ - manage_forms
73
+ - Removed dashboard operations due to API limitations:
74
+ - manage_dashboards
75
+
76
+ ## [0.1.0] - 2025-03-20
77
+
78
+ ### Added
79
+ - Initial release
80
+ - Basic MCP server implementation
81
+ - Support for Quickbase API operations
82
+ - Documentation and examples
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Quickbase MCP Server Contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,301 @@
1
+ # Quickbase MCP Server
2
+
3
+ A TypeScript-based Model Context Protocol (MCP) connector for Quickbase, designed for seamless integration with Claude and other AI assistants.
4
+
5
+ ## 🚀 Quick Start
6
+
7
+ ### Installation via NPM (Recommended)
8
+
9
+ ```bash
10
+ # Use directly with npx (no installation needed)
11
+ npx -y mcp-quickbase
12
+
13
+ # Or install globally
14
+ npm install -g mcp-quickbase
15
+ ```
16
+
17
+ ### Installation from Source
18
+
19
+ ```bash
20
+ # Clone the repository
21
+ git clone https://github.com/danielbushman/MCP-Quickbase.git
22
+ cd MCP-Quickbase
23
+
24
+ # Install dependencies
25
+ npm install
26
+
27
+ # Build the project
28
+ npm run build
29
+ ```
30
+
31
+ ### Configuration
32
+
33
+ #### For NPM Users
34
+
35
+ Configure directly in Claude Desktop:
36
+
37
+ ```json
38
+ {
39
+ "mcpServers": {
40
+ "quickbase": {
41
+ "command": "npx",
42
+ "args": ["-y", "mcp-quickbase"],
43
+ "env": {
44
+ "QUICKBASE_REALM_HOST": "your-realm.quickbase.com",
45
+ "QUICKBASE_USER_TOKEN": "your-user-token",
46
+ "QUICKBASE_APP_ID": "your-app-id",
47
+ "QUICKBASE_CACHE_ENABLED": "true",
48
+ "QUICKBASE_CACHE_TTL": "3600"
49
+ }
50
+ }
51
+ }
52
+ }
53
+ ```
54
+
55
+ #### For Local Development
56
+
57
+ Create a `.env` file in the root directory:
58
+
59
+ ```env
60
+ QUICKBASE_REALM_HOST=your-realm.quickbase.com
61
+ QUICKBASE_USER_TOKEN=your-user-token
62
+ QUICKBASE_APP_ID=your-app-id
63
+ QUICKBASE_CACHE_ENABLED=true
64
+ QUICKBASE_CACHE_TTL=3600
65
+ DEBUG=false
66
+ ```
67
+
68
+ Then configure Claude Desktop:
69
+
70
+ ```json
71
+ {
72
+ "mcpServers": {
73
+ "quickbase": {
74
+ "command": "node",
75
+ "args": ["/path/to/MCP-Quickbase/dist/mcp-stdio-server.js"],
76
+ "env": {
77
+ "QUICKBASE_REALM_HOST": "your-realm.quickbase.com",
78
+ "QUICKBASE_USER_TOKEN": "your-user-token",
79
+ "QUICKBASE_APP_ID": "your-app-id"
80
+ }
81
+ }
82
+ }
83
+ }
84
+ ```
85
+
86
+ 2. **Start using tools**: The connector provides 18 comprehensive tools for Quickbase operations.
87
+
88
+ ## 🛠️ Available Tools
89
+
90
+ ### Connection & Configuration
91
+ - **`test_connection`** - Test connection to Quickbase
92
+ - **`configure_cache`** - Configure caching behavior
93
+
94
+ ### Application Management
95
+ - **`create_app`** - Create new Quickbase applications
96
+ - **`update_app`** - Update existing applications
97
+ - **`list_tables`** - List all tables in an application
98
+
99
+ ### Table Operations
100
+ - **`create_table`** - Create new tables
101
+ - **`update_table`** - Update existing tables
102
+ - **`get_table_fields`** - Retrieve table field definitions
103
+
104
+ ### Field Management
105
+ - **`create_field`** - Create new fields in tables
106
+ - **`update_field`** - Update existing field properties
107
+
108
+ ### Record Operations
109
+ - **`query_records`** - Query records with advanced filtering
110
+ - **`create_record`** - Create single records
111
+ - **`update_record`** - Update existing records
112
+ - **`bulk_create_records`** - Create multiple records efficiently
113
+ - **`bulk_update_records`** - Update multiple records efficiently
114
+
115
+ ### File Handling
116
+ - **`upload_file`** - Upload files to record fields
117
+ - **`download_file`** - Download files from record fields
118
+
119
+ ### Reports
120
+ - **`run_report`** - Execute Quickbase reports with filters
121
+
122
+ ## 🏗️ Architecture
123
+
124
+ ### TypeScript-First Design
125
+ - **100% TypeScript** for type safety and developer experience
126
+ - **Comprehensive type definitions** for all Quickbase API interactions
127
+ - **Modern async/await** patterns throughout
128
+
129
+ ### Performance Features
130
+ - **Intelligent caching** with configurable TTL
131
+ - **Automatic retry logic** for transient failures
132
+ - **Bulk operations** for high-performance data manipulation
133
+ - **Pagination support** for large datasets
134
+
135
+ ### Error Handling
136
+ - **Structured error responses** with detailed context
137
+ - **Graceful degradation** for API failures
138
+ - **Comprehensive logging** for debugging
139
+
140
+ ## 📚 Examples
141
+
142
+ ### Basic Record Operations
143
+
144
+ ```typescript
145
+ // Query records
146
+ const records = await queryRecords({
147
+ table_id: "bqrxzt5wq",
148
+ where: "{6.CT.'Project'}",
149
+ select: ["1", "6", "7", "8"]
150
+ });
151
+
152
+ // Create a record
153
+ const newRecord = await createRecord({
154
+ table_id: "bqrxzt5wq",
155
+ data: {
156
+ "6": "New Project",
157
+ "7": "Project description",
158
+ "8": "High"
159
+ }
160
+ });
161
+
162
+ // Update multiple records
163
+ const updates = await bulkUpdateRecords({
164
+ table_id: "bqrxzt5wq",
165
+ records: [
166
+ { "3": "123", "8": "Critical" },
167
+ { "3": "124", "8": "Low" }
168
+ ]
169
+ });
170
+ ```
171
+
172
+ ### File Operations
173
+
174
+ ```typescript
175
+ // Upload a file
176
+ const upload = await uploadFile({
177
+ table_id: "bqrxzt5wq",
178
+ record_id: "123",
179
+ field_id: "9",
180
+ file_path: "/path/to/document.pdf"
181
+ });
182
+
183
+ // Download a file
184
+ const download = await downloadFile({
185
+ table_id: "bqrxzt5wq",
186
+ record_id: "123",
187
+ field_id: "9",
188
+ output_path: "/downloads/document.pdf"
189
+ });
190
+ ```
191
+
192
+ ### Advanced Queries with Pagination
193
+
194
+ ```typescript
195
+ // Paginated query for large datasets
196
+ const largeDataset = await queryRecords({
197
+ table_id: "bqrxzt5wq",
198
+ select: ["1", "6", "7", "8"],
199
+ paginate: true,
200
+ max_records: "1000",
201
+ options: {
202
+ orderBy: [{ fieldId: "6", order: "ASC" }],
203
+ top: 100
204
+ }
205
+ });
206
+ ```
207
+
208
+ ## 🧪 Testing
209
+
210
+ ```bash
211
+ # Run all tests
212
+ npm test
213
+
214
+ # Run tests with coverage
215
+ npm test -- --coverage
216
+
217
+ # Run tests in watch mode
218
+ npm test -- --watch
219
+ ```
220
+
221
+ ## 🔧 Development
222
+
223
+ ### Project Structure
224
+
225
+ ```
226
+ src/
227
+ ├── client/ # Quickbase API client
228
+ ├── tools/ # MCP tool implementations
229
+ │ ├── apps/ # Application management tools
230
+ │ ├── fields/ # Field management tools
231
+ │ ├── files/ # File operation tools
232
+ │ ├── records/ # Record operation tools
233
+ │ ├── reports/ # Report execution tools
234
+ │ └── tables/ # Table operation tools
235
+ ├── types/ # TypeScript type definitions
236
+ ├── utils/ # Utility functions
237
+ └── mcp/ # MCP server implementation
238
+ ```
239
+
240
+ ### Adding New Tools
241
+
242
+ 1. Create tool class extending `BaseTool<TParams, TResult>`
243
+ 2. Implement required properties and `run()` method
244
+ 3. Register in appropriate tool category
245
+ 4. Add comprehensive tests
246
+
247
+ Example:
248
+
249
+ ```typescript
250
+ export class MyCustomTool extends BaseTool<MyParams, MyResult> {
251
+ public readonly name = 'my_custom_tool';
252
+ public readonly description = 'Description of my tool';
253
+ public readonly paramSchema = { /* JSON Schema */ };
254
+
255
+ protected async run(params: MyParams): Promise<MyResult> {
256
+ // Implementation
257
+ }
258
+ }
259
+ ```
260
+
261
+ ## 🚦 Deployment
262
+
263
+ ### HTTP Server Mode
264
+ ```bash
265
+ npm start # Runs on port 3536
266
+ ```
267
+
268
+ ### MCP Stdio Mode
269
+ ```bash
270
+ node dist/mcp-stdio-server.js
271
+ ```
272
+
273
+ ## 📋 Requirements
274
+
275
+ - **Node.js** 18+
276
+ - **TypeScript** 5.2+
277
+ - **Quickbase** account with API access
278
+ - **Valid user token** with appropriate permissions
279
+
280
+ ## 🤝 Contributing
281
+
282
+ 1. Fork the repository
283
+ 2. Create a feature branch
284
+ 3. Add tests for new functionality
285
+ 4. Ensure all tests pass
286
+ 5. Submit a pull request
287
+
288
+ ## 📄 License
289
+
290
+ MIT License - see LICENSE file for details.
291
+
292
+ ## 🆘 Support
293
+
294
+ For issues and questions:
295
+ - Check the [documentation](docs/)
296
+ - Review the [Quick Start Guide](docs/quickstart.md)
297
+ - Open an issue on GitHub
298
+
299
+ ---
300
+
301
+ Built with ❤️ for seamless Quickbase integration with AI assistants.
@@ -0,0 +1,28 @@
1
+ import { QuickbaseConfig } from '../types/config';
2
+ import { ApiResponse, RequestOptions } from '../types/api';
3
+ /**
4
+ * Client for interacting with the Quickbase API
5
+ */
6
+ export declare class QuickbaseClient {
7
+ private config;
8
+ private cache;
9
+ private baseUrl;
10
+ private headers;
11
+ private rateLimiter;
12
+ /**
13
+ * Creates a new Quickbase client
14
+ * @param config Client configuration
15
+ */
16
+ constructor(config: QuickbaseConfig);
17
+ /**
18
+ * Get the client configuration
19
+ * @returns Current configuration
20
+ */
21
+ getConfig(): QuickbaseConfig;
22
+ /**
23
+ * Sends a request to the Quickbase API with retry logic
24
+ * @param options Request options
25
+ * @returns API response
26
+ */
27
+ request<T>(options: RequestOptions): Promise<ApiResponse<T>>;
28
+ }
@@ -0,0 +1,235 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.QuickbaseClient = void 0;
4
+ const cache_1 = require("../utils/cache");
5
+ const logger_1 = require("../utils/logger");
6
+ const retry_1 = require("../utils/retry");
7
+ const logger = (0, logger_1.createLogger)('QuickbaseClient');
8
+ /**
9
+ * Thread-safe rate limiter to prevent API overload
10
+ */
11
+ class RateLimiter {
12
+ constructor(maxRequests = 10, windowMs = 1000) {
13
+ this.requests = [];
14
+ this.pending = Promise.resolve();
15
+ this.maxRequests = maxRequests;
16
+ this.windowMs = windowMs;
17
+ }
18
+ async wait() {
19
+ // Serialize all rate limit checks to prevent race conditions
20
+ this.pending = this.pending.then(() => this.checkRateLimit());
21
+ return this.pending;
22
+ }
23
+ async checkRateLimit() {
24
+ const now = Date.now();
25
+ // Remove requests outside the current window
26
+ this.requests = this.requests.filter(time => now - time < this.windowMs);
27
+ if (this.requests.length >= this.maxRequests) {
28
+ // Calculate wait time until oldest request expires
29
+ const oldestRequest = Math.min(...this.requests);
30
+ const waitTime = this.windowMs - (now - oldestRequest) + 10; // +10ms buffer
31
+ if (waitTime > 0) {
32
+ logger.debug(`Rate limiting: waiting ${waitTime}ms`);
33
+ await new Promise(resolve => setTimeout(resolve, waitTime));
34
+ // Re-check after waiting (recursive but bounded by maxRequests)
35
+ return this.checkRateLimit();
36
+ }
37
+ }
38
+ // Add this request to the window
39
+ this.requests.push(Date.now());
40
+ }
41
+ }
42
+ /**
43
+ * Client for interacting with the Quickbase API
44
+ */
45
+ class QuickbaseClient {
46
+ /**
47
+ * Creates a new Quickbase client
48
+ * @param config Client configuration
49
+ */
50
+ constructor(config) {
51
+ this.config = {
52
+ userAgent: 'QuickbaseMCPConnector/2.0',
53
+ cacheEnabled: true,
54
+ cacheTtl: 3600,
55
+ maxRetries: 3,
56
+ retryDelay: 1000,
57
+ debug: false,
58
+ ...config
59
+ };
60
+ if (!this.config.realmHost) {
61
+ throw new Error('Realm hostname is required');
62
+ }
63
+ if (!this.config.userToken) {
64
+ throw new Error('User token is required');
65
+ }
66
+ this.baseUrl = `https://api.quickbase.com/v1`;
67
+ this.headers = {
68
+ 'QB-Realm-Hostname': this.config.realmHost,
69
+ 'Authorization': `QB-USER-TOKEN ${this.config.userToken}`,
70
+ 'Content-Type': 'application/json',
71
+ 'User-Agent': this.config.userAgent || 'QuickbaseMCPConnector/2.0'
72
+ };
73
+ this.cache = new cache_1.CacheService(this.config.cacheTtl, this.config.cacheEnabled);
74
+ // Initialize rate limiter (10 requests per second by default)
75
+ this.rateLimiter = new RateLimiter(this.config.rateLimit || 10, 1000);
76
+ logger.info('Quickbase client initialized', {
77
+ realmHost: this.config.realmHost,
78
+ appId: this.config.appId,
79
+ cacheEnabled: this.config.cacheEnabled,
80
+ rateLimit: this.config.rateLimit || 10
81
+ });
82
+ }
83
+ /**
84
+ * Get the client configuration
85
+ * @returns Current configuration
86
+ */
87
+ getConfig() {
88
+ return { ...this.config };
89
+ }
90
+ /**
91
+ * Sends a request to the Quickbase API with retry logic
92
+ * @param options Request options
93
+ * @returns API response
94
+ */
95
+ async request(options) {
96
+ const makeRequest = async () => {
97
+ const { method, path, body, params, headers = {}, skipCache = false } = options;
98
+ // Build full URL with query parameters
99
+ let url = `${this.baseUrl}${path}`;
100
+ if (params && Object.keys(params).length > 0) {
101
+ const searchParams = new URLSearchParams();
102
+ Object.entries(params).forEach(([key, value]) => {
103
+ searchParams.append(key, value);
104
+ });
105
+ url += `?${searchParams.toString()}`;
106
+ }
107
+ // Check cache for GET requests
108
+ const cacheKey = `${method}:${url}`;
109
+ if (method === 'GET' && !skipCache) {
110
+ const cachedResponse = this.cache.get(cacheKey);
111
+ if (cachedResponse) {
112
+ logger.debug('Returning cached response', { url, method });
113
+ return cachedResponse;
114
+ }
115
+ }
116
+ // Apply rate limiting before making the request
117
+ await this.rateLimiter.wait();
118
+ // Combine default headers with request-specific headers
119
+ const requestHeaders = { ...this.headers, ...headers };
120
+ // Log request (with redacted sensitive info)
121
+ const redactedHeaders = { ...requestHeaders };
122
+ if (redactedHeaders.Authorization) {
123
+ redactedHeaders.Authorization = '***REDACTED***';
124
+ }
125
+ if (redactedHeaders['QB-Realm-Hostname']) {
126
+ // Keep realm hostname for debugging but redact sensitive parts
127
+ redactedHeaders['QB-Realm-Hostname'] = redactedHeaders['QB-Realm-Hostname'].replace(/[a-zA-Z0-9-]+/, '***');
128
+ }
129
+ logger.debug('Sending API request', {
130
+ url: url.replace(/[?&]userToken=[^&]*/g, '&userToken=***REDACTED***'), // Redact tokens in URL too
131
+ method,
132
+ headers: redactedHeaders,
133
+ body: body ? JSON.stringify(body) : undefined
134
+ });
135
+ // Send request with timeout protection
136
+ const controller = new AbortController();
137
+ const timeoutId = setTimeout(() => controller.abort(), this.config.requestTimeout || 30000);
138
+ let response;
139
+ try {
140
+ response = await fetch(url, {
141
+ method,
142
+ headers: requestHeaders,
143
+ body: body ? JSON.stringify(body) : undefined,
144
+ signal: controller.signal
145
+ });
146
+ }
147
+ finally {
148
+ clearTimeout(timeoutId);
149
+ }
150
+ // Parse response safely
151
+ let responseData;
152
+ try {
153
+ responseData = await response.json();
154
+ }
155
+ catch (error) {
156
+ throw new Error(`Invalid JSON response: ${error instanceof Error ? error.message : 'Unknown error'}`);
157
+ }
158
+ // Ensure responseData is an object
159
+ if (typeof responseData !== 'object' || responseData === null) {
160
+ throw new Error('API response is not a valid object');
161
+ }
162
+ const data = responseData;
163
+ // Check for error response
164
+ if (!response.ok) {
165
+ const errorMessage = typeof data.message === 'string' ? data.message : response.statusText;
166
+ const error = {
167
+ message: errorMessage,
168
+ code: response.status,
169
+ details: data
170
+ };
171
+ logger.error('API request failed', {
172
+ status: response.status,
173
+ error
174
+ });
175
+ // Create error with proper metadata for retry logic
176
+ const httpError = new Error(`HTTP Error ${response.status}: ${errorMessage}`);
177
+ Object.assign(httpError, { status: response.status, data: responseData });
178
+ // Always throw HTTP errors - let retry logic determine if they're retryable
179
+ // The retry logic will check the status code and decide whether to retry
180
+ throw httpError;
181
+ }
182
+ // Successful response
183
+ const result = {
184
+ success: true,
185
+ data: responseData
186
+ };
187
+ // Cache successful GET responses
188
+ if (method === 'GET' && !skipCache) {
189
+ this.cache.set(cacheKey, result);
190
+ }
191
+ return result;
192
+ };
193
+ // Retry configuration
194
+ const retryOptions = {
195
+ maxRetries: this.config.maxRetries || 3,
196
+ baseDelay: this.config.retryDelay || 1000,
197
+ isRetryable: (error) => {
198
+ // Only retry certain HTTP errors and network errors
199
+ if (!error)
200
+ return false;
201
+ // Handle HTTP errors
202
+ if (typeof error === 'object' && error !== null && 'status' in error) {
203
+ const httpError = error;
204
+ return httpError.status === 429 || // Too Many Requests
205
+ httpError.status === 408 || // Request Timeout
206
+ (httpError.status >= 500 && httpError.status < 600); // Server errors
207
+ }
208
+ // Handle network errors
209
+ if (error instanceof Error) {
210
+ return error.message.includes('network') ||
211
+ error.message.includes('timeout') ||
212
+ error.message.includes('connection');
213
+ }
214
+ return false;
215
+ }
216
+ };
217
+ try {
218
+ // Use withRetry to add retry logic to the request
219
+ return await (0, retry_1.withRetry)(makeRequest, retryOptions)();
220
+ }
221
+ catch (error) {
222
+ // Handle errors that weren't handled by the retry logic
223
+ logger.error('Request failed after retries', { error });
224
+ return {
225
+ success: false,
226
+ error: {
227
+ message: error instanceof Error ? error.message : 'Unknown error',
228
+ type: 'NetworkError'
229
+ }
230
+ };
231
+ }
232
+ }
233
+ }
234
+ exports.QuickbaseClient = QuickbaseClient;
235
+ //# sourceMappingURL=quickbase.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"quickbase.js","sourceRoot":"","sources":["../../src/client/quickbase.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ /**
2
+ * MCP (Model Context Protocol) module exports
3
+ */
4
+ export * from './server';