Skip to main content
Glama
createServer.ts19.3 kB
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'; import { z } from 'zod'; import { SpecifyStartSchema, SpecifyDescribeSchema, specifyStart, specifyDescribe, } from '../tools/specify.js'; import { PlanCreateSchema, planCreate, } from '../tools/plan.js'; import { TasksGenerateSchema, TasksTickSchema, tasksGenerate, tasksTick, } from '../tools/tasks.js'; import { QualityFormatSchema, QualityLintSchema, QualityTestSchema, QualitySecurityAuditSchema, QualityDepsUpdateSchema, QualityLicenseCheckSchema, qualityFormat, qualityLint, qualityTest, qualitySecurityAudit, qualityDepsUpdate, qualityLicenseCheck, } from '../tools/quality.js'; import { ArtifactsReadSchema, artifactsRead, } from '../tools/artifacts.js'; import { ResearchAppendSchema, researchAppend, } from '../tools/research.js'; import { GitCreateBranchSchema, gitCreateBranch, } from '../tools/git.js'; import { ConstitutionCreateSchema, constitutionCreate, } from '../tools/constitution.js'; import { ClarifyAddSchema, ClarifyResolveSchema, ClarifyListSchema, clarifyAdd, clarifyResolve, clarifyList, } from '../tools/clarify.js'; import { SpecValidateSchema, ArtifactsAnalyzeSchema, specValidate, artifactsAnalyze, } from '../tools/validate.js'; import { SpecRefineSchema, specRefine, } from '../tools/refine.js'; import { PrereqsCheckSchema, prereqsCheck, } from '../tools/prereqs.js'; import { TasksVisualizeSchema, tasksVisualize, } from '../tools/visualize.js'; import { TasksFilterSchema, tasksFilter, } from '../tools/filter.js'; import { TasksTickRangeSchema, tasksTickRange, } from '../tools/batch.js'; import { TasksSearchSchema, tasksSearch, } from '../tools/search.js'; import { TasksStatsSchema, tasksStats, } from '../tools/stats.js'; import { ContractsGenerateSchema, contractsGenerate, } from '../tools/contracts.js'; import { TemplatesListSchema, TemplatesCustomizeSchema, templatesList, templatesCustomize, } from '../tools/templates-mgmt.js'; import { MetricsReportSchema, MetricsExportSchema, metricsReport, metricsExport, } from '../tools/metrics.js'; import { SpecLintSchema, specLint, } from '../tools/lint.js'; import { registerPrompts } from './prompts.js'; /** * Server configuration schema */ export const ServerConfigSchema = z.object({ name: z.string().default('mcp-dincoder'), version: z.string().default('0.0.1'), capabilities: z.object({ tools: z.boolean().default(true), resources: z.boolean().default(false), prompts: z.boolean().default(true), }).default({}), }); export type ServerConfig = z.infer<typeof ServerConfigSchema>; /** * Creates and configures an MCP server instance */ export function createServer(config: Partial<ServerConfig> = {}): McpServer { const validatedConfig = ServerConfigSchema.parse(config); const server = new McpServer({ name: validatedConfig.name, version: validatedConfig.version, }); // Register capabilities if (validatedConfig.capabilities.tools) { registerTools(server); } if (validatedConfig.capabilities.resources) { registerResources(server); } if (validatedConfig.capabilities.prompts) { registerPrompts(server); } return server; } /** * Register MCP tools */ function registerTools(server: McpServer): void { // Spec Kit tools // Constitution tool - define project principles server.tool( 'constitution_create', 'Define project principles, constraints, and preferences that guide all AI-generated artifacts. Use this before specify_start to establish project guardrails.', ConstitutionCreateSchema.shape, async (params) => { return await constitutionCreate(ConstitutionCreateSchema.parse(params)); } ); // Clarification tools - track and resolve ambiguities server.tool( 'clarify_add', 'Flag ambiguities or questions in specifications that need clarification. Creates a tracked clarification with unique ID.', ClarifyAddSchema.shape, async (params) => { return await clarifyAdd(ClarifyAddSchema.parse(params)); } ); server.tool( 'clarify_resolve', 'Resolve a pending clarification with an answer. Updates spec.md and logs resolution in research.md.', ClarifyResolveSchema.shape, async (params) => { return await clarifyResolve(ClarifyResolveSchema.parse(params)); } ); server.tool( 'clarify_list', 'List all clarifications with optional status filter (pending/resolved/all). Useful for tracking progress.', ClarifyListSchema.shape, async (params) => { return await clarifyList(ClarifyListSchema.parse(params)); } ); server.tool( 'spec_validate', 'Check specification quality and completeness. Validates required sections, acceptance criteria, clarifications, and checks for premature implementation details.', SpecValidateSchema.shape, async (params) => { return await specValidate(SpecValidateSchema.parse(params)); } ); server.tool( 'artifacts_analyze', 'Analyze consistency across spec, plan, and tasks artifacts. Verifies that all artifacts are aligned and complete.', ArtifactsAnalyzeSchema.shape, async (params) => { return await artifactsAnalyze(ArtifactsAnalyzeSchema.parse(params)); } ); server.tool( 'spec_refine', 'Refine/update an existing specification. Supports updating specific sections (goals, requirements, acceptance, edge-cases) or the full spec. Changes are logged to research.md.', SpecRefineSchema.shape, async (params) => { return await specRefine(SpecRefineSchema.parse(params)); } ); server.tool( 'prereqs_check', 'Check environment prerequisites before project setup. Verifies Node.js version, npm, git, and custom commands are available.', PrereqsCheckSchema.shape, async (params) => { return await prereqsCheck(PrereqsCheckSchema.parse(params)); } ); server.tool( 'specify_start', 'Initialize a new spec-driven project. Creates .dincoder directory with spec.json template. Use this as the first step when starting a new project.', SpecifyStartSchema.shape, async (params) => { const result = await specifyStart(SpecifyStartSchema.parse(params)); return { content: [ { type: 'text', text: JSON.stringify(result, null, 2), }, ], }; } ); server.tool( 'specify_describe', 'Create or update project specification with detailed requirements, goals, and constraints. Use after specify_start to define what the project should do.', SpecifyDescribeSchema.shape, async (params) => { const result = await specifyDescribe(SpecifyDescribeSchema.parse(params)); return { content: [ { type: 'text', text: JSON.stringify(result, null, 2), }, ], }; } ); server.tool( 'plan_create', 'Generate technical implementation plan from the project specification. Creates a step-by-step technical approach with milestones and architecture decisions.', PlanCreateSchema.shape, async (params) => { const result = await planCreate(PlanCreateSchema.parse(params)); return { content: [ { type: 'text', text: JSON.stringify(result, null, 2), }, ], }; } ); server.tool( 'tasks_generate', 'Generate granular, actionable tasks from the technical plan. Creates a task list with specific implementation steps that can be executed sequentially.', TasksGenerateSchema.shape, async (params) => { const result = await tasksGenerate(TasksGenerateSchema.parse(params)); return { content: [ { type: 'text', text: JSON.stringify(result, null, 2), }, ], }; } ); server.tool( 'tasks_tick', 'Mark a specific task as complete by its ID. Updates the task status and tracks progress through the implementation.', TasksTickSchema.shape, async (params) => { const result = await tasksTick(TasksTickSchema.parse(params)); return { content: [ { type: 'text', text: JSON.stringify(result, null, 2), }, ], }; } ); server.tool( 'tasks_visualize', 'Generate visual dependency graphs from tasks.md. Supports Mermaid flowcharts, Graphviz DOT, and ASCII tree formats. Shows task dependencies, status colors, and optional phase grouping.', TasksVisualizeSchema.shape, async (params) => { const result = await tasksVisualize(TasksVisualizeSchema.parse(params)); return { content: [ { type: 'text', text: result, }, ], }; } ); server.tool( 'tasks_filter', 'Filter tasks by status, phase, type, priority, blockers, or tags. Includes smart presets (next, frontend, backend, ready, cleanup) for common workflows. Returns markdown-formatted task list.', TasksFilterSchema.shape, async (params) => { const result = await tasksFilter(TasksFilterSchema.parse(params)); return { content: [ { type: 'text', text: result, }, ], }; } ); server.tool( 'tasks_tick_range', 'Mark multiple tasks as complete at once. Supports array format ["T001", "T003"], range format "T001-T005", or mixed format. Includes strict mode for all-or-nothing completion.', TasksTickRangeSchema.shape, async (params) => { const result = await tasksTickRange(TasksTickRangeSchema.parse(params)); return { content: [ { type: 'text', text: result, }, ], }; } ); server.tool( 'tasks_search', 'Full-text search across task descriptions and metadata. Supports plain text, regex patterns, and fuzzy matching for typo tolerance. Returns ranked results with relevance scores.', TasksSearchSchema.shape, async (params) => { const result = await tasksSearch(TasksSearchSchema.parse(params)); return { content: [ { type: 'text', text: result, }, ], }; } ); server.tool( 'tasks_stats', 'Generate comprehensive task statistics and progress metrics. Provides insights on completion rates, phase/type distribution, priority breakdown, blocker analysis, and ASCII progress charts.', TasksStatsSchema.shape, async (params) => { const result = await tasksStats(TasksStatsSchema.parse(params)); return { content: [ { type: 'text', text: result, }, ], }; } ); // Contract generation tools server.tool( 'contracts_generate', 'Generate OpenAPI 3.1, GraphQL, or JSON Schema contracts from specifications. Supports automatic extraction from spec.md or TypeScript code using tsoa.', ContractsGenerateSchema.shape, async (params) => { const result = await contractsGenerate(ContractsGenerateSchema.parse(params)); return { content: [ { type: 'text', text: JSON.stringify(result, null, 2), }, ], }; } ); // Template management tools server.tool( 'templates_list', 'List all available templates (built-in and custom). Filter by category and discover customization points.', TemplatesListSchema.shape, async (params) => { const result = await templatesList(TemplatesListSchema.parse(params)); return { content: [ { type: 'text', text: JSON.stringify(result, null, 2), }, ], }; } ); server.tool( 'templates_customize', 'Create or update template customization with hooks, variable substitution, and inheritance. Supports before/after/transform/validate hooks.', TemplatesCustomizeSchema.shape, async (params) => { const result = await templatesCustomize(TemplatesCustomizeSchema.parse(params)); return { content: [ { type: 'text', text: JSON.stringify(result, null, 2), }, ], }; } ); // Metrics tools server.tool( 'metrics_report', 'Generate comprehensive metrics report with DORA and SPACE metrics. Tracks development velocity, cycle time, quality, and trends using Git history for timestamps.', MetricsReportSchema.shape, async (params) => { const result = await metricsReport(MetricsReportSchema.parse(params)); return { content: [ { type: 'text', text: result.formattedReport || JSON.stringify(result, null, 2), }, ], }; } ); server.tool( 'metrics_export', 'Export metrics to CSV or JSON format for external analysis. Includes DORA metrics, cycle time, quality metrics, and custom date ranges.', MetricsExportSchema.shape, async (params) => { const result = await metricsExport(MetricsExportSchema.parse(params)); return { content: [ { type: 'text', text: JSON.stringify(result, null, 2), }, ], }; } ); // Linting tools server.tool( 'spec_lint', 'Automated spec quality checking with markdownlint, spec-specific rules, and prose quality analysis. Checks for required sections, acceptance criteria format, passive voice, vague language, and more. Supports auto-fix for simple issues.', SpecLintSchema.shape, async (params) => { const result = await specLint(SpecLintSchema.parse(params)); return { content: [ { type: 'text', text: result.report || JSON.stringify(result, null, 2), }, ], }; } ); // Quality tools server.tool( 'quality_format', 'Run Prettier code formatter to ensure consistent code style. Automatically formats JavaScript, TypeScript, JSON, and other supported files.', QualityFormatSchema.shape, async (params) => { const result = await qualityFormat(QualityFormatSchema.parse(params)); return { content: [ { type: 'text', text: JSON.stringify(result, null, 2), }, ], }; } ); server.tool( 'quality_lint', 'Run ESLint to check for code quality issues, potential bugs, and style violations. Helps maintain code standards and catch errors early.', QualityLintSchema.shape, async (params) => { const result = await qualityLint(QualityLintSchema.parse(params)); return { content: [ { type: 'text', text: JSON.stringify(result, null, 2), }, ], }; } ); server.tool( 'quality_test', 'Run test suite with optional code coverage reporting. Executes all unit and integration tests to ensure code correctness.', QualityTestSchema.shape, async (params) => { const result = await qualityTest(QualityTestSchema.parse(params)); return { content: [ { type: 'text', text: JSON.stringify(result, null, 2), }, ], }; } ); server.tool( 'quality_security_audit', 'Run npm/yarn security audit to check for known vulnerabilities in dependencies. Identifies and reports security issues that need attention.', QualitySecurityAuditSchema.shape, async (params) => { const result = await qualitySecurityAudit(QualitySecurityAuditSchema.parse(params)); return { content: [ { type: 'text', text: JSON.stringify(result, null, 2), }, ], }; } ); server.tool( 'quality_deps_update', 'Check for available updates to project dependencies. Lists outdated packages and their latest versions for potential upgrades.', QualityDepsUpdateSchema.shape, async (params) => { const result = await qualityDepsUpdate(QualityDepsUpdateSchema.parse(params)); return { content: [ { type: 'text', text: JSON.stringify(result, null, 2), }, ], }; } ); server.tool( 'quality_license_check', 'Analyze licenses of all dependencies to ensure compatibility with project requirements. Identifies potential licensing conflicts or restrictions.', QualityLicenseCheckSchema.shape, async (params) => { const result = await qualityLicenseCheck(QualityLicenseCheckSchema.parse(params)); return { content: [ { type: 'text', text: JSON.stringify(result, null, 2), }, ], }; } ); // Artifacts tools server.tool( 'artifacts_read', 'Read and return the current state of spec.json, plan.json, or tasks.json files. Use to retrieve project artifacts in normalized JSON format.', ArtifactsReadSchema.shape, async (params) => { const result = await artifactsRead(ArtifactsReadSchema.parse(params)); return { content: [ { type: 'text', text: JSON.stringify(result, null, 2), }, ], }; } ); // Research tools server.tool( 'research_append', 'Append technical decisions, trade-offs, and research findings to the research.md document. Maintains a record of architectural choices and reasoning.', ResearchAppendSchema.shape, async (params) => { const result = await researchAppend(ResearchAppendSchema.parse(params)); return { content: [ { type: 'text', text: JSON.stringify(result, null, 2), }, ], }; } ); // Git tools server.tool( 'git_create_branch', 'Create a new Git branch for implementing a specific feature or fix. Follows naming conventions and ensures clean branch creation from main/master.', GitCreateBranchSchema.shape, async (params) => { const result = await gitCreateBranch(GitCreateBranchSchema.parse(params)); return { content: [ { type: 'text', text: JSON.stringify(result, null, 2), }, ], }; } ); // Keep test tool for compatibility server.tool( 'test_echo', 'Simple echo tool for testing MCP server connectivity. Returns the input message prefixed with "Echo:". Use for debugging and connection verification.', { message: z.string().describe('Message to echo'), }, async ({ message }) => { return { content: [ { type: 'text', text: `Echo: ${message}`, }, ], }; } ); } /** * Register MCP resources */ function registerResources(_server: McpServer): void { // TODO: Implement resource handlers if needed } // Note: registerPrompts is imported from './prompts.js' at the top of this file

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/flight505/MCP_DinCoder'

If you have feedback or need assistance with the MCP directory API, please join our Discord server