mcp-quickbase 2.0.4 → 2.0.5
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/README.md +8 -2
- package/dist/mcp-stdio-server.js +89 -48
- package/dist/mcp-stdio-server.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Quickbase MCP Server
|
|
2
2
|
|
|
3
|
-
A TypeScript-based Model Context Protocol (MCP)
|
|
3
|
+
A TypeScript-based Model Context Protocol (MCP) server for Quickbase, designed for seamless integration with Claude Desktop and other AI assistants.
|
|
4
4
|
|
|
5
5
|
> **📋 Community Project Notice**
|
|
6
6
|
> This is a community-developed integration that is not an official Quickbase product. While it uses Quickbase's public APIs, it is not officially supported by Quickbase, Inc. This project is provided "as is" and maintained by the community. For official Quickbase products and support, please visit [quickbase.com](https://www.quickbase.com).
|
|
@@ -86,11 +86,16 @@ For source installation, use this Claude Desktop configuration:
|
|
|
86
86
|
|
|
87
87
|
## 🔧 Configuration
|
|
88
88
|
|
|
89
|
+
The server can start without environment variables configured, but tools will not be functional until proper configuration is provided. Use the `check_configuration` tool to verify your setup.
|
|
90
|
+
|
|
89
91
|
### Required Environment Variables
|
|
90
92
|
|
|
91
93
|
- **`QUICKBASE_REALM_HOST`** - Your Quickbase realm (e.g., `company.quickbase.com`)
|
|
92
94
|
- **`QUICKBASE_USER_TOKEN`** - Your Quickbase API token ([Get one here](https://help.quickbase.com/en/articles/8672050))
|
|
93
|
-
|
|
95
|
+
|
|
96
|
+
### Optional Environment Variables
|
|
97
|
+
|
|
98
|
+
- **`QUICKBASE_APP_ID`** - Default application ID
|
|
94
99
|
|
|
95
100
|
### Optional Settings
|
|
96
101
|
|
|
@@ -102,6 +107,7 @@ For source installation, use this Claude Desktop configuration:
|
|
|
102
107
|
## 🛠️ Available Tools
|
|
103
108
|
|
|
104
109
|
### Connection & Configuration
|
|
110
|
+
- **`check_configuration`** - Check if Quickbase configuration is properly set up
|
|
105
111
|
- **`test_connection`** - Test connection to Quickbase
|
|
106
112
|
- **`configure_cache`** - Configure caching behavior
|
|
107
113
|
|
package/dist/mcp-stdio-server.js
CHANGED
|
@@ -62,60 +62,101 @@ async function main() {
|
|
|
62
62
|
version: '2.0.0',
|
|
63
63
|
});
|
|
64
64
|
logger.info('MCP Server created');
|
|
65
|
-
//
|
|
66
|
-
const
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
cacheTtl: parseInt(process.env.QUICKBASE_CACHE_TTL || '3600', 10),
|
|
72
|
-
debug: process.env.DEBUG === 'true'
|
|
73
|
-
};
|
|
74
|
-
// Validate required configuration
|
|
75
|
-
if (!config.realmHost || !config.userToken) {
|
|
76
|
-
throw new Error('QUICKBASE_REALM_HOST and QUICKBASE_USER_TOKEN are required');
|
|
77
|
-
}
|
|
78
|
-
// Validate realm host format
|
|
79
|
-
if (!config.realmHost.match(/^[a-zA-Z0-9-]+\.quickbase\.com$/)) {
|
|
80
|
-
throw new Error('QUICKBASE_REALM_HOST must be in format: yourcompany.quickbase.com');
|
|
81
|
-
}
|
|
82
|
-
// Validate cache TTL
|
|
83
|
-
if (isNaN(config.cacheTtl) || config.cacheTtl <= 0) {
|
|
84
|
-
throw new Error('QUICKBASE_CACHE_TTL must be a positive number');
|
|
65
|
+
// Check if environment variables are configured
|
|
66
|
+
const hasConfig = process.env.QUICKBASE_REALM_HOST && process.env.QUICKBASE_USER_TOKEN;
|
|
67
|
+
if (!hasConfig) {
|
|
68
|
+
logger.warn('Quickbase configuration not found in environment variables');
|
|
69
|
+
logger.info('Server will start but tools will not be functional until configuration is provided');
|
|
70
|
+
logger.info('Required environment variables: QUICKBASE_REALM_HOST, QUICKBASE_USER_TOKEN');
|
|
85
71
|
}
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
72
|
+
let quickbaseClient = null;
|
|
73
|
+
let cacheService = null;
|
|
74
|
+
if (hasConfig) {
|
|
75
|
+
// Initialize Quickbase client with configuration
|
|
76
|
+
const config = {
|
|
77
|
+
realmHost: process.env.QUICKBASE_REALM_HOST || '',
|
|
78
|
+
userToken: process.env.QUICKBASE_USER_TOKEN || '',
|
|
79
|
+
appId: process.env.QUICKBASE_APP_ID,
|
|
80
|
+
cacheEnabled: process.env.QUICKBASE_CACHE_ENABLED !== 'false',
|
|
81
|
+
cacheTtl: parseInt(process.env.QUICKBASE_CACHE_TTL || '3600', 10),
|
|
82
|
+
debug: process.env.DEBUG === 'true'
|
|
83
|
+
};
|
|
84
|
+
// Validate realm host format if provided
|
|
85
|
+
if (config.realmHost && !config.realmHost.match(/^[a-zA-Z0-9-]+\.quickbase\.com$/)) {
|
|
86
|
+
logger.error('QUICKBASE_REALM_HOST must be in format: yourcompany.quickbase.com');
|
|
87
|
+
logger.warn('Continuing without Quickbase client initialization');
|
|
88
|
+
}
|
|
89
|
+
else {
|
|
90
|
+
// Validate cache TTL
|
|
91
|
+
if (isNaN(config.cacheTtl) || config.cacheTtl <= 0) {
|
|
92
|
+
config.cacheTtl = 3600; // Default to 1 hour
|
|
93
|
+
logger.warn('Invalid QUICKBASE_CACHE_TTL, using default: 3600');
|
|
94
|
+
}
|
|
95
95
|
try {
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
//
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
logger.error(`Tool ${tool.name} failed`, { error: apiResponse.error });
|
|
102
|
-
throw new Error(errorMessage);
|
|
103
|
-
}
|
|
104
|
-
return {
|
|
105
|
-
content: [{
|
|
106
|
-
type: 'text',
|
|
107
|
-
text: JSON.stringify(apiResponse.data, null, 2)
|
|
108
|
-
}]
|
|
109
|
-
};
|
|
96
|
+
quickbaseClient = new quickbase_1.QuickbaseClient(config);
|
|
97
|
+
cacheService = new cache_1.CacheService(config.cacheTtl, config.cacheEnabled);
|
|
98
|
+
// Initialize tools
|
|
99
|
+
(0, tools_1.initializeTools)(quickbaseClient, cacheService);
|
|
100
|
+
logger.info('Quickbase client and tools initialized successfully');
|
|
110
101
|
}
|
|
111
102
|
catch (error) {
|
|
112
|
-
logger.error(
|
|
113
|
-
|
|
103
|
+
logger.error('Failed to initialize Quickbase client', { error });
|
|
104
|
+
logger.warn('Server will continue without functional tools');
|
|
114
105
|
}
|
|
115
|
-
}
|
|
116
|
-
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
// Register a configuration check tool that's always available
|
|
109
|
+
server.tool('check_configuration', 'Check if Quickbase configuration is properly set up', {}, async () => {
|
|
110
|
+
const configured = !!quickbaseClient;
|
|
111
|
+
const status = configured ?
|
|
112
|
+
'Quickbase client is configured and ready' :
|
|
113
|
+
'Quickbase client is not configured. Please set QUICKBASE_REALM_HOST and QUICKBASE_USER_TOKEN environment variables';
|
|
114
|
+
return {
|
|
115
|
+
content: [{
|
|
116
|
+
type: 'text',
|
|
117
|
+
text: JSON.stringify({
|
|
118
|
+
configured,
|
|
119
|
+
status,
|
|
120
|
+
requiredVars: ['QUICKBASE_REALM_HOST', 'QUICKBASE_USER_TOKEN'],
|
|
121
|
+
optionalVars: ['QUICKBASE_APP_ID', 'QUICKBASE_CACHE_ENABLED', 'QUICKBASE_CACHE_TTL', 'DEBUG']
|
|
122
|
+
}, null, 2)
|
|
123
|
+
}]
|
|
124
|
+
};
|
|
117
125
|
});
|
|
118
|
-
|
|
126
|
+
// Register tools with MCP server if client is initialized
|
|
127
|
+
if (quickbaseClient) {
|
|
128
|
+
const tools = tools_1.toolRegistry.getAllTools();
|
|
129
|
+
tools.forEach(tool => {
|
|
130
|
+
const schema = (0, validation_1.createMcpZodSchema)(tool.paramSchema);
|
|
131
|
+
server.tool(tool.name, tool.description, schema, async (params) => {
|
|
132
|
+
try {
|
|
133
|
+
logger.info(`Executing MCP tool: ${tool.name}`);
|
|
134
|
+
const apiResponse = await tool.execute(params);
|
|
135
|
+
// Handle API response - only return the data if successful
|
|
136
|
+
if (!apiResponse.success || apiResponse.error) {
|
|
137
|
+
const errorMessage = apiResponse.error?.message || 'Tool execution failed';
|
|
138
|
+
logger.error(`Tool ${tool.name} failed`, { error: apiResponse.error });
|
|
139
|
+
throw new Error(errorMessage);
|
|
140
|
+
}
|
|
141
|
+
return {
|
|
142
|
+
content: [{
|
|
143
|
+
type: 'text',
|
|
144
|
+
text: JSON.stringify(apiResponse.data, null, 2)
|
|
145
|
+
}]
|
|
146
|
+
};
|
|
147
|
+
}
|
|
148
|
+
catch (error) {
|
|
149
|
+
logger.error(`Error executing MCP tool ${tool.name}`, { error });
|
|
150
|
+
throw error;
|
|
151
|
+
}
|
|
152
|
+
});
|
|
153
|
+
logger.info(`Registered MCP tool: ${tool.name}`);
|
|
154
|
+
});
|
|
155
|
+
logger.info(`Registered ${tools.length} Quickbase tools with MCP Server`);
|
|
156
|
+
}
|
|
157
|
+
else {
|
|
158
|
+
logger.info('No Quickbase tools registered (configuration missing)');
|
|
159
|
+
}
|
|
119
160
|
// Create stdio transport
|
|
120
161
|
const transport = new stdio_js_1.StdioServerTransport();
|
|
121
162
|
// Connect and run
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mcp-stdio-server.js","sourceRoot":"","sources":["../src/mcp-stdio-server.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAEA;;GAEG;AACH,oEAAoE;AACpE,wEAAiF;AACjF,oDAA4B;AAC5B,2CAA8C;AAC9C,kDAAqD;AAErD,yCAA6C;AAC7C,mCAAwD;AACxD,mDAAwD;AAExD,6BAA6B;AAC7B,gBAAM,CAAC,MAAM,EAAE,CAAC;AAEhB,MAAM,MAAM,GAAG,IAAA,qBAAY,EAAC,kBAAkB,CAAC,CAAC;AAGhD;;GAEG;AACH,KAAK,UAAU,IAAI;IACjB,IAAI,CAAC;QACH,4BAA4B;QAC5B,MAAM,MAAM,GAAG,IAAI,kBAAS,CAAC;YAC3B,IAAI,EAAE,sBAAsB;YAC5B,OAAO,EAAE,OAAO;SACjB,CAAC,CAAC;QAEH,MAAM,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC;QAElC,
|
|
1
|
+
{"version":3,"file":"mcp-stdio-server.js","sourceRoot":"","sources":["../src/mcp-stdio-server.ts"],"names":[],"mappings":"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"}
|