- deal-dashboard: Overview stats, won/lost ratio, revenue forecast - deal-detail: Full deal with products, activities, participants, timeline - deal-grid: Sortable deal list with filters - pipeline-kanban: Drag-drop pipeline board - pipeline-analytics: Conversion rates, velocity, bottleneck analysis - pipeline-funnel: Visual funnel with stage metrics - person-detail: Contact card with deals, activities, files - person-grid: Contact directory with search - org-detail: Organization with people, deals, activities - org-grid: Organization directory - activity-dashboard: Activity calendar/list with completion tracking - activity-calendar: Monthly calendar view - lead-inbox: Lead list with labels and quick actions - product-catalog: Product list with pricing - goal-tracker: Goals with progress bars - revenue-dashboard: Revenue analytics, forecasting - email-inbox: Mail threads with preview - deals-timeline: Timeline of deal progression - search-results: Universal search - won-deals: Closed-won deals celebration view All apps use React with dark theme. Self-contained with inline shared components. Each app has App.tsx, index.html, and vite.config.ts. Ports 3000-3019 for dev servers.
126 lines
3.8 KiB
TypeScript
126 lines
3.8 KiB
TypeScript
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
|
|
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
import {
|
|
CallToolRequestSchema,
|
|
ListToolsRequestSchema,
|
|
ListResourcesRequestSchema,
|
|
ReadResourceRequestSchema,
|
|
ErrorCode,
|
|
McpError,
|
|
} from '@modelcontextprotocol/sdk/types.js';
|
|
import { createClientFromEnv } from './clients/zendesk.js';
|
|
import { registerTicketsTools } from './tools/tickets-tools.js';
|
|
import { registerUsersTools } from './tools/users-tools.js';
|
|
import { registerOrganizationsTools } from './tools/organizations-tools.js';
|
|
import { registerGroupsTools } from './tools/groups-tools.js';
|
|
import { registerViewsTools } from './tools/views-tools.js';
|
|
import { registerMacrosTools } from './tools/macros-tools.js';
|
|
import { registerTriggersTools } from './tools/triggers-tools.js';
|
|
import { registerAutomationsTools } from './tools/automations-tools.js';
|
|
import { registerSLATools } from './tools/sla-tools.js';
|
|
import { registerBrandsTools } from './tools/brands-tools.js';
|
|
import { registerSearchTools } from './tools/search-tools.js';
|
|
import { registerSatisfactionTools } from './tools/satisfaction-tools.js';
|
|
import { registerSuspendedTicketsTools } from './tools/suspended-tickets-tools.js';
|
|
import { registerTagsTools } from './tools/tags-tools.js';
|
|
import { registerCustomFieldsTools } from './tools/custom-fields-tools.js';
|
|
|
|
export function createZendeskServer() {
|
|
const server = new Server(
|
|
{
|
|
name: 'zendesk-mcp-server',
|
|
version: '1.0.0',
|
|
},
|
|
{
|
|
capabilities: {
|
|
tools: {},
|
|
resources: {},
|
|
},
|
|
}
|
|
);
|
|
|
|
// Initialize Zendesk client
|
|
let client;
|
|
try {
|
|
client = createClientFromEnv();
|
|
} catch (error) {
|
|
console.error('Failed to initialize Zendesk client:', error);
|
|
throw error;
|
|
}
|
|
|
|
// Register all tools
|
|
const allTools = [
|
|
...registerTicketsTools(client),
|
|
...registerUsersTools(client),
|
|
...registerOrganizationsTools(client),
|
|
...registerGroupsTools(client),
|
|
...registerViewsTools(client),
|
|
...registerMacrosTools(client),
|
|
...registerTriggersTools(client),
|
|
...registerAutomationsTools(client),
|
|
...registerSLATools(client),
|
|
...registerBrandsTools(client),
|
|
...registerSearchTools(client),
|
|
...registerSatisfactionTools(client),
|
|
...registerSuspendedTicketsTools(client),
|
|
...registerTagsTools(client),
|
|
...registerCustomFieldsTools(client),
|
|
];
|
|
|
|
// Map of tool handlers by name
|
|
const toolHandlers = new Map(
|
|
allTools.map(tool => [tool.name, tool.handler])
|
|
);
|
|
|
|
// List tools handler
|
|
server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
return {
|
|
tools: allTools.map(tool => ({
|
|
name: tool.name,
|
|
description: tool.description,
|
|
inputSchema: tool.inputSchema,
|
|
})),
|
|
};
|
|
});
|
|
|
|
// Call tool handler
|
|
server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
const { name, arguments: args } = request.params;
|
|
|
|
const handler = toolHandlers.get(name);
|
|
if (!handler) {
|
|
throw new McpError(
|
|
ErrorCode.MethodNotFound,
|
|
`Unknown tool: ${name}`
|
|
);
|
|
}
|
|
|
|
try {
|
|
return await handler(args || {});
|
|
} catch (error) {
|
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
throw new McpError(
|
|
ErrorCode.InternalError,
|
|
`Tool execution failed: ${errorMessage}`
|
|
);
|
|
}
|
|
});
|
|
|
|
// List resources handler (for future app resources)
|
|
server.setRequestHandler(ListResourcesRequestSchema, async () => {
|
|
return {
|
|
resources: [],
|
|
};
|
|
});
|
|
|
|
// Read resource handler (for future app resources)
|
|
server.setRequestHandler(ReadResourceRequestSchema, async (request) => {
|
|
throw new McpError(
|
|
ErrorCode.InvalidRequest,
|
|
`Resource not found: ${request.params.uri}`
|
|
);
|
|
});
|
|
|
|
return server;
|
|
}
|