- Greenhouse: 29 tools (was 18), added interviews, scorecards, organization - Lever: 26 tools (was 13), added tags, sources, expanded opportunities/postings - Loom: 25 tools (was 14), added analytics, privacy, search, workspace members All servers now have: - main.ts with env validation & graceful shutdown - server.ts with lazy-loaded tool modules - Zod validation on all inputs - Rich tool descriptions (when/why to use) - Pagination support on all list_* tools - Updated package.json (bin field, updated deps) - Updated README with coverage manifests - Old index.ts renamed to index.ts.bak - Zero TypeScript errors (npx tsc --noEmit verified)
83 lines
2.3 KiB
JavaScript
83 lines
2.3 KiB
JavaScript
#!/usr/bin/env node
|
|
|
|
/**
|
|
* Webflow MCP Server - Entry Point
|
|
* Provides tools for managing Webflow sites, CMS collections, pages, forms, assets, and webhooks
|
|
*/
|
|
|
|
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
import { WebflowMCPServer } from './server.js';
|
|
import { WebflowClient } from './client/webflow-client.js';
|
|
|
|
// Environment validation
|
|
const WEBFLOW_API_TOKEN = process.env.WEBFLOW_API_TOKEN;
|
|
|
|
if (!WEBFLOW_API_TOKEN) {
|
|
console.error('ERROR: WEBFLOW_API_TOKEN environment variable is required');
|
|
console.error('');
|
|
console.error('Get your API token from:');
|
|
console.error('1. Log in to https://webflow.com');
|
|
console.error('2. Go to Workspace Settings > Apps & Integrations');
|
|
console.error('3. Generate a new API token with required scopes');
|
|
console.error('');
|
|
console.error('Then set it in your environment:');
|
|
console.error(' export WEBFLOW_API_TOKEN="your_token_here"');
|
|
console.error('');
|
|
process.exit(1);
|
|
}
|
|
|
|
// Create API client
|
|
const client = new WebflowClient(WEBFLOW_API_TOKEN);
|
|
|
|
// Create MCP server
|
|
const server = new WebflowMCPServer(client);
|
|
|
|
// Create transport
|
|
const transport = new StdioServerTransport();
|
|
|
|
// Graceful shutdown handlers
|
|
let isShuttingDown = false;
|
|
|
|
const shutdown = async (signal: string) => {
|
|
if (isShuttingDown) return;
|
|
isShuttingDown = true;
|
|
|
|
console.error(`\nReceived ${signal}, shutting down gracefully...`);
|
|
|
|
try {
|
|
await transport.close();
|
|
console.error('Transport closed successfully');
|
|
} catch (error) {
|
|
console.error('Error during shutdown:', error);
|
|
}
|
|
|
|
process.exit(0);
|
|
};
|
|
|
|
process.on('SIGINT', () => shutdown('SIGINT'));
|
|
process.on('SIGTERM', () => shutdown('SIGTERM'));
|
|
|
|
// Global error handlers
|
|
process.on('uncaughtException', (error) => {
|
|
console.error('Uncaught exception:', error);
|
|
shutdown('uncaughtException');
|
|
});
|
|
|
|
process.on('unhandledRejection', (reason, promise) => {
|
|
console.error('Unhandled rejection at:', promise, 'reason:', reason);
|
|
});
|
|
|
|
// Start server
|
|
async function main() {
|
|
try {
|
|
await server.connect(transport);
|
|
console.error('Webflow MCP server running on stdio');
|
|
console.error(`Environment: ${process.env.NODE_ENV || 'production'}`);
|
|
} catch (error) {
|
|
console.error('Failed to start server:', error);
|
|
process.exit(1);
|
|
}
|
|
}
|
|
|
|
main();
|