Register MCP Server
register_serverRegister an MCP server with configurable transport, alerts, and check interval to monitor its health and uptime.
Instructions
Register an MCP server to monitor. Supports http, sse, and stdio transports.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| name | Yes | Unique name for this MCP server | |
| type | Yes | Transport type: http (Streamable HTTP), sse (legacy SSE), stdio | |
| url | No | URL for http/sse servers (e.g. https://mcp-ssh-tool.onrender.com/mcp) | |
| command | No | Command for stdio servers (e.g. npx mcp-debug-recorder) | |
| args | No | Args for stdio command | |
| tags | No | Tags for grouping | |
| alert_on_down | No | Alert when server goes down | |
| check_interval_minutes | No |
Implementation Reference
- src/types.ts:13-31 (schema)Zod schema for register_server input validation: defines name, type (http/stdio/sse), url, command, args, tags, alert_on_down, and check_interval_minutes.
export const RegisterServerSchema = z.object({ name: z.string().min(1).max(100).describe('Unique name for this MCP server'), type: McpServerTypeSchema.describe( 'Transport type: http (Streamable HTTP), sse (legacy SSE), stdio' ), url: z .string() .url() .optional() .describe('URL for http/sse servers (e.g. https://mcp-ssh-tool.onrender.com/mcp)'), command: z .string() .optional() .describe('Command for stdio servers (e.g. npx mcp-debug-recorder)'), args: z.array(z.string()).default([]).describe('Args for stdio command'), tags: z.array(z.string()).default([]).describe('Tags for grouping'), alert_on_down: z.boolean().default(true).describe('Alert when server goes down'), check_interval_minutes: z.number().int().min(1).max(60).default(5) }); - src/app.ts:217-237 (registration)Tool registration: registers the 'register_server' tool with title, description, inputSchema (RegisterServerSchema), and handler invocation.
server.registerTool( 'register_server', { title: 'Register MCP Server', description: 'Register an MCP server to monitor. Supports http, sse, and stdio transports.', inputSchema: RegisterServerSchema, annotations: { readOnlyHint: false, destructiveHint: false, openWorldHint: false } }, async (input: RegisterServerInput) => { const result = registerServer(input); return formatResponse({ ...result, message: `${input.name} registered. Run check_server to verify connectivity.` }); } ); - src/registry.ts:122-162 (handler)Handler function: inserts/upserts server config into the database using SQLite (better-sqlite3), returns registered=true and the server name.
export function registerServer(input: RegisterServerInput): { registered: true; name: string } { const db = getDb(); const now = Date.now(); db.prepare( ` INSERT INTO servers ( name, type, url, command, args, tags, alert_on_down, check_interval_minutes, created_at ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?) ON CONFLICT(name) DO UPDATE SET type = excluded.type, url = excluded.url, command = excluded.command, args = excluded.args, tags = excluded.tags, alert_on_down = excluded.alert_on_down, check_interval_minutes = excluded.check_interval_minutes ` ).run( input.name, input.type, input.url ?? null, input.command ?? null, JSON.stringify(input.args), JSON.stringify(input.tags), input.alert_on_down ? 1 : 0, input.check_interval_minutes, now ); return { registered: true, name: input.name }; } - src/app.ts:57-230 (helper)Handler wrapper in app.ts: calls registerServer(input) and wraps result with a message via formatResponse.
} from './types.js'; type ToolResponse = { content: Array<{ type: 'text'; text: string; }>; }; type ToolConfig = { title?: string; description?: string; inputSchema?: object; annotations?: { readOnlyHint?: boolean; destructiveHint?: boolean; openWorldHint?: boolean; }; }; type ToolRegistrar = { registerTool: (name: string, config: ToolConfig, handler: unknown) => unknown; }; function formatResponse(payload: unknown): ToolResponse { return { content: [ { type: 'text', text: JSON.stringify(payload, null, 2) } ] }; } function formatTextResponse(text: string): ToolResponse { return { content: [ { type: 'text', text } ] }; } function buildErrorResult(error: unknown): CheckResult { return { status: 'error', response_time_ms: null, tool_count: null, error_message: error instanceof Error ? error.message : 'Unknown error', tools: null }; } function enrichWithAlerts( serverName: string, result: CheckResult, options: { hours?: number } = {} ): AlertEvaluation { return options.hours === undefined ? evaluateAlertState(serverName, result) : evaluateAlertState(serverName, result, { uptimeWindowHours: options.hours }); } function getLatestDashboardResult(server: Pick<RegisteredServer, 'name'>): CheckResult | null { const latest = getLatestHealthCheck(server.name); if (!latest) { return null; } return { status: latest.status, response_time_ms: latest.response_time_ms, tool_count: latest.tool_count, error_message: latest.error_message, tools: latest.tools_snapshot ? (JSON.parse(latest.tools_snapshot) as string[]) : null }; } function formatCurrentStatus(status: string): string { if (status === 'up') { return 'UP'; } if (status === 'unknown') { return 'UNKNOWN'; } return status.toUpperCase(); } function formatMetric(value: number | null, suffix = ''): string { return value === null ? '--' : `${value}${suffix}`; } function formatMarkdownReport(input: GetReportInput): string { const report = getDashboardReport(input.hours); const lines = [ '# MCP Health Report', '', `Generated: ${new Date().toISOString()}`, `Period: ${input.hours}h`, '', '| Server | Status | Uptime | Avg RT | P50 RT | P95 RT | Failures |', '| ------ | ------ | ------ | ------ | ------ | ------ | -------- |' ]; for (const entry of report) { lines.push( `| ${entry.name} | ${formatCurrentStatus(entry.current_status)} | ${formatMetric( entry.uptime_percent, '%' )} | ${formatMetric(entry.avg_response_time_ms, 'ms')} | ${formatMetric( entry.p50_response_time_ms, 'ms' )} | ${formatMetric(entry.p95_response_time_ms, 'ms')} | ${entry.consecutive_failures} |` ); } if (report.length === 0) { lines.push('| -- | -- | -- | -- | -- | -- | -- |'); } return lines.join('\n'); } export function registerMonitoringTools(server: ToolRegistrar): void { server.registerTool( 'register_azure_pipelines', { title: 'Register Azure DevOps Pipelines', description: 'Register Azure DevOps pipelines to monitor for CI, publish, and mirror status.', inputSchema: RegisterAzurePipelineSchema, annotations: { readOnlyHint: false, destructiveHint: false, openWorldHint: true } }, async (input: RegisterAzurePipelineInput) => { const available = await listPipelines(input.organization, input.project, input.pat_token); const resolved: Array<{ name: string; id: number | null }> = input.pipeline_names.map( (name: string) => ({ name, id: available.find((pipeline) => pipeline.name === name)?.id ?? null }) ); registerAzurePipelines(input, resolved); return formatResponse({ registered: true, group: input.name, pipelines: resolved.map((pipeline) => pipeline.name), resolved_ids: resolved }); } ); server.registerTool( 'register_server', { title: 'Register MCP Server', description: 'Register an MCP server to monitor. Supports http, sse, and stdio transports.', inputSchema: RegisterServerSchema, annotations: { readOnlyHint: false, destructiveHint: false, openWorldHint: false } }, async (input: RegisterServerInput) => { - src/types.ts:122-122 (schema)TypeScript type derived from the Zod schema for RegisterServerInput.
export type RegisterServerInput = z.infer<typeof RegisterServerSchema>;