@rashidazarang/airtable-mcp 1.6.0 โ 2.1.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/README.md +1 -0
- package/airtable_simple_production.js +532 -0
- package/package.json +15 -6
- package/.claude/settings.local.json +0 -12
- package/.github/ISSUE_TEMPLATE/bug_report.md +0 -38
- package/.github/ISSUE_TEMPLATE/custom.md +0 -10
- package/.github/ISSUE_TEMPLATE/feature_request.md +0 -20
- package/CAPABILITY_REPORT.md +0 -118
- package/CLAUDE_INTEGRATION.md +0 -96
- package/CONTRIBUTING.md +0 -81
- package/DEVELOPMENT.md +0 -190
- package/Dockerfile +0 -39
- package/Dockerfile.node +0 -20
- package/IMPROVEMENT_PROPOSAL.md +0 -371
- package/INSTALLATION.md +0 -183
- package/ISSUE_RESPONSES.md +0 -171
- package/MCP_REVIEW_SUMMARY.md +0 -142
- package/QUICK_START.md +0 -60
- package/RELEASE_NOTES_v1.2.0.md +0 -50
- package/RELEASE_NOTES_v1.2.1.md +0 -40
- package/RELEASE_NOTES_v1.2.2.md +0 -48
- package/RELEASE_NOTES_v1.2.3.md +0 -105
- package/RELEASE_NOTES_v1.2.4.md +0 -60
- package/RELEASE_NOTES_v1.4.0.md +0 -104
- package/RELEASE_NOTES_v1.5.0.md +0 -185
- package/RELEASE_NOTES_v1.6.0.md +0 -248
- package/SECURITY_NOTICE.md +0 -40
- package/airtable-mcp-1.1.0.tgz +0 -0
- package/airtable_enhanced.js +0 -499
- package/airtable_mcp/__init__.py +0 -5
- package/airtable_mcp/src/server.py +0 -329
- package/airtable_simple_v1.2.4_backup.js +0 -277
- package/airtable_v1.4.0.js +0 -654
- package/cleanup.sh +0 -71
- package/index.js +0 -179
- package/inspector.py +0 -148
- package/inspector_server.py +0 -337
- package/publish-steps.txt +0 -27
- package/quick_test.sh +0 -30
- package/rashidazarang-airtable-mcp-1.1.0.tgz +0 -0
- package/rashidazarang-airtable-mcp-1.2.0.tgz +0 -0
- package/rashidazarang-airtable-mcp-1.2.1.tgz +0 -0
- package/requirements.txt +0 -10
- package/setup.py +0 -29
- package/simple_airtable_server.py +0 -151
- package/smithery.yaml +0 -45
- package/test_all_features.sh +0 -146
- package/test_all_operations.sh +0 -120
- package/test_client.py +0 -70
- package/test_enhanced_features.js +0 -389
- package/test_mcp_comprehensive.js +0 -163
- package/test_mock_server.js +0 -180
- package/test_v1.4.0_final.sh +0 -131
- package/test_v1.5.0_comprehensive.sh +0 -96
- package/test_v1.5.0_final.sh +0 -224
- package/test_v1.6.0_comprehensive.sh +0 -187
- package/test_webhooks.sh +0 -105
package/cleanup.sh
DELETED
|
@@ -1,71 +0,0 @@
|
|
|
1
|
-
#!/bin/bash
|
|
2
|
-
|
|
3
|
-
echo "๐งน Airtable MCP Cleanup Script"
|
|
4
|
-
echo "=============================="
|
|
5
|
-
|
|
6
|
-
# Function to check if port is in use
|
|
7
|
-
check_port() {
|
|
8
|
-
if lsof -Pi :8010 -sTCP:LISTEN -t >/dev/null ; then
|
|
9
|
-
echo "โ ๏ธ Port 8010 is in use"
|
|
10
|
-
return 0
|
|
11
|
-
else
|
|
12
|
-
echo "โ
Port 8010 is free"
|
|
13
|
-
return 1
|
|
14
|
-
fi
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
# Function to kill processes on port 8010
|
|
18
|
-
kill_port() {
|
|
19
|
-
echo "๐ Killing processes on port 8010..."
|
|
20
|
-
lsof -ti:8010 | xargs kill -9 2>/dev/null
|
|
21
|
-
echo "โ
Port 8010 cleared"
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
# Function to clean up temporary files
|
|
25
|
-
cleanup_files() {
|
|
26
|
-
echo "๐งน Cleaning up temporary files..."
|
|
27
|
-
|
|
28
|
-
# Remove test files if they exist
|
|
29
|
-
if [ -f "test_mcp_comprehensive.js" ]; then
|
|
30
|
-
rm test_mcp_comprehensive.js
|
|
31
|
-
echo "โ
Removed test_mcp_comprehensive.js"
|
|
32
|
-
fi
|
|
33
|
-
|
|
34
|
-
if [ -f "quick_test.sh" ]; then
|
|
35
|
-
rm quick_test.sh
|
|
36
|
-
echo "โ
Removed quick_test.sh"
|
|
37
|
-
fi
|
|
38
|
-
|
|
39
|
-
if [ -f "MCP_REVIEW_SUMMARY.md" ]; then
|
|
40
|
-
rm MCP_REVIEW_SUMMARY.md
|
|
41
|
-
echo "โ
Removed MCP_REVIEW_SUMMARY.md"
|
|
42
|
-
fi
|
|
43
|
-
|
|
44
|
-
if [ -f "cleanup.sh" ]; then
|
|
45
|
-
rm cleanup.sh
|
|
46
|
-
echo "โ
Removed cleanup.sh"
|
|
47
|
-
fi
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
# Main cleanup process
|
|
51
|
-
echo "1. Checking port status..."
|
|
52
|
-
if check_port; then
|
|
53
|
-
echo "2. Clearing port 8010..."
|
|
54
|
-
kill_port
|
|
55
|
-
else
|
|
56
|
-
echo "2. Port is already free"
|
|
57
|
-
fi
|
|
58
|
-
|
|
59
|
-
echo "3. Cleaning up temporary files..."
|
|
60
|
-
cleanup_files
|
|
61
|
-
|
|
62
|
-
echo ""
|
|
63
|
-
echo "๐ Cleanup completed!"
|
|
64
|
-
echo ""
|
|
65
|
-
echo "To start the MCP server again:"
|
|
66
|
-
echo " node airtable_simple.js --token YOUR_TOKEN --base YOUR_BASE_ID"
|
|
67
|
-
echo ""
|
|
68
|
-
echo "To test the MCP:"
|
|
69
|
-
echo " npm run test"
|
|
70
|
-
|
|
71
|
-
|
package/index.js
DELETED
|
@@ -1,179 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
const path = require('path');
|
|
4
|
-
const { execSync } = require('child_process');
|
|
5
|
-
const { spawn } = require('child_process');
|
|
6
|
-
|
|
7
|
-
// Polyfill for AbortController in older Node.js versions
|
|
8
|
-
if (typeof globalThis.AbortController === 'undefined') {
|
|
9
|
-
globalThis.AbortController = class AbortController {
|
|
10
|
-
constructor() {
|
|
11
|
-
this.signal = {
|
|
12
|
-
aborted: false,
|
|
13
|
-
addEventListener: () => {},
|
|
14
|
-
removeEventListener: () => {},
|
|
15
|
-
dispatchEvent: () => true
|
|
16
|
-
};
|
|
17
|
-
}
|
|
18
|
-
abort() {
|
|
19
|
-
this.signal.aborted = true;
|
|
20
|
-
}
|
|
21
|
-
};
|
|
22
|
-
console.log('โน๏ธ Added AbortController polyfill for compatibility with older Node.js versions');
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
// Parse command-line arguments
|
|
26
|
-
const args = process.argv.slice(2);
|
|
27
|
-
let tokenIndex = args.indexOf('--token');
|
|
28
|
-
let baseIndex = args.indexOf('--base');
|
|
29
|
-
let configIndex = args.indexOf('--config');
|
|
30
|
-
|
|
31
|
-
// Extract token, base ID and config
|
|
32
|
-
const token = tokenIndex !== -1 && tokenIndex + 1 < args.length ? args[tokenIndex + 1] : null;
|
|
33
|
-
const baseId = baseIndex !== -1 && baseIndex + 1 < args.length ? args[baseIndex + 1] : null;
|
|
34
|
-
const config = configIndex !== -1 && configIndex + 1 < args.length ? args[configIndex + 1] : null;
|
|
35
|
-
|
|
36
|
-
console.log('๐ Airtable MCP - Connecting your AI to Airtable');
|
|
37
|
-
console.log('-----------------------------------------------');
|
|
38
|
-
|
|
39
|
-
// Find Python interpreter
|
|
40
|
-
const getPythonPath = () => {
|
|
41
|
-
try {
|
|
42
|
-
const whichPython = execSync('which python3.10').toString().trim();
|
|
43
|
-
return whichPython;
|
|
44
|
-
} catch (e) {
|
|
45
|
-
try {
|
|
46
|
-
const whichPython = execSync('which python3').toString().trim();
|
|
47
|
-
return whichPython;
|
|
48
|
-
} catch (e) {
|
|
49
|
-
return 'python';
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
};
|
|
53
|
-
|
|
54
|
-
// Check Python version
|
|
55
|
-
const checkPythonVersion = (pythonPath) => {
|
|
56
|
-
try {
|
|
57
|
-
const versionStr = execSync(`${pythonPath} --version`).toString().trim();
|
|
58
|
-
const versionMatch = versionStr.match(/Python (\d+)\.(\d+)/);
|
|
59
|
-
if (versionMatch) {
|
|
60
|
-
const major = parseInt(versionMatch[1]);
|
|
61
|
-
const minor = parseInt(versionMatch[2]);
|
|
62
|
-
return (major > 3 || (major === 3 && minor >= 10));
|
|
63
|
-
}
|
|
64
|
-
return false;
|
|
65
|
-
} catch (e) {
|
|
66
|
-
return false;
|
|
67
|
-
}
|
|
68
|
-
};
|
|
69
|
-
|
|
70
|
-
const pythonPath = getPythonPath();
|
|
71
|
-
|
|
72
|
-
// Verify Python compatibility
|
|
73
|
-
if (!checkPythonVersion(pythonPath)) {
|
|
74
|
-
console.error('โ Error: MCP SDK requires Python 3.10+');
|
|
75
|
-
console.error('Please install Python 3.10 or newer and try again.');
|
|
76
|
-
process.exit(1);
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
// We now use inspector_server.py instead of server.py
|
|
80
|
-
const serverScript = path.join(__dirname, 'inspector_server.py');
|
|
81
|
-
|
|
82
|
-
// Check if the script exists
|
|
83
|
-
try {
|
|
84
|
-
require('fs').accessSync(serverScript, require('fs').constants.F_OK);
|
|
85
|
-
} catch (e) {
|
|
86
|
-
console.error(`โ Error: Could not find server script at ${serverScript}`);
|
|
87
|
-
console.error('Please make sure you have the complete package installed.');
|
|
88
|
-
process.exit(1);
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
// Prepare arguments for the Python script
|
|
92
|
-
const scriptArgs = [serverScript];
|
|
93
|
-
if (token) {
|
|
94
|
-
scriptArgs.push('--token', token);
|
|
95
|
-
}
|
|
96
|
-
if (baseId) {
|
|
97
|
-
scriptArgs.push('--base', baseId);
|
|
98
|
-
}
|
|
99
|
-
if (config) {
|
|
100
|
-
scriptArgs.push('--config', config);
|
|
101
|
-
|
|
102
|
-
// Try to extract and log info from config
|
|
103
|
-
try {
|
|
104
|
-
const configObj = JSON.parse(config);
|
|
105
|
-
if (configObj.airtable_token) {
|
|
106
|
-
console.log('โ
Using API token from config');
|
|
107
|
-
}
|
|
108
|
-
if (configObj.base_id) {
|
|
109
|
-
console.log(`โ
Using base ID from config: ${configObj.base_id}`);
|
|
110
|
-
}
|
|
111
|
-
} catch (e) {
|
|
112
|
-
console.warn('โ ๏ธ Could not parse config JSON, attempting to sanitize...');
|
|
113
|
-
|
|
114
|
-
// Sanitize config JSON - fix common formatting issues
|
|
115
|
-
try {
|
|
116
|
-
// Remove any unexpected line breaks, extra quotes, and escape characters
|
|
117
|
-
const sanitizedConfig = config
|
|
118
|
-
.replace(/[\r\n]+/g, '')
|
|
119
|
-
.replace(/\\+"/g, '"')
|
|
120
|
-
.replace(/^"/, '')
|
|
121
|
-
.replace(/"$/, '')
|
|
122
|
-
.replace(/\\/g, '');
|
|
123
|
-
|
|
124
|
-
// Try parsing it
|
|
125
|
-
const configObj = JSON.parse(sanitizedConfig);
|
|
126
|
-
if (configObj) {
|
|
127
|
-
console.log('โ
Successfully sanitized config JSON');
|
|
128
|
-
// Update config with sanitized version
|
|
129
|
-
scriptArgs[scriptArgs.indexOf(config)] = sanitizedConfig;
|
|
130
|
-
config = sanitizedConfig;
|
|
131
|
-
|
|
132
|
-
if (configObj.airtable_token) {
|
|
133
|
-
console.log('โ
Using API token from sanitized config');
|
|
134
|
-
}
|
|
135
|
-
if (configObj.base_id) {
|
|
136
|
-
console.log(`โ
Using base ID from sanitized config: ${configObj.base_id}`);
|
|
137
|
-
}
|
|
138
|
-
}
|
|
139
|
-
} catch (sanitizeErr) {
|
|
140
|
-
console.warn('โ ๏ธ Could not sanitize config JSON, passing it directly to Python script');
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
|
-
} else {
|
|
144
|
-
if (token) {
|
|
145
|
-
console.log('โ
Using provided API token');
|
|
146
|
-
} else {
|
|
147
|
-
console.log('โ ๏ธ No API token provided, will try to use .env file');
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
if (baseId) {
|
|
151
|
-
console.log(`โ
Using base ID: ${baseId}`);
|
|
152
|
-
} else {
|
|
153
|
-
console.log('โน๏ธ No base ID provided, will need to set one later');
|
|
154
|
-
}
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
// Execute the Python script
|
|
158
|
-
const serverProcess = spawn(pythonPath, scriptArgs, {
|
|
159
|
-
stdio: 'inherit',
|
|
160
|
-
});
|
|
161
|
-
|
|
162
|
-
// Handle process exit
|
|
163
|
-
serverProcess.on('close', (code) => {
|
|
164
|
-
if (code !== 0) {
|
|
165
|
-
console.error(`โ Airtable MCP server exited with code ${code}`);
|
|
166
|
-
}
|
|
167
|
-
process.exit(code);
|
|
168
|
-
});
|
|
169
|
-
|
|
170
|
-
// Handle signals
|
|
171
|
-
process.on('SIGINT', () => {
|
|
172
|
-
console.log('\n๐ Shutting down Airtable MCP server...');
|
|
173
|
-
serverProcess.kill('SIGINT');
|
|
174
|
-
});
|
|
175
|
-
|
|
176
|
-
process.on('SIGTERM', () => {
|
|
177
|
-
console.log('\n๐ Shutting down Airtable MCP server...');
|
|
178
|
-
serverProcess.kill('SIGTERM');
|
|
179
|
-
});
|
package/inspector.py
DELETED
|
@@ -1,148 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env python3
|
|
2
|
-
"""
|
|
3
|
-
MCP Tool Inspector
|
|
4
|
-
-----------------
|
|
5
|
-
A simple script to list tools in a format Smithery can understand
|
|
6
|
-
"""
|
|
7
|
-
import json
|
|
8
|
-
|
|
9
|
-
# Define the tools manually
|
|
10
|
-
tools = [
|
|
11
|
-
{
|
|
12
|
-
"name": "list_bases",
|
|
13
|
-
"description": "List all accessible Airtable bases",
|
|
14
|
-
"parameters": {
|
|
15
|
-
"type": "object",
|
|
16
|
-
"properties": {},
|
|
17
|
-
"required": []
|
|
18
|
-
},
|
|
19
|
-
"returns": {
|
|
20
|
-
"type": "string"
|
|
21
|
-
}
|
|
22
|
-
},
|
|
23
|
-
{
|
|
24
|
-
"name": "list_tables",
|
|
25
|
-
"description": "List all tables in the specified base or the default base",
|
|
26
|
-
"parameters": {
|
|
27
|
-
"type": "object",
|
|
28
|
-
"properties": {
|
|
29
|
-
"base_id": {
|
|
30
|
-
"type": "string",
|
|
31
|
-
"description": "Optional base ID to use instead of the default"
|
|
32
|
-
}
|
|
33
|
-
},
|
|
34
|
-
"required": []
|
|
35
|
-
},
|
|
36
|
-
"returns": {
|
|
37
|
-
"type": "string"
|
|
38
|
-
}
|
|
39
|
-
},
|
|
40
|
-
{
|
|
41
|
-
"name": "list_records",
|
|
42
|
-
"description": "List records from a table with optional filtering",
|
|
43
|
-
"parameters": {
|
|
44
|
-
"type": "object",
|
|
45
|
-
"properties": {
|
|
46
|
-
"table_name": {
|
|
47
|
-
"type": "string",
|
|
48
|
-
"description": "Name of the table to list records from"
|
|
49
|
-
},
|
|
50
|
-
"max_records": {
|
|
51
|
-
"type": "integer",
|
|
52
|
-
"description": "Maximum number of records to return (default: 100)"
|
|
53
|
-
},
|
|
54
|
-
"filter_formula": {
|
|
55
|
-
"type": "string",
|
|
56
|
-
"description": "Optional Airtable formula to filter records"
|
|
57
|
-
}
|
|
58
|
-
},
|
|
59
|
-
"required": ["table_name"]
|
|
60
|
-
},
|
|
61
|
-
"returns": {
|
|
62
|
-
"type": "string"
|
|
63
|
-
}
|
|
64
|
-
},
|
|
65
|
-
{
|
|
66
|
-
"name": "get_record",
|
|
67
|
-
"description": "Get a specific record from a table",
|
|
68
|
-
"parameters": {
|
|
69
|
-
"type": "object",
|
|
70
|
-
"properties": {
|
|
71
|
-
"table_name": {
|
|
72
|
-
"type": "string",
|
|
73
|
-
"description": "Name of the table"
|
|
74
|
-
},
|
|
75
|
-
"record_id": {
|
|
76
|
-
"type": "string",
|
|
77
|
-
"description": "ID of the record to retrieve"
|
|
78
|
-
}
|
|
79
|
-
},
|
|
80
|
-
"required": ["table_name", "record_id"]
|
|
81
|
-
},
|
|
82
|
-
"returns": {
|
|
83
|
-
"type": "string"
|
|
84
|
-
}
|
|
85
|
-
},
|
|
86
|
-
{
|
|
87
|
-
"name": "create_records",
|
|
88
|
-
"description": "Create records in a table from JSON string",
|
|
89
|
-
"parameters": {
|
|
90
|
-
"type": "object",
|
|
91
|
-
"properties": {
|
|
92
|
-
"table_name": {
|
|
93
|
-
"type": "string",
|
|
94
|
-
"description": "Name of the table"
|
|
95
|
-
},
|
|
96
|
-
"records_json": {
|
|
97
|
-
"type": "string",
|
|
98
|
-
"description": "JSON string containing the records to create"
|
|
99
|
-
}
|
|
100
|
-
},
|
|
101
|
-
"required": ["table_name", "records_json"]
|
|
102
|
-
},
|
|
103
|
-
"returns": {
|
|
104
|
-
"type": "string"
|
|
105
|
-
}
|
|
106
|
-
},
|
|
107
|
-
{
|
|
108
|
-
"name": "update_records",
|
|
109
|
-
"description": "Update records in a table from JSON string",
|
|
110
|
-
"parameters": {
|
|
111
|
-
"type": "object",
|
|
112
|
-
"properties": {
|
|
113
|
-
"table_name": {
|
|
114
|
-
"type": "string",
|
|
115
|
-
"description": "Name of the table"
|
|
116
|
-
},
|
|
117
|
-
"records_json": {
|
|
118
|
-
"type": "string",
|
|
119
|
-
"description": "JSON string containing the records to update with IDs"
|
|
120
|
-
}
|
|
121
|
-
},
|
|
122
|
-
"required": ["table_name", "records_json"]
|
|
123
|
-
},
|
|
124
|
-
"returns": {
|
|
125
|
-
"type": "string"
|
|
126
|
-
}
|
|
127
|
-
},
|
|
128
|
-
{
|
|
129
|
-
"name": "set_base_id",
|
|
130
|
-
"description": "Set the current Airtable base ID",
|
|
131
|
-
"parameters": {
|
|
132
|
-
"type": "object",
|
|
133
|
-
"properties": {
|
|
134
|
-
"base_id": {
|
|
135
|
-
"type": "string",
|
|
136
|
-
"description": "Base ID to set as the current base"
|
|
137
|
-
}
|
|
138
|
-
},
|
|
139
|
-
"required": ["base_id"]
|
|
140
|
-
},
|
|
141
|
-
"returns": {
|
|
142
|
-
"type": "string"
|
|
143
|
-
}
|
|
144
|
-
}
|
|
145
|
-
]
|
|
146
|
-
|
|
147
|
-
# Print the tools as JSON
|
|
148
|
-
print(json.dumps({"tools": tools}, indent=2))
|