import 'dotenv/config';
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
import { z } from 'zod';
import { GHLApiClient } from './clients/ghl-api-client.js';
import { DEFAULT_GHL_BASE_URL, configSchema } from './config.js';
import { GHLMCPServer } from './server.js';
export { configSchema };
export type { SmitheryConfig } from './config.js';
interface CreateServerOptions {
config?: z.infer<typeof configSchema>;
}
export default function createServer({ config }: CreateServerOptions = {}) {
// Enhanced configuration resolution with Smithery support
let smitheryConfig: any = {};
if (process.env.SMITHERY_CONFIG) {
try {
smitheryConfig = JSON.parse(process.env.SMITHERY_CONFIG);
} catch (error) {
console.error('Failed to parse SMITHERY_CONFIG:', error);
}
}
const resolvedConfig = configSchema.parse({
ghlApiKey: config?.ghlApiKey ??
smitheryConfig.ghlApiKey ??
process.env.GHL_API_KEY ??
process.env.ghlApiKey,
ghlLocationId: config?.ghlLocationId ??
smitheryConfig.ghlLocationId ??
process.env.GHL_LOCATION_ID ??
process.env.ghlLocationId,
ghlBaseUrl: config?.ghlBaseUrl ??
smitheryConfig.ghlBaseUrl ??
process.env.GHL_BASE_URL ??
process.env.ghlBaseUrl ??
DEFAULT_GHL_BASE_URL,
});
// Validate required configuration early
if (!resolvedConfig.ghlApiKey || resolvedConfig.ghlApiKey.trim() === '') {
throw new Error('GHL_API_KEY is required and cannot be empty');
}
if (!resolvedConfig.ghlLocationId || resolvedConfig.ghlLocationId.trim() === '') {
throw new Error('GHL_LOCATION_ID is required and cannot be empty');
}
const server = new Server(
{
name: 'ghl-mcp-server',
version: '1.0.0',
},
{
capabilities: {
tools: {},
},
}
);
const ghlClient = new GHLApiClient({
accessToken: resolvedConfig.ghlApiKey,
baseUrl: resolvedConfig.ghlBaseUrl ?? DEFAULT_GHL_BASE_URL,
version: '2021-07-28',
locationId: resolvedConfig.ghlLocationId,
});
// Initialize the GHL MCP Server which sets up all tools and handlers
new GHLMCPServer({ server, ghlClient });
return server;
}