@vostride/agent-qa-mcp 0.1.14 → 0.1.15
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +11 -7
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +12 -7
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
package/dist/index.cjs
CHANGED
|
@@ -342,17 +342,21 @@ function classifyRunFailureFromDashboardData(input) {
|
|
|
342
342
|
};
|
|
343
343
|
}
|
|
344
344
|
function maskSensitive(value, parentKey = "") {
|
|
345
|
+
const authRedacted = (0, import_agent_qa_core2.redactAuthStateValue)(value);
|
|
345
346
|
const lower = parentKey.toLowerCase();
|
|
346
|
-
if (typeof
|
|
347
|
-
return
|
|
347
|
+
if (typeof authRedacted === "string" && authRedacted !== value) {
|
|
348
|
+
return authRedacted;
|
|
348
349
|
}
|
|
349
|
-
if (
|
|
350
|
-
|
|
350
|
+
if (typeof authRedacted === "string" && (lower.includes("key") || lower.includes("token") || lower.includes("secret") || lower.includes("password"))) {
|
|
351
|
+
return authRedacted.length > 8 ? `${authRedacted.slice(0, 3)}****${authRedacted.slice(-4)}` : "****";
|
|
352
|
+
}
|
|
353
|
+
if (Array.isArray(authRedacted)) return authRedacted.map((item) => maskSensitive(item, parentKey));
|
|
354
|
+
if (authRedacted && typeof authRedacted === "object") {
|
|
351
355
|
return Object.fromEntries(
|
|
352
|
-
Object.entries(
|
|
356
|
+
Object.entries(authRedacted).map(([key, child]) => [key, maskSensitive(child, key)])
|
|
353
357
|
);
|
|
354
358
|
}
|
|
355
|
-
return
|
|
359
|
+
return authRedacted;
|
|
356
360
|
}
|
|
357
361
|
async function readConfig(configPath) {
|
|
358
362
|
const path = (0, import_node_path.resolve)(configPath ?? "agent-qa.config.yaml");
|
|
@@ -449,7 +453,7 @@ function createAgentQaMcpServer(options = {}) {
|
|
|
449
453
|
method,
|
|
450
454
|
body
|
|
451
455
|
});
|
|
452
|
-
return jsonContent(result);
|
|
456
|
+
return jsonContent((0, import_agent_qa_core2.redactAuthStateValue)(result));
|
|
453
457
|
} catch (err) {
|
|
454
458
|
return errorContent(err instanceof Error ? err.message : String(err));
|
|
455
459
|
}
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/server.ts","../src/agent-qa-server.ts","../src/schema-reference.ts","../src/local-http.ts"],"sourcesContent":["export { MCP_STDIO_STARTUP_MESSAGE, createMcpServer, startMcpServer } from './server.js'\nexport type { StartMcpServerOptions } from './server.js'\nexport {\n AGENT_QA_SCHEMA_REFERENCES,\n classifyRunFailureFromDashboardData,\n resolveDashboardApiUrl,\n createAgentQaMcpServer,\n validateAgentQaDefinition,\n} from './agent-qa-server.js'\nexport type {\n AgentQaMcpServerOptions,\n FailureCategory,\n FailureClassification,\n} from './agent-qa-server.js'\nexport {\n SCHEMA_REFERENCE_NAMES,\n VALIDATION_KINDS,\n} from './schema-reference.js'\nexport type {\n DefinitionValidationResult,\n SchemaReferenceName,\n ValidationKind,\n ValidationIssue,\n} from './schema-reference.js'\nexport {\n DEFAULT_MCP_HOST,\n DEFAULT_MCP_PATH,\n DEFAULT_MCP_PORT,\n createLocalMcpHttpHandler,\n resolveLocalMcpEndpoint,\n resolveMcpEndpointShape,\n} from './local-http.js'\nexport type {\n LocalMcpEndpointConfig,\n LocalMcpEndpoint,\n LocalMcpEndpointShape,\n LocalMcpTransport,\n McpHttpHandlerOptions,\n} from './local-http.js'\n","import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'\nimport {\n buildAnalyticsEvent,\n captureAnalytics,\n resolveAnalyticsStandardProperties,\n} from '@vostride/agent-qa-core'\nimport { createAgentQaMcpServer, type AgentQaMcpServerOptions } from './agent-qa-server.js'\n\nexport const MCP_STDIO_STARTUP_MESSAGE =\n 'agent-qa MCP server running over stdio. Waiting for MCP client messages on stdin. Stdout is reserved for MCP protocol traffic.'\n\nexport interface StartMcpServerOptions extends AgentQaMcpServerOptions {\n startupOutput?: Pick<NodeJS.WritableStream, 'write'>\n}\n\nexport function createMcpServer(options: AgentQaMcpServerOptions = {}) {\n return createAgentQaMcpServer(options)\n}\n\nexport async function startMcpServer(options: StartMcpServerOptions = {}): Promise<void> {\n const { startupOutput, ...serverOptions } = options\n const server = createMcpServer({ ...serverOptions, transport: 'stdio' })\n const transport = new StdioServerTransport()\n await server.connect(transport)\n try {\n startupOutput?.write(`${MCP_STDIO_STARTUP_MESSAGE}\\n`)\n } catch {\n // Startup visibility is best-effort; the MCP server is already connected.\n }\n try {\n if (options.analyticsConfig?.analytics?.privacy !== true) {\n const standardProperties = options.analyticsStandardProperties\n ?? await resolveAnalyticsStandardProperties({ surface: 'mcp' })\n const event = buildAnalyticsEvent({\n name: 'agent-qa.mcp.server.lifecycle',\n properties: {\n ...standardProperties,\n surface: standardProperties.surface ?? 'mcp',\n mcp_server_state: 'started',\n mcp_transport: 'stdio',\n },\n })\n if (options.analyticsService) {\n await options.analyticsService.capture(event).catch(() => {})\n } else {\n await captureAnalytics(event, {\n config: options.analyticsConfig,\n surface: 'mcp',\n }).catch(() => {})\n }\n }\n } catch {\n // MCP startup analytics is intentionally best-effort.\n }\n}\n","import { readFile } from 'node:fs/promises'\nimport { resolve } from 'node:path'\nimport { McpServer, type ToolCallback } from '@modelcontextprotocol/sdk/server/mcp.js'\nimport type { AnySchema, ZodRawShapeCompat } from '@modelcontextprotocol/sdk/server/zod-compat.js'\nimport type { ToolAnnotations } from '@modelcontextprotocol/sdk/types.js'\nimport {\n AgentQaConfigSchema,\n buildAnalyticsEvent,\n captureAnalytics,\n createAnalyticsService,\n getAgentQaVersion,\n resolveAnalyticsStandardProperties,\n type AnalyticsEventProperties,\n type AnalyticsService,\n type AnalyticsServiceConfig,\n} from '@vostride/agent-qa-core'\nimport {\n ENTITY_ID_TYPES,\n generateCanonicalId,\n getEntityIdContract,\n getEntityIdContracts,\n isCanonicalId,\n} from '@vostride/agent-qa-ids'\nimport { parse as parseYaml } from 'yaml'\nimport { z } from 'zod'\nimport {\n AGENT_QA_SCHEMA_REFERENCES,\n SCHEMA_REFERENCE_NAMES,\n VALIDATION_KINDS,\n validateAgentQaDefinition,\n type SchemaReferenceName,\n type ValidationKind,\n} from './schema-reference.js'\n\nexport interface AgentQaMcpServerOptions {\n configPath?: string\n dashboardUrl?: string\n endpointUrl?: string\n analyticsService?: AnalyticsService\n analyticsConfig?: AnalyticsServiceConfig\n analyticsStandardProperties?: AnalyticsEventProperties\n transport?: 'stdio' | 'http'\n}\n\ntype McpToolCategory = NonNullable<AnalyticsEventProperties['mcp_tool_category']>\ntype McpErrorCategory = NonNullable<AnalyticsEventProperties['mcp_error_category']>\ntype McpToolDefinition<\n OutputArgs extends ZodRawShapeCompat | AnySchema = ZodRawShapeCompat,\n InputArgs extends undefined | ZodRawShapeCompat | AnySchema = undefined,\n> = {\n title?: string\n description?: string\n inputSchema?: InputArgs\n outputSchema?: OutputArgs\n annotations?: ToolAnnotations\n _meta?: Record<string, unknown>\n}\n\nconst DISCOVERY = {\n name: 'agent-qa',\n purpose: 'Author, validate, run, and triage agent-qa tests through local trusted MCP.',\n tools: [\n 'agent_qa_discover',\n 'agent_qa_get_config',\n 'agent_qa_schema_reference',\n 'agent_qa_validate_definition',\n 'agent_qa_generate_id',\n 'agent_qa_validate_id',\n 'agent_qa_list_tests',\n 'agent_qa_read_test',\n 'agent_qa_validate_test',\n 'agent_qa_create_test',\n 'agent_qa_update_test',\n 'agent_qa_delete_test',\n 'agent_qa_list_suites',\n 'agent_qa_read_suite',\n 'agent_qa_validate_suite',\n 'agent_qa_create_suite',\n 'agent_qa_update_suite',\n 'agent_qa_delete_suite',\n 'agent_qa_list_hooks',\n 'agent_qa_read_hook',\n 'agent_qa_create_hook',\n 'agent_qa_update_hook',\n 'agent_qa_delete_hook',\n 'agent_qa_run_hook',\n 'agent_qa_enqueue_test_run',\n 'agent_qa_enqueue_suite_run',\n 'agent_qa_get_run',\n 'agent_qa_get_run_steps',\n 'agent_qa_get_run_logs',\n 'agent_qa_get_run_execution_logs',\n 'agent_qa_get_run_artifact',\n 'agent_qa_cancel_run',\n 'agent_qa_classify_failure',\n ],\n resources: SCHEMA_REFERENCE_NAMES.map(name => `agent-qa://schema/${name}`),\n prompts: ['agent_qa_authoring_context'],\n phases: {\n current: 'discovery-schema-id-contracts',\n next: ['authoring tools', 'run execution and triage tools'],\n },\n}\n\nfunction jsonContent(value: unknown) {\n return {\n content: [{\n type: 'text' as const,\n text: JSON.stringify(value, null, 2),\n }],\n }\n}\n\nfunction errorContent(message: string) {\n return {\n isError: true,\n content: [{\n type: 'text' as const,\n text: message,\n }],\n }\n}\n\nexport function categorizeMcpTool(name: string): McpToolCategory {\n if (name === 'agent_qa_discover') return 'discovery'\n if (name.includes('schema') || name.includes('definition') || name.includes('config')) return 'schema'\n if (name.includes('_id')) return 'id'\n if (name.includes('_hook')) return 'hook'\n if (name.includes('classify')) return 'triage'\n if (name.includes('_run') || name.includes('_logs') || name.includes('_artifact') || name.includes('_fix') || name.includes('_failure')) return 'run'\n if (name.includes('_test') || name.includes('_suite')) return 'authoring'\n return 'unknown'\n}\n\nfunction isErrorResult(value: unknown): boolean {\n return Boolean(value && typeof value === 'object' && (value as { isError?: unknown }).isError === true)\n}\n\nfunction isDashboardErrorResult(value: unknown): boolean {\n const parsed = parseToolJsonContent(value)\n return Boolean(parsed && typeof parsed === 'object' && (parsed as Record<string, unknown>).ok === false)\n}\n\nfunction parseToolJsonContent(value: unknown): unknown {\n if (!value || typeof value !== 'object') return undefined\n const content = (value as { content?: unknown }).content\n if (!Array.isArray(content)) return undefined\n const firstText = content.find(item =>\n item && typeof item === 'object'\n && (item as { type?: unknown }).type === 'text'\n && typeof (item as { text?: unknown }).text === 'string'\n ) as { text: string } | undefined\n if (!firstText) return undefined\n try {\n return JSON.parse(firstText.text)\n } catch {\n return undefined\n }\n}\n\nexport function categorizeMcpError(errOrResult: unknown): McpErrorCategory {\n if (errOrResult instanceof z.ZodError) return 'validation'\n const parsed = parseToolJsonContent(errOrResult)\n const candidate = parsed && typeof parsed === 'object'\n ? parsed as Record<string, unknown>\n : undefined\n if (candidate && candidate.ok === false) return 'dashboard_error'\n if (errOrResult instanceof Error) return 'tool_error'\n if (isErrorResult(errOrResult)) return 'tool_error'\n return 'unknown'\n}\n\nexport function extractExplicitCanonicalRunId(input: unknown): string | undefined {\n if (!input || typeof input !== 'object' || Array.isArray(input)) return undefined\n const runId = (input as Record<string, unknown>).runId\n return typeof runId === 'string' && isCanonicalId('run', runId) ? runId : undefined\n}\n\nexport function extractSuccessfulEnqueueRunId(result: unknown): string | undefined {\n if (isErrorResult(result)) return undefined\n const parsed = parseToolJsonContent(result)\n const container = parsed && typeof parsed === 'object'\n ? parsed as Record<string, unknown>\n : undefined\n if (!container) return undefined\n const body = container.body && typeof container.body === 'object'\n ? container.body as Record<string, unknown>\n : container\n for (const key of ['runId', 'id', 'parentRunId']) {\n const value = body[key]\n if (typeof value === 'string' && isCanonicalId('run', value)) return value\n }\n return undefined\n}\n\nexport function resolveDashboardApiUrl(dashboardUrl: string, apiPath: string): string {\n const base = dashboardUrl.endsWith('/') ? dashboardUrl : `${dashboardUrl}/`\n const normalizedPath = apiPath.startsWith('/') ? apiPath.slice(1) : apiPath\n return new URL(normalizedPath, base).toString()\n}\n\nfunction withQuery(path: string, query: Record<string, string | number | boolean | undefined>): string {\n const params = new URLSearchParams()\n for (const [key, value] of Object.entries(query)) {\n if (value !== undefined) params.set(key, String(value))\n }\n const queryString = params.toString()\n return queryString ? `${path}?${queryString}` : path\n}\n\nasync function callDashboardApi(input: {\n dashboardUrl: string\n path: string\n method?: 'GET' | 'POST' | 'PUT' | 'DELETE'\n body?: unknown\n}): Promise<{\n ok: boolean\n status: number\n body: unknown\n}> {\n const response = await fetch(resolveDashboardApiUrl(input.dashboardUrl, input.path), {\n method: input.method ?? 'GET',\n headers: input.body === undefined ? undefined : { 'content-type': 'application/json' },\n body: input.body === undefined ? undefined : JSON.stringify(input.body),\n })\n const text = await response.text()\n let body: unknown = null\n if (text.length > 0) {\n try {\n body = JSON.parse(text)\n } catch {\n body = text\n }\n }\n\n return {\n ok: response.ok,\n status: response.status,\n body,\n }\n}\n\nexport type FailureCategory =\n | 'passed'\n | 'timeout'\n | 'appium_startup'\n | 'browser_disconnect'\n | 'element_not_found'\n | 'assertion_failure'\n | 'hook_failure'\n | 'infrastructure'\n | 'unknown_failure'\n\nexport interface FailureClassification {\n category: FailureCategory\n confidence: number\n evidence: string[]\n recentRelatedCount: number\n}\n\nfunction collectStrings(value: unknown, output: string[] = [], limit = 80): string[] {\n if (output.length >= limit) return output\n if (typeof value === 'string' && value.trim().length > 0) {\n output.push(value)\n } else if (Array.isArray(value)) {\n for (const item of value) collectStrings(item, output, limit)\n } else if (value && typeof value === 'object') {\n for (const child of Object.values(value as Record<string, unknown>)) collectStrings(child, output, limit)\n }\n return output\n}\n\nfunction classifyByNeedle(\n haystack: string,\n evidence: string[],\n needles: string[],\n category: FailureCategory,\n confidence: number,\n): FailureClassification | null {\n const match = needles.find(needle => haystack.includes(needle))\n if (!match) return null\n const matchingEvidence = evidence.find(item => item.toLowerCase().includes(match)) ?? evidence[0] ?? match\n return {\n category,\n confidence,\n evidence: [matchingEvidence].filter(Boolean).slice(0, 5),\n recentRelatedCount: 0,\n }\n}\n\nexport function classifyRunFailureFromDashboardData(input: {\n runDetail: unknown\n artifact?: unknown\n logs?: unknown\n executionLogs?: unknown\n recentRuns?: unknown\n}): FailureClassification {\n const run = input.runDetail && typeof input.runDetail === 'object'\n ? (input.runDetail as Record<string, unknown>).run\n : undefined\n const status = run && typeof run === 'object'\n ? (run as Record<string, unknown>).status\n : undefined\n const evidence = collectStrings([input.runDetail, input.artifact, input.logs, input.executionLogs])\n const haystack = evidence.join('\\n').toLowerCase()\n const recentRelatedCount = Array.isArray((input.recentRuns as Record<string, unknown> | undefined)?.runs)\n ? ((input.recentRuns as Record<string, unknown>).runs as unknown[]).length\n : 0\n\n if (status && status !== 'failed') {\n return {\n category: 'passed',\n confidence: 0.95,\n evidence: [`Run status is ${String(status)}.`],\n recentRelatedCount,\n }\n }\n\n const checks: Array<[string[], FailureCategory, number]> = [\n [['timed out', 'timeout'], 'timeout', 0.9],\n [['appium server failed', 'appium'], 'appium_startup', 0.9],\n [['browser closed', 'target page, context or browser has been closed', 'browser disconnect'], 'browser_disconnect', 0.85],\n [['hook_not_runnable', 'hook failed', 'hook registry', 'hook'], 'hook_failure', 0.8],\n [['not found', 'no element', 'strict mode violation', 'selector'], 'element_not_found', 0.8],\n [['assert', 'expected', 'verify'], 'assertion_failure', 0.75],\n [['econnrefused', 'enotfound', 'network', 'docker'], 'infrastructure', 0.7],\n ]\n\n for (const [needles, category, confidence] of checks) {\n const result = classifyByNeedle(haystack, evidence, needles, category, confidence)\n if (result) return { ...result, recentRelatedCount }\n }\n\n return {\n category: 'unknown_failure',\n confidence: 0.3,\n evidence: evidence.slice(0, 5),\n recentRelatedCount,\n }\n}\n\nfunction maskSensitive(value: unknown, parentKey = ''): unknown {\n const lower = parentKey.toLowerCase()\n if (typeof value === 'string' && (\n lower.includes('key')\n || lower.includes('token')\n || lower.includes('secret')\n || lower.includes('password')\n )) {\n return value.length > 8 ? `${value.slice(0, 3)}****${value.slice(-4)}` : '****'\n }\n if (Array.isArray(value)) return value.map(item => maskSensitive(item, parentKey))\n if (value && typeof value === 'object') {\n return Object.fromEntries(\n Object.entries(value as Record<string, unknown>).map(([key, child]) => [key, maskSensitive(child, key)]),\n )\n }\n return value\n}\n\nasync function readConfig(configPath?: string): Promise<{\n path: string\n raw: unknown\n valid: boolean\n issues: Array<{ path: string; message: string }>\n summary: Record<string, unknown>\n}> {\n const path = resolve(configPath ?? 'agent-qa.config.yaml')\n const content = await readFile(path, 'utf-8')\n const raw = parseYaml(content) ?? {}\n const validation = AgentQaConfigSchema.safeParse(raw)\n const record = raw && typeof raw === 'object' && !Array.isArray(raw)\n ? raw as Record<string, unknown>\n : {}\n const registry = record.registry && typeof record.registry === 'object' && !Array.isArray(record.registry)\n ? record.registry as Record<string, unknown>\n : {}\n const services = record.services && typeof record.services === 'object' && !Array.isArray(record.services)\n ? record.services as Record<string, unknown>\n : {}\n\n return {\n path,\n raw: maskSensitive(raw),\n valid: validation.success,\n issues: validation.success\n ? []\n : validation.error.issues.map(issue => ({\n path: issue.path.map(String).join('.') || '(root)',\n message: issue.message,\n })),\n summary: {\n workspaceConfigured: Boolean(record.workspace),\n serviceKeys: Object.keys(services),\n targetNames: Object.keys((registry.targets as Record<string, unknown> | undefined) ?? {}),\n deviceNames: Object.keys((registry.devices as Record<string, unknown> | undefined) ?? {}),\n providerNames: Object.keys((registry.providers as Record<string, unknown> | undefined) ?? {}),\n llmNames: Array.isArray(registry.llms)\n ? registry.llms\n .map(llm => llm && typeof llm === 'object' ? (llm as Record<string, unknown>).name : undefined)\n .filter((name): name is string => typeof name === 'string')\n : [],\n },\n }\n}\n\nexport function createAgentQaMcpServer(options: AgentQaMcpServerOptions = {}): McpServer {\n const server = new McpServer({\n name: 'agent-qa',\n version: getAgentQaVersion(),\n })\n const analyticsService = options.analyticsService ?? createAnalyticsService({ config: options.analyticsConfig })\n const analyticsTransport = options.transport ?? 'stdio'\n const registerAnalyticsTool = <\n OutputArgs extends ZodRawShapeCompat | AnySchema = ZodRawShapeCompat,\n InputArgs extends undefined | ZodRawShapeCompat | AnySchema = undefined,\n >(\n name: string,\n definition: McpToolDefinition<OutputArgs, InputArgs>,\n handler: ToolCallback<InputArgs>,\n ) => server.registerTool(name, definition, (async (input: unknown, extra: unknown) => {\n const startedAt = Date.now()\n let result: unknown\n let thrown: unknown\n\n try {\n result = await (handler as (input: unknown, extra: unknown) => unknown | Promise<unknown>)(input, extra)\n return result\n } catch (err) {\n thrown = err\n throw err\n } finally {\n const isError = thrown !== undefined || isErrorResult(result) || isDashboardErrorResult(result)\n const explicitRunId = extractExplicitCanonicalRunId(input)\n const enqueueRunId = !isError && (name === 'agent_qa_enqueue_test_run' || name === 'agent_qa_enqueue_suite_run')\n ? extractSuccessfulEnqueueRunId(result)\n : undefined\n\n try {\n if (options.analyticsConfig?.analytics?.privacy !== true) {\n const standardProperties = options.analyticsStandardProperties\n ?? await resolveAnalyticsStandardProperties({ surface: 'mcp' })\n const event = buildAnalyticsEvent({\n name: 'agent-qa.mcp.tool.invoked',\n properties: {\n ...standardProperties,\n surface: standardProperties.surface ?? 'mcp',\n tool_name: name,\n mcp_tool_category: categorizeMcpTool(name),\n mcp_tool_status: isError ? 'error' : 'success',\n duration_ms: Math.max(0, Date.now() - startedAt),\n mcp_transport: analyticsTransport,\n ...(isError ? { mcp_error_category: categorizeMcpError(thrown ?? result) } : {}),\n ...(explicitRunId ?? enqueueRunId ? { run_id: explicitRunId ?? enqueueRunId } : {}),\n },\n })\n\n if (options.analyticsService) {\n await analyticsService.capture(event).catch(() => {})\n } else {\n await captureAnalytics(event, {\n config: options.analyticsConfig,\n surface: 'mcp',\n }).catch(() => {})\n }\n }\n } catch {\n // MCP analytics must never alter tool behavior.\n }\n }\n }) as ToolCallback<InputArgs>)\n const dashboardUrlField = z.string().url().optional().describe('Dashboard base URL; defaults to the MCP server dashboard URL.')\n const dashboardUrlFor = (inputUrl?: string): string => {\n const dashboardUrl = inputUrl ?? options.dashboardUrl\n if (!dashboardUrl) {\n throw new Error('dashboardUrl is required for authoring tools. Start MCP via `agent-qa dashboard` or pass dashboardUrl.')\n }\n return dashboardUrl\n }\n const dashboardTool = async (\n dashboardUrl: string | undefined,\n path: string,\n method?: 'GET' | 'POST' | 'PUT' | 'DELETE',\n body?: unknown,\n ) => {\n try {\n const result = await callDashboardApi({\n dashboardUrl: dashboardUrlFor(dashboardUrl),\n path,\n method,\n body,\n })\n return jsonContent(result)\n } catch (err) {\n return errorContent(err instanceof Error ? err.message : String(err))\n }\n }\n\n registerAnalyticsTool(\n 'agent_qa_discover',\n {\n title: 'Discover agent-qa MCP capabilities',\n description: 'Return structured metadata for agent-qa MCP tools, resources, prompts, and current rollout scope.',\n inputSchema: {},\n },\n async () => jsonContent({\n ...DISCOVERY,\n endpoint: options.endpointUrl,\n dashboard: options.dashboardUrl,\n configPath: options.configPath,\n }),\n )\n\n registerAnalyticsTool(\n 'agent_qa_get_config',\n {\n title: 'Inspect agent-qa config',\n description: 'Read the active agent-qa config and return a masked raw config plus targets/devices/providers summary.',\n inputSchema: {\n configPath: z.string().optional().describe('Config path; defaults to the MCP server config path or agent-qa.config.yaml'),\n section: z.enum(['raw', 'summary']).optional().describe('Return full masked raw config or summary only'),\n },\n },\n async ({ configPath, section }) => {\n const config = await readConfig(configPath ?? options.configPath)\n return jsonContent(section === 'summary'\n ? { path: config.path, valid: config.valid, issues: config.issues, summary: config.summary }\n : config)\n },\n )\n\n registerAnalyticsTool(\n 'agent_qa_schema_reference',\n {\n title: 'Get agent-qa schema reference',\n description: 'Return structured references for config, test YAML, suite YAML, hooks, or canonical IDs.',\n inputSchema: {\n schema: z.enum(SCHEMA_REFERENCE_NAMES).describe('Reference name to return'),\n },\n },\n async ({ schema }) => jsonContent(AGENT_QA_SCHEMA_REFERENCES[schema as SchemaReferenceName]),\n )\n\n registerAnalyticsTool(\n 'agent_qa_validate_definition',\n {\n title: 'Validate agent-qa definition',\n description: 'Validate config/test/suite/hooks objects with the same core schemas agent-qa uses.',\n inputSchema: {\n kind: z.enum(VALIDATION_KINDS).describe('Definition kind'),\n definition: z.unknown().describe('Parsed config/test/suite/hooks object'),\n },\n },\n async ({ kind, definition }) => jsonContent(validateAgentQaDefinition(kind as ValidationKind, definition)),\n )\n\n registerAnalyticsTool(\n 'agent_qa_generate_id',\n {\n title: 'Generate canonical agent-qa ID',\n description: 'Generate a canonical id-agent backed ID for a test, suite, hook, run, or observation.',\n inputSchema: {\n type: z.enum(ENTITY_ID_TYPES).describe('ID entity type'),\n },\n },\n async ({ type }) => {\n const idType = type as typeof ENTITY_ID_TYPES[number]\n return jsonContent({\n id: generateCanonicalId(idType),\n type: idType,\n contract: getEntityIdContract(idType),\n })\n },\n )\n\n registerAnalyticsTool(\n 'agent_qa_validate_id',\n {\n title: 'Validate canonical agent-qa ID',\n description: 'Validate canonical id-agent backed IDs and return the expected contract.',\n inputSchema: {\n type: z.enum(ENTITY_ID_TYPES).describe('ID entity type'),\n id: z.string().describe('ID to validate'),\n },\n },\n async ({ type, id }) => {\n const idType = type as typeof ENTITY_ID_TYPES[number]\n const contract = getEntityIdContract(idType)\n const valid = isCanonicalId(idType, id)\n return jsonContent({\n valid,\n id,\n type: idType,\n contract,\n message: valid\n ? 'ID is canonical.'\n : `Expected ${contract.prefixWithSeparator} followed by ${contract.words} id-agent words.`,\n })\n },\n )\n\n registerAnalyticsTool(\n 'agent_qa_list_tests',\n {\n title: 'List agent-qa tests',\n description: 'List tests through the dashboard API using dashboard workspace discovery.',\n inputSchema: { dashboardUrl: dashboardUrlField },\n },\n async ({ dashboardUrl }) => dashboardTool(dashboardUrl, '/api/tests'),\n )\n\n registerAnalyticsTool(\n 'agent_qa_read_test',\n {\n title: 'Read agent-qa test',\n description: 'Read a test by canonical test ID through the dashboard API.',\n inputSchema: {\n dashboardUrl: dashboardUrlField,\n testId: z.string().describe('Canonical t_ test ID'),\n },\n },\n async ({ dashboardUrl, testId }) => dashboardTool(dashboardUrl, `/api/tests/${encodeURIComponent(testId)}`),\n )\n\n registerAnalyticsTool(\n 'agent_qa_validate_test',\n {\n title: 'Validate agent-qa test YAML',\n description: 'Validate test YAML through the dashboard test-file manager.',\n inputSchema: {\n dashboardUrl: dashboardUrlField,\n content: z.string().describe('Test YAML content'),\n filePath: z.string().optional().describe('Optional file path for suite/test routing hints'),\n },\n },\n async ({ dashboardUrl, content, filePath }) => dashboardTool(dashboardUrl, '/api/tests/validate', 'POST', { content, filePath }),\n )\n\n registerAnalyticsTool(\n 'agent_qa_create_test',\n {\n title: 'Create agent-qa test',\n description: 'Create a test file through the dashboard workspace-safe file manager.',\n inputSchema: {\n dashboardUrl: dashboardUrlField,\n path: z.string().describe('Workspace-relative test path matched by workspace.testMatch'),\n content: z.string().describe('Test YAML content'),\n },\n },\n async ({ dashboardUrl, path, content }) => dashboardTool(dashboardUrl, '/api/tests', 'POST', { path, content }),\n )\n\n registerAnalyticsTool(\n 'agent_qa_update_test',\n {\n title: 'Update agent-qa test',\n description: 'Update a test by canonical test ID through the dashboard API.',\n inputSchema: {\n dashboardUrl: dashboardUrlField,\n testId: z.string().describe('Canonical t_ test ID'),\n content: z.string().describe('Replacement test YAML content'),\n },\n },\n async ({ dashboardUrl, testId, content }) => dashboardTool(dashboardUrl, `/api/tests/${encodeURIComponent(testId)}`, 'PUT', { content }),\n )\n\n registerAnalyticsTool(\n 'agent_qa_delete_test',\n {\n title: 'Delete agent-qa test',\n description: 'Delete a test by canonical test ID through the dashboard API.',\n inputSchema: {\n dashboardUrl: dashboardUrlField,\n testId: z.string().describe('Canonical t_ test ID'),\n },\n },\n async ({ dashboardUrl, testId }) => dashboardTool(dashboardUrl, `/api/tests/${encodeURIComponent(testId)}`, 'DELETE'),\n )\n\n registerAnalyticsTool(\n 'agent_qa_list_suites',\n {\n title: 'List agent-qa suites',\n description: 'List suites through the dashboard API using dashboard workspace discovery.',\n inputSchema: { dashboardUrl: dashboardUrlField },\n },\n async ({ dashboardUrl }) => dashboardTool(dashboardUrl, '/api/suites'),\n )\n\n registerAnalyticsTool(\n 'agent_qa_read_suite',\n {\n title: 'Read agent-qa suite',\n description: 'Read a suite by canonical suite ID through the dashboard API.',\n inputSchema: {\n dashboardUrl: dashboardUrlField,\n suiteId: z.string().describe('Canonical s_ suite ID'),\n },\n },\n async ({ dashboardUrl, suiteId }) => dashboardTool(dashboardUrl, `/api/suites/${encodeURIComponent(suiteId)}`),\n )\n\n registerAnalyticsTool(\n 'agent_qa_validate_suite',\n {\n title: 'Validate agent-qa suite YAML',\n description: 'Validate suite YAML through the dashboard suite-file manager.',\n inputSchema: {\n dashboardUrl: dashboardUrlField,\n content: z.string().describe('Suite YAML content'),\n },\n },\n async ({ dashboardUrl, content }) => dashboardTool(dashboardUrl, '/api/suites/validate', 'POST', { content }),\n )\n\n registerAnalyticsTool(\n 'agent_qa_create_suite',\n {\n title: 'Create agent-qa suite',\n description: 'Create a suite file through the dashboard workspace-safe suite manager.',\n inputSchema: {\n dashboardUrl: dashboardUrlField,\n path: z.string().describe('Workspace-relative suite path matched by workspace.suiteMatch'),\n content: z.string().describe('Suite YAML content'),\n },\n },\n async ({ dashboardUrl, path, content }) => dashboardTool(dashboardUrl, '/api/suites', 'POST', { path, content }),\n )\n\n registerAnalyticsTool(\n 'agent_qa_update_suite',\n {\n title: 'Update agent-qa suite',\n description: 'Update a suite by canonical suite ID through the dashboard API.',\n inputSchema: {\n dashboardUrl: dashboardUrlField,\n suiteId: z.string().describe('Canonical s_ suite ID'),\n content: z.string().describe('Replacement suite YAML content'),\n },\n },\n async ({ dashboardUrl, suiteId, content }) => dashboardTool(dashboardUrl, `/api/suites/${encodeURIComponent(suiteId)}`, 'PUT', { content }),\n )\n\n registerAnalyticsTool(\n 'agent_qa_delete_suite',\n {\n title: 'Delete agent-qa suite',\n description: 'Delete a suite through the dashboard API. Prefer suiteId; path is supported for the dashboard delete route.',\n inputSchema: {\n dashboardUrl: dashboardUrlField,\n suiteId: z.string().optional().describe('Canonical s_ suite ID'),\n path: z.string().optional().describe('Workspace-relative suite path'),\n },\n },\n async ({ dashboardUrl, suiteId, path }) => {\n if (path) return dashboardTool(dashboardUrl, `/api/suites/${encodeURIComponent(path)}`, 'DELETE')\n if (!suiteId) return errorContent('Either suiteId or path is required.')\n let readResult: Awaited<ReturnType<typeof callDashboardApi>>\n try {\n readResult = await callDashboardApi({\n dashboardUrl: dashboardUrlFor(dashboardUrl),\n path: `/api/suites/${encodeURIComponent(suiteId)}`,\n })\n } catch (err) {\n return errorContent(err instanceof Error ? err.message : String(err))\n }\n if (!readResult.ok || !readResult.body || typeof readResult.body !== 'object') return jsonContent(readResult)\n const foundPath = (readResult.body as Record<string, unknown>).path\n if (typeof foundPath !== 'string') return errorContent('Suite read response did not include a path.')\n return dashboardTool(dashboardUrl, `/api/suites/${encodeURIComponent(foundPath)}`, 'DELETE')\n },\n )\n\n registerAnalyticsTool(\n 'agent_qa_list_hooks',\n {\n title: 'List agent-qa hooks',\n description: 'List hooks through the dashboard hook registry API.',\n inputSchema: { dashboardUrl: dashboardUrlField },\n },\n async ({ dashboardUrl }) => dashboardTool(dashboardUrl, '/api/hooks'),\n )\n\n registerAnalyticsTool(\n 'agent_qa_read_hook',\n {\n title: 'Read agent-qa hook',\n description: 'Read hook metadata and source by canonical hook ID.',\n inputSchema: {\n dashboardUrl: dashboardUrlField,\n hookId: z.string().describe('Canonical h_ hook ID'),\n },\n },\n async ({ dashboardUrl, hookId }) => dashboardTool(dashboardUrl, `/api/hooks/${encodeURIComponent(hookId)}`),\n )\n\n registerAnalyticsTool(\n 'agent_qa_create_hook',\n {\n title: 'Create agent-qa hook',\n description: 'Create a hook through the dashboard hook registry API.',\n inputSchema: {\n dashboardUrl: dashboardUrlField,\n payload: z.record(z.string(), z.unknown()).describe('Dashboard HookMutationRequest payload'),\n },\n },\n async ({ dashboardUrl, payload }) => dashboardTool(dashboardUrl, '/api/hooks', 'POST', payload),\n )\n\n registerAnalyticsTool(\n 'agent_qa_update_hook',\n {\n title: 'Update agent-qa hook',\n description: 'Update a hook through the dashboard hook registry API.',\n inputSchema: {\n dashboardUrl: dashboardUrlField,\n hookId: z.string().describe('Canonical h_ hook ID'),\n payload: z.record(z.string(), z.unknown()).describe('Dashboard HookMutationRequest payload'),\n },\n },\n async ({ dashboardUrl, hookId, payload }) => dashboardTool(dashboardUrl, `/api/hooks/${encodeURIComponent(hookId)}`, 'PUT', payload),\n )\n\n registerAnalyticsTool(\n 'agent_qa_delete_hook',\n {\n title: 'Delete agent-qa hook',\n description: 'Delete a hook through the dashboard hook registry API.',\n inputSchema: {\n dashboardUrl: dashboardUrlField,\n hookId: z.string().describe('Canonical h_ hook ID'),\n force: z.boolean().optional().describe('Delete even when references exist'),\n },\n },\n async ({ dashboardUrl, hookId, force }) => dashboardTool(dashboardUrl, `/api/hooks/${encodeURIComponent(hookId)}${force ? '?force=true' : ''}`, 'DELETE'),\n )\n\n registerAnalyticsTool(\n 'agent_qa_run_hook',\n {\n title: 'Run agent-qa hook',\n description: 'Run a hook through the dashboard hook execution API.',\n inputSchema: {\n dashboardUrl: dashboardUrlField,\n hookId: z.string().describe('Canonical h_ hook ID'),\n payload: z.record(z.string(), z.unknown()).optional().describe('Dashboard HookRunRequest payload'),\n },\n },\n async ({ dashboardUrl, hookId, payload }) => dashboardTool(dashboardUrl, `/api/hooks/${encodeURIComponent(hookId)}/run`, 'POST', payload ?? {}),\n )\n\n registerAnalyticsTool(\n 'agent_qa_enqueue_test_run',\n {\n title: 'Enqueue agent-qa test run',\n description: 'Queue a test run through the dashboard run trigger API and return the canonical run ID.',\n inputSchema: {\n dashboardUrl: dashboardUrlField,\n file: z.string().optional().describe('Workspace-relative test file path'),\n patterns: z.array(z.string()).optional().describe('Optional test patterns'),\n noCache: z.boolean().optional(),\n noMemory: z.boolean().optional(),\n local: z.boolean().optional(),\n },\n },\n async ({ dashboardUrl, file, patterns, noCache, noMemory, local }) => dashboardTool(dashboardUrl, '/api/runs/trigger', 'POST', { file, patterns, noCache, noMemory, local, triggerSource: 'mcp' }),\n )\n\n registerAnalyticsTool(\n 'agent_qa_enqueue_suite_run',\n {\n title: 'Enqueue agent-qa suite run',\n description: 'Queue a suite run through the dashboard run trigger API and return parent run context.',\n inputSchema: {\n dashboardUrl: dashboardUrlField,\n file: z.string().describe('Workspace-relative suite file path'),\n noCache: z.boolean().optional(),\n noMemory: z.boolean().optional(),\n local: z.boolean().optional(),\n },\n },\n async ({ dashboardUrl, file, noCache, noMemory, local }) => dashboardTool(dashboardUrl, '/api/runs/trigger', 'POST', { file, noCache, noMemory, local, triggerSource: 'mcp' }),\n )\n\n registerAnalyticsTool(\n 'agent_qa_get_run',\n {\n title: 'Get agent-qa run',\n description: 'Get run detail, steps, attempts, and suite child context through the dashboard API.',\n inputSchema: {\n dashboardUrl: dashboardUrlField,\n runId: z.string().describe('Canonical r_ run ID'),\n },\n },\n async ({ dashboardUrl, runId }) => dashboardTool(dashboardUrl, `/api/runs/${encodeURIComponent(runId)}`),\n )\n\n registerAnalyticsTool(\n 'agent_qa_get_run_steps',\n {\n title: 'Get agent-qa run steps',\n description: 'Get run steps through the dashboard API.',\n inputSchema: {\n dashboardUrl: dashboardUrlField,\n runId: z.string().describe('Canonical r_ run ID'),\n },\n },\n async ({ dashboardUrl, runId }) => dashboardTool(dashboardUrl, `/api/runs/${encodeURIComponent(runId)}/steps`),\n )\n\n registerAnalyticsTool(\n 'agent_qa_get_run_logs',\n {\n title: 'Get agent-qa run logs',\n description: 'Get run log rows through the dashboard API.',\n inputSchema: {\n dashboardUrl: dashboardUrlField,\n runId: z.string().describe('Canonical r_ run ID'),\n stepId: z.string().optional(),\n level: z.string().optional(),\n source: z.string().optional(),\n limit: z.number().int().positive().optional(),\n offset: z.number().int().min(0).optional(),\n },\n },\n async ({ dashboardUrl, runId, stepId, level, source, limit, offset }) => dashboardTool(\n dashboardUrl,\n withQuery(`/api/runs/${encodeURIComponent(runId)}/logs`, { stepId, level, source, limit, offset }),\n ),\n )\n\n registerAnalyticsTool(\n 'agent_qa_get_run_execution_logs',\n {\n title: 'Get agent-qa execution logs',\n description: 'Get structured execution logs through the dashboard API.',\n inputSchema: {\n dashboardUrl: dashboardUrlField,\n runId: z.string().describe('Canonical r_ run ID'),\n stepId: z.string().optional(),\n type: z.string().optional(),\n },\n },\n async ({ dashboardUrl, runId, stepId, type }) => dashboardTool(\n dashboardUrl,\n withQuery(`/api/runs/${encodeURIComponent(runId)}/execution-logs`, { stepId, type }),\n ),\n )\n\n registerAnalyticsTool(\n 'agent_qa_get_run_artifact',\n {\n title: 'Get agent-qa run artifact bundle',\n description: 'Get sanitized run artifact bundle, child artifacts, and missing artifact sections.',\n inputSchema: {\n dashboardUrl: dashboardUrlField,\n runId: z.string().describe('Canonical r_ run ID'),\n },\n },\n async ({ dashboardUrl, runId }) => dashboardTool(dashboardUrl, `/api/runs/${encodeURIComponent(runId)}/artifact`),\n )\n\n registerAnalyticsTool(\n 'agent_qa_cancel_run',\n {\n title: 'Cancel agent-qa run',\n description: 'Cancel a pending or running run through the dashboard queue.',\n inputSchema: {\n dashboardUrl: dashboardUrlField,\n runId: z.string().describe('Canonical r_ run ID'),\n },\n },\n async ({ dashboardUrl, runId }) => dashboardTool(dashboardUrl, `/api/runs/${encodeURIComponent(runId)}/cancel`, 'POST', {}),\n )\n\n registerAnalyticsTool(\n 'agent_qa_classify_failure',\n {\n title: 'Classify agent-qa failure',\n description: 'Classify a failed run using dashboard run detail, artifacts, logs, execution logs, and recent related runs.',\n inputSchema: {\n dashboardUrl: dashboardUrlField,\n runId: z.string().describe('Canonical r_ run ID'),\n },\n },\n async ({ dashboardUrl, runId }) => {\n try {\n const baseUrl = dashboardUrlFor(dashboardUrl)\n const runDetail = await callDashboardApi({ dashboardUrl: baseUrl, path: `/api/runs/${encodeURIComponent(runId)}` })\n const artifact = await callDashboardApi({ dashboardUrl: baseUrl, path: `/api/runs/${encodeURIComponent(runId)}/artifact` })\n const logs = await callDashboardApi({ dashboardUrl: baseUrl, path: `/api/runs/${encodeURIComponent(runId)}/logs` })\n const executionLogs = await callDashboardApi({ dashboardUrl: baseUrl, path: `/api/runs/${encodeURIComponent(runId)}/execution-logs` })\n const runName = runDetail.body && typeof runDetail.body === 'object'\n && (runDetail.body as Record<string, unknown>).run\n && typeof (runDetail.body as { run?: { name?: unknown } }).run?.name === 'string'\n ? (runDetail.body as { run: { name: string } }).run.name\n : undefined\n const recentRuns = runName\n ? await callDashboardApi({ dashboardUrl: baseUrl, path: withQuery('/api/runs', { name: runName, limit: 5 }) })\n : { ok: true, status: 200, body: { runs: [] } }\n return jsonContent({\n runId,\n classification: classifyRunFailureFromDashboardData({\n runDetail: runDetail.body,\n artifact: artifact.body,\n logs: logs.body,\n executionLogs: executionLogs.body,\n recentRuns: recentRuns.body,\n }),\n sources: {\n run: { ok: runDetail.ok, status: runDetail.status },\n artifact: { ok: artifact.ok, status: artifact.status },\n logs: { ok: logs.ok, status: logs.status },\n executionLogs: { ok: executionLogs.ok, status: executionLogs.status },\n recentRuns: { ok: recentRuns.ok, status: recentRuns.status },\n },\n })\n } catch (err) {\n return errorContent(err instanceof Error ? err.message : String(err))\n }\n },\n )\n\n for (const schema of SCHEMA_REFERENCE_NAMES) {\n server.registerResource(\n `agent_qa.schema.${schema}`,\n `agent-qa://schema/${schema}`,\n {\n title: `agent-qa ${schema} schema reference`,\n description: `Structured agent-qa reference for ${schema}.`,\n mimeType: 'application/json',\n },\n async uri => ({\n contents: [{\n uri: uri.href,\n mimeType: 'application/json',\n text: JSON.stringify(AGENT_QA_SCHEMA_REFERENCES[schema], null, 2),\n }],\n }),\n )\n }\n\n server.registerPrompt(\n 'agent_qa_authoring_context',\n {\n title: 'agent-qa authoring context',\n description: 'Prompt context for agents writing agent-qa tests and suites.',\n argsSchema: {},\n },\n async () => ({\n messages: [{\n role: 'user',\n content: {\n type: 'text',\n text: [\n 'Use agent-qa MCP tools before editing files.',\n 'Call agent_qa_get_config to inspect targets/devices/providers.',\n 'Call agent_qa_generate_id for test, suite, hook, run, and observation IDs.',\n 'Call agent_qa_validate_definition before saving config, test, suite, or hooks YAML.',\n `Canonical ID contracts: ${JSON.stringify(getEntityIdContracts())}`,\n ].join('\\n'),\n },\n }],\n }),\n )\n\n return server\n}\n\nexport {\n AGENT_QA_SCHEMA_REFERENCES,\n validateAgentQaDefinition,\n} from './schema-reference.js'\n","import {\n AgentQaConfigSchema,\n HooksFileSchema,\n SuiteDefinitionSchema,\n TestDefinitionSchema,\n} from '@vostride/agent-qa-core'\nimport {\n getEntityIdContracts,\n type EntityIdType,\n} from '@vostride/agent-qa-ids'\n\nexport const SCHEMA_REFERENCE_NAMES = ['config', 'test', 'suite', 'hooks', 'ids'] as const\nexport type SchemaReferenceName = typeof SCHEMA_REFERENCE_NAMES[number]\nexport const VALIDATION_KINDS = ['config', 'test', 'suite', 'hooks'] as const\nexport type ValidationKind = typeof VALIDATION_KINDS[number]\n\nexport const AGENT_QA_SCHEMA_REFERENCES = {\n config: {\n name: 'agent-qa config',\n rootKeys: ['workspace', 'services', 'registry', 'use', 'analytics'],\n services: {\n dashboard: ['port', 'dbPath', 'artifactsDir'],\n mcp: ['enabled', 'transport', 'host', 'port', 'path'],\n cache: ['dir', 'ttl'],\n logging: ['level'],\n recording: ['enabled'],\n accessibility: ['enabled', 'standard', 'runAfter', 'failOnViolation', 'disableRules', 'exclude'],\n memory: ['enabled', 'provider', 'dir', 'minTrust', 'maxInjections', 'curatorEnabled'],\n },\n mcpLocalOnly: {\n transports: ['http', 'stdio'],\n hosts: ['localhost', '127.0.0.1', '::1'],\n defaultPort: 3471,\n defaultPath: '/mcp',\n },\n },\n test: {\n name: 'agent-qa test YAML',\n requiredKeys: ['test-id', 'name', 'target', 'steps'],\n optionalKeys: ['context', 'use', 'meta', 'setup', 'teardown'],\n idType: 'test' as EntityIdType,\n hookReferences: 'setup and teardown arrays must contain canonical h_ hook IDs.',\n stepFormats: ['string', 'object with step/timeout/retries/screenshot/capture/maxAttempts'],\n },\n suite: {\n name: 'agent-qa suite YAML',\n requiredKeys: ['name', 'target', 'tests'],\n optionalKeys: ['suite-id', 'context', 'setup', 'teardown', 'use'],\n idType: 'suite' as EntityIdType,\n testReference: 'Each tests[] entry uses { test: path, id: canonical t_ test ID }.',\n hookReferences: 'setup and teardown arrays must contain canonical h_ hook IDs.',\n },\n hooks: {\n name: 'agent-qa hooks file',\n rootKeys: ['hooks'],\n hookKeys: ['id', 'name', 'runtime', 'file', 'deps', 'packageFile', 'timeout', 'network'],\n idType: 'hook' as EntityIdType,\n runtimes: ['node', 'bun', 'python', 'bash'],\n },\n ids: {\n name: 'agent-qa canonical IDs',\n instruction: 'Generate IDs with agent_qa_generate_id or `agent-qa ids generate <type>`; never hand-write IDs.',\n contracts: getEntityIdContracts(),\n },\n} as const\n\nconst VALIDATION_SCHEMAS = {\n config: AgentQaConfigSchema,\n test: TestDefinitionSchema,\n suite: SuiteDefinitionSchema,\n hooks: HooksFileSchema,\n} as const\n\nexport interface ValidationIssue {\n path: string\n message: string\n}\n\nexport interface DefinitionValidationResult {\n valid: boolean\n kind: ValidationKind\n issues: ValidationIssue[]\n}\n\nexport function validateAgentQaDefinition(\n kind: ValidationKind,\n definition: unknown,\n): DefinitionValidationResult {\n const result = VALIDATION_SCHEMAS[kind].safeParse(definition)\n if (result.success) {\n return {\n valid: true,\n kind,\n issues: [],\n }\n }\n\n return {\n valid: false,\n kind,\n issues: result.error.issues.map(issue => ({\n path: issue.path.map(String).join('.') || '(root)',\n message: issue.message,\n })),\n }\n}\n","import type { IncomingMessage, ServerResponse } from 'node:http'\nimport { StreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/streamableHttp.js'\nimport { createAgentQaMcpServer, type AgentQaMcpServerOptions } from './agent-qa-server.js'\n\nexport const DEFAULT_MCP_HOST = '127.0.0.1'\nexport const DEFAULT_MCP_PORT = 3471\nexport const DEFAULT_MCP_PATH = '/mcp'\n\nexport type LocalMcpTransport = 'http' | 'stdio'\n\nexport interface LocalMcpEndpointConfig {\n enabled?: boolean\n transport?: LocalMcpTransport\n host?: string\n port?: number\n path?: string\n}\n\nexport interface LocalMcpEndpoint {\n enabled: boolean\n transport: LocalMcpTransport\n host: string\n port: number\n path: string\n url: string\n}\n\nexport interface McpHttpHandlerOptions {\n endpoint?: Partial<LocalMcpEndpoint>\n dashboardUrl?: string\n configPath?: string\n analyticsConfig?: AgentQaMcpServerOptions['analyticsConfig']\n}\n\nexport interface LocalMcpEndpointShape {\n mcp_host_kind: 'loopback' | 'other'\n mcp_port_kind: 'default' | 'custom'\n mcp_path_kind: 'default' | 'custom'\n}\n\nfunction normalizePath(path: string | undefined): string {\n if (!path) return DEFAULT_MCP_PATH\n return path.startsWith('/') ? path : `/${path}`\n}\n\nfunction jsonRpcError(res: ServerResponse, status: number, message: string): void {\n res.writeHead(status, {\n 'Content-Type': 'application/json',\n 'Access-Control-Allow-Origin': '*',\n })\n res.end(JSON.stringify({\n jsonrpc: '2.0',\n error: {\n code: -32000,\n message,\n },\n id: null,\n }))\n}\n\nexport function resolveLocalMcpEndpoint(config: LocalMcpEndpointConfig = {}): LocalMcpEndpoint {\n const transport = config.transport ?? 'http'\n const host = config.host ?? DEFAULT_MCP_HOST\n const port = config.port ?? DEFAULT_MCP_PORT\n const path = normalizePath(config.path)\n const displayHost = host === '::1' ? '[::1]' : host\n\n return {\n enabled: config.enabled !== false,\n transport,\n host,\n port,\n path,\n url: `http://${displayHost}:${port}${path}`,\n }\n}\n\nexport function resolveMcpEndpointShape(\n endpoint: Pick<LocalMcpEndpoint, 'host' | 'port' | 'path'>,\n): LocalMcpEndpointShape {\n return {\n mcp_host_kind: ['127.0.0.1', 'localhost', '::1'].includes(endpoint.host) ? 'loopback' : 'other',\n mcp_port_kind: endpoint.port === DEFAULT_MCP_PORT ? 'default' : 'custom',\n mcp_path_kind: endpoint.path === DEFAULT_MCP_PATH ? 'default' : 'custom',\n }\n}\n\nexport function createLocalMcpHttpHandler(options: McpHttpHandlerOptions = {}) {\n const endpoint = resolveLocalMcpEndpoint(options.endpoint)\n const baseHost = endpoint.host === '::1' ? '[::1]' : endpoint.host\n\n return async (req: IncomingMessage, res: ServerResponse): Promise<void> => {\n const requestUrl = new URL(req.url ?? '/', `http://${baseHost}:${endpoint.port}`)\n if (requestUrl.pathname !== endpoint.path) {\n jsonRpcError(res, 404, `MCP endpoint is available at ${endpoint.path}`)\n return\n }\n\n if (req.method === 'OPTIONS') {\n res.writeHead(204, {\n 'Access-Control-Allow-Origin': '*',\n 'Access-Control-Allow-Methods': 'GET, POST, DELETE, OPTIONS',\n 'Access-Control-Allow-Headers': 'Content-Type, MCP-Protocol-Version, mcp-session-id',\n })\n res.end()\n return\n }\n\n const server = createAgentQaMcpServer({\n configPath: options.configPath,\n dashboardUrl: options.dashboardUrl,\n endpointUrl: endpoint.url,\n analyticsConfig: options.analyticsConfig,\n transport: 'http',\n })\n const transport = new StreamableHTTPServerTransport({\n sessionIdGenerator: undefined,\n })\n\n try {\n await server.connect(transport)\n await transport.handleRequest(req, res)\n res.on('close', () => {\n void transport.close()\n void server.close()\n })\n } catch (err) {\n void transport.close()\n void server.close()\n if (!res.headersSent) {\n jsonRpcError(\n res,\n 500,\n err instanceof Error ? err.message : 'Internal MCP server error',\n )\n }\n }\n }\n}\n"],"mappings":"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","names":["import_agent_qa_core","import_agent_qa_core","import_agent_qa_ids","parseYaml"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/server.ts","../src/agent-qa-server.ts","../src/schema-reference.ts","../src/local-http.ts"],"sourcesContent":["export { MCP_STDIO_STARTUP_MESSAGE, createMcpServer, startMcpServer } from './server.js'\nexport type { StartMcpServerOptions } from './server.js'\nexport {\n AGENT_QA_SCHEMA_REFERENCES,\n classifyRunFailureFromDashboardData,\n resolveDashboardApiUrl,\n createAgentQaMcpServer,\n validateAgentQaDefinition,\n} from './agent-qa-server.js'\nexport type {\n AgentQaMcpServerOptions,\n FailureCategory,\n FailureClassification,\n} from './agent-qa-server.js'\nexport {\n SCHEMA_REFERENCE_NAMES,\n VALIDATION_KINDS,\n} from './schema-reference.js'\nexport type {\n DefinitionValidationResult,\n SchemaReferenceName,\n ValidationKind,\n ValidationIssue,\n} from './schema-reference.js'\nexport {\n DEFAULT_MCP_HOST,\n DEFAULT_MCP_PATH,\n DEFAULT_MCP_PORT,\n createLocalMcpHttpHandler,\n resolveLocalMcpEndpoint,\n resolveMcpEndpointShape,\n} from './local-http.js'\nexport type {\n LocalMcpEndpointConfig,\n LocalMcpEndpoint,\n LocalMcpEndpointShape,\n LocalMcpTransport,\n McpHttpHandlerOptions,\n} from './local-http.js'\n","import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'\nimport {\n buildAnalyticsEvent,\n captureAnalytics,\n resolveAnalyticsStandardProperties,\n} from '@vostride/agent-qa-core'\nimport { createAgentQaMcpServer, type AgentQaMcpServerOptions } from './agent-qa-server.js'\n\nexport const MCP_STDIO_STARTUP_MESSAGE =\n 'agent-qa MCP server running over stdio. Waiting for MCP client messages on stdin. Stdout is reserved for MCP protocol traffic.'\n\nexport interface StartMcpServerOptions extends AgentQaMcpServerOptions {\n startupOutput?: Pick<NodeJS.WritableStream, 'write'>\n}\n\nexport function createMcpServer(options: AgentQaMcpServerOptions = {}) {\n return createAgentQaMcpServer(options)\n}\n\nexport async function startMcpServer(options: StartMcpServerOptions = {}): Promise<void> {\n const { startupOutput, ...serverOptions } = options\n const server = createMcpServer({ ...serverOptions, transport: 'stdio' })\n const transport = new StdioServerTransport()\n await server.connect(transport)\n try {\n startupOutput?.write(`${MCP_STDIO_STARTUP_MESSAGE}\\n`)\n } catch {\n // Startup visibility is best-effort; the MCP server is already connected.\n }\n try {\n if (options.analyticsConfig?.analytics?.privacy !== true) {\n const standardProperties = options.analyticsStandardProperties\n ?? await resolveAnalyticsStandardProperties({ surface: 'mcp' })\n const event = buildAnalyticsEvent({\n name: 'agent-qa.mcp.server.lifecycle',\n properties: {\n ...standardProperties,\n surface: standardProperties.surface ?? 'mcp',\n mcp_server_state: 'started',\n mcp_transport: 'stdio',\n },\n })\n if (options.analyticsService) {\n await options.analyticsService.capture(event).catch(() => {})\n } else {\n await captureAnalytics(event, {\n config: options.analyticsConfig,\n surface: 'mcp',\n }).catch(() => {})\n }\n }\n } catch {\n // MCP startup analytics is intentionally best-effort.\n }\n}\n","import { readFile } from 'node:fs/promises'\nimport { resolve } from 'node:path'\nimport { McpServer, type ToolCallback } from '@modelcontextprotocol/sdk/server/mcp.js'\nimport type { AnySchema, ZodRawShapeCompat } from '@modelcontextprotocol/sdk/server/zod-compat.js'\nimport type { ToolAnnotations } from '@modelcontextprotocol/sdk/types.js'\nimport {\n AgentQaConfigSchema,\n buildAnalyticsEvent,\n captureAnalytics,\n createAnalyticsService,\n getAgentQaVersion,\n redactAuthStateValue,\n resolveAnalyticsStandardProperties,\n type AnalyticsEventProperties,\n type AnalyticsService,\n type AnalyticsServiceConfig,\n} from '@vostride/agent-qa-core'\nimport {\n ENTITY_ID_TYPES,\n generateCanonicalId,\n getEntityIdContract,\n getEntityIdContracts,\n isCanonicalId,\n} from '@vostride/agent-qa-ids'\nimport { parse as parseYaml } from 'yaml'\nimport { z } from 'zod'\nimport {\n AGENT_QA_SCHEMA_REFERENCES,\n SCHEMA_REFERENCE_NAMES,\n VALIDATION_KINDS,\n validateAgentQaDefinition,\n type SchemaReferenceName,\n type ValidationKind,\n} from './schema-reference.js'\n\nexport interface AgentQaMcpServerOptions {\n configPath?: string\n dashboardUrl?: string\n endpointUrl?: string\n analyticsService?: AnalyticsService\n analyticsConfig?: AnalyticsServiceConfig\n analyticsStandardProperties?: AnalyticsEventProperties\n transport?: 'stdio' | 'http'\n}\n\ntype McpToolCategory = NonNullable<AnalyticsEventProperties['mcp_tool_category']>\ntype McpErrorCategory = NonNullable<AnalyticsEventProperties['mcp_error_category']>\ntype McpToolDefinition<\n OutputArgs extends ZodRawShapeCompat | AnySchema = ZodRawShapeCompat,\n InputArgs extends undefined | ZodRawShapeCompat | AnySchema = undefined,\n> = {\n title?: string\n description?: string\n inputSchema?: InputArgs\n outputSchema?: OutputArgs\n annotations?: ToolAnnotations\n _meta?: Record<string, unknown>\n}\n\nconst DISCOVERY = {\n name: 'agent-qa',\n purpose: 'Author, validate, run, and triage agent-qa tests through local trusted MCP.',\n tools: [\n 'agent_qa_discover',\n 'agent_qa_get_config',\n 'agent_qa_schema_reference',\n 'agent_qa_validate_definition',\n 'agent_qa_generate_id',\n 'agent_qa_validate_id',\n 'agent_qa_list_tests',\n 'agent_qa_read_test',\n 'agent_qa_validate_test',\n 'agent_qa_create_test',\n 'agent_qa_update_test',\n 'agent_qa_delete_test',\n 'agent_qa_list_suites',\n 'agent_qa_read_suite',\n 'agent_qa_validate_suite',\n 'agent_qa_create_suite',\n 'agent_qa_update_suite',\n 'agent_qa_delete_suite',\n 'agent_qa_list_hooks',\n 'agent_qa_read_hook',\n 'agent_qa_create_hook',\n 'agent_qa_update_hook',\n 'agent_qa_delete_hook',\n 'agent_qa_run_hook',\n 'agent_qa_enqueue_test_run',\n 'agent_qa_enqueue_suite_run',\n 'agent_qa_get_run',\n 'agent_qa_get_run_steps',\n 'agent_qa_get_run_logs',\n 'agent_qa_get_run_execution_logs',\n 'agent_qa_get_run_artifact',\n 'agent_qa_cancel_run',\n 'agent_qa_classify_failure',\n ],\n resources: SCHEMA_REFERENCE_NAMES.map(name => `agent-qa://schema/${name}`),\n prompts: ['agent_qa_authoring_context'],\n phases: {\n current: 'discovery-schema-id-contracts',\n next: ['authoring tools', 'run execution and triage tools'],\n },\n}\n\nfunction jsonContent(value: unknown) {\n return {\n content: [{\n type: 'text' as const,\n text: JSON.stringify(value, null, 2),\n }],\n }\n}\n\nfunction errorContent(message: string) {\n return {\n isError: true,\n content: [{\n type: 'text' as const,\n text: message,\n }],\n }\n}\n\nexport function categorizeMcpTool(name: string): McpToolCategory {\n if (name === 'agent_qa_discover') return 'discovery'\n if (name.includes('schema') || name.includes('definition') || name.includes('config')) return 'schema'\n if (name.includes('_id')) return 'id'\n if (name.includes('_hook')) return 'hook'\n if (name.includes('classify')) return 'triage'\n if (name.includes('_run') || name.includes('_logs') || name.includes('_artifact') || name.includes('_fix') || name.includes('_failure')) return 'run'\n if (name.includes('_test') || name.includes('_suite')) return 'authoring'\n return 'unknown'\n}\n\nfunction isErrorResult(value: unknown): boolean {\n return Boolean(value && typeof value === 'object' && (value as { isError?: unknown }).isError === true)\n}\n\nfunction isDashboardErrorResult(value: unknown): boolean {\n const parsed = parseToolJsonContent(value)\n return Boolean(parsed && typeof parsed === 'object' && (parsed as Record<string, unknown>).ok === false)\n}\n\nfunction parseToolJsonContent(value: unknown): unknown {\n if (!value || typeof value !== 'object') return undefined\n const content = (value as { content?: unknown }).content\n if (!Array.isArray(content)) return undefined\n const firstText = content.find(item =>\n item && typeof item === 'object'\n && (item as { type?: unknown }).type === 'text'\n && typeof (item as { text?: unknown }).text === 'string'\n ) as { text: string } | undefined\n if (!firstText) return undefined\n try {\n return JSON.parse(firstText.text)\n } catch {\n return undefined\n }\n}\n\nexport function categorizeMcpError(errOrResult: unknown): McpErrorCategory {\n if (errOrResult instanceof z.ZodError) return 'validation'\n const parsed = parseToolJsonContent(errOrResult)\n const candidate = parsed && typeof parsed === 'object'\n ? parsed as Record<string, unknown>\n : undefined\n if (candidate && candidate.ok === false) return 'dashboard_error'\n if (errOrResult instanceof Error) return 'tool_error'\n if (isErrorResult(errOrResult)) return 'tool_error'\n return 'unknown'\n}\n\nexport function extractExplicitCanonicalRunId(input: unknown): string | undefined {\n if (!input || typeof input !== 'object' || Array.isArray(input)) return undefined\n const runId = (input as Record<string, unknown>).runId\n return typeof runId === 'string' && isCanonicalId('run', runId) ? runId : undefined\n}\n\nexport function extractSuccessfulEnqueueRunId(result: unknown): string | undefined {\n if (isErrorResult(result)) return undefined\n const parsed = parseToolJsonContent(result)\n const container = parsed && typeof parsed === 'object'\n ? parsed as Record<string, unknown>\n : undefined\n if (!container) return undefined\n const body = container.body && typeof container.body === 'object'\n ? container.body as Record<string, unknown>\n : container\n for (const key of ['runId', 'id', 'parentRunId']) {\n const value = body[key]\n if (typeof value === 'string' && isCanonicalId('run', value)) return value\n }\n return undefined\n}\n\nexport function resolveDashboardApiUrl(dashboardUrl: string, apiPath: string): string {\n const base = dashboardUrl.endsWith('/') ? dashboardUrl : `${dashboardUrl}/`\n const normalizedPath = apiPath.startsWith('/') ? apiPath.slice(1) : apiPath\n return new URL(normalizedPath, base).toString()\n}\n\nfunction withQuery(path: string, query: Record<string, string | number | boolean | undefined>): string {\n const params = new URLSearchParams()\n for (const [key, value] of Object.entries(query)) {\n if (value !== undefined) params.set(key, String(value))\n }\n const queryString = params.toString()\n return queryString ? `${path}?${queryString}` : path\n}\n\nasync function callDashboardApi(input: {\n dashboardUrl: string\n path: string\n method?: 'GET' | 'POST' | 'PUT' | 'DELETE'\n body?: unknown\n}): Promise<{\n ok: boolean\n status: number\n body: unknown\n}> {\n const response = await fetch(resolveDashboardApiUrl(input.dashboardUrl, input.path), {\n method: input.method ?? 'GET',\n headers: input.body === undefined ? undefined : { 'content-type': 'application/json' },\n body: input.body === undefined ? undefined : JSON.stringify(input.body),\n })\n const text = await response.text()\n let body: unknown = null\n if (text.length > 0) {\n try {\n body = JSON.parse(text)\n } catch {\n body = text\n }\n }\n\n return {\n ok: response.ok,\n status: response.status,\n body,\n }\n}\n\nexport type FailureCategory =\n | 'passed'\n | 'timeout'\n | 'appium_startup'\n | 'browser_disconnect'\n | 'element_not_found'\n | 'assertion_failure'\n | 'hook_failure'\n | 'infrastructure'\n | 'unknown_failure'\n\nexport interface FailureClassification {\n category: FailureCategory\n confidence: number\n evidence: string[]\n recentRelatedCount: number\n}\n\nfunction collectStrings(value: unknown, output: string[] = [], limit = 80): string[] {\n if (output.length >= limit) return output\n if (typeof value === 'string' && value.trim().length > 0) {\n output.push(value)\n } else if (Array.isArray(value)) {\n for (const item of value) collectStrings(item, output, limit)\n } else if (value && typeof value === 'object') {\n for (const child of Object.values(value as Record<string, unknown>)) collectStrings(child, output, limit)\n }\n return output\n}\n\nfunction classifyByNeedle(\n haystack: string,\n evidence: string[],\n needles: string[],\n category: FailureCategory,\n confidence: number,\n): FailureClassification | null {\n const match = needles.find(needle => haystack.includes(needle))\n if (!match) return null\n const matchingEvidence = evidence.find(item => item.toLowerCase().includes(match)) ?? evidence[0] ?? match\n return {\n category,\n confidence,\n evidence: [matchingEvidence].filter(Boolean).slice(0, 5),\n recentRelatedCount: 0,\n }\n}\n\nexport function classifyRunFailureFromDashboardData(input: {\n runDetail: unknown\n artifact?: unknown\n logs?: unknown\n executionLogs?: unknown\n recentRuns?: unknown\n}): FailureClassification {\n const run = input.runDetail && typeof input.runDetail === 'object'\n ? (input.runDetail as Record<string, unknown>).run\n : undefined\n const status = run && typeof run === 'object'\n ? (run as Record<string, unknown>).status\n : undefined\n const evidence = collectStrings([input.runDetail, input.artifact, input.logs, input.executionLogs])\n const haystack = evidence.join('\\n').toLowerCase()\n const recentRelatedCount = Array.isArray((input.recentRuns as Record<string, unknown> | undefined)?.runs)\n ? ((input.recentRuns as Record<string, unknown>).runs as unknown[]).length\n : 0\n\n if (status && status !== 'failed') {\n return {\n category: 'passed',\n confidence: 0.95,\n evidence: [`Run status is ${String(status)}.`],\n recentRelatedCount,\n }\n }\n\n const checks: Array<[string[], FailureCategory, number]> = [\n [['timed out', 'timeout'], 'timeout', 0.9],\n [['appium server failed', 'appium'], 'appium_startup', 0.9],\n [['browser closed', 'target page, context or browser has been closed', 'browser disconnect'], 'browser_disconnect', 0.85],\n [['hook_not_runnable', 'hook failed', 'hook registry', 'hook'], 'hook_failure', 0.8],\n [['not found', 'no element', 'strict mode violation', 'selector'], 'element_not_found', 0.8],\n [['assert', 'expected', 'verify'], 'assertion_failure', 0.75],\n [['econnrefused', 'enotfound', 'network', 'docker'], 'infrastructure', 0.7],\n ]\n\n for (const [needles, category, confidence] of checks) {\n const result = classifyByNeedle(haystack, evidence, needles, category, confidence)\n if (result) return { ...result, recentRelatedCount }\n }\n\n return {\n category: 'unknown_failure',\n confidence: 0.3,\n evidence: evidence.slice(0, 5),\n recentRelatedCount,\n }\n}\n\nfunction maskSensitive(value: unknown, parentKey = ''): unknown {\n const authRedacted = redactAuthStateValue(value)\n const lower = parentKey.toLowerCase()\n if (typeof authRedacted === 'string' && authRedacted !== value) {\n return authRedacted\n }\n if (typeof authRedacted === 'string' && (\n lower.includes('key')\n || lower.includes('token')\n || lower.includes('secret')\n || lower.includes('password')\n )) {\n return authRedacted.length > 8 ? `${authRedacted.slice(0, 3)}****${authRedacted.slice(-4)}` : '****'\n }\n if (Array.isArray(authRedacted)) return authRedacted.map(item => maskSensitive(item, parentKey))\n if (authRedacted && typeof authRedacted === 'object') {\n return Object.fromEntries(\n Object.entries(authRedacted as Record<string, unknown>).map(([key, child]) => [key, maskSensitive(child, key)]),\n )\n }\n return authRedacted\n}\n\nasync function readConfig(configPath?: string): Promise<{\n path: string\n raw: unknown\n valid: boolean\n issues: Array<{ path: string; message: string }>\n summary: Record<string, unknown>\n}> {\n const path = resolve(configPath ?? 'agent-qa.config.yaml')\n const content = await readFile(path, 'utf-8')\n const raw = parseYaml(content) ?? {}\n const validation = AgentQaConfigSchema.safeParse(raw)\n const record = raw && typeof raw === 'object' && !Array.isArray(raw)\n ? raw as Record<string, unknown>\n : {}\n const registry = record.registry && typeof record.registry === 'object' && !Array.isArray(record.registry)\n ? record.registry as Record<string, unknown>\n : {}\n const services = record.services && typeof record.services === 'object' && !Array.isArray(record.services)\n ? record.services as Record<string, unknown>\n : {}\n\n return {\n path,\n raw: maskSensitive(raw),\n valid: validation.success,\n issues: validation.success\n ? []\n : validation.error.issues.map(issue => ({\n path: issue.path.map(String).join('.') || '(root)',\n message: issue.message,\n })),\n summary: {\n workspaceConfigured: Boolean(record.workspace),\n serviceKeys: Object.keys(services),\n targetNames: Object.keys((registry.targets as Record<string, unknown> | undefined) ?? {}),\n deviceNames: Object.keys((registry.devices as Record<string, unknown> | undefined) ?? {}),\n providerNames: Object.keys((registry.providers as Record<string, unknown> | undefined) ?? {}),\n llmNames: Array.isArray(registry.llms)\n ? registry.llms\n .map(llm => llm && typeof llm === 'object' ? (llm as Record<string, unknown>).name : undefined)\n .filter((name): name is string => typeof name === 'string')\n : [],\n },\n }\n}\n\nexport function createAgentQaMcpServer(options: AgentQaMcpServerOptions = {}): McpServer {\n const server = new McpServer({\n name: 'agent-qa',\n version: getAgentQaVersion(),\n })\n const analyticsService = options.analyticsService ?? createAnalyticsService({ config: options.analyticsConfig })\n const analyticsTransport = options.transport ?? 'stdio'\n const registerAnalyticsTool = <\n OutputArgs extends ZodRawShapeCompat | AnySchema = ZodRawShapeCompat,\n InputArgs extends undefined | ZodRawShapeCompat | AnySchema = undefined,\n >(\n name: string,\n definition: McpToolDefinition<OutputArgs, InputArgs>,\n handler: ToolCallback<InputArgs>,\n ) => server.registerTool(name, definition, (async (input: unknown, extra: unknown) => {\n const startedAt = Date.now()\n let result: unknown\n let thrown: unknown\n\n try {\n result = await (handler as (input: unknown, extra: unknown) => unknown | Promise<unknown>)(input, extra)\n return result\n } catch (err) {\n thrown = err\n throw err\n } finally {\n const isError = thrown !== undefined || isErrorResult(result) || isDashboardErrorResult(result)\n const explicitRunId = extractExplicitCanonicalRunId(input)\n const enqueueRunId = !isError && (name === 'agent_qa_enqueue_test_run' || name === 'agent_qa_enqueue_suite_run')\n ? extractSuccessfulEnqueueRunId(result)\n : undefined\n\n try {\n if (options.analyticsConfig?.analytics?.privacy !== true) {\n const standardProperties = options.analyticsStandardProperties\n ?? await resolveAnalyticsStandardProperties({ surface: 'mcp' })\n const event = buildAnalyticsEvent({\n name: 'agent-qa.mcp.tool.invoked',\n properties: {\n ...standardProperties,\n surface: standardProperties.surface ?? 'mcp',\n tool_name: name,\n mcp_tool_category: categorizeMcpTool(name),\n mcp_tool_status: isError ? 'error' : 'success',\n duration_ms: Math.max(0, Date.now() - startedAt),\n mcp_transport: analyticsTransport,\n ...(isError ? { mcp_error_category: categorizeMcpError(thrown ?? result) } : {}),\n ...(explicitRunId ?? enqueueRunId ? { run_id: explicitRunId ?? enqueueRunId } : {}),\n },\n })\n\n if (options.analyticsService) {\n await analyticsService.capture(event).catch(() => {})\n } else {\n await captureAnalytics(event, {\n config: options.analyticsConfig,\n surface: 'mcp',\n }).catch(() => {})\n }\n }\n } catch {\n // MCP analytics must never alter tool behavior.\n }\n }\n }) as ToolCallback<InputArgs>)\n const dashboardUrlField = z.string().url().optional().describe('Dashboard base URL; defaults to the MCP server dashboard URL.')\n const dashboardUrlFor = (inputUrl?: string): string => {\n const dashboardUrl = inputUrl ?? options.dashboardUrl\n if (!dashboardUrl) {\n throw new Error('dashboardUrl is required for authoring tools. Start MCP via `agent-qa dashboard` or pass dashboardUrl.')\n }\n return dashboardUrl\n }\n const dashboardTool = async (\n dashboardUrl: string | undefined,\n path: string,\n method?: 'GET' | 'POST' | 'PUT' | 'DELETE',\n body?: unknown,\n ) => {\n try {\n const result = await callDashboardApi({\n dashboardUrl: dashboardUrlFor(dashboardUrl),\n path,\n method,\n body,\n })\n return jsonContent(redactAuthStateValue(result))\n } catch (err) {\n return errorContent(err instanceof Error ? err.message : String(err))\n }\n }\n\n registerAnalyticsTool(\n 'agent_qa_discover',\n {\n title: 'Discover agent-qa MCP capabilities',\n description: 'Return structured metadata for agent-qa MCP tools, resources, prompts, and current rollout scope.',\n inputSchema: {},\n },\n async () => jsonContent({\n ...DISCOVERY,\n endpoint: options.endpointUrl,\n dashboard: options.dashboardUrl,\n configPath: options.configPath,\n }),\n )\n\n registerAnalyticsTool(\n 'agent_qa_get_config',\n {\n title: 'Inspect agent-qa config',\n description: 'Read the active agent-qa config and return a masked raw config plus targets/devices/providers summary.',\n inputSchema: {\n configPath: z.string().optional().describe('Config path; defaults to the MCP server config path or agent-qa.config.yaml'),\n section: z.enum(['raw', 'summary']).optional().describe('Return full masked raw config or summary only'),\n },\n },\n async ({ configPath, section }) => {\n const config = await readConfig(configPath ?? options.configPath)\n return jsonContent(section === 'summary'\n ? { path: config.path, valid: config.valid, issues: config.issues, summary: config.summary }\n : config)\n },\n )\n\n registerAnalyticsTool(\n 'agent_qa_schema_reference',\n {\n title: 'Get agent-qa schema reference',\n description: 'Return structured references for config, test YAML, suite YAML, hooks, or canonical IDs.',\n inputSchema: {\n schema: z.enum(SCHEMA_REFERENCE_NAMES).describe('Reference name to return'),\n },\n },\n async ({ schema }) => jsonContent(AGENT_QA_SCHEMA_REFERENCES[schema as SchemaReferenceName]),\n )\n\n registerAnalyticsTool(\n 'agent_qa_validate_definition',\n {\n title: 'Validate agent-qa definition',\n description: 'Validate config/test/suite/hooks objects with the same core schemas agent-qa uses.',\n inputSchema: {\n kind: z.enum(VALIDATION_KINDS).describe('Definition kind'),\n definition: z.unknown().describe('Parsed config/test/suite/hooks object'),\n },\n },\n async ({ kind, definition }) => jsonContent(validateAgentQaDefinition(kind as ValidationKind, definition)),\n )\n\n registerAnalyticsTool(\n 'agent_qa_generate_id',\n {\n title: 'Generate canonical agent-qa ID',\n description: 'Generate a canonical id-agent backed ID for a test, suite, hook, run, or observation.',\n inputSchema: {\n type: z.enum(ENTITY_ID_TYPES).describe('ID entity type'),\n },\n },\n async ({ type }) => {\n const idType = type as typeof ENTITY_ID_TYPES[number]\n return jsonContent({\n id: generateCanonicalId(idType),\n type: idType,\n contract: getEntityIdContract(idType),\n })\n },\n )\n\n registerAnalyticsTool(\n 'agent_qa_validate_id',\n {\n title: 'Validate canonical agent-qa ID',\n description: 'Validate canonical id-agent backed IDs and return the expected contract.',\n inputSchema: {\n type: z.enum(ENTITY_ID_TYPES).describe('ID entity type'),\n id: z.string().describe('ID to validate'),\n },\n },\n async ({ type, id }) => {\n const idType = type as typeof ENTITY_ID_TYPES[number]\n const contract = getEntityIdContract(idType)\n const valid = isCanonicalId(idType, id)\n return jsonContent({\n valid,\n id,\n type: idType,\n contract,\n message: valid\n ? 'ID is canonical.'\n : `Expected ${contract.prefixWithSeparator} followed by ${contract.words} id-agent words.`,\n })\n },\n )\n\n registerAnalyticsTool(\n 'agent_qa_list_tests',\n {\n title: 'List agent-qa tests',\n description: 'List tests through the dashboard API using dashboard workspace discovery.',\n inputSchema: { dashboardUrl: dashboardUrlField },\n },\n async ({ dashboardUrl }) => dashboardTool(dashboardUrl, '/api/tests'),\n )\n\n registerAnalyticsTool(\n 'agent_qa_read_test',\n {\n title: 'Read agent-qa test',\n description: 'Read a test by canonical test ID through the dashboard API.',\n inputSchema: {\n dashboardUrl: dashboardUrlField,\n testId: z.string().describe('Canonical t_ test ID'),\n },\n },\n async ({ dashboardUrl, testId }) => dashboardTool(dashboardUrl, `/api/tests/${encodeURIComponent(testId)}`),\n )\n\n registerAnalyticsTool(\n 'agent_qa_validate_test',\n {\n title: 'Validate agent-qa test YAML',\n description: 'Validate test YAML through the dashboard test-file manager.',\n inputSchema: {\n dashboardUrl: dashboardUrlField,\n content: z.string().describe('Test YAML content'),\n filePath: z.string().optional().describe('Optional file path for suite/test routing hints'),\n },\n },\n async ({ dashboardUrl, content, filePath }) => dashboardTool(dashboardUrl, '/api/tests/validate', 'POST', { content, filePath }),\n )\n\n registerAnalyticsTool(\n 'agent_qa_create_test',\n {\n title: 'Create agent-qa test',\n description: 'Create a test file through the dashboard workspace-safe file manager.',\n inputSchema: {\n dashboardUrl: dashboardUrlField,\n path: z.string().describe('Workspace-relative test path matched by workspace.testMatch'),\n content: z.string().describe('Test YAML content'),\n },\n },\n async ({ dashboardUrl, path, content }) => dashboardTool(dashboardUrl, '/api/tests', 'POST', { path, content }),\n )\n\n registerAnalyticsTool(\n 'agent_qa_update_test',\n {\n title: 'Update agent-qa test',\n description: 'Update a test by canonical test ID through the dashboard API.',\n inputSchema: {\n dashboardUrl: dashboardUrlField,\n testId: z.string().describe('Canonical t_ test ID'),\n content: z.string().describe('Replacement test YAML content'),\n },\n },\n async ({ dashboardUrl, testId, content }) => dashboardTool(dashboardUrl, `/api/tests/${encodeURIComponent(testId)}`, 'PUT', { content }),\n )\n\n registerAnalyticsTool(\n 'agent_qa_delete_test',\n {\n title: 'Delete agent-qa test',\n description: 'Delete a test by canonical test ID through the dashboard API.',\n inputSchema: {\n dashboardUrl: dashboardUrlField,\n testId: z.string().describe('Canonical t_ test ID'),\n },\n },\n async ({ dashboardUrl, testId }) => dashboardTool(dashboardUrl, `/api/tests/${encodeURIComponent(testId)}`, 'DELETE'),\n )\n\n registerAnalyticsTool(\n 'agent_qa_list_suites',\n {\n title: 'List agent-qa suites',\n description: 'List suites through the dashboard API using dashboard workspace discovery.',\n inputSchema: { dashboardUrl: dashboardUrlField },\n },\n async ({ dashboardUrl }) => dashboardTool(dashboardUrl, '/api/suites'),\n )\n\n registerAnalyticsTool(\n 'agent_qa_read_suite',\n {\n title: 'Read agent-qa suite',\n description: 'Read a suite by canonical suite ID through the dashboard API.',\n inputSchema: {\n dashboardUrl: dashboardUrlField,\n suiteId: z.string().describe('Canonical s_ suite ID'),\n },\n },\n async ({ dashboardUrl, suiteId }) => dashboardTool(dashboardUrl, `/api/suites/${encodeURIComponent(suiteId)}`),\n )\n\n registerAnalyticsTool(\n 'agent_qa_validate_suite',\n {\n title: 'Validate agent-qa suite YAML',\n description: 'Validate suite YAML through the dashboard suite-file manager.',\n inputSchema: {\n dashboardUrl: dashboardUrlField,\n content: z.string().describe('Suite YAML content'),\n },\n },\n async ({ dashboardUrl, content }) => dashboardTool(dashboardUrl, '/api/suites/validate', 'POST', { content }),\n )\n\n registerAnalyticsTool(\n 'agent_qa_create_suite',\n {\n title: 'Create agent-qa suite',\n description: 'Create a suite file through the dashboard workspace-safe suite manager.',\n inputSchema: {\n dashboardUrl: dashboardUrlField,\n path: z.string().describe('Workspace-relative suite path matched by workspace.suiteMatch'),\n content: z.string().describe('Suite YAML content'),\n },\n },\n async ({ dashboardUrl, path, content }) => dashboardTool(dashboardUrl, '/api/suites', 'POST', { path, content }),\n )\n\n registerAnalyticsTool(\n 'agent_qa_update_suite',\n {\n title: 'Update agent-qa suite',\n description: 'Update a suite by canonical suite ID through the dashboard API.',\n inputSchema: {\n dashboardUrl: dashboardUrlField,\n suiteId: z.string().describe('Canonical s_ suite ID'),\n content: z.string().describe('Replacement suite YAML content'),\n },\n },\n async ({ dashboardUrl, suiteId, content }) => dashboardTool(dashboardUrl, `/api/suites/${encodeURIComponent(suiteId)}`, 'PUT', { content }),\n )\n\n registerAnalyticsTool(\n 'agent_qa_delete_suite',\n {\n title: 'Delete agent-qa suite',\n description: 'Delete a suite through the dashboard API. Prefer suiteId; path is supported for the dashboard delete route.',\n inputSchema: {\n dashboardUrl: dashboardUrlField,\n suiteId: z.string().optional().describe('Canonical s_ suite ID'),\n path: z.string().optional().describe('Workspace-relative suite path'),\n },\n },\n async ({ dashboardUrl, suiteId, path }) => {\n if (path) return dashboardTool(dashboardUrl, `/api/suites/${encodeURIComponent(path)}`, 'DELETE')\n if (!suiteId) return errorContent('Either suiteId or path is required.')\n let readResult: Awaited<ReturnType<typeof callDashboardApi>>\n try {\n readResult = await callDashboardApi({\n dashboardUrl: dashboardUrlFor(dashboardUrl),\n path: `/api/suites/${encodeURIComponent(suiteId)}`,\n })\n } catch (err) {\n return errorContent(err instanceof Error ? err.message : String(err))\n }\n if (!readResult.ok || !readResult.body || typeof readResult.body !== 'object') return jsonContent(readResult)\n const foundPath = (readResult.body as Record<string, unknown>).path\n if (typeof foundPath !== 'string') return errorContent('Suite read response did not include a path.')\n return dashboardTool(dashboardUrl, `/api/suites/${encodeURIComponent(foundPath)}`, 'DELETE')\n },\n )\n\n registerAnalyticsTool(\n 'agent_qa_list_hooks',\n {\n title: 'List agent-qa hooks',\n description: 'List hooks through the dashboard hook registry API.',\n inputSchema: { dashboardUrl: dashboardUrlField },\n },\n async ({ dashboardUrl }) => dashboardTool(dashboardUrl, '/api/hooks'),\n )\n\n registerAnalyticsTool(\n 'agent_qa_read_hook',\n {\n title: 'Read agent-qa hook',\n description: 'Read hook metadata and source by canonical hook ID.',\n inputSchema: {\n dashboardUrl: dashboardUrlField,\n hookId: z.string().describe('Canonical h_ hook ID'),\n },\n },\n async ({ dashboardUrl, hookId }) => dashboardTool(dashboardUrl, `/api/hooks/${encodeURIComponent(hookId)}`),\n )\n\n registerAnalyticsTool(\n 'agent_qa_create_hook',\n {\n title: 'Create agent-qa hook',\n description: 'Create a hook through the dashboard hook registry API.',\n inputSchema: {\n dashboardUrl: dashboardUrlField,\n payload: z.record(z.string(), z.unknown()).describe('Dashboard HookMutationRequest payload'),\n },\n },\n async ({ dashboardUrl, payload }) => dashboardTool(dashboardUrl, '/api/hooks', 'POST', payload),\n )\n\n registerAnalyticsTool(\n 'agent_qa_update_hook',\n {\n title: 'Update agent-qa hook',\n description: 'Update a hook through the dashboard hook registry API.',\n inputSchema: {\n dashboardUrl: dashboardUrlField,\n hookId: z.string().describe('Canonical h_ hook ID'),\n payload: z.record(z.string(), z.unknown()).describe('Dashboard HookMutationRequest payload'),\n },\n },\n async ({ dashboardUrl, hookId, payload }) => dashboardTool(dashboardUrl, `/api/hooks/${encodeURIComponent(hookId)}`, 'PUT', payload),\n )\n\n registerAnalyticsTool(\n 'agent_qa_delete_hook',\n {\n title: 'Delete agent-qa hook',\n description: 'Delete a hook through the dashboard hook registry API.',\n inputSchema: {\n dashboardUrl: dashboardUrlField,\n hookId: z.string().describe('Canonical h_ hook ID'),\n force: z.boolean().optional().describe('Delete even when references exist'),\n },\n },\n async ({ dashboardUrl, hookId, force }) => dashboardTool(dashboardUrl, `/api/hooks/${encodeURIComponent(hookId)}${force ? '?force=true' : ''}`, 'DELETE'),\n )\n\n registerAnalyticsTool(\n 'agent_qa_run_hook',\n {\n title: 'Run agent-qa hook',\n description: 'Run a hook through the dashboard hook execution API.',\n inputSchema: {\n dashboardUrl: dashboardUrlField,\n hookId: z.string().describe('Canonical h_ hook ID'),\n payload: z.record(z.string(), z.unknown()).optional().describe('Dashboard HookRunRequest payload'),\n },\n },\n async ({ dashboardUrl, hookId, payload }) => dashboardTool(dashboardUrl, `/api/hooks/${encodeURIComponent(hookId)}/run`, 'POST', payload ?? {}),\n )\n\n registerAnalyticsTool(\n 'agent_qa_enqueue_test_run',\n {\n title: 'Enqueue agent-qa test run',\n description: 'Queue a test run through the dashboard run trigger API and return the canonical run ID.',\n inputSchema: {\n dashboardUrl: dashboardUrlField,\n file: z.string().optional().describe('Workspace-relative test file path'),\n patterns: z.array(z.string()).optional().describe('Optional test patterns'),\n noCache: z.boolean().optional(),\n noMemory: z.boolean().optional(),\n local: z.boolean().optional(),\n },\n },\n async ({ dashboardUrl, file, patterns, noCache, noMemory, local }) => dashboardTool(dashboardUrl, '/api/runs/trigger', 'POST', { file, patterns, noCache, noMemory, local, triggerSource: 'mcp' }),\n )\n\n registerAnalyticsTool(\n 'agent_qa_enqueue_suite_run',\n {\n title: 'Enqueue agent-qa suite run',\n description: 'Queue a suite run through the dashboard run trigger API and return parent run context.',\n inputSchema: {\n dashboardUrl: dashboardUrlField,\n file: z.string().describe('Workspace-relative suite file path'),\n noCache: z.boolean().optional(),\n noMemory: z.boolean().optional(),\n local: z.boolean().optional(),\n },\n },\n async ({ dashboardUrl, file, noCache, noMemory, local }) => dashboardTool(dashboardUrl, '/api/runs/trigger', 'POST', { file, noCache, noMemory, local, triggerSource: 'mcp' }),\n )\n\n registerAnalyticsTool(\n 'agent_qa_get_run',\n {\n title: 'Get agent-qa run',\n description: 'Get run detail, steps, attempts, and suite child context through the dashboard API.',\n inputSchema: {\n dashboardUrl: dashboardUrlField,\n runId: z.string().describe('Canonical r_ run ID'),\n },\n },\n async ({ dashboardUrl, runId }) => dashboardTool(dashboardUrl, `/api/runs/${encodeURIComponent(runId)}`),\n )\n\n registerAnalyticsTool(\n 'agent_qa_get_run_steps',\n {\n title: 'Get agent-qa run steps',\n description: 'Get run steps through the dashboard API.',\n inputSchema: {\n dashboardUrl: dashboardUrlField,\n runId: z.string().describe('Canonical r_ run ID'),\n },\n },\n async ({ dashboardUrl, runId }) => dashboardTool(dashboardUrl, `/api/runs/${encodeURIComponent(runId)}/steps`),\n )\n\n registerAnalyticsTool(\n 'agent_qa_get_run_logs',\n {\n title: 'Get agent-qa run logs',\n description: 'Get run log rows through the dashboard API.',\n inputSchema: {\n dashboardUrl: dashboardUrlField,\n runId: z.string().describe('Canonical r_ run ID'),\n stepId: z.string().optional(),\n level: z.string().optional(),\n source: z.string().optional(),\n limit: z.number().int().positive().optional(),\n offset: z.number().int().min(0).optional(),\n },\n },\n async ({ dashboardUrl, runId, stepId, level, source, limit, offset }) => dashboardTool(\n dashboardUrl,\n withQuery(`/api/runs/${encodeURIComponent(runId)}/logs`, { stepId, level, source, limit, offset }),\n ),\n )\n\n registerAnalyticsTool(\n 'agent_qa_get_run_execution_logs',\n {\n title: 'Get agent-qa execution logs',\n description: 'Get structured execution logs through the dashboard API.',\n inputSchema: {\n dashboardUrl: dashboardUrlField,\n runId: z.string().describe('Canonical r_ run ID'),\n stepId: z.string().optional(),\n type: z.string().optional(),\n },\n },\n async ({ dashboardUrl, runId, stepId, type }) => dashboardTool(\n dashboardUrl,\n withQuery(`/api/runs/${encodeURIComponent(runId)}/execution-logs`, { stepId, type }),\n ),\n )\n\n registerAnalyticsTool(\n 'agent_qa_get_run_artifact',\n {\n title: 'Get agent-qa run artifact bundle',\n description: 'Get sanitized run artifact bundle, child artifacts, and missing artifact sections.',\n inputSchema: {\n dashboardUrl: dashboardUrlField,\n runId: z.string().describe('Canonical r_ run ID'),\n },\n },\n async ({ dashboardUrl, runId }) => dashboardTool(dashboardUrl, `/api/runs/${encodeURIComponent(runId)}/artifact`),\n )\n\n registerAnalyticsTool(\n 'agent_qa_cancel_run',\n {\n title: 'Cancel agent-qa run',\n description: 'Cancel a pending or running run through the dashboard queue.',\n inputSchema: {\n dashboardUrl: dashboardUrlField,\n runId: z.string().describe('Canonical r_ run ID'),\n },\n },\n async ({ dashboardUrl, runId }) => dashboardTool(dashboardUrl, `/api/runs/${encodeURIComponent(runId)}/cancel`, 'POST', {}),\n )\n\n registerAnalyticsTool(\n 'agent_qa_classify_failure',\n {\n title: 'Classify agent-qa failure',\n description: 'Classify a failed run using dashboard run detail, artifacts, logs, execution logs, and recent related runs.',\n inputSchema: {\n dashboardUrl: dashboardUrlField,\n runId: z.string().describe('Canonical r_ run ID'),\n },\n },\n async ({ dashboardUrl, runId }) => {\n try {\n const baseUrl = dashboardUrlFor(dashboardUrl)\n const runDetail = await callDashboardApi({ dashboardUrl: baseUrl, path: `/api/runs/${encodeURIComponent(runId)}` })\n const artifact = await callDashboardApi({ dashboardUrl: baseUrl, path: `/api/runs/${encodeURIComponent(runId)}/artifact` })\n const logs = await callDashboardApi({ dashboardUrl: baseUrl, path: `/api/runs/${encodeURIComponent(runId)}/logs` })\n const executionLogs = await callDashboardApi({ dashboardUrl: baseUrl, path: `/api/runs/${encodeURIComponent(runId)}/execution-logs` })\n const runName = runDetail.body && typeof runDetail.body === 'object'\n && (runDetail.body as Record<string, unknown>).run\n && typeof (runDetail.body as { run?: { name?: unknown } }).run?.name === 'string'\n ? (runDetail.body as { run: { name: string } }).run.name\n : undefined\n const recentRuns = runName\n ? await callDashboardApi({ dashboardUrl: baseUrl, path: withQuery('/api/runs', { name: runName, limit: 5 }) })\n : { ok: true, status: 200, body: { runs: [] } }\n return jsonContent({\n runId,\n classification: classifyRunFailureFromDashboardData({\n runDetail: runDetail.body,\n artifact: artifact.body,\n logs: logs.body,\n executionLogs: executionLogs.body,\n recentRuns: recentRuns.body,\n }),\n sources: {\n run: { ok: runDetail.ok, status: runDetail.status },\n artifact: { ok: artifact.ok, status: artifact.status },\n logs: { ok: logs.ok, status: logs.status },\n executionLogs: { ok: executionLogs.ok, status: executionLogs.status },\n recentRuns: { ok: recentRuns.ok, status: recentRuns.status },\n },\n })\n } catch (err) {\n return errorContent(err instanceof Error ? err.message : String(err))\n }\n },\n )\n\n for (const schema of SCHEMA_REFERENCE_NAMES) {\n server.registerResource(\n `agent_qa.schema.${schema}`,\n `agent-qa://schema/${schema}`,\n {\n title: `agent-qa ${schema} schema reference`,\n description: `Structured agent-qa reference for ${schema}.`,\n mimeType: 'application/json',\n },\n async uri => ({\n contents: [{\n uri: uri.href,\n mimeType: 'application/json',\n text: JSON.stringify(AGENT_QA_SCHEMA_REFERENCES[schema], null, 2),\n }],\n }),\n )\n }\n\n server.registerPrompt(\n 'agent_qa_authoring_context',\n {\n title: 'agent-qa authoring context',\n description: 'Prompt context for agents writing agent-qa tests and suites.',\n argsSchema: {},\n },\n async () => ({\n messages: [{\n role: 'user',\n content: {\n type: 'text',\n text: [\n 'Use agent-qa MCP tools before editing files.',\n 'Call agent_qa_get_config to inspect targets/devices/providers.',\n 'Call agent_qa_generate_id for test, suite, hook, run, and observation IDs.',\n 'Call agent_qa_validate_definition before saving config, test, suite, or hooks YAML.',\n `Canonical ID contracts: ${JSON.stringify(getEntityIdContracts())}`,\n ].join('\\n'),\n },\n }],\n }),\n )\n\n return server\n}\n\nexport {\n AGENT_QA_SCHEMA_REFERENCES,\n validateAgentQaDefinition,\n} from './schema-reference.js'\n","import {\n AgentQaConfigSchema,\n HooksFileSchema,\n SuiteDefinitionSchema,\n TestDefinitionSchema,\n} from '@vostride/agent-qa-core'\nimport {\n getEntityIdContracts,\n type EntityIdType,\n} from '@vostride/agent-qa-ids'\n\nexport const SCHEMA_REFERENCE_NAMES = ['config', 'test', 'suite', 'hooks', 'ids'] as const\nexport type SchemaReferenceName = typeof SCHEMA_REFERENCE_NAMES[number]\nexport const VALIDATION_KINDS = ['config', 'test', 'suite', 'hooks'] as const\nexport type ValidationKind = typeof VALIDATION_KINDS[number]\n\nexport const AGENT_QA_SCHEMA_REFERENCES = {\n config: {\n name: 'agent-qa config',\n rootKeys: ['workspace', 'services', 'registry', 'use', 'analytics'],\n services: {\n dashboard: ['port', 'dbPath', 'artifactsDir'],\n mcp: ['enabled', 'transport', 'host', 'port', 'path'],\n cache: ['dir', 'ttl'],\n logging: ['level'],\n recording: ['enabled'],\n accessibility: ['enabled', 'standard', 'runAfter', 'failOnViolation', 'disableRules', 'exclude'],\n memory: ['enabled', 'provider', 'dir', 'minTrust', 'maxInjections', 'curatorEnabled'],\n },\n mcpLocalOnly: {\n transports: ['http', 'stdio'],\n hosts: ['localhost', '127.0.0.1', '::1'],\n defaultPort: 3471,\n defaultPath: '/mcp',\n },\n },\n test: {\n name: 'agent-qa test YAML',\n requiredKeys: ['test-id', 'name', 'target', 'steps'],\n optionalKeys: ['context', 'use', 'meta', 'setup', 'teardown'],\n idType: 'test' as EntityIdType,\n hookReferences: 'setup and teardown arrays must contain canonical h_ hook IDs.',\n stepFormats: ['string', 'object with step/timeout/retries/screenshot/capture/maxAttempts'],\n },\n suite: {\n name: 'agent-qa suite YAML',\n requiredKeys: ['name', 'target', 'tests'],\n optionalKeys: ['suite-id', 'context', 'setup', 'teardown', 'use'],\n idType: 'suite' as EntityIdType,\n testReference: 'Each tests[] entry uses { test: path, id: canonical t_ test ID }.',\n hookReferences: 'setup and teardown arrays must contain canonical h_ hook IDs.',\n },\n hooks: {\n name: 'agent-qa hooks file',\n rootKeys: ['hooks'],\n hookKeys: ['id', 'name', 'runtime', 'file', 'deps', 'packageFile', 'timeout', 'network'],\n idType: 'hook' as EntityIdType,\n runtimes: ['node', 'bun', 'python', 'bash'],\n },\n ids: {\n name: 'agent-qa canonical IDs',\n instruction: 'Generate IDs with agent_qa_generate_id or `agent-qa ids generate <type>`; never hand-write IDs.',\n contracts: getEntityIdContracts(),\n },\n} as const\n\nconst VALIDATION_SCHEMAS = {\n config: AgentQaConfigSchema,\n test: TestDefinitionSchema,\n suite: SuiteDefinitionSchema,\n hooks: HooksFileSchema,\n} as const\n\nexport interface ValidationIssue {\n path: string\n message: string\n}\n\nexport interface DefinitionValidationResult {\n valid: boolean\n kind: ValidationKind\n issues: ValidationIssue[]\n}\n\nexport function validateAgentQaDefinition(\n kind: ValidationKind,\n definition: unknown,\n): DefinitionValidationResult {\n const result = VALIDATION_SCHEMAS[kind].safeParse(definition)\n if (result.success) {\n return {\n valid: true,\n kind,\n issues: [],\n }\n }\n\n return {\n valid: false,\n kind,\n issues: result.error.issues.map(issue => ({\n path: issue.path.map(String).join('.') || '(root)',\n message: issue.message,\n })),\n }\n}\n","import type { IncomingMessage, ServerResponse } from 'node:http'\nimport { StreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/streamableHttp.js'\nimport { createAgentQaMcpServer, type AgentQaMcpServerOptions } from './agent-qa-server.js'\n\nexport const DEFAULT_MCP_HOST = '127.0.0.1'\nexport const DEFAULT_MCP_PORT = 3471\nexport const DEFAULT_MCP_PATH = '/mcp'\n\nexport type LocalMcpTransport = 'http' | 'stdio'\n\nexport interface LocalMcpEndpointConfig {\n enabled?: boolean\n transport?: LocalMcpTransport\n host?: string\n port?: number\n path?: string\n}\n\nexport interface LocalMcpEndpoint {\n enabled: boolean\n transport: LocalMcpTransport\n host: string\n port: number\n path: string\n url: string\n}\n\nexport interface McpHttpHandlerOptions {\n endpoint?: Partial<LocalMcpEndpoint>\n dashboardUrl?: string\n configPath?: string\n analyticsConfig?: AgentQaMcpServerOptions['analyticsConfig']\n}\n\nexport interface LocalMcpEndpointShape {\n mcp_host_kind: 'loopback' | 'other'\n mcp_port_kind: 'default' | 'custom'\n mcp_path_kind: 'default' | 'custom'\n}\n\nfunction normalizePath(path: string | undefined): string {\n if (!path) return DEFAULT_MCP_PATH\n return path.startsWith('/') ? path : `/${path}`\n}\n\nfunction jsonRpcError(res: ServerResponse, status: number, message: string): void {\n res.writeHead(status, {\n 'Content-Type': 'application/json',\n 'Access-Control-Allow-Origin': '*',\n })\n res.end(JSON.stringify({\n jsonrpc: '2.0',\n error: {\n code: -32000,\n message,\n },\n id: null,\n }))\n}\n\nexport function resolveLocalMcpEndpoint(config: LocalMcpEndpointConfig = {}): LocalMcpEndpoint {\n const transport = config.transport ?? 'http'\n const host = config.host ?? DEFAULT_MCP_HOST\n const port = config.port ?? DEFAULT_MCP_PORT\n const path = normalizePath(config.path)\n const displayHost = host === '::1' ? '[::1]' : host\n\n return {\n enabled: config.enabled !== false,\n transport,\n host,\n port,\n path,\n url: `http://${displayHost}:${port}${path}`,\n }\n}\n\nexport function resolveMcpEndpointShape(\n endpoint: Pick<LocalMcpEndpoint, 'host' | 'port' | 'path'>,\n): LocalMcpEndpointShape {\n return {\n mcp_host_kind: ['127.0.0.1', 'localhost', '::1'].includes(endpoint.host) ? 'loopback' : 'other',\n mcp_port_kind: endpoint.port === DEFAULT_MCP_PORT ? 'default' : 'custom',\n mcp_path_kind: endpoint.path === DEFAULT_MCP_PATH ? 'default' : 'custom',\n }\n}\n\nexport function createLocalMcpHttpHandler(options: McpHttpHandlerOptions = {}) {\n const endpoint = resolveLocalMcpEndpoint(options.endpoint)\n const baseHost = endpoint.host === '::1' ? '[::1]' : endpoint.host\n\n return async (req: IncomingMessage, res: ServerResponse): Promise<void> => {\n const requestUrl = new URL(req.url ?? '/', `http://${baseHost}:${endpoint.port}`)\n if (requestUrl.pathname !== endpoint.path) {\n jsonRpcError(res, 404, `MCP endpoint is available at ${endpoint.path}`)\n return\n }\n\n if (req.method === 'OPTIONS') {\n res.writeHead(204, {\n 'Access-Control-Allow-Origin': '*',\n 'Access-Control-Allow-Methods': 'GET, POST, DELETE, OPTIONS',\n 'Access-Control-Allow-Headers': 'Content-Type, MCP-Protocol-Version, mcp-session-id',\n })\n res.end()\n return\n }\n\n const server = createAgentQaMcpServer({\n configPath: options.configPath,\n dashboardUrl: options.dashboardUrl,\n endpointUrl: endpoint.url,\n analyticsConfig: options.analyticsConfig,\n transport: 'http',\n })\n const transport = new StreamableHTTPServerTransport({\n sessionIdGenerator: undefined,\n })\n\n try {\n await server.connect(transport)\n await transport.handleRequest(req, res)\n res.on('close', () => {\n void transport.close()\n void server.close()\n })\n } catch (err) {\n void transport.close()\n void server.close()\n if (!res.headersSent) {\n jsonRpcError(\n res,\n 500,\n err instanceof Error ? err.message : 'Internal MCP server error',\n )\n }\n }\n }\n}\n"],"mappings":"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","names":["import_agent_qa_core","import_agent_qa_core","import_agent_qa_ids","parseYaml"]}
|
package/dist/index.js
CHANGED
|
@@ -16,6 +16,7 @@ import {
|
|
|
16
16
|
captureAnalytics,
|
|
17
17
|
createAnalyticsService,
|
|
18
18
|
getAgentQaVersion,
|
|
19
|
+
redactAuthStateValue,
|
|
19
20
|
resolveAnalyticsStandardProperties
|
|
20
21
|
} from "@vostride/agent-qa-core";
|
|
21
22
|
import {
|
|
@@ -325,17 +326,21 @@ function classifyRunFailureFromDashboardData(input) {
|
|
|
325
326
|
};
|
|
326
327
|
}
|
|
327
328
|
function maskSensitive(value, parentKey = "") {
|
|
329
|
+
const authRedacted = redactAuthStateValue(value);
|
|
328
330
|
const lower = parentKey.toLowerCase();
|
|
329
|
-
if (typeof
|
|
330
|
-
return
|
|
331
|
+
if (typeof authRedacted === "string" && authRedacted !== value) {
|
|
332
|
+
return authRedacted;
|
|
331
333
|
}
|
|
332
|
-
if (
|
|
333
|
-
|
|
334
|
+
if (typeof authRedacted === "string" && (lower.includes("key") || lower.includes("token") || lower.includes("secret") || lower.includes("password"))) {
|
|
335
|
+
return authRedacted.length > 8 ? `${authRedacted.slice(0, 3)}****${authRedacted.slice(-4)}` : "****";
|
|
336
|
+
}
|
|
337
|
+
if (Array.isArray(authRedacted)) return authRedacted.map((item) => maskSensitive(item, parentKey));
|
|
338
|
+
if (authRedacted && typeof authRedacted === "object") {
|
|
334
339
|
return Object.fromEntries(
|
|
335
|
-
Object.entries(
|
|
340
|
+
Object.entries(authRedacted).map(([key, child]) => [key, maskSensitive(child, key)])
|
|
336
341
|
);
|
|
337
342
|
}
|
|
338
|
-
return
|
|
343
|
+
return authRedacted;
|
|
339
344
|
}
|
|
340
345
|
async function readConfig(configPath) {
|
|
341
346
|
const path = resolve(configPath ?? "agent-qa.config.yaml");
|
|
@@ -432,7 +437,7 @@ function createAgentQaMcpServer(options = {}) {
|
|
|
432
437
|
method,
|
|
433
438
|
body
|
|
434
439
|
});
|
|
435
|
-
return jsonContent(result);
|
|
440
|
+
return jsonContent(redactAuthStateValue(result));
|
|
436
441
|
} catch (err) {
|
|
437
442
|
return errorContent(err instanceof Error ? err.message : String(err));
|
|
438
443
|
}
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/server.ts","../src/agent-qa-server.ts","../src/schema-reference.ts","../src/local-http.ts"],"sourcesContent":["import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'\nimport {\n buildAnalyticsEvent,\n captureAnalytics,\n resolveAnalyticsStandardProperties,\n} from '@vostride/agent-qa-core'\nimport { createAgentQaMcpServer, type AgentQaMcpServerOptions } from './agent-qa-server.js'\n\nexport const MCP_STDIO_STARTUP_MESSAGE =\n 'agent-qa MCP server running over stdio. Waiting for MCP client messages on stdin. Stdout is reserved for MCP protocol traffic.'\n\nexport interface StartMcpServerOptions extends AgentQaMcpServerOptions {\n startupOutput?: Pick<NodeJS.WritableStream, 'write'>\n}\n\nexport function createMcpServer(options: AgentQaMcpServerOptions = {}) {\n return createAgentQaMcpServer(options)\n}\n\nexport async function startMcpServer(options: StartMcpServerOptions = {}): Promise<void> {\n const { startupOutput, ...serverOptions } = options\n const server = createMcpServer({ ...serverOptions, transport: 'stdio' })\n const transport = new StdioServerTransport()\n await server.connect(transport)\n try {\n startupOutput?.write(`${MCP_STDIO_STARTUP_MESSAGE}\\n`)\n } catch {\n // Startup visibility is best-effort; the MCP server is already connected.\n }\n try {\n if (options.analyticsConfig?.analytics?.privacy !== true) {\n const standardProperties = options.analyticsStandardProperties\n ?? await resolveAnalyticsStandardProperties({ surface: 'mcp' })\n const event = buildAnalyticsEvent({\n name: 'agent-qa.mcp.server.lifecycle',\n properties: {\n ...standardProperties,\n surface: standardProperties.surface ?? 'mcp',\n mcp_server_state: 'started',\n mcp_transport: 'stdio',\n },\n })\n if (options.analyticsService) {\n await options.analyticsService.capture(event).catch(() => {})\n } else {\n await captureAnalytics(event, {\n config: options.analyticsConfig,\n surface: 'mcp',\n }).catch(() => {})\n }\n }\n } catch {\n // MCP startup analytics is intentionally best-effort.\n }\n}\n","import { readFile } from 'node:fs/promises'\nimport { resolve } from 'node:path'\nimport { McpServer, type ToolCallback } from '@modelcontextprotocol/sdk/server/mcp.js'\nimport type { AnySchema, ZodRawShapeCompat } from '@modelcontextprotocol/sdk/server/zod-compat.js'\nimport type { ToolAnnotations } from '@modelcontextprotocol/sdk/types.js'\nimport {\n AgentQaConfigSchema,\n buildAnalyticsEvent,\n captureAnalytics,\n createAnalyticsService,\n getAgentQaVersion,\n resolveAnalyticsStandardProperties,\n type AnalyticsEventProperties,\n type AnalyticsService,\n type AnalyticsServiceConfig,\n} from '@vostride/agent-qa-core'\nimport {\n ENTITY_ID_TYPES,\n generateCanonicalId,\n getEntityIdContract,\n getEntityIdContracts,\n isCanonicalId,\n} from '@vostride/agent-qa-ids'\nimport { parse as parseYaml } from 'yaml'\nimport { z } from 'zod'\nimport {\n AGENT_QA_SCHEMA_REFERENCES,\n SCHEMA_REFERENCE_NAMES,\n VALIDATION_KINDS,\n validateAgentQaDefinition,\n type SchemaReferenceName,\n type ValidationKind,\n} from './schema-reference.js'\n\nexport interface AgentQaMcpServerOptions {\n configPath?: string\n dashboardUrl?: string\n endpointUrl?: string\n analyticsService?: AnalyticsService\n analyticsConfig?: AnalyticsServiceConfig\n analyticsStandardProperties?: AnalyticsEventProperties\n transport?: 'stdio' | 'http'\n}\n\ntype McpToolCategory = NonNullable<AnalyticsEventProperties['mcp_tool_category']>\ntype McpErrorCategory = NonNullable<AnalyticsEventProperties['mcp_error_category']>\ntype McpToolDefinition<\n OutputArgs extends ZodRawShapeCompat | AnySchema = ZodRawShapeCompat,\n InputArgs extends undefined | ZodRawShapeCompat | AnySchema = undefined,\n> = {\n title?: string\n description?: string\n inputSchema?: InputArgs\n outputSchema?: OutputArgs\n annotations?: ToolAnnotations\n _meta?: Record<string, unknown>\n}\n\nconst DISCOVERY = {\n name: 'agent-qa',\n purpose: 'Author, validate, run, and triage agent-qa tests through local trusted MCP.',\n tools: [\n 'agent_qa_discover',\n 'agent_qa_get_config',\n 'agent_qa_schema_reference',\n 'agent_qa_validate_definition',\n 'agent_qa_generate_id',\n 'agent_qa_validate_id',\n 'agent_qa_list_tests',\n 'agent_qa_read_test',\n 'agent_qa_validate_test',\n 'agent_qa_create_test',\n 'agent_qa_update_test',\n 'agent_qa_delete_test',\n 'agent_qa_list_suites',\n 'agent_qa_read_suite',\n 'agent_qa_validate_suite',\n 'agent_qa_create_suite',\n 'agent_qa_update_suite',\n 'agent_qa_delete_suite',\n 'agent_qa_list_hooks',\n 'agent_qa_read_hook',\n 'agent_qa_create_hook',\n 'agent_qa_update_hook',\n 'agent_qa_delete_hook',\n 'agent_qa_run_hook',\n 'agent_qa_enqueue_test_run',\n 'agent_qa_enqueue_suite_run',\n 'agent_qa_get_run',\n 'agent_qa_get_run_steps',\n 'agent_qa_get_run_logs',\n 'agent_qa_get_run_execution_logs',\n 'agent_qa_get_run_artifact',\n 'agent_qa_cancel_run',\n 'agent_qa_classify_failure',\n ],\n resources: SCHEMA_REFERENCE_NAMES.map(name => `agent-qa://schema/${name}`),\n prompts: ['agent_qa_authoring_context'],\n phases: {\n current: 'discovery-schema-id-contracts',\n next: ['authoring tools', 'run execution and triage tools'],\n },\n}\n\nfunction jsonContent(value: unknown) {\n return {\n content: [{\n type: 'text' as const,\n text: JSON.stringify(value, null, 2),\n }],\n }\n}\n\nfunction errorContent(message: string) {\n return {\n isError: true,\n content: [{\n type: 'text' as const,\n text: message,\n }],\n }\n}\n\nexport function categorizeMcpTool(name: string): McpToolCategory {\n if (name === 'agent_qa_discover') return 'discovery'\n if (name.includes('schema') || name.includes('definition') || name.includes('config')) return 'schema'\n if (name.includes('_id')) return 'id'\n if (name.includes('_hook')) return 'hook'\n if (name.includes('classify')) return 'triage'\n if (name.includes('_run') || name.includes('_logs') || name.includes('_artifact') || name.includes('_fix') || name.includes('_failure')) return 'run'\n if (name.includes('_test') || name.includes('_suite')) return 'authoring'\n return 'unknown'\n}\n\nfunction isErrorResult(value: unknown): boolean {\n return Boolean(value && typeof value === 'object' && (value as { isError?: unknown }).isError === true)\n}\n\nfunction isDashboardErrorResult(value: unknown): boolean {\n const parsed = parseToolJsonContent(value)\n return Boolean(parsed && typeof parsed === 'object' && (parsed as Record<string, unknown>).ok === false)\n}\n\nfunction parseToolJsonContent(value: unknown): unknown {\n if (!value || typeof value !== 'object') return undefined\n const content = (value as { content?: unknown }).content\n if (!Array.isArray(content)) return undefined\n const firstText = content.find(item =>\n item && typeof item === 'object'\n && (item as { type?: unknown }).type === 'text'\n && typeof (item as { text?: unknown }).text === 'string'\n ) as { text: string } | undefined\n if (!firstText) return undefined\n try {\n return JSON.parse(firstText.text)\n } catch {\n return undefined\n }\n}\n\nexport function categorizeMcpError(errOrResult: unknown): McpErrorCategory {\n if (errOrResult instanceof z.ZodError) return 'validation'\n const parsed = parseToolJsonContent(errOrResult)\n const candidate = parsed && typeof parsed === 'object'\n ? parsed as Record<string, unknown>\n : undefined\n if (candidate && candidate.ok === false) return 'dashboard_error'\n if (errOrResult instanceof Error) return 'tool_error'\n if (isErrorResult(errOrResult)) return 'tool_error'\n return 'unknown'\n}\n\nexport function extractExplicitCanonicalRunId(input: unknown): string | undefined {\n if (!input || typeof input !== 'object' || Array.isArray(input)) return undefined\n const runId = (input as Record<string, unknown>).runId\n return typeof runId === 'string' && isCanonicalId('run', runId) ? runId : undefined\n}\n\nexport function extractSuccessfulEnqueueRunId(result: unknown): string | undefined {\n if (isErrorResult(result)) return undefined\n const parsed = parseToolJsonContent(result)\n const container = parsed && typeof parsed === 'object'\n ? parsed as Record<string, unknown>\n : undefined\n if (!container) return undefined\n const body = container.body && typeof container.body === 'object'\n ? container.body as Record<string, unknown>\n : container\n for (const key of ['runId', 'id', 'parentRunId']) {\n const value = body[key]\n if (typeof value === 'string' && isCanonicalId('run', value)) return value\n }\n return undefined\n}\n\nexport function resolveDashboardApiUrl(dashboardUrl: string, apiPath: string): string {\n const base = dashboardUrl.endsWith('/') ? dashboardUrl : `${dashboardUrl}/`\n const normalizedPath = apiPath.startsWith('/') ? apiPath.slice(1) : apiPath\n return new URL(normalizedPath, base).toString()\n}\n\nfunction withQuery(path: string, query: Record<string, string | number | boolean | undefined>): string {\n const params = new URLSearchParams()\n for (const [key, value] of Object.entries(query)) {\n if (value !== undefined) params.set(key, String(value))\n }\n const queryString = params.toString()\n return queryString ? `${path}?${queryString}` : path\n}\n\nasync function callDashboardApi(input: {\n dashboardUrl: string\n path: string\n method?: 'GET' | 'POST' | 'PUT' | 'DELETE'\n body?: unknown\n}): Promise<{\n ok: boolean\n status: number\n body: unknown\n}> {\n const response = await fetch(resolveDashboardApiUrl(input.dashboardUrl, input.path), {\n method: input.method ?? 'GET',\n headers: input.body === undefined ? undefined : { 'content-type': 'application/json' },\n body: input.body === undefined ? undefined : JSON.stringify(input.body),\n })\n const text = await response.text()\n let body: unknown = null\n if (text.length > 0) {\n try {\n body = JSON.parse(text)\n } catch {\n body = text\n }\n }\n\n return {\n ok: response.ok,\n status: response.status,\n body,\n }\n}\n\nexport type FailureCategory =\n | 'passed'\n | 'timeout'\n | 'appium_startup'\n | 'browser_disconnect'\n | 'element_not_found'\n | 'assertion_failure'\n | 'hook_failure'\n | 'infrastructure'\n | 'unknown_failure'\n\nexport interface FailureClassification {\n category: FailureCategory\n confidence: number\n evidence: string[]\n recentRelatedCount: number\n}\n\nfunction collectStrings(value: unknown, output: string[] = [], limit = 80): string[] {\n if (output.length >= limit) return output\n if (typeof value === 'string' && value.trim().length > 0) {\n output.push(value)\n } else if (Array.isArray(value)) {\n for (const item of value) collectStrings(item, output, limit)\n } else if (value && typeof value === 'object') {\n for (const child of Object.values(value as Record<string, unknown>)) collectStrings(child, output, limit)\n }\n return output\n}\n\nfunction classifyByNeedle(\n haystack: string,\n evidence: string[],\n needles: string[],\n category: FailureCategory,\n confidence: number,\n): FailureClassification | null {\n const match = needles.find(needle => haystack.includes(needle))\n if (!match) return null\n const matchingEvidence = evidence.find(item => item.toLowerCase().includes(match)) ?? evidence[0] ?? match\n return {\n category,\n confidence,\n evidence: [matchingEvidence].filter(Boolean).slice(0, 5),\n recentRelatedCount: 0,\n }\n}\n\nexport function classifyRunFailureFromDashboardData(input: {\n runDetail: unknown\n artifact?: unknown\n logs?: unknown\n executionLogs?: unknown\n recentRuns?: unknown\n}): FailureClassification {\n const run = input.runDetail && typeof input.runDetail === 'object'\n ? (input.runDetail as Record<string, unknown>).run\n : undefined\n const status = run && typeof run === 'object'\n ? (run as Record<string, unknown>).status\n : undefined\n const evidence = collectStrings([input.runDetail, input.artifact, input.logs, input.executionLogs])\n const haystack = evidence.join('\\n').toLowerCase()\n const recentRelatedCount = Array.isArray((input.recentRuns as Record<string, unknown> | undefined)?.runs)\n ? ((input.recentRuns as Record<string, unknown>).runs as unknown[]).length\n : 0\n\n if (status && status !== 'failed') {\n return {\n category: 'passed',\n confidence: 0.95,\n evidence: [`Run status is ${String(status)}.`],\n recentRelatedCount,\n }\n }\n\n const checks: Array<[string[], FailureCategory, number]> = [\n [['timed out', 'timeout'], 'timeout', 0.9],\n [['appium server failed', 'appium'], 'appium_startup', 0.9],\n [['browser closed', 'target page, context or browser has been closed', 'browser disconnect'], 'browser_disconnect', 0.85],\n [['hook_not_runnable', 'hook failed', 'hook registry', 'hook'], 'hook_failure', 0.8],\n [['not found', 'no element', 'strict mode violation', 'selector'], 'element_not_found', 0.8],\n [['assert', 'expected', 'verify'], 'assertion_failure', 0.75],\n [['econnrefused', 'enotfound', 'network', 'docker'], 'infrastructure', 0.7],\n ]\n\n for (const [needles, category, confidence] of checks) {\n const result = classifyByNeedle(haystack, evidence, needles, category, confidence)\n if (result) return { ...result, recentRelatedCount }\n }\n\n return {\n category: 'unknown_failure',\n confidence: 0.3,\n evidence: evidence.slice(0, 5),\n recentRelatedCount,\n }\n}\n\nfunction maskSensitive(value: unknown, parentKey = ''): unknown {\n const lower = parentKey.toLowerCase()\n if (typeof value === 'string' && (\n lower.includes('key')\n || lower.includes('token')\n || lower.includes('secret')\n || lower.includes('password')\n )) {\n return value.length > 8 ? `${value.slice(0, 3)}****${value.slice(-4)}` : '****'\n }\n if (Array.isArray(value)) return value.map(item => maskSensitive(item, parentKey))\n if (value && typeof value === 'object') {\n return Object.fromEntries(\n Object.entries(value as Record<string, unknown>).map(([key, child]) => [key, maskSensitive(child, key)]),\n )\n }\n return value\n}\n\nasync function readConfig(configPath?: string): Promise<{\n path: string\n raw: unknown\n valid: boolean\n issues: Array<{ path: string; message: string }>\n summary: Record<string, unknown>\n}> {\n const path = resolve(configPath ?? 'agent-qa.config.yaml')\n const content = await readFile(path, 'utf-8')\n const raw = parseYaml(content) ?? {}\n const validation = AgentQaConfigSchema.safeParse(raw)\n const record = raw && typeof raw === 'object' && !Array.isArray(raw)\n ? raw as Record<string, unknown>\n : {}\n const registry = record.registry && typeof record.registry === 'object' && !Array.isArray(record.registry)\n ? record.registry as Record<string, unknown>\n : {}\n const services = record.services && typeof record.services === 'object' && !Array.isArray(record.services)\n ? record.services as Record<string, unknown>\n : {}\n\n return {\n path,\n raw: maskSensitive(raw),\n valid: validation.success,\n issues: validation.success\n ? []\n : validation.error.issues.map(issue => ({\n path: issue.path.map(String).join('.') || '(root)',\n message: issue.message,\n })),\n summary: {\n workspaceConfigured: Boolean(record.workspace),\n serviceKeys: Object.keys(services),\n targetNames: Object.keys((registry.targets as Record<string, unknown> | undefined) ?? {}),\n deviceNames: Object.keys((registry.devices as Record<string, unknown> | undefined) ?? {}),\n providerNames: Object.keys((registry.providers as Record<string, unknown> | undefined) ?? {}),\n llmNames: Array.isArray(registry.llms)\n ? registry.llms\n .map(llm => llm && typeof llm === 'object' ? (llm as Record<string, unknown>).name : undefined)\n .filter((name): name is string => typeof name === 'string')\n : [],\n },\n }\n}\n\nexport function createAgentQaMcpServer(options: AgentQaMcpServerOptions = {}): McpServer {\n const server = new McpServer({\n name: 'agent-qa',\n version: getAgentQaVersion(),\n })\n const analyticsService = options.analyticsService ?? createAnalyticsService({ config: options.analyticsConfig })\n const analyticsTransport = options.transport ?? 'stdio'\n const registerAnalyticsTool = <\n OutputArgs extends ZodRawShapeCompat | AnySchema = ZodRawShapeCompat,\n InputArgs extends undefined | ZodRawShapeCompat | AnySchema = undefined,\n >(\n name: string,\n definition: McpToolDefinition<OutputArgs, InputArgs>,\n handler: ToolCallback<InputArgs>,\n ) => server.registerTool(name, definition, (async (input: unknown, extra: unknown) => {\n const startedAt = Date.now()\n let result: unknown\n let thrown: unknown\n\n try {\n result = await (handler as (input: unknown, extra: unknown) => unknown | Promise<unknown>)(input, extra)\n return result\n } catch (err) {\n thrown = err\n throw err\n } finally {\n const isError = thrown !== undefined || isErrorResult(result) || isDashboardErrorResult(result)\n const explicitRunId = extractExplicitCanonicalRunId(input)\n const enqueueRunId = !isError && (name === 'agent_qa_enqueue_test_run' || name === 'agent_qa_enqueue_suite_run')\n ? extractSuccessfulEnqueueRunId(result)\n : undefined\n\n try {\n if (options.analyticsConfig?.analytics?.privacy !== true) {\n const standardProperties = options.analyticsStandardProperties\n ?? await resolveAnalyticsStandardProperties({ surface: 'mcp' })\n const event = buildAnalyticsEvent({\n name: 'agent-qa.mcp.tool.invoked',\n properties: {\n ...standardProperties,\n surface: standardProperties.surface ?? 'mcp',\n tool_name: name,\n mcp_tool_category: categorizeMcpTool(name),\n mcp_tool_status: isError ? 'error' : 'success',\n duration_ms: Math.max(0, Date.now() - startedAt),\n mcp_transport: analyticsTransport,\n ...(isError ? { mcp_error_category: categorizeMcpError(thrown ?? result) } : {}),\n ...(explicitRunId ?? enqueueRunId ? { run_id: explicitRunId ?? enqueueRunId } : {}),\n },\n })\n\n if (options.analyticsService) {\n await analyticsService.capture(event).catch(() => {})\n } else {\n await captureAnalytics(event, {\n config: options.analyticsConfig,\n surface: 'mcp',\n }).catch(() => {})\n }\n }\n } catch {\n // MCP analytics must never alter tool behavior.\n }\n }\n }) as ToolCallback<InputArgs>)\n const dashboardUrlField = z.string().url().optional().describe('Dashboard base URL; defaults to the MCP server dashboard URL.')\n const dashboardUrlFor = (inputUrl?: string): string => {\n const dashboardUrl = inputUrl ?? options.dashboardUrl\n if (!dashboardUrl) {\n throw new Error('dashboardUrl is required for authoring tools. Start MCP via `agent-qa dashboard` or pass dashboardUrl.')\n }\n return dashboardUrl\n }\n const dashboardTool = async (\n dashboardUrl: string | undefined,\n path: string,\n method?: 'GET' | 'POST' | 'PUT' | 'DELETE',\n body?: unknown,\n ) => {\n try {\n const result = await callDashboardApi({\n dashboardUrl: dashboardUrlFor(dashboardUrl),\n path,\n method,\n body,\n })\n return jsonContent(result)\n } catch (err) {\n return errorContent(err instanceof Error ? err.message : String(err))\n }\n }\n\n registerAnalyticsTool(\n 'agent_qa_discover',\n {\n title: 'Discover agent-qa MCP capabilities',\n description: 'Return structured metadata for agent-qa MCP tools, resources, prompts, and current rollout scope.',\n inputSchema: {},\n },\n async () => jsonContent({\n ...DISCOVERY,\n endpoint: options.endpointUrl,\n dashboard: options.dashboardUrl,\n configPath: options.configPath,\n }),\n )\n\n registerAnalyticsTool(\n 'agent_qa_get_config',\n {\n title: 'Inspect agent-qa config',\n description: 'Read the active agent-qa config and return a masked raw config plus targets/devices/providers summary.',\n inputSchema: {\n configPath: z.string().optional().describe('Config path; defaults to the MCP server config path or agent-qa.config.yaml'),\n section: z.enum(['raw', 'summary']).optional().describe('Return full masked raw config or summary only'),\n },\n },\n async ({ configPath, section }) => {\n const config = await readConfig(configPath ?? options.configPath)\n return jsonContent(section === 'summary'\n ? { path: config.path, valid: config.valid, issues: config.issues, summary: config.summary }\n : config)\n },\n )\n\n registerAnalyticsTool(\n 'agent_qa_schema_reference',\n {\n title: 'Get agent-qa schema reference',\n description: 'Return structured references for config, test YAML, suite YAML, hooks, or canonical IDs.',\n inputSchema: {\n schema: z.enum(SCHEMA_REFERENCE_NAMES).describe('Reference name to return'),\n },\n },\n async ({ schema }) => jsonContent(AGENT_QA_SCHEMA_REFERENCES[schema as SchemaReferenceName]),\n )\n\n registerAnalyticsTool(\n 'agent_qa_validate_definition',\n {\n title: 'Validate agent-qa definition',\n description: 'Validate config/test/suite/hooks objects with the same core schemas agent-qa uses.',\n inputSchema: {\n kind: z.enum(VALIDATION_KINDS).describe('Definition kind'),\n definition: z.unknown().describe('Parsed config/test/suite/hooks object'),\n },\n },\n async ({ kind, definition }) => jsonContent(validateAgentQaDefinition(kind as ValidationKind, definition)),\n )\n\n registerAnalyticsTool(\n 'agent_qa_generate_id',\n {\n title: 'Generate canonical agent-qa ID',\n description: 'Generate a canonical id-agent backed ID for a test, suite, hook, run, or observation.',\n inputSchema: {\n type: z.enum(ENTITY_ID_TYPES).describe('ID entity type'),\n },\n },\n async ({ type }) => {\n const idType = type as typeof ENTITY_ID_TYPES[number]\n return jsonContent({\n id: generateCanonicalId(idType),\n type: idType,\n contract: getEntityIdContract(idType),\n })\n },\n )\n\n registerAnalyticsTool(\n 'agent_qa_validate_id',\n {\n title: 'Validate canonical agent-qa ID',\n description: 'Validate canonical id-agent backed IDs and return the expected contract.',\n inputSchema: {\n type: z.enum(ENTITY_ID_TYPES).describe('ID entity type'),\n id: z.string().describe('ID to validate'),\n },\n },\n async ({ type, id }) => {\n const idType = type as typeof ENTITY_ID_TYPES[number]\n const contract = getEntityIdContract(idType)\n const valid = isCanonicalId(idType, id)\n return jsonContent({\n valid,\n id,\n type: idType,\n contract,\n message: valid\n ? 'ID is canonical.'\n : `Expected ${contract.prefixWithSeparator} followed by ${contract.words} id-agent words.`,\n })\n },\n )\n\n registerAnalyticsTool(\n 'agent_qa_list_tests',\n {\n title: 'List agent-qa tests',\n description: 'List tests through the dashboard API using dashboard workspace discovery.',\n inputSchema: { dashboardUrl: dashboardUrlField },\n },\n async ({ dashboardUrl }) => dashboardTool(dashboardUrl, '/api/tests'),\n )\n\n registerAnalyticsTool(\n 'agent_qa_read_test',\n {\n title: 'Read agent-qa test',\n description: 'Read a test by canonical test ID through the dashboard API.',\n inputSchema: {\n dashboardUrl: dashboardUrlField,\n testId: z.string().describe('Canonical t_ test ID'),\n },\n },\n async ({ dashboardUrl, testId }) => dashboardTool(dashboardUrl, `/api/tests/${encodeURIComponent(testId)}`),\n )\n\n registerAnalyticsTool(\n 'agent_qa_validate_test',\n {\n title: 'Validate agent-qa test YAML',\n description: 'Validate test YAML through the dashboard test-file manager.',\n inputSchema: {\n dashboardUrl: dashboardUrlField,\n content: z.string().describe('Test YAML content'),\n filePath: z.string().optional().describe('Optional file path for suite/test routing hints'),\n },\n },\n async ({ dashboardUrl, content, filePath }) => dashboardTool(dashboardUrl, '/api/tests/validate', 'POST', { content, filePath }),\n )\n\n registerAnalyticsTool(\n 'agent_qa_create_test',\n {\n title: 'Create agent-qa test',\n description: 'Create a test file through the dashboard workspace-safe file manager.',\n inputSchema: {\n dashboardUrl: dashboardUrlField,\n path: z.string().describe('Workspace-relative test path matched by workspace.testMatch'),\n content: z.string().describe('Test YAML content'),\n },\n },\n async ({ dashboardUrl, path, content }) => dashboardTool(dashboardUrl, '/api/tests', 'POST', { path, content }),\n )\n\n registerAnalyticsTool(\n 'agent_qa_update_test',\n {\n title: 'Update agent-qa test',\n description: 'Update a test by canonical test ID through the dashboard API.',\n inputSchema: {\n dashboardUrl: dashboardUrlField,\n testId: z.string().describe('Canonical t_ test ID'),\n content: z.string().describe('Replacement test YAML content'),\n },\n },\n async ({ dashboardUrl, testId, content }) => dashboardTool(dashboardUrl, `/api/tests/${encodeURIComponent(testId)}`, 'PUT', { content }),\n )\n\n registerAnalyticsTool(\n 'agent_qa_delete_test',\n {\n title: 'Delete agent-qa test',\n description: 'Delete a test by canonical test ID through the dashboard API.',\n inputSchema: {\n dashboardUrl: dashboardUrlField,\n testId: z.string().describe('Canonical t_ test ID'),\n },\n },\n async ({ dashboardUrl, testId }) => dashboardTool(dashboardUrl, `/api/tests/${encodeURIComponent(testId)}`, 'DELETE'),\n )\n\n registerAnalyticsTool(\n 'agent_qa_list_suites',\n {\n title: 'List agent-qa suites',\n description: 'List suites through the dashboard API using dashboard workspace discovery.',\n inputSchema: { dashboardUrl: dashboardUrlField },\n },\n async ({ dashboardUrl }) => dashboardTool(dashboardUrl, '/api/suites'),\n )\n\n registerAnalyticsTool(\n 'agent_qa_read_suite',\n {\n title: 'Read agent-qa suite',\n description: 'Read a suite by canonical suite ID through the dashboard API.',\n inputSchema: {\n dashboardUrl: dashboardUrlField,\n suiteId: z.string().describe('Canonical s_ suite ID'),\n },\n },\n async ({ dashboardUrl, suiteId }) => dashboardTool(dashboardUrl, `/api/suites/${encodeURIComponent(suiteId)}`),\n )\n\n registerAnalyticsTool(\n 'agent_qa_validate_suite',\n {\n title: 'Validate agent-qa suite YAML',\n description: 'Validate suite YAML through the dashboard suite-file manager.',\n inputSchema: {\n dashboardUrl: dashboardUrlField,\n content: z.string().describe('Suite YAML content'),\n },\n },\n async ({ dashboardUrl, content }) => dashboardTool(dashboardUrl, '/api/suites/validate', 'POST', { content }),\n )\n\n registerAnalyticsTool(\n 'agent_qa_create_suite',\n {\n title: 'Create agent-qa suite',\n description: 'Create a suite file through the dashboard workspace-safe suite manager.',\n inputSchema: {\n dashboardUrl: dashboardUrlField,\n path: z.string().describe('Workspace-relative suite path matched by workspace.suiteMatch'),\n content: z.string().describe('Suite YAML content'),\n },\n },\n async ({ dashboardUrl, path, content }) => dashboardTool(dashboardUrl, '/api/suites', 'POST', { path, content }),\n )\n\n registerAnalyticsTool(\n 'agent_qa_update_suite',\n {\n title: 'Update agent-qa suite',\n description: 'Update a suite by canonical suite ID through the dashboard API.',\n inputSchema: {\n dashboardUrl: dashboardUrlField,\n suiteId: z.string().describe('Canonical s_ suite ID'),\n content: z.string().describe('Replacement suite YAML content'),\n },\n },\n async ({ dashboardUrl, suiteId, content }) => dashboardTool(dashboardUrl, `/api/suites/${encodeURIComponent(suiteId)}`, 'PUT', { content }),\n )\n\n registerAnalyticsTool(\n 'agent_qa_delete_suite',\n {\n title: 'Delete agent-qa suite',\n description: 'Delete a suite through the dashboard API. Prefer suiteId; path is supported for the dashboard delete route.',\n inputSchema: {\n dashboardUrl: dashboardUrlField,\n suiteId: z.string().optional().describe('Canonical s_ suite ID'),\n path: z.string().optional().describe('Workspace-relative suite path'),\n },\n },\n async ({ dashboardUrl, suiteId, path }) => {\n if (path) return dashboardTool(dashboardUrl, `/api/suites/${encodeURIComponent(path)}`, 'DELETE')\n if (!suiteId) return errorContent('Either suiteId or path is required.')\n let readResult: Awaited<ReturnType<typeof callDashboardApi>>\n try {\n readResult = await callDashboardApi({\n dashboardUrl: dashboardUrlFor(dashboardUrl),\n path: `/api/suites/${encodeURIComponent(suiteId)}`,\n })\n } catch (err) {\n return errorContent(err instanceof Error ? err.message : String(err))\n }\n if (!readResult.ok || !readResult.body || typeof readResult.body !== 'object') return jsonContent(readResult)\n const foundPath = (readResult.body as Record<string, unknown>).path\n if (typeof foundPath !== 'string') return errorContent('Suite read response did not include a path.')\n return dashboardTool(dashboardUrl, `/api/suites/${encodeURIComponent(foundPath)}`, 'DELETE')\n },\n )\n\n registerAnalyticsTool(\n 'agent_qa_list_hooks',\n {\n title: 'List agent-qa hooks',\n description: 'List hooks through the dashboard hook registry API.',\n inputSchema: { dashboardUrl: dashboardUrlField },\n },\n async ({ dashboardUrl }) => dashboardTool(dashboardUrl, '/api/hooks'),\n )\n\n registerAnalyticsTool(\n 'agent_qa_read_hook',\n {\n title: 'Read agent-qa hook',\n description: 'Read hook metadata and source by canonical hook ID.',\n inputSchema: {\n dashboardUrl: dashboardUrlField,\n hookId: z.string().describe('Canonical h_ hook ID'),\n },\n },\n async ({ dashboardUrl, hookId }) => dashboardTool(dashboardUrl, `/api/hooks/${encodeURIComponent(hookId)}`),\n )\n\n registerAnalyticsTool(\n 'agent_qa_create_hook',\n {\n title: 'Create agent-qa hook',\n description: 'Create a hook through the dashboard hook registry API.',\n inputSchema: {\n dashboardUrl: dashboardUrlField,\n payload: z.record(z.string(), z.unknown()).describe('Dashboard HookMutationRequest payload'),\n },\n },\n async ({ dashboardUrl, payload }) => dashboardTool(dashboardUrl, '/api/hooks', 'POST', payload),\n )\n\n registerAnalyticsTool(\n 'agent_qa_update_hook',\n {\n title: 'Update agent-qa hook',\n description: 'Update a hook through the dashboard hook registry API.',\n inputSchema: {\n dashboardUrl: dashboardUrlField,\n hookId: z.string().describe('Canonical h_ hook ID'),\n payload: z.record(z.string(), z.unknown()).describe('Dashboard HookMutationRequest payload'),\n },\n },\n async ({ dashboardUrl, hookId, payload }) => dashboardTool(dashboardUrl, `/api/hooks/${encodeURIComponent(hookId)}`, 'PUT', payload),\n )\n\n registerAnalyticsTool(\n 'agent_qa_delete_hook',\n {\n title: 'Delete agent-qa hook',\n description: 'Delete a hook through the dashboard hook registry API.',\n inputSchema: {\n dashboardUrl: dashboardUrlField,\n hookId: z.string().describe('Canonical h_ hook ID'),\n force: z.boolean().optional().describe('Delete even when references exist'),\n },\n },\n async ({ dashboardUrl, hookId, force }) => dashboardTool(dashboardUrl, `/api/hooks/${encodeURIComponent(hookId)}${force ? '?force=true' : ''}`, 'DELETE'),\n )\n\n registerAnalyticsTool(\n 'agent_qa_run_hook',\n {\n title: 'Run agent-qa hook',\n description: 'Run a hook through the dashboard hook execution API.',\n inputSchema: {\n dashboardUrl: dashboardUrlField,\n hookId: z.string().describe('Canonical h_ hook ID'),\n payload: z.record(z.string(), z.unknown()).optional().describe('Dashboard HookRunRequest payload'),\n },\n },\n async ({ dashboardUrl, hookId, payload }) => dashboardTool(dashboardUrl, `/api/hooks/${encodeURIComponent(hookId)}/run`, 'POST', payload ?? {}),\n )\n\n registerAnalyticsTool(\n 'agent_qa_enqueue_test_run',\n {\n title: 'Enqueue agent-qa test run',\n description: 'Queue a test run through the dashboard run trigger API and return the canonical run ID.',\n inputSchema: {\n dashboardUrl: dashboardUrlField,\n file: z.string().optional().describe('Workspace-relative test file path'),\n patterns: z.array(z.string()).optional().describe('Optional test patterns'),\n noCache: z.boolean().optional(),\n noMemory: z.boolean().optional(),\n local: z.boolean().optional(),\n },\n },\n async ({ dashboardUrl, file, patterns, noCache, noMemory, local }) => dashboardTool(dashboardUrl, '/api/runs/trigger', 'POST', { file, patterns, noCache, noMemory, local, triggerSource: 'mcp' }),\n )\n\n registerAnalyticsTool(\n 'agent_qa_enqueue_suite_run',\n {\n title: 'Enqueue agent-qa suite run',\n description: 'Queue a suite run through the dashboard run trigger API and return parent run context.',\n inputSchema: {\n dashboardUrl: dashboardUrlField,\n file: z.string().describe('Workspace-relative suite file path'),\n noCache: z.boolean().optional(),\n noMemory: z.boolean().optional(),\n local: z.boolean().optional(),\n },\n },\n async ({ dashboardUrl, file, noCache, noMemory, local }) => dashboardTool(dashboardUrl, '/api/runs/trigger', 'POST', { file, noCache, noMemory, local, triggerSource: 'mcp' }),\n )\n\n registerAnalyticsTool(\n 'agent_qa_get_run',\n {\n title: 'Get agent-qa run',\n description: 'Get run detail, steps, attempts, and suite child context through the dashboard API.',\n inputSchema: {\n dashboardUrl: dashboardUrlField,\n runId: z.string().describe('Canonical r_ run ID'),\n },\n },\n async ({ dashboardUrl, runId }) => dashboardTool(dashboardUrl, `/api/runs/${encodeURIComponent(runId)}`),\n )\n\n registerAnalyticsTool(\n 'agent_qa_get_run_steps',\n {\n title: 'Get agent-qa run steps',\n description: 'Get run steps through the dashboard API.',\n inputSchema: {\n dashboardUrl: dashboardUrlField,\n runId: z.string().describe('Canonical r_ run ID'),\n },\n },\n async ({ dashboardUrl, runId }) => dashboardTool(dashboardUrl, `/api/runs/${encodeURIComponent(runId)}/steps`),\n )\n\n registerAnalyticsTool(\n 'agent_qa_get_run_logs',\n {\n title: 'Get agent-qa run logs',\n description: 'Get run log rows through the dashboard API.',\n inputSchema: {\n dashboardUrl: dashboardUrlField,\n runId: z.string().describe('Canonical r_ run ID'),\n stepId: z.string().optional(),\n level: z.string().optional(),\n source: z.string().optional(),\n limit: z.number().int().positive().optional(),\n offset: z.number().int().min(0).optional(),\n },\n },\n async ({ dashboardUrl, runId, stepId, level, source, limit, offset }) => dashboardTool(\n dashboardUrl,\n withQuery(`/api/runs/${encodeURIComponent(runId)}/logs`, { stepId, level, source, limit, offset }),\n ),\n )\n\n registerAnalyticsTool(\n 'agent_qa_get_run_execution_logs',\n {\n title: 'Get agent-qa execution logs',\n description: 'Get structured execution logs through the dashboard API.',\n inputSchema: {\n dashboardUrl: dashboardUrlField,\n runId: z.string().describe('Canonical r_ run ID'),\n stepId: z.string().optional(),\n type: z.string().optional(),\n },\n },\n async ({ dashboardUrl, runId, stepId, type }) => dashboardTool(\n dashboardUrl,\n withQuery(`/api/runs/${encodeURIComponent(runId)}/execution-logs`, { stepId, type }),\n ),\n )\n\n registerAnalyticsTool(\n 'agent_qa_get_run_artifact',\n {\n title: 'Get agent-qa run artifact bundle',\n description: 'Get sanitized run artifact bundle, child artifacts, and missing artifact sections.',\n inputSchema: {\n dashboardUrl: dashboardUrlField,\n runId: z.string().describe('Canonical r_ run ID'),\n },\n },\n async ({ dashboardUrl, runId }) => dashboardTool(dashboardUrl, `/api/runs/${encodeURIComponent(runId)}/artifact`),\n )\n\n registerAnalyticsTool(\n 'agent_qa_cancel_run',\n {\n title: 'Cancel agent-qa run',\n description: 'Cancel a pending or running run through the dashboard queue.',\n inputSchema: {\n dashboardUrl: dashboardUrlField,\n runId: z.string().describe('Canonical r_ run ID'),\n },\n },\n async ({ dashboardUrl, runId }) => dashboardTool(dashboardUrl, `/api/runs/${encodeURIComponent(runId)}/cancel`, 'POST', {}),\n )\n\n registerAnalyticsTool(\n 'agent_qa_classify_failure',\n {\n title: 'Classify agent-qa failure',\n description: 'Classify a failed run using dashboard run detail, artifacts, logs, execution logs, and recent related runs.',\n inputSchema: {\n dashboardUrl: dashboardUrlField,\n runId: z.string().describe('Canonical r_ run ID'),\n },\n },\n async ({ dashboardUrl, runId }) => {\n try {\n const baseUrl = dashboardUrlFor(dashboardUrl)\n const runDetail = await callDashboardApi({ dashboardUrl: baseUrl, path: `/api/runs/${encodeURIComponent(runId)}` })\n const artifact = await callDashboardApi({ dashboardUrl: baseUrl, path: `/api/runs/${encodeURIComponent(runId)}/artifact` })\n const logs = await callDashboardApi({ dashboardUrl: baseUrl, path: `/api/runs/${encodeURIComponent(runId)}/logs` })\n const executionLogs = await callDashboardApi({ dashboardUrl: baseUrl, path: `/api/runs/${encodeURIComponent(runId)}/execution-logs` })\n const runName = runDetail.body && typeof runDetail.body === 'object'\n && (runDetail.body as Record<string, unknown>).run\n && typeof (runDetail.body as { run?: { name?: unknown } }).run?.name === 'string'\n ? (runDetail.body as { run: { name: string } }).run.name\n : undefined\n const recentRuns = runName\n ? await callDashboardApi({ dashboardUrl: baseUrl, path: withQuery('/api/runs', { name: runName, limit: 5 }) })\n : { ok: true, status: 200, body: { runs: [] } }\n return jsonContent({\n runId,\n classification: classifyRunFailureFromDashboardData({\n runDetail: runDetail.body,\n artifact: artifact.body,\n logs: logs.body,\n executionLogs: executionLogs.body,\n recentRuns: recentRuns.body,\n }),\n sources: {\n run: { ok: runDetail.ok, status: runDetail.status },\n artifact: { ok: artifact.ok, status: artifact.status },\n logs: { ok: logs.ok, status: logs.status },\n executionLogs: { ok: executionLogs.ok, status: executionLogs.status },\n recentRuns: { ok: recentRuns.ok, status: recentRuns.status },\n },\n })\n } catch (err) {\n return errorContent(err instanceof Error ? err.message : String(err))\n }\n },\n )\n\n for (const schema of SCHEMA_REFERENCE_NAMES) {\n server.registerResource(\n `agent_qa.schema.${schema}`,\n `agent-qa://schema/${schema}`,\n {\n title: `agent-qa ${schema} schema reference`,\n description: `Structured agent-qa reference for ${schema}.`,\n mimeType: 'application/json',\n },\n async uri => ({\n contents: [{\n uri: uri.href,\n mimeType: 'application/json',\n text: JSON.stringify(AGENT_QA_SCHEMA_REFERENCES[schema], null, 2),\n }],\n }),\n )\n }\n\n server.registerPrompt(\n 'agent_qa_authoring_context',\n {\n title: 'agent-qa authoring context',\n description: 'Prompt context for agents writing agent-qa tests and suites.',\n argsSchema: {},\n },\n async () => ({\n messages: [{\n role: 'user',\n content: {\n type: 'text',\n text: [\n 'Use agent-qa MCP tools before editing files.',\n 'Call agent_qa_get_config to inspect targets/devices/providers.',\n 'Call agent_qa_generate_id for test, suite, hook, run, and observation IDs.',\n 'Call agent_qa_validate_definition before saving config, test, suite, or hooks YAML.',\n `Canonical ID contracts: ${JSON.stringify(getEntityIdContracts())}`,\n ].join('\\n'),\n },\n }],\n }),\n )\n\n return server\n}\n\nexport {\n AGENT_QA_SCHEMA_REFERENCES,\n validateAgentQaDefinition,\n} from './schema-reference.js'\n","import {\n AgentQaConfigSchema,\n HooksFileSchema,\n SuiteDefinitionSchema,\n TestDefinitionSchema,\n} from '@vostride/agent-qa-core'\nimport {\n getEntityIdContracts,\n type EntityIdType,\n} from '@vostride/agent-qa-ids'\n\nexport const SCHEMA_REFERENCE_NAMES = ['config', 'test', 'suite', 'hooks', 'ids'] as const\nexport type SchemaReferenceName = typeof SCHEMA_REFERENCE_NAMES[number]\nexport const VALIDATION_KINDS = ['config', 'test', 'suite', 'hooks'] as const\nexport type ValidationKind = typeof VALIDATION_KINDS[number]\n\nexport const AGENT_QA_SCHEMA_REFERENCES = {\n config: {\n name: 'agent-qa config',\n rootKeys: ['workspace', 'services', 'registry', 'use', 'analytics'],\n services: {\n dashboard: ['port', 'dbPath', 'artifactsDir'],\n mcp: ['enabled', 'transport', 'host', 'port', 'path'],\n cache: ['dir', 'ttl'],\n logging: ['level'],\n recording: ['enabled'],\n accessibility: ['enabled', 'standard', 'runAfter', 'failOnViolation', 'disableRules', 'exclude'],\n memory: ['enabled', 'provider', 'dir', 'minTrust', 'maxInjections', 'curatorEnabled'],\n },\n mcpLocalOnly: {\n transports: ['http', 'stdio'],\n hosts: ['localhost', '127.0.0.1', '::1'],\n defaultPort: 3471,\n defaultPath: '/mcp',\n },\n },\n test: {\n name: 'agent-qa test YAML',\n requiredKeys: ['test-id', 'name', 'target', 'steps'],\n optionalKeys: ['context', 'use', 'meta', 'setup', 'teardown'],\n idType: 'test' as EntityIdType,\n hookReferences: 'setup and teardown arrays must contain canonical h_ hook IDs.',\n stepFormats: ['string', 'object with step/timeout/retries/screenshot/capture/maxAttempts'],\n },\n suite: {\n name: 'agent-qa suite YAML',\n requiredKeys: ['name', 'target', 'tests'],\n optionalKeys: ['suite-id', 'context', 'setup', 'teardown', 'use'],\n idType: 'suite' as EntityIdType,\n testReference: 'Each tests[] entry uses { test: path, id: canonical t_ test ID }.',\n hookReferences: 'setup and teardown arrays must contain canonical h_ hook IDs.',\n },\n hooks: {\n name: 'agent-qa hooks file',\n rootKeys: ['hooks'],\n hookKeys: ['id', 'name', 'runtime', 'file', 'deps', 'packageFile', 'timeout', 'network'],\n idType: 'hook' as EntityIdType,\n runtimes: ['node', 'bun', 'python', 'bash'],\n },\n ids: {\n name: 'agent-qa canonical IDs',\n instruction: 'Generate IDs with agent_qa_generate_id or `agent-qa ids generate <type>`; never hand-write IDs.',\n contracts: getEntityIdContracts(),\n },\n} as const\n\nconst VALIDATION_SCHEMAS = {\n config: AgentQaConfigSchema,\n test: TestDefinitionSchema,\n suite: SuiteDefinitionSchema,\n hooks: HooksFileSchema,\n} as const\n\nexport interface ValidationIssue {\n path: string\n message: string\n}\n\nexport interface DefinitionValidationResult {\n valid: boolean\n kind: ValidationKind\n issues: ValidationIssue[]\n}\n\nexport function validateAgentQaDefinition(\n kind: ValidationKind,\n definition: unknown,\n): DefinitionValidationResult {\n const result = VALIDATION_SCHEMAS[kind].safeParse(definition)\n if (result.success) {\n return {\n valid: true,\n kind,\n issues: [],\n }\n }\n\n return {\n valid: false,\n kind,\n issues: result.error.issues.map(issue => ({\n path: issue.path.map(String).join('.') || '(root)',\n message: issue.message,\n })),\n }\n}\n","import type { IncomingMessage, ServerResponse } from 'node:http'\nimport { StreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/streamableHttp.js'\nimport { createAgentQaMcpServer, type AgentQaMcpServerOptions } from './agent-qa-server.js'\n\nexport const DEFAULT_MCP_HOST = '127.0.0.1'\nexport const DEFAULT_MCP_PORT = 3471\nexport const DEFAULT_MCP_PATH = '/mcp'\n\nexport type LocalMcpTransport = 'http' | 'stdio'\n\nexport interface LocalMcpEndpointConfig {\n enabled?: boolean\n transport?: LocalMcpTransport\n host?: string\n port?: number\n path?: string\n}\n\nexport interface LocalMcpEndpoint {\n enabled: boolean\n transport: LocalMcpTransport\n host: string\n port: number\n path: string\n url: string\n}\n\nexport interface McpHttpHandlerOptions {\n endpoint?: Partial<LocalMcpEndpoint>\n dashboardUrl?: string\n configPath?: string\n analyticsConfig?: AgentQaMcpServerOptions['analyticsConfig']\n}\n\nexport interface LocalMcpEndpointShape {\n mcp_host_kind: 'loopback' | 'other'\n mcp_port_kind: 'default' | 'custom'\n mcp_path_kind: 'default' | 'custom'\n}\n\nfunction normalizePath(path: string | undefined): string {\n if (!path) return DEFAULT_MCP_PATH\n return path.startsWith('/') ? path : `/${path}`\n}\n\nfunction jsonRpcError(res: ServerResponse, status: number, message: string): void {\n res.writeHead(status, {\n 'Content-Type': 'application/json',\n 'Access-Control-Allow-Origin': '*',\n })\n res.end(JSON.stringify({\n jsonrpc: '2.0',\n error: {\n code: -32000,\n message,\n },\n id: null,\n }))\n}\n\nexport function resolveLocalMcpEndpoint(config: LocalMcpEndpointConfig = {}): LocalMcpEndpoint {\n const transport = config.transport ?? 'http'\n const host = config.host ?? DEFAULT_MCP_HOST\n const port = config.port ?? DEFAULT_MCP_PORT\n const path = normalizePath(config.path)\n const displayHost = host === '::1' ? '[::1]' : host\n\n return {\n enabled: config.enabled !== false,\n transport,\n host,\n port,\n path,\n url: `http://${displayHost}:${port}${path}`,\n }\n}\n\nexport function resolveMcpEndpointShape(\n endpoint: Pick<LocalMcpEndpoint, 'host' | 'port' | 'path'>,\n): LocalMcpEndpointShape {\n return {\n mcp_host_kind: ['127.0.0.1', 'localhost', '::1'].includes(endpoint.host) ? 'loopback' : 'other',\n mcp_port_kind: endpoint.port === DEFAULT_MCP_PORT ? 'default' : 'custom',\n mcp_path_kind: endpoint.path === DEFAULT_MCP_PATH ? 'default' : 'custom',\n }\n}\n\nexport function createLocalMcpHttpHandler(options: McpHttpHandlerOptions = {}) {\n const endpoint = resolveLocalMcpEndpoint(options.endpoint)\n const baseHost = endpoint.host === '::1' ? '[::1]' : endpoint.host\n\n return async (req: IncomingMessage, res: ServerResponse): Promise<void> => {\n const requestUrl = new URL(req.url ?? '/', `http://${baseHost}:${endpoint.port}`)\n if (requestUrl.pathname !== endpoint.path) {\n jsonRpcError(res, 404, `MCP endpoint is available at ${endpoint.path}`)\n return\n }\n\n if (req.method === 'OPTIONS') {\n res.writeHead(204, {\n 'Access-Control-Allow-Origin': '*',\n 'Access-Control-Allow-Methods': 'GET, POST, DELETE, OPTIONS',\n 'Access-Control-Allow-Headers': 'Content-Type, MCP-Protocol-Version, mcp-session-id',\n })\n res.end()\n return\n }\n\n const server = createAgentQaMcpServer({\n configPath: options.configPath,\n dashboardUrl: options.dashboardUrl,\n endpointUrl: endpoint.url,\n analyticsConfig: options.analyticsConfig,\n transport: 'http',\n })\n const transport = new StreamableHTTPServerTransport({\n sessionIdGenerator: undefined,\n })\n\n try {\n await server.connect(transport)\n await transport.handleRequest(req, res)\n res.on('close', () => {\n void transport.close()\n void server.close()\n })\n } catch (err) {\n void transport.close()\n void server.close()\n if (!res.headersSent) {\n jsonRpcError(\n res,\n 500,\n err instanceof Error ? err.message : 'Internal MCP server error',\n )\n }\n }\n }\n}\n"],"mappings":"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","names":["buildAnalyticsEvent","captureAnalytics","resolveAnalyticsStandardProperties","AgentQaConfigSchema","getEntityIdContracts","AgentQaConfigSchema","getEntityIdContracts","resolveAnalyticsStandardProperties","buildAnalyticsEvent","captureAnalytics"]}
|
|
1
|
+
{"version":3,"sources":["../src/server.ts","../src/agent-qa-server.ts","../src/schema-reference.ts","../src/local-http.ts"],"sourcesContent":["import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'\nimport {\n buildAnalyticsEvent,\n captureAnalytics,\n resolveAnalyticsStandardProperties,\n} from '@vostride/agent-qa-core'\nimport { createAgentQaMcpServer, type AgentQaMcpServerOptions } from './agent-qa-server.js'\n\nexport const MCP_STDIO_STARTUP_MESSAGE =\n 'agent-qa MCP server running over stdio. Waiting for MCP client messages on stdin. Stdout is reserved for MCP protocol traffic.'\n\nexport interface StartMcpServerOptions extends AgentQaMcpServerOptions {\n startupOutput?: Pick<NodeJS.WritableStream, 'write'>\n}\n\nexport function createMcpServer(options: AgentQaMcpServerOptions = {}) {\n return createAgentQaMcpServer(options)\n}\n\nexport async function startMcpServer(options: StartMcpServerOptions = {}): Promise<void> {\n const { startupOutput, ...serverOptions } = options\n const server = createMcpServer({ ...serverOptions, transport: 'stdio' })\n const transport = new StdioServerTransport()\n await server.connect(transport)\n try {\n startupOutput?.write(`${MCP_STDIO_STARTUP_MESSAGE}\\n`)\n } catch {\n // Startup visibility is best-effort; the MCP server is already connected.\n }\n try {\n if (options.analyticsConfig?.analytics?.privacy !== true) {\n const standardProperties = options.analyticsStandardProperties\n ?? await resolveAnalyticsStandardProperties({ surface: 'mcp' })\n const event = buildAnalyticsEvent({\n name: 'agent-qa.mcp.server.lifecycle',\n properties: {\n ...standardProperties,\n surface: standardProperties.surface ?? 'mcp',\n mcp_server_state: 'started',\n mcp_transport: 'stdio',\n },\n })\n if (options.analyticsService) {\n await options.analyticsService.capture(event).catch(() => {})\n } else {\n await captureAnalytics(event, {\n config: options.analyticsConfig,\n surface: 'mcp',\n }).catch(() => {})\n }\n }\n } catch {\n // MCP startup analytics is intentionally best-effort.\n }\n}\n","import { readFile } from 'node:fs/promises'\nimport { resolve } from 'node:path'\nimport { McpServer, type ToolCallback } from '@modelcontextprotocol/sdk/server/mcp.js'\nimport type { AnySchema, ZodRawShapeCompat } from '@modelcontextprotocol/sdk/server/zod-compat.js'\nimport type { ToolAnnotations } from '@modelcontextprotocol/sdk/types.js'\nimport {\n AgentQaConfigSchema,\n buildAnalyticsEvent,\n captureAnalytics,\n createAnalyticsService,\n getAgentQaVersion,\n redactAuthStateValue,\n resolveAnalyticsStandardProperties,\n type AnalyticsEventProperties,\n type AnalyticsService,\n type AnalyticsServiceConfig,\n} from '@vostride/agent-qa-core'\nimport {\n ENTITY_ID_TYPES,\n generateCanonicalId,\n getEntityIdContract,\n getEntityIdContracts,\n isCanonicalId,\n} from '@vostride/agent-qa-ids'\nimport { parse as parseYaml } from 'yaml'\nimport { z } from 'zod'\nimport {\n AGENT_QA_SCHEMA_REFERENCES,\n SCHEMA_REFERENCE_NAMES,\n VALIDATION_KINDS,\n validateAgentQaDefinition,\n type SchemaReferenceName,\n type ValidationKind,\n} from './schema-reference.js'\n\nexport interface AgentQaMcpServerOptions {\n configPath?: string\n dashboardUrl?: string\n endpointUrl?: string\n analyticsService?: AnalyticsService\n analyticsConfig?: AnalyticsServiceConfig\n analyticsStandardProperties?: AnalyticsEventProperties\n transport?: 'stdio' | 'http'\n}\n\ntype McpToolCategory = NonNullable<AnalyticsEventProperties['mcp_tool_category']>\ntype McpErrorCategory = NonNullable<AnalyticsEventProperties['mcp_error_category']>\ntype McpToolDefinition<\n OutputArgs extends ZodRawShapeCompat | AnySchema = ZodRawShapeCompat,\n InputArgs extends undefined | ZodRawShapeCompat | AnySchema = undefined,\n> = {\n title?: string\n description?: string\n inputSchema?: InputArgs\n outputSchema?: OutputArgs\n annotations?: ToolAnnotations\n _meta?: Record<string, unknown>\n}\n\nconst DISCOVERY = {\n name: 'agent-qa',\n purpose: 'Author, validate, run, and triage agent-qa tests through local trusted MCP.',\n tools: [\n 'agent_qa_discover',\n 'agent_qa_get_config',\n 'agent_qa_schema_reference',\n 'agent_qa_validate_definition',\n 'agent_qa_generate_id',\n 'agent_qa_validate_id',\n 'agent_qa_list_tests',\n 'agent_qa_read_test',\n 'agent_qa_validate_test',\n 'agent_qa_create_test',\n 'agent_qa_update_test',\n 'agent_qa_delete_test',\n 'agent_qa_list_suites',\n 'agent_qa_read_suite',\n 'agent_qa_validate_suite',\n 'agent_qa_create_suite',\n 'agent_qa_update_suite',\n 'agent_qa_delete_suite',\n 'agent_qa_list_hooks',\n 'agent_qa_read_hook',\n 'agent_qa_create_hook',\n 'agent_qa_update_hook',\n 'agent_qa_delete_hook',\n 'agent_qa_run_hook',\n 'agent_qa_enqueue_test_run',\n 'agent_qa_enqueue_suite_run',\n 'agent_qa_get_run',\n 'agent_qa_get_run_steps',\n 'agent_qa_get_run_logs',\n 'agent_qa_get_run_execution_logs',\n 'agent_qa_get_run_artifact',\n 'agent_qa_cancel_run',\n 'agent_qa_classify_failure',\n ],\n resources: SCHEMA_REFERENCE_NAMES.map(name => `agent-qa://schema/${name}`),\n prompts: ['agent_qa_authoring_context'],\n phases: {\n current: 'discovery-schema-id-contracts',\n next: ['authoring tools', 'run execution and triage tools'],\n },\n}\n\nfunction jsonContent(value: unknown) {\n return {\n content: [{\n type: 'text' as const,\n text: JSON.stringify(value, null, 2),\n }],\n }\n}\n\nfunction errorContent(message: string) {\n return {\n isError: true,\n content: [{\n type: 'text' as const,\n text: message,\n }],\n }\n}\n\nexport function categorizeMcpTool(name: string): McpToolCategory {\n if (name === 'agent_qa_discover') return 'discovery'\n if (name.includes('schema') || name.includes('definition') || name.includes('config')) return 'schema'\n if (name.includes('_id')) return 'id'\n if (name.includes('_hook')) return 'hook'\n if (name.includes('classify')) return 'triage'\n if (name.includes('_run') || name.includes('_logs') || name.includes('_artifact') || name.includes('_fix') || name.includes('_failure')) return 'run'\n if (name.includes('_test') || name.includes('_suite')) return 'authoring'\n return 'unknown'\n}\n\nfunction isErrorResult(value: unknown): boolean {\n return Boolean(value && typeof value === 'object' && (value as { isError?: unknown }).isError === true)\n}\n\nfunction isDashboardErrorResult(value: unknown): boolean {\n const parsed = parseToolJsonContent(value)\n return Boolean(parsed && typeof parsed === 'object' && (parsed as Record<string, unknown>).ok === false)\n}\n\nfunction parseToolJsonContent(value: unknown): unknown {\n if (!value || typeof value !== 'object') return undefined\n const content = (value as { content?: unknown }).content\n if (!Array.isArray(content)) return undefined\n const firstText = content.find(item =>\n item && typeof item === 'object'\n && (item as { type?: unknown }).type === 'text'\n && typeof (item as { text?: unknown }).text === 'string'\n ) as { text: string } | undefined\n if (!firstText) return undefined\n try {\n return JSON.parse(firstText.text)\n } catch {\n return undefined\n }\n}\n\nexport function categorizeMcpError(errOrResult: unknown): McpErrorCategory {\n if (errOrResult instanceof z.ZodError) return 'validation'\n const parsed = parseToolJsonContent(errOrResult)\n const candidate = parsed && typeof parsed === 'object'\n ? parsed as Record<string, unknown>\n : undefined\n if (candidate && candidate.ok === false) return 'dashboard_error'\n if (errOrResult instanceof Error) return 'tool_error'\n if (isErrorResult(errOrResult)) return 'tool_error'\n return 'unknown'\n}\n\nexport function extractExplicitCanonicalRunId(input: unknown): string | undefined {\n if (!input || typeof input !== 'object' || Array.isArray(input)) return undefined\n const runId = (input as Record<string, unknown>).runId\n return typeof runId === 'string' && isCanonicalId('run', runId) ? runId : undefined\n}\n\nexport function extractSuccessfulEnqueueRunId(result: unknown): string | undefined {\n if (isErrorResult(result)) return undefined\n const parsed = parseToolJsonContent(result)\n const container = parsed && typeof parsed === 'object'\n ? parsed as Record<string, unknown>\n : undefined\n if (!container) return undefined\n const body = container.body && typeof container.body === 'object'\n ? container.body as Record<string, unknown>\n : container\n for (const key of ['runId', 'id', 'parentRunId']) {\n const value = body[key]\n if (typeof value === 'string' && isCanonicalId('run', value)) return value\n }\n return undefined\n}\n\nexport function resolveDashboardApiUrl(dashboardUrl: string, apiPath: string): string {\n const base = dashboardUrl.endsWith('/') ? dashboardUrl : `${dashboardUrl}/`\n const normalizedPath = apiPath.startsWith('/') ? apiPath.slice(1) : apiPath\n return new URL(normalizedPath, base).toString()\n}\n\nfunction withQuery(path: string, query: Record<string, string | number | boolean | undefined>): string {\n const params = new URLSearchParams()\n for (const [key, value] of Object.entries(query)) {\n if (value !== undefined) params.set(key, String(value))\n }\n const queryString = params.toString()\n return queryString ? `${path}?${queryString}` : path\n}\n\nasync function callDashboardApi(input: {\n dashboardUrl: string\n path: string\n method?: 'GET' | 'POST' | 'PUT' | 'DELETE'\n body?: unknown\n}): Promise<{\n ok: boolean\n status: number\n body: unknown\n}> {\n const response = await fetch(resolveDashboardApiUrl(input.dashboardUrl, input.path), {\n method: input.method ?? 'GET',\n headers: input.body === undefined ? undefined : { 'content-type': 'application/json' },\n body: input.body === undefined ? undefined : JSON.stringify(input.body),\n })\n const text = await response.text()\n let body: unknown = null\n if (text.length > 0) {\n try {\n body = JSON.parse(text)\n } catch {\n body = text\n }\n }\n\n return {\n ok: response.ok,\n status: response.status,\n body,\n }\n}\n\nexport type FailureCategory =\n | 'passed'\n | 'timeout'\n | 'appium_startup'\n | 'browser_disconnect'\n | 'element_not_found'\n | 'assertion_failure'\n | 'hook_failure'\n | 'infrastructure'\n | 'unknown_failure'\n\nexport interface FailureClassification {\n category: FailureCategory\n confidence: number\n evidence: string[]\n recentRelatedCount: number\n}\n\nfunction collectStrings(value: unknown, output: string[] = [], limit = 80): string[] {\n if (output.length >= limit) return output\n if (typeof value === 'string' && value.trim().length > 0) {\n output.push(value)\n } else if (Array.isArray(value)) {\n for (const item of value) collectStrings(item, output, limit)\n } else if (value && typeof value === 'object') {\n for (const child of Object.values(value as Record<string, unknown>)) collectStrings(child, output, limit)\n }\n return output\n}\n\nfunction classifyByNeedle(\n haystack: string,\n evidence: string[],\n needles: string[],\n category: FailureCategory,\n confidence: number,\n): FailureClassification | null {\n const match = needles.find(needle => haystack.includes(needle))\n if (!match) return null\n const matchingEvidence = evidence.find(item => item.toLowerCase().includes(match)) ?? evidence[0] ?? match\n return {\n category,\n confidence,\n evidence: [matchingEvidence].filter(Boolean).slice(0, 5),\n recentRelatedCount: 0,\n }\n}\n\nexport function classifyRunFailureFromDashboardData(input: {\n runDetail: unknown\n artifact?: unknown\n logs?: unknown\n executionLogs?: unknown\n recentRuns?: unknown\n}): FailureClassification {\n const run = input.runDetail && typeof input.runDetail === 'object'\n ? (input.runDetail as Record<string, unknown>).run\n : undefined\n const status = run && typeof run === 'object'\n ? (run as Record<string, unknown>).status\n : undefined\n const evidence = collectStrings([input.runDetail, input.artifact, input.logs, input.executionLogs])\n const haystack = evidence.join('\\n').toLowerCase()\n const recentRelatedCount = Array.isArray((input.recentRuns as Record<string, unknown> | undefined)?.runs)\n ? ((input.recentRuns as Record<string, unknown>).runs as unknown[]).length\n : 0\n\n if (status && status !== 'failed') {\n return {\n category: 'passed',\n confidence: 0.95,\n evidence: [`Run status is ${String(status)}.`],\n recentRelatedCount,\n }\n }\n\n const checks: Array<[string[], FailureCategory, number]> = [\n [['timed out', 'timeout'], 'timeout', 0.9],\n [['appium server failed', 'appium'], 'appium_startup', 0.9],\n [['browser closed', 'target page, context or browser has been closed', 'browser disconnect'], 'browser_disconnect', 0.85],\n [['hook_not_runnable', 'hook failed', 'hook registry', 'hook'], 'hook_failure', 0.8],\n [['not found', 'no element', 'strict mode violation', 'selector'], 'element_not_found', 0.8],\n [['assert', 'expected', 'verify'], 'assertion_failure', 0.75],\n [['econnrefused', 'enotfound', 'network', 'docker'], 'infrastructure', 0.7],\n ]\n\n for (const [needles, category, confidence] of checks) {\n const result = classifyByNeedle(haystack, evidence, needles, category, confidence)\n if (result) return { ...result, recentRelatedCount }\n }\n\n return {\n category: 'unknown_failure',\n confidence: 0.3,\n evidence: evidence.slice(0, 5),\n recentRelatedCount,\n }\n}\n\nfunction maskSensitive(value: unknown, parentKey = ''): unknown {\n const authRedacted = redactAuthStateValue(value)\n const lower = parentKey.toLowerCase()\n if (typeof authRedacted === 'string' && authRedacted !== value) {\n return authRedacted\n }\n if (typeof authRedacted === 'string' && (\n lower.includes('key')\n || lower.includes('token')\n || lower.includes('secret')\n || lower.includes('password')\n )) {\n return authRedacted.length > 8 ? `${authRedacted.slice(0, 3)}****${authRedacted.slice(-4)}` : '****'\n }\n if (Array.isArray(authRedacted)) return authRedacted.map(item => maskSensitive(item, parentKey))\n if (authRedacted && typeof authRedacted === 'object') {\n return Object.fromEntries(\n Object.entries(authRedacted as Record<string, unknown>).map(([key, child]) => [key, maskSensitive(child, key)]),\n )\n }\n return authRedacted\n}\n\nasync function readConfig(configPath?: string): Promise<{\n path: string\n raw: unknown\n valid: boolean\n issues: Array<{ path: string; message: string }>\n summary: Record<string, unknown>\n}> {\n const path = resolve(configPath ?? 'agent-qa.config.yaml')\n const content = await readFile(path, 'utf-8')\n const raw = parseYaml(content) ?? {}\n const validation = AgentQaConfigSchema.safeParse(raw)\n const record = raw && typeof raw === 'object' && !Array.isArray(raw)\n ? raw as Record<string, unknown>\n : {}\n const registry = record.registry && typeof record.registry === 'object' && !Array.isArray(record.registry)\n ? record.registry as Record<string, unknown>\n : {}\n const services = record.services && typeof record.services === 'object' && !Array.isArray(record.services)\n ? record.services as Record<string, unknown>\n : {}\n\n return {\n path,\n raw: maskSensitive(raw),\n valid: validation.success,\n issues: validation.success\n ? []\n : validation.error.issues.map(issue => ({\n path: issue.path.map(String).join('.') || '(root)',\n message: issue.message,\n })),\n summary: {\n workspaceConfigured: Boolean(record.workspace),\n serviceKeys: Object.keys(services),\n targetNames: Object.keys((registry.targets as Record<string, unknown> | undefined) ?? {}),\n deviceNames: Object.keys((registry.devices as Record<string, unknown> | undefined) ?? {}),\n providerNames: Object.keys((registry.providers as Record<string, unknown> | undefined) ?? {}),\n llmNames: Array.isArray(registry.llms)\n ? registry.llms\n .map(llm => llm && typeof llm === 'object' ? (llm as Record<string, unknown>).name : undefined)\n .filter((name): name is string => typeof name === 'string')\n : [],\n },\n }\n}\n\nexport function createAgentQaMcpServer(options: AgentQaMcpServerOptions = {}): McpServer {\n const server = new McpServer({\n name: 'agent-qa',\n version: getAgentQaVersion(),\n })\n const analyticsService = options.analyticsService ?? createAnalyticsService({ config: options.analyticsConfig })\n const analyticsTransport = options.transport ?? 'stdio'\n const registerAnalyticsTool = <\n OutputArgs extends ZodRawShapeCompat | AnySchema = ZodRawShapeCompat,\n InputArgs extends undefined | ZodRawShapeCompat | AnySchema = undefined,\n >(\n name: string,\n definition: McpToolDefinition<OutputArgs, InputArgs>,\n handler: ToolCallback<InputArgs>,\n ) => server.registerTool(name, definition, (async (input: unknown, extra: unknown) => {\n const startedAt = Date.now()\n let result: unknown\n let thrown: unknown\n\n try {\n result = await (handler as (input: unknown, extra: unknown) => unknown | Promise<unknown>)(input, extra)\n return result\n } catch (err) {\n thrown = err\n throw err\n } finally {\n const isError = thrown !== undefined || isErrorResult(result) || isDashboardErrorResult(result)\n const explicitRunId = extractExplicitCanonicalRunId(input)\n const enqueueRunId = !isError && (name === 'agent_qa_enqueue_test_run' || name === 'agent_qa_enqueue_suite_run')\n ? extractSuccessfulEnqueueRunId(result)\n : undefined\n\n try {\n if (options.analyticsConfig?.analytics?.privacy !== true) {\n const standardProperties = options.analyticsStandardProperties\n ?? await resolveAnalyticsStandardProperties({ surface: 'mcp' })\n const event = buildAnalyticsEvent({\n name: 'agent-qa.mcp.tool.invoked',\n properties: {\n ...standardProperties,\n surface: standardProperties.surface ?? 'mcp',\n tool_name: name,\n mcp_tool_category: categorizeMcpTool(name),\n mcp_tool_status: isError ? 'error' : 'success',\n duration_ms: Math.max(0, Date.now() - startedAt),\n mcp_transport: analyticsTransport,\n ...(isError ? { mcp_error_category: categorizeMcpError(thrown ?? result) } : {}),\n ...(explicitRunId ?? enqueueRunId ? { run_id: explicitRunId ?? enqueueRunId } : {}),\n },\n })\n\n if (options.analyticsService) {\n await analyticsService.capture(event).catch(() => {})\n } else {\n await captureAnalytics(event, {\n config: options.analyticsConfig,\n surface: 'mcp',\n }).catch(() => {})\n }\n }\n } catch {\n // MCP analytics must never alter tool behavior.\n }\n }\n }) as ToolCallback<InputArgs>)\n const dashboardUrlField = z.string().url().optional().describe('Dashboard base URL; defaults to the MCP server dashboard URL.')\n const dashboardUrlFor = (inputUrl?: string): string => {\n const dashboardUrl = inputUrl ?? options.dashboardUrl\n if (!dashboardUrl) {\n throw new Error('dashboardUrl is required for authoring tools. Start MCP via `agent-qa dashboard` or pass dashboardUrl.')\n }\n return dashboardUrl\n }\n const dashboardTool = async (\n dashboardUrl: string | undefined,\n path: string,\n method?: 'GET' | 'POST' | 'PUT' | 'DELETE',\n body?: unknown,\n ) => {\n try {\n const result = await callDashboardApi({\n dashboardUrl: dashboardUrlFor(dashboardUrl),\n path,\n method,\n body,\n })\n return jsonContent(redactAuthStateValue(result))\n } catch (err) {\n return errorContent(err instanceof Error ? err.message : String(err))\n }\n }\n\n registerAnalyticsTool(\n 'agent_qa_discover',\n {\n title: 'Discover agent-qa MCP capabilities',\n description: 'Return structured metadata for agent-qa MCP tools, resources, prompts, and current rollout scope.',\n inputSchema: {},\n },\n async () => jsonContent({\n ...DISCOVERY,\n endpoint: options.endpointUrl,\n dashboard: options.dashboardUrl,\n configPath: options.configPath,\n }),\n )\n\n registerAnalyticsTool(\n 'agent_qa_get_config',\n {\n title: 'Inspect agent-qa config',\n description: 'Read the active agent-qa config and return a masked raw config plus targets/devices/providers summary.',\n inputSchema: {\n configPath: z.string().optional().describe('Config path; defaults to the MCP server config path or agent-qa.config.yaml'),\n section: z.enum(['raw', 'summary']).optional().describe('Return full masked raw config or summary only'),\n },\n },\n async ({ configPath, section }) => {\n const config = await readConfig(configPath ?? options.configPath)\n return jsonContent(section === 'summary'\n ? { path: config.path, valid: config.valid, issues: config.issues, summary: config.summary }\n : config)\n },\n )\n\n registerAnalyticsTool(\n 'agent_qa_schema_reference',\n {\n title: 'Get agent-qa schema reference',\n description: 'Return structured references for config, test YAML, suite YAML, hooks, or canonical IDs.',\n inputSchema: {\n schema: z.enum(SCHEMA_REFERENCE_NAMES).describe('Reference name to return'),\n },\n },\n async ({ schema }) => jsonContent(AGENT_QA_SCHEMA_REFERENCES[schema as SchemaReferenceName]),\n )\n\n registerAnalyticsTool(\n 'agent_qa_validate_definition',\n {\n title: 'Validate agent-qa definition',\n description: 'Validate config/test/suite/hooks objects with the same core schemas agent-qa uses.',\n inputSchema: {\n kind: z.enum(VALIDATION_KINDS).describe('Definition kind'),\n definition: z.unknown().describe('Parsed config/test/suite/hooks object'),\n },\n },\n async ({ kind, definition }) => jsonContent(validateAgentQaDefinition(kind as ValidationKind, definition)),\n )\n\n registerAnalyticsTool(\n 'agent_qa_generate_id',\n {\n title: 'Generate canonical agent-qa ID',\n description: 'Generate a canonical id-agent backed ID for a test, suite, hook, run, or observation.',\n inputSchema: {\n type: z.enum(ENTITY_ID_TYPES).describe('ID entity type'),\n },\n },\n async ({ type }) => {\n const idType = type as typeof ENTITY_ID_TYPES[number]\n return jsonContent({\n id: generateCanonicalId(idType),\n type: idType,\n contract: getEntityIdContract(idType),\n })\n },\n )\n\n registerAnalyticsTool(\n 'agent_qa_validate_id',\n {\n title: 'Validate canonical agent-qa ID',\n description: 'Validate canonical id-agent backed IDs and return the expected contract.',\n inputSchema: {\n type: z.enum(ENTITY_ID_TYPES).describe('ID entity type'),\n id: z.string().describe('ID to validate'),\n },\n },\n async ({ type, id }) => {\n const idType = type as typeof ENTITY_ID_TYPES[number]\n const contract = getEntityIdContract(idType)\n const valid = isCanonicalId(idType, id)\n return jsonContent({\n valid,\n id,\n type: idType,\n contract,\n message: valid\n ? 'ID is canonical.'\n : `Expected ${contract.prefixWithSeparator} followed by ${contract.words} id-agent words.`,\n })\n },\n )\n\n registerAnalyticsTool(\n 'agent_qa_list_tests',\n {\n title: 'List agent-qa tests',\n description: 'List tests through the dashboard API using dashboard workspace discovery.',\n inputSchema: { dashboardUrl: dashboardUrlField },\n },\n async ({ dashboardUrl }) => dashboardTool(dashboardUrl, '/api/tests'),\n )\n\n registerAnalyticsTool(\n 'agent_qa_read_test',\n {\n title: 'Read agent-qa test',\n description: 'Read a test by canonical test ID through the dashboard API.',\n inputSchema: {\n dashboardUrl: dashboardUrlField,\n testId: z.string().describe('Canonical t_ test ID'),\n },\n },\n async ({ dashboardUrl, testId }) => dashboardTool(dashboardUrl, `/api/tests/${encodeURIComponent(testId)}`),\n )\n\n registerAnalyticsTool(\n 'agent_qa_validate_test',\n {\n title: 'Validate agent-qa test YAML',\n description: 'Validate test YAML through the dashboard test-file manager.',\n inputSchema: {\n dashboardUrl: dashboardUrlField,\n content: z.string().describe('Test YAML content'),\n filePath: z.string().optional().describe('Optional file path for suite/test routing hints'),\n },\n },\n async ({ dashboardUrl, content, filePath }) => dashboardTool(dashboardUrl, '/api/tests/validate', 'POST', { content, filePath }),\n )\n\n registerAnalyticsTool(\n 'agent_qa_create_test',\n {\n title: 'Create agent-qa test',\n description: 'Create a test file through the dashboard workspace-safe file manager.',\n inputSchema: {\n dashboardUrl: dashboardUrlField,\n path: z.string().describe('Workspace-relative test path matched by workspace.testMatch'),\n content: z.string().describe('Test YAML content'),\n },\n },\n async ({ dashboardUrl, path, content }) => dashboardTool(dashboardUrl, '/api/tests', 'POST', { path, content }),\n )\n\n registerAnalyticsTool(\n 'agent_qa_update_test',\n {\n title: 'Update agent-qa test',\n description: 'Update a test by canonical test ID through the dashboard API.',\n inputSchema: {\n dashboardUrl: dashboardUrlField,\n testId: z.string().describe('Canonical t_ test ID'),\n content: z.string().describe('Replacement test YAML content'),\n },\n },\n async ({ dashboardUrl, testId, content }) => dashboardTool(dashboardUrl, `/api/tests/${encodeURIComponent(testId)}`, 'PUT', { content }),\n )\n\n registerAnalyticsTool(\n 'agent_qa_delete_test',\n {\n title: 'Delete agent-qa test',\n description: 'Delete a test by canonical test ID through the dashboard API.',\n inputSchema: {\n dashboardUrl: dashboardUrlField,\n testId: z.string().describe('Canonical t_ test ID'),\n },\n },\n async ({ dashboardUrl, testId }) => dashboardTool(dashboardUrl, `/api/tests/${encodeURIComponent(testId)}`, 'DELETE'),\n )\n\n registerAnalyticsTool(\n 'agent_qa_list_suites',\n {\n title: 'List agent-qa suites',\n description: 'List suites through the dashboard API using dashboard workspace discovery.',\n inputSchema: { dashboardUrl: dashboardUrlField },\n },\n async ({ dashboardUrl }) => dashboardTool(dashboardUrl, '/api/suites'),\n )\n\n registerAnalyticsTool(\n 'agent_qa_read_suite',\n {\n title: 'Read agent-qa suite',\n description: 'Read a suite by canonical suite ID through the dashboard API.',\n inputSchema: {\n dashboardUrl: dashboardUrlField,\n suiteId: z.string().describe('Canonical s_ suite ID'),\n },\n },\n async ({ dashboardUrl, suiteId }) => dashboardTool(dashboardUrl, `/api/suites/${encodeURIComponent(suiteId)}`),\n )\n\n registerAnalyticsTool(\n 'agent_qa_validate_suite',\n {\n title: 'Validate agent-qa suite YAML',\n description: 'Validate suite YAML through the dashboard suite-file manager.',\n inputSchema: {\n dashboardUrl: dashboardUrlField,\n content: z.string().describe('Suite YAML content'),\n },\n },\n async ({ dashboardUrl, content }) => dashboardTool(dashboardUrl, '/api/suites/validate', 'POST', { content }),\n )\n\n registerAnalyticsTool(\n 'agent_qa_create_suite',\n {\n title: 'Create agent-qa suite',\n description: 'Create a suite file through the dashboard workspace-safe suite manager.',\n inputSchema: {\n dashboardUrl: dashboardUrlField,\n path: z.string().describe('Workspace-relative suite path matched by workspace.suiteMatch'),\n content: z.string().describe('Suite YAML content'),\n },\n },\n async ({ dashboardUrl, path, content }) => dashboardTool(dashboardUrl, '/api/suites', 'POST', { path, content }),\n )\n\n registerAnalyticsTool(\n 'agent_qa_update_suite',\n {\n title: 'Update agent-qa suite',\n description: 'Update a suite by canonical suite ID through the dashboard API.',\n inputSchema: {\n dashboardUrl: dashboardUrlField,\n suiteId: z.string().describe('Canonical s_ suite ID'),\n content: z.string().describe('Replacement suite YAML content'),\n },\n },\n async ({ dashboardUrl, suiteId, content }) => dashboardTool(dashboardUrl, `/api/suites/${encodeURIComponent(suiteId)}`, 'PUT', { content }),\n )\n\n registerAnalyticsTool(\n 'agent_qa_delete_suite',\n {\n title: 'Delete agent-qa suite',\n description: 'Delete a suite through the dashboard API. Prefer suiteId; path is supported for the dashboard delete route.',\n inputSchema: {\n dashboardUrl: dashboardUrlField,\n suiteId: z.string().optional().describe('Canonical s_ suite ID'),\n path: z.string().optional().describe('Workspace-relative suite path'),\n },\n },\n async ({ dashboardUrl, suiteId, path }) => {\n if (path) return dashboardTool(dashboardUrl, `/api/suites/${encodeURIComponent(path)}`, 'DELETE')\n if (!suiteId) return errorContent('Either suiteId or path is required.')\n let readResult: Awaited<ReturnType<typeof callDashboardApi>>\n try {\n readResult = await callDashboardApi({\n dashboardUrl: dashboardUrlFor(dashboardUrl),\n path: `/api/suites/${encodeURIComponent(suiteId)}`,\n })\n } catch (err) {\n return errorContent(err instanceof Error ? err.message : String(err))\n }\n if (!readResult.ok || !readResult.body || typeof readResult.body !== 'object') return jsonContent(readResult)\n const foundPath = (readResult.body as Record<string, unknown>).path\n if (typeof foundPath !== 'string') return errorContent('Suite read response did not include a path.')\n return dashboardTool(dashboardUrl, `/api/suites/${encodeURIComponent(foundPath)}`, 'DELETE')\n },\n )\n\n registerAnalyticsTool(\n 'agent_qa_list_hooks',\n {\n title: 'List agent-qa hooks',\n description: 'List hooks through the dashboard hook registry API.',\n inputSchema: { dashboardUrl: dashboardUrlField },\n },\n async ({ dashboardUrl }) => dashboardTool(dashboardUrl, '/api/hooks'),\n )\n\n registerAnalyticsTool(\n 'agent_qa_read_hook',\n {\n title: 'Read agent-qa hook',\n description: 'Read hook metadata and source by canonical hook ID.',\n inputSchema: {\n dashboardUrl: dashboardUrlField,\n hookId: z.string().describe('Canonical h_ hook ID'),\n },\n },\n async ({ dashboardUrl, hookId }) => dashboardTool(dashboardUrl, `/api/hooks/${encodeURIComponent(hookId)}`),\n )\n\n registerAnalyticsTool(\n 'agent_qa_create_hook',\n {\n title: 'Create agent-qa hook',\n description: 'Create a hook through the dashboard hook registry API.',\n inputSchema: {\n dashboardUrl: dashboardUrlField,\n payload: z.record(z.string(), z.unknown()).describe('Dashboard HookMutationRequest payload'),\n },\n },\n async ({ dashboardUrl, payload }) => dashboardTool(dashboardUrl, '/api/hooks', 'POST', payload),\n )\n\n registerAnalyticsTool(\n 'agent_qa_update_hook',\n {\n title: 'Update agent-qa hook',\n description: 'Update a hook through the dashboard hook registry API.',\n inputSchema: {\n dashboardUrl: dashboardUrlField,\n hookId: z.string().describe('Canonical h_ hook ID'),\n payload: z.record(z.string(), z.unknown()).describe('Dashboard HookMutationRequest payload'),\n },\n },\n async ({ dashboardUrl, hookId, payload }) => dashboardTool(dashboardUrl, `/api/hooks/${encodeURIComponent(hookId)}`, 'PUT', payload),\n )\n\n registerAnalyticsTool(\n 'agent_qa_delete_hook',\n {\n title: 'Delete agent-qa hook',\n description: 'Delete a hook through the dashboard hook registry API.',\n inputSchema: {\n dashboardUrl: dashboardUrlField,\n hookId: z.string().describe('Canonical h_ hook ID'),\n force: z.boolean().optional().describe('Delete even when references exist'),\n },\n },\n async ({ dashboardUrl, hookId, force }) => dashboardTool(dashboardUrl, `/api/hooks/${encodeURIComponent(hookId)}${force ? '?force=true' : ''}`, 'DELETE'),\n )\n\n registerAnalyticsTool(\n 'agent_qa_run_hook',\n {\n title: 'Run agent-qa hook',\n description: 'Run a hook through the dashboard hook execution API.',\n inputSchema: {\n dashboardUrl: dashboardUrlField,\n hookId: z.string().describe('Canonical h_ hook ID'),\n payload: z.record(z.string(), z.unknown()).optional().describe('Dashboard HookRunRequest payload'),\n },\n },\n async ({ dashboardUrl, hookId, payload }) => dashboardTool(dashboardUrl, `/api/hooks/${encodeURIComponent(hookId)}/run`, 'POST', payload ?? {}),\n )\n\n registerAnalyticsTool(\n 'agent_qa_enqueue_test_run',\n {\n title: 'Enqueue agent-qa test run',\n description: 'Queue a test run through the dashboard run trigger API and return the canonical run ID.',\n inputSchema: {\n dashboardUrl: dashboardUrlField,\n file: z.string().optional().describe('Workspace-relative test file path'),\n patterns: z.array(z.string()).optional().describe('Optional test patterns'),\n noCache: z.boolean().optional(),\n noMemory: z.boolean().optional(),\n local: z.boolean().optional(),\n },\n },\n async ({ dashboardUrl, file, patterns, noCache, noMemory, local }) => dashboardTool(dashboardUrl, '/api/runs/trigger', 'POST', { file, patterns, noCache, noMemory, local, triggerSource: 'mcp' }),\n )\n\n registerAnalyticsTool(\n 'agent_qa_enqueue_suite_run',\n {\n title: 'Enqueue agent-qa suite run',\n description: 'Queue a suite run through the dashboard run trigger API and return parent run context.',\n inputSchema: {\n dashboardUrl: dashboardUrlField,\n file: z.string().describe('Workspace-relative suite file path'),\n noCache: z.boolean().optional(),\n noMemory: z.boolean().optional(),\n local: z.boolean().optional(),\n },\n },\n async ({ dashboardUrl, file, noCache, noMemory, local }) => dashboardTool(dashboardUrl, '/api/runs/trigger', 'POST', { file, noCache, noMemory, local, triggerSource: 'mcp' }),\n )\n\n registerAnalyticsTool(\n 'agent_qa_get_run',\n {\n title: 'Get agent-qa run',\n description: 'Get run detail, steps, attempts, and suite child context through the dashboard API.',\n inputSchema: {\n dashboardUrl: dashboardUrlField,\n runId: z.string().describe('Canonical r_ run ID'),\n },\n },\n async ({ dashboardUrl, runId }) => dashboardTool(dashboardUrl, `/api/runs/${encodeURIComponent(runId)}`),\n )\n\n registerAnalyticsTool(\n 'agent_qa_get_run_steps',\n {\n title: 'Get agent-qa run steps',\n description: 'Get run steps through the dashboard API.',\n inputSchema: {\n dashboardUrl: dashboardUrlField,\n runId: z.string().describe('Canonical r_ run ID'),\n },\n },\n async ({ dashboardUrl, runId }) => dashboardTool(dashboardUrl, `/api/runs/${encodeURIComponent(runId)}/steps`),\n )\n\n registerAnalyticsTool(\n 'agent_qa_get_run_logs',\n {\n title: 'Get agent-qa run logs',\n description: 'Get run log rows through the dashboard API.',\n inputSchema: {\n dashboardUrl: dashboardUrlField,\n runId: z.string().describe('Canonical r_ run ID'),\n stepId: z.string().optional(),\n level: z.string().optional(),\n source: z.string().optional(),\n limit: z.number().int().positive().optional(),\n offset: z.number().int().min(0).optional(),\n },\n },\n async ({ dashboardUrl, runId, stepId, level, source, limit, offset }) => dashboardTool(\n dashboardUrl,\n withQuery(`/api/runs/${encodeURIComponent(runId)}/logs`, { stepId, level, source, limit, offset }),\n ),\n )\n\n registerAnalyticsTool(\n 'agent_qa_get_run_execution_logs',\n {\n title: 'Get agent-qa execution logs',\n description: 'Get structured execution logs through the dashboard API.',\n inputSchema: {\n dashboardUrl: dashboardUrlField,\n runId: z.string().describe('Canonical r_ run ID'),\n stepId: z.string().optional(),\n type: z.string().optional(),\n },\n },\n async ({ dashboardUrl, runId, stepId, type }) => dashboardTool(\n dashboardUrl,\n withQuery(`/api/runs/${encodeURIComponent(runId)}/execution-logs`, { stepId, type }),\n ),\n )\n\n registerAnalyticsTool(\n 'agent_qa_get_run_artifact',\n {\n title: 'Get agent-qa run artifact bundle',\n description: 'Get sanitized run artifact bundle, child artifacts, and missing artifact sections.',\n inputSchema: {\n dashboardUrl: dashboardUrlField,\n runId: z.string().describe('Canonical r_ run ID'),\n },\n },\n async ({ dashboardUrl, runId }) => dashboardTool(dashboardUrl, `/api/runs/${encodeURIComponent(runId)}/artifact`),\n )\n\n registerAnalyticsTool(\n 'agent_qa_cancel_run',\n {\n title: 'Cancel agent-qa run',\n description: 'Cancel a pending or running run through the dashboard queue.',\n inputSchema: {\n dashboardUrl: dashboardUrlField,\n runId: z.string().describe('Canonical r_ run ID'),\n },\n },\n async ({ dashboardUrl, runId }) => dashboardTool(dashboardUrl, `/api/runs/${encodeURIComponent(runId)}/cancel`, 'POST', {}),\n )\n\n registerAnalyticsTool(\n 'agent_qa_classify_failure',\n {\n title: 'Classify agent-qa failure',\n description: 'Classify a failed run using dashboard run detail, artifacts, logs, execution logs, and recent related runs.',\n inputSchema: {\n dashboardUrl: dashboardUrlField,\n runId: z.string().describe('Canonical r_ run ID'),\n },\n },\n async ({ dashboardUrl, runId }) => {\n try {\n const baseUrl = dashboardUrlFor(dashboardUrl)\n const runDetail = await callDashboardApi({ dashboardUrl: baseUrl, path: `/api/runs/${encodeURIComponent(runId)}` })\n const artifact = await callDashboardApi({ dashboardUrl: baseUrl, path: `/api/runs/${encodeURIComponent(runId)}/artifact` })\n const logs = await callDashboardApi({ dashboardUrl: baseUrl, path: `/api/runs/${encodeURIComponent(runId)}/logs` })\n const executionLogs = await callDashboardApi({ dashboardUrl: baseUrl, path: `/api/runs/${encodeURIComponent(runId)}/execution-logs` })\n const runName = runDetail.body && typeof runDetail.body === 'object'\n && (runDetail.body as Record<string, unknown>).run\n && typeof (runDetail.body as { run?: { name?: unknown } }).run?.name === 'string'\n ? (runDetail.body as { run: { name: string } }).run.name\n : undefined\n const recentRuns = runName\n ? await callDashboardApi({ dashboardUrl: baseUrl, path: withQuery('/api/runs', { name: runName, limit: 5 }) })\n : { ok: true, status: 200, body: { runs: [] } }\n return jsonContent({\n runId,\n classification: classifyRunFailureFromDashboardData({\n runDetail: runDetail.body,\n artifact: artifact.body,\n logs: logs.body,\n executionLogs: executionLogs.body,\n recentRuns: recentRuns.body,\n }),\n sources: {\n run: { ok: runDetail.ok, status: runDetail.status },\n artifact: { ok: artifact.ok, status: artifact.status },\n logs: { ok: logs.ok, status: logs.status },\n executionLogs: { ok: executionLogs.ok, status: executionLogs.status },\n recentRuns: { ok: recentRuns.ok, status: recentRuns.status },\n },\n })\n } catch (err) {\n return errorContent(err instanceof Error ? err.message : String(err))\n }\n },\n )\n\n for (const schema of SCHEMA_REFERENCE_NAMES) {\n server.registerResource(\n `agent_qa.schema.${schema}`,\n `agent-qa://schema/${schema}`,\n {\n title: `agent-qa ${schema} schema reference`,\n description: `Structured agent-qa reference for ${schema}.`,\n mimeType: 'application/json',\n },\n async uri => ({\n contents: [{\n uri: uri.href,\n mimeType: 'application/json',\n text: JSON.stringify(AGENT_QA_SCHEMA_REFERENCES[schema], null, 2),\n }],\n }),\n )\n }\n\n server.registerPrompt(\n 'agent_qa_authoring_context',\n {\n title: 'agent-qa authoring context',\n description: 'Prompt context for agents writing agent-qa tests and suites.',\n argsSchema: {},\n },\n async () => ({\n messages: [{\n role: 'user',\n content: {\n type: 'text',\n text: [\n 'Use agent-qa MCP tools before editing files.',\n 'Call agent_qa_get_config to inspect targets/devices/providers.',\n 'Call agent_qa_generate_id for test, suite, hook, run, and observation IDs.',\n 'Call agent_qa_validate_definition before saving config, test, suite, or hooks YAML.',\n `Canonical ID contracts: ${JSON.stringify(getEntityIdContracts())}`,\n ].join('\\n'),\n },\n }],\n }),\n )\n\n return server\n}\n\nexport {\n AGENT_QA_SCHEMA_REFERENCES,\n validateAgentQaDefinition,\n} from './schema-reference.js'\n","import {\n AgentQaConfigSchema,\n HooksFileSchema,\n SuiteDefinitionSchema,\n TestDefinitionSchema,\n} from '@vostride/agent-qa-core'\nimport {\n getEntityIdContracts,\n type EntityIdType,\n} from '@vostride/agent-qa-ids'\n\nexport const SCHEMA_REFERENCE_NAMES = ['config', 'test', 'suite', 'hooks', 'ids'] as const\nexport type SchemaReferenceName = typeof SCHEMA_REFERENCE_NAMES[number]\nexport const VALIDATION_KINDS = ['config', 'test', 'suite', 'hooks'] as const\nexport type ValidationKind = typeof VALIDATION_KINDS[number]\n\nexport const AGENT_QA_SCHEMA_REFERENCES = {\n config: {\n name: 'agent-qa config',\n rootKeys: ['workspace', 'services', 'registry', 'use', 'analytics'],\n services: {\n dashboard: ['port', 'dbPath', 'artifactsDir'],\n mcp: ['enabled', 'transport', 'host', 'port', 'path'],\n cache: ['dir', 'ttl'],\n logging: ['level'],\n recording: ['enabled'],\n accessibility: ['enabled', 'standard', 'runAfter', 'failOnViolation', 'disableRules', 'exclude'],\n memory: ['enabled', 'provider', 'dir', 'minTrust', 'maxInjections', 'curatorEnabled'],\n },\n mcpLocalOnly: {\n transports: ['http', 'stdio'],\n hosts: ['localhost', '127.0.0.1', '::1'],\n defaultPort: 3471,\n defaultPath: '/mcp',\n },\n },\n test: {\n name: 'agent-qa test YAML',\n requiredKeys: ['test-id', 'name', 'target', 'steps'],\n optionalKeys: ['context', 'use', 'meta', 'setup', 'teardown'],\n idType: 'test' as EntityIdType,\n hookReferences: 'setup and teardown arrays must contain canonical h_ hook IDs.',\n stepFormats: ['string', 'object with step/timeout/retries/screenshot/capture/maxAttempts'],\n },\n suite: {\n name: 'agent-qa suite YAML',\n requiredKeys: ['name', 'target', 'tests'],\n optionalKeys: ['suite-id', 'context', 'setup', 'teardown', 'use'],\n idType: 'suite' as EntityIdType,\n testReference: 'Each tests[] entry uses { test: path, id: canonical t_ test ID }.',\n hookReferences: 'setup and teardown arrays must contain canonical h_ hook IDs.',\n },\n hooks: {\n name: 'agent-qa hooks file',\n rootKeys: ['hooks'],\n hookKeys: ['id', 'name', 'runtime', 'file', 'deps', 'packageFile', 'timeout', 'network'],\n idType: 'hook' as EntityIdType,\n runtimes: ['node', 'bun', 'python', 'bash'],\n },\n ids: {\n name: 'agent-qa canonical IDs',\n instruction: 'Generate IDs with agent_qa_generate_id or `agent-qa ids generate <type>`; never hand-write IDs.',\n contracts: getEntityIdContracts(),\n },\n} as const\n\nconst VALIDATION_SCHEMAS = {\n config: AgentQaConfigSchema,\n test: TestDefinitionSchema,\n suite: SuiteDefinitionSchema,\n hooks: HooksFileSchema,\n} as const\n\nexport interface ValidationIssue {\n path: string\n message: string\n}\n\nexport interface DefinitionValidationResult {\n valid: boolean\n kind: ValidationKind\n issues: ValidationIssue[]\n}\n\nexport function validateAgentQaDefinition(\n kind: ValidationKind,\n definition: unknown,\n): DefinitionValidationResult {\n const result = VALIDATION_SCHEMAS[kind].safeParse(definition)\n if (result.success) {\n return {\n valid: true,\n kind,\n issues: [],\n }\n }\n\n return {\n valid: false,\n kind,\n issues: result.error.issues.map(issue => ({\n path: issue.path.map(String).join('.') || '(root)',\n message: issue.message,\n })),\n }\n}\n","import type { IncomingMessage, ServerResponse } from 'node:http'\nimport { StreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/streamableHttp.js'\nimport { createAgentQaMcpServer, type AgentQaMcpServerOptions } from './agent-qa-server.js'\n\nexport const DEFAULT_MCP_HOST = '127.0.0.1'\nexport const DEFAULT_MCP_PORT = 3471\nexport const DEFAULT_MCP_PATH = '/mcp'\n\nexport type LocalMcpTransport = 'http' | 'stdio'\n\nexport interface LocalMcpEndpointConfig {\n enabled?: boolean\n transport?: LocalMcpTransport\n host?: string\n port?: number\n path?: string\n}\n\nexport interface LocalMcpEndpoint {\n enabled: boolean\n transport: LocalMcpTransport\n host: string\n port: number\n path: string\n url: string\n}\n\nexport interface McpHttpHandlerOptions {\n endpoint?: Partial<LocalMcpEndpoint>\n dashboardUrl?: string\n configPath?: string\n analyticsConfig?: AgentQaMcpServerOptions['analyticsConfig']\n}\n\nexport interface LocalMcpEndpointShape {\n mcp_host_kind: 'loopback' | 'other'\n mcp_port_kind: 'default' | 'custom'\n mcp_path_kind: 'default' | 'custom'\n}\n\nfunction normalizePath(path: string | undefined): string {\n if (!path) return DEFAULT_MCP_PATH\n return path.startsWith('/') ? path : `/${path}`\n}\n\nfunction jsonRpcError(res: ServerResponse, status: number, message: string): void {\n res.writeHead(status, {\n 'Content-Type': 'application/json',\n 'Access-Control-Allow-Origin': '*',\n })\n res.end(JSON.stringify({\n jsonrpc: '2.0',\n error: {\n code: -32000,\n message,\n },\n id: null,\n }))\n}\n\nexport function resolveLocalMcpEndpoint(config: LocalMcpEndpointConfig = {}): LocalMcpEndpoint {\n const transport = config.transport ?? 'http'\n const host = config.host ?? DEFAULT_MCP_HOST\n const port = config.port ?? DEFAULT_MCP_PORT\n const path = normalizePath(config.path)\n const displayHost = host === '::1' ? '[::1]' : host\n\n return {\n enabled: config.enabled !== false,\n transport,\n host,\n port,\n path,\n url: `http://${displayHost}:${port}${path}`,\n }\n}\n\nexport function resolveMcpEndpointShape(\n endpoint: Pick<LocalMcpEndpoint, 'host' | 'port' | 'path'>,\n): LocalMcpEndpointShape {\n return {\n mcp_host_kind: ['127.0.0.1', 'localhost', '::1'].includes(endpoint.host) ? 'loopback' : 'other',\n mcp_port_kind: endpoint.port === DEFAULT_MCP_PORT ? 'default' : 'custom',\n mcp_path_kind: endpoint.path === DEFAULT_MCP_PATH ? 'default' : 'custom',\n }\n}\n\nexport function createLocalMcpHttpHandler(options: McpHttpHandlerOptions = {}) {\n const endpoint = resolveLocalMcpEndpoint(options.endpoint)\n const baseHost = endpoint.host === '::1' ? '[::1]' : endpoint.host\n\n return async (req: IncomingMessage, res: ServerResponse): Promise<void> => {\n const requestUrl = new URL(req.url ?? '/', `http://${baseHost}:${endpoint.port}`)\n if (requestUrl.pathname !== endpoint.path) {\n jsonRpcError(res, 404, `MCP endpoint is available at ${endpoint.path}`)\n return\n }\n\n if (req.method === 'OPTIONS') {\n res.writeHead(204, {\n 'Access-Control-Allow-Origin': '*',\n 'Access-Control-Allow-Methods': 'GET, POST, DELETE, OPTIONS',\n 'Access-Control-Allow-Headers': 'Content-Type, MCP-Protocol-Version, mcp-session-id',\n })\n res.end()\n return\n }\n\n const server = createAgentQaMcpServer({\n configPath: options.configPath,\n dashboardUrl: options.dashboardUrl,\n endpointUrl: endpoint.url,\n analyticsConfig: options.analyticsConfig,\n transport: 'http',\n })\n const transport = new StreamableHTTPServerTransport({\n sessionIdGenerator: undefined,\n })\n\n try {\n await server.connect(transport)\n await transport.handleRequest(req, res)\n res.on('close', () => {\n void transport.close()\n void server.close()\n })\n } catch (err) {\n void transport.close()\n void server.close()\n if (!res.headersSent) {\n jsonRpcError(\n res,\n 500,\n err instanceof Error ? err.message : 'Internal MCP server error',\n )\n }\n }\n }\n}\n"],"mappings":"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","names":["buildAnalyticsEvent","captureAnalytics","resolveAnalyticsStandardProperties","AgentQaConfigSchema","getEntityIdContracts","AgentQaConfigSchema","getEntityIdContracts","resolveAnalyticsStandardProperties","buildAnalyticsEvent","captureAnalytics"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vostride/agent-qa-mcp",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.15",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "Model Context Protocol server and tools for agent-qa authoring and triage.",
|
|
6
6
|
"keywords": [
|
|
@@ -49,8 +49,8 @@
|
|
|
49
49
|
},
|
|
50
50
|
"dependencies": {
|
|
51
51
|
"@modelcontextprotocol/sdk": "1.29.0",
|
|
52
|
-
"@vostride/agent-qa-core": "0.1.
|
|
53
|
-
"@vostride/agent-qa-ids": "0.1.
|
|
52
|
+
"@vostride/agent-qa-core": "0.1.15",
|
|
53
|
+
"@vostride/agent-qa-ids": "0.1.15",
|
|
54
54
|
"glob": "13.0.6",
|
|
55
55
|
"yaml": "2.8.4",
|
|
56
56
|
"zod": "4.4.2"
|