@cocaxcode/api-testing-mcp 0.8.3 → 0.9.0

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.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/server.ts","../src/lib/storage.ts","../src/tools/request.ts","../src/lib/http-client.ts","../src/lib/interpolation.ts","../src/lib/url.ts","../src/lib/schemas.ts","../src/tools/collection.ts","../src/tools/environment.ts","../src/tools/api-spec.ts","../src/lib/openapi-parser.ts","../src/tools/assert.ts","../src/lib/path.ts","../src/tools/flow.ts","../src/tools/utilities.ts","../src/tools/mock.ts","../src/tools/load-test.ts"],"sourcesContent":["import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'\nimport { createServer } from './server.js'\n\nasync function main() {\n const server = createServer()\n const transport = new StdioServerTransport()\n await server.connect(transport)\n console.error('api-testing-mcp server running on stdio')\n}\n\nmain().catch((error) => {\n console.error('Fatal:', error)\n process.exit(1)\n})\n","import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'\nimport { Storage } from './lib/storage.js'\nimport { registerRequestTool } from './tools/request.js'\nimport { registerCollectionTools } from './tools/collection.js'\nimport { registerEnvironmentTools } from './tools/environment.js'\nimport { registerApiSpecTools } from './tools/api-spec.js'\nimport { registerAssertTool } from './tools/assert.js'\nimport { registerFlowTool } from './tools/flow.js'\nimport { registerUtilityTools } from './tools/utilities.js'\nimport { registerMockTool } from './tools/mock.js'\nimport { registerLoadTestTool } from './tools/load-test.js'\n\n// Leer version del package.json en build time no es posible con ESM fácilmente,\n// así que la definimos como constante sincronizada manualmente.\nconst VERSION = '0.8.0'\n\n/**\n * Crea y configura el MCP server con todos los tools registrados.\n * Exportada como factory para testabilidad con InMemoryTransport.\n */\nexport function createServer(storageDir?: string): McpServer {\n const server = new McpServer({\n name: 'api-testing-mcp',\n version: VERSION,\n })\n\n const storage = new Storage(storageDir)\n\n // Registrar tools\n registerRequestTool(server, storage)\n registerCollectionTools(server, storage)\n registerEnvironmentTools(server, storage)\n registerApiSpecTools(server, storage)\n registerAssertTool(server, storage)\n registerFlowTool(server, storage)\n registerUtilityTools(server, storage)\n registerMockTool(server, storage)\n registerLoadTestTool(server, storage)\n\n return server\n}\n","import { mkdir, readFile, writeFile, readdir, unlink } from 'node:fs/promises'\nimport { homedir } from 'node:os'\nimport { join } from 'node:path'\nimport type {\n SavedRequest,\n CollectionListItem,\n Environment,\n EnvironmentListItem,\n ApiSpec,\n ApiSpecListItem,\n} from './types.js'\n\nexport class Storage {\n private readonly baseDir: string\n private readonly collectionsDir: string\n private readonly environmentsDir: string\n private readonly specsDir: string\n private readonly activeEnvFile: string\n private readonly projectEnvsFile: string\n\n constructor(baseDir?: string) {\n this.baseDir = baseDir ?? process.env.API_TESTING_DIR ?? join(homedir(), '.api-testing')\n this.collectionsDir = join(this.baseDir, 'collections')\n this.environmentsDir = join(this.baseDir, 'environments')\n this.specsDir = join(this.baseDir, 'specs')\n this.activeEnvFile = join(this.baseDir, 'active-env')\n this.projectEnvsFile = join(this.baseDir, 'project-envs.json')\n }\n\n // ── Collections ──\n\n async saveCollection(saved: SavedRequest): Promise<void> {\n await this.ensureDir('collections')\n const filePath = join(this.collectionsDir, `${this.sanitizeName(saved.name)}.json`)\n await this.writeJson(filePath, saved)\n }\n\n async getCollection(name: string): Promise<SavedRequest | null> {\n const filePath = join(this.collectionsDir, `${this.sanitizeName(name)}.json`)\n return this.readJson<SavedRequest>(filePath)\n }\n\n async listCollections(tag?: string): Promise<CollectionListItem[]> {\n await this.ensureDir('collections')\n const files = await this.listJsonFiles(this.collectionsDir)\n\n const allSaved = await Promise.all(\n files.map((file) => this.readJson<SavedRequest>(join(this.collectionsDir, file))),\n )\n\n return allSaved\n .filter((saved): saved is SavedRequest => {\n if (!saved) return false\n if (tag && !(saved.tags ?? []).includes(tag)) return false\n return true\n })\n .map((saved) => ({\n name: saved.name,\n method: saved.request.method,\n url: saved.request.url,\n tags: saved.tags ?? [],\n }))\n }\n\n async deleteCollection(name: string): Promise<boolean> {\n const filePath = join(this.collectionsDir, `${this.sanitizeName(name)}.json`)\n try {\n await unlink(filePath)\n return true\n } catch {\n return false\n }\n }\n\n // ── Environments ──\n\n async createEnvironment(env: Environment): Promise<void> {\n await this.ensureDir('environments')\n const filePath = join(this.environmentsDir, `${this.sanitizeName(env.name)}.json`)\n await this.writeJson(filePath, env)\n }\n\n async getEnvironment(name: string): Promise<Environment | null> {\n const filePath = join(this.environmentsDir, `${this.sanitizeName(name)}.json`)\n return this.readJson<Environment>(filePath)\n }\n\n async listEnvironments(): Promise<EnvironmentListItem[]> {\n await this.ensureDir('environments')\n const files = await this.listJsonFiles(this.environmentsDir)\n const activeEnv = await this.getActiveEnvironment()\n\n const allEnvs = await Promise.all(\n files.map((file) => this.readJson<Environment>(join(this.environmentsDir, file))),\n )\n\n return allEnvs\n .filter((env): env is Environment => env !== null)\n .map((env) => ({\n name: env.name,\n active: env.name === activeEnv,\n variableCount: Object.keys(env.variables).length,\n spec: env.spec,\n }))\n }\n\n async updateEnvironment(name: string, variables: Record<string, string>): Promise<void> {\n const env = await this.getEnvironment(name)\n if (!env) {\n throw new Error(`Entorno '${name}' no encontrado`)\n }\n\n env.variables = { ...env.variables, ...variables }\n env.updatedAt = new Date().toISOString()\n\n const filePath = join(this.environmentsDir, `${this.sanitizeName(name)}.json`)\n await this.writeJson(filePath, env)\n }\n\n async getActiveEnvironment(project?: string): Promise<string | null> {\n // Primero buscar entorno específico del proyecto\n const projectPath = project ?? process.cwd()\n const projectEnvs = await this.getProjectEnvs()\n const projectEnv = projectEnvs[projectPath]\n if (projectEnv) {\n // Verificar que el entorno aún existe\n const env = await this.getEnvironment(projectEnv)\n if (env) return projectEnv\n }\n\n // Fallback al entorno global\n try {\n const content = await readFile(this.activeEnvFile, 'utf-8')\n return content.trim() || null\n } catch {\n return null\n }\n }\n\n async setActiveEnvironment(name: string, project?: string): Promise<void> {\n // Verificar que el entorno existe\n const env = await this.getEnvironment(name)\n if (!env) {\n throw new Error(`Entorno '${name}' no encontrado`)\n }\n\n if (project) {\n // Guardar como entorno específico del proyecto\n const projectEnvs = await this.getProjectEnvs()\n projectEnvs[project] = name\n await this.ensureDir('')\n await this.writeJson(this.projectEnvsFile, projectEnvs)\n } else {\n // Guardar como entorno global\n await this.ensureDir('')\n await writeFile(this.activeEnvFile, name, 'utf-8')\n }\n }\n\n async clearProjectEnvironment(project: string): Promise<boolean> {\n const projectEnvs = await this.getProjectEnvs()\n if (!(project in projectEnvs)) return false\n delete projectEnvs[project]\n await this.writeJson(this.projectEnvsFile, projectEnvs)\n return true\n }\n\n async listProjectEnvironments(): Promise<Record<string, string>> {\n return this.getProjectEnvs()\n }\n\n private async getProjectEnvs(): Promise<Record<string, string>> {\n return (await this.readJson<Record<string, string>>(this.projectEnvsFile)) ?? {}\n }\n\n async setEnvironmentSpec(envName: string, specName: string | null): Promise<void> {\n const env = await this.getEnvironment(envName)\n if (!env) {\n throw new Error(`Entorno '${envName}' no encontrado`)\n }\n\n env.spec = specName ?? undefined\n env.updatedAt = new Date().toISOString()\n\n const filePath = join(this.environmentsDir, `${this.sanitizeName(envName)}.json`)\n await this.writeJson(filePath, env)\n }\n\n async getActiveSpec(): Promise<string | null> {\n const activeName = await this.getActiveEnvironment()\n if (!activeName) return null\n\n const env = await this.getEnvironment(activeName)\n return env?.spec ?? null\n }\n\n async renameEnvironment(oldName: string, newName: string): Promise<void> {\n const env = await this.getEnvironment(oldName)\n if (!env) {\n throw new Error(`Entorno '${oldName}' no encontrado`)\n }\n\n // Verificar que el nuevo nombre no exista\n const existing = await this.getEnvironment(newName)\n if (existing) {\n throw new Error(`Ya existe un entorno con el nombre '${newName}'`)\n }\n\n // Crear con nuevo nombre y eliminar el anterior\n env.name = newName\n env.updatedAt = new Date().toISOString()\n await this.createEnvironment(env)\n await unlink(join(this.environmentsDir, `${this.sanitizeName(oldName)}.json`))\n\n // Actualizar active-env global si era el activo\n try {\n const globalActive = await readFile(this.activeEnvFile, 'utf-8')\n if (globalActive.trim() === oldName) {\n await writeFile(this.activeEnvFile, newName, 'utf-8')\n }\n } catch {\n // No hay active-env global\n }\n\n // Actualizar project-envs\n const projectEnvs = await this.getProjectEnvs()\n let changed = false\n for (const [project, envName] of Object.entries(projectEnvs)) {\n if (envName === oldName) {\n projectEnvs[project] = newName\n changed = true\n }\n }\n if (changed) {\n await this.writeJson(this.projectEnvsFile, projectEnvs)\n }\n }\n\n async deleteEnvironment(name: string): Promise<void> {\n const env = await this.getEnvironment(name)\n if (!env) {\n throw new Error(`Entorno '${name}' no encontrado`)\n }\n\n await unlink(join(this.environmentsDir, `${this.sanitizeName(name)}.json`))\n\n // Limpiar active-env global si era el activo\n try {\n const globalActive = await readFile(this.activeEnvFile, 'utf-8')\n if (globalActive.trim() === name) {\n await unlink(this.activeEnvFile)\n }\n } catch {\n // No hay active-env global\n }\n\n // Limpiar project-envs\n const projectEnvs = await this.getProjectEnvs()\n let changed = false\n for (const [project, envName] of Object.entries(projectEnvs)) {\n if (envName === name) {\n delete projectEnvs[project]\n changed = true\n }\n }\n if (changed) {\n await this.writeJson(this.projectEnvsFile, projectEnvs)\n }\n }\n\n /**\n * Carga las variables del entorno activo.\n * Retorna objeto vacío si no hay entorno activo.\n */\n async getActiveVariables(): Promise<Record<string, string>> {\n const activeName = await this.getActiveEnvironment()\n if (!activeName) return {}\n\n const env = await this.getEnvironment(activeName)\n return env?.variables ?? {}\n }\n\n // ── API Specs ──\n\n async saveSpec(spec: ApiSpec): Promise<void> {\n await this.ensureDir('specs')\n const filePath = join(this.specsDir, `${this.sanitizeName(spec.name)}.json`)\n await this.writeJson(filePath, spec)\n }\n\n async getSpec(name: string): Promise<ApiSpec | null> {\n const filePath = join(this.specsDir, `${this.sanitizeName(name)}.json`)\n return this.readJson<ApiSpec>(filePath)\n }\n\n async listSpecs(): Promise<ApiSpecListItem[]> {\n await this.ensureDir('specs')\n const files = await this.listJsonFiles(this.specsDir)\n\n const allSpecs = await Promise.all(\n files.map((file) => this.readJson<ApiSpec>(join(this.specsDir, file))),\n )\n\n return allSpecs\n .filter((spec): spec is ApiSpec => spec !== null)\n .map((spec) => ({\n name: spec.name,\n source: spec.source,\n endpointCount: spec.endpoints.length,\n version: spec.version,\n }))\n }\n\n async deleteSpec(name: string): Promise<boolean> {\n const filePath = join(this.specsDir, `${this.sanitizeName(name)}.json`)\n try {\n await unlink(filePath)\n return true\n } catch {\n return false\n }\n }\n\n // ── Internal ──\n\n private async ensureDir(subdir: string): Promise<void> {\n const dir = subdir ? join(this.baseDir, subdir) : this.baseDir\n await mkdir(dir, { recursive: true })\n }\n\n private async readJson<T>(filePath: string): Promise<T | null> {\n try {\n const content = await readFile(filePath, 'utf-8')\n return JSON.parse(content) as T\n } catch {\n return null\n }\n }\n\n private async writeJson(filePath: string, data: unknown): Promise<void> {\n await writeFile(filePath, JSON.stringify(data, null, 2), 'utf-8')\n }\n\n private async listJsonFiles(dir: string): Promise<string[]> {\n try {\n const entries = await readdir(dir)\n return entries.filter((f) => f.endsWith('.json')).sort()\n } catch {\n return []\n }\n }\n\n /**\n * Sanitiza un nombre para usarlo como nombre de archivo.\n * Reemplaza caracteres no alfanuméricos por guiones.\n */\n private sanitizeName(name: string): string {\n const sanitized = name\n .toLowerCase()\n .replace(/[^a-z0-9_-]/g, '-')\n .replace(/-+/g, '-')\n .replace(/^-|-$/g, '')\n\n if (!sanitized) {\n throw new Error(`Nombre inválido: '${name}'`)\n }\n\n return sanitized\n }\n}\n","import { z } from 'zod'\nimport type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'\nimport type { Storage } from '../lib/storage.js'\nimport { executeRequest } from '../lib/http-client.js'\nimport { interpolateRequest } from '../lib/interpolation.js'\nimport { resolveUrl } from '../lib/url.js'\nimport { AuthSchemaShape } from '../lib/schemas.js'\nimport type { RequestConfig } from '../lib/types.js'\n\nexport function registerRequestTool(server: McpServer, storage: Storage): void {\n server.tool(\n 'request',\n 'Ejecuta un HTTP request. URLs relativas (/path) usan BASE_URL del entorno activo. Soporta {{variables}}.',\n {\n method: z\n .enum(['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'HEAD', 'OPTIONS'])\n .describe('HTTP method'),\n url: z\n .string()\n .describe(\n 'URL del endpoint. Si empieza con / se antepone BASE_URL del entorno activo. Soporta {{variables}}.',\n ),\n headers: z\n .record(z.string())\n .optional()\n .describe('Headers HTTP como key-value pairs'),\n body: z.any().optional().describe('Body del request (JSON). Soporta {{variables}}'),\n query: z\n .record(z.string())\n .optional()\n .describe('Query parameters como key-value pairs'),\n timeout: z.number().optional().describe('Timeout en milisegundos (default: 30000)'),\n auth: z\n .object(AuthSchemaShape)\n .optional()\n .describe('Configuración de autenticación'),\n },\n async (params) => {\n try {\n const variables = await storage.getActiveVariables()\n const resolvedUrl = resolveUrl(params.url, variables)\n\n const config: RequestConfig = {\n method: params.method,\n url: resolvedUrl,\n headers: params.headers,\n body: params.body,\n query: params.query,\n timeout: params.timeout,\n auth: params.auth,\n }\n\n const interpolated = interpolateRequest(config, variables)\n const response = await executeRequest(interpolated)\n\n return {\n content: [\n {\n type: 'text' as const,\n text: JSON.stringify(response, null, 2),\n },\n ],\n }\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error)\n return {\n content: [{ type: 'text' as const, text: `Error: ${message}` }],\n isError: true,\n }\n }\n },\n )\n}\n","import type { RequestConfig, RequestResponse, AuthConfig } from './types.js'\n\nconst DEFAULT_TIMEOUT = 30_000\n\n/**\n * Aplica la configuración de auth a los headers del request.\n */\nfunction applyAuth(\n headers: Record<string, string>,\n auth: AuthConfig,\n): Record<string, string> {\n const result = { ...headers }\n\n switch (auth.type) {\n case 'bearer':\n if (auth.token) {\n result['Authorization'] = `Bearer ${auth.token}`\n }\n break\n\n case 'api-key':\n if (auth.key) {\n const headerName = auth.header ?? 'X-API-Key'\n result[headerName] = auth.key\n }\n break\n\n case 'basic':\n if (auth.username && auth.password) {\n const credentials = Buffer.from(`${auth.username}:${auth.password}`).toString('base64')\n result['Authorization'] = `Basic ${credentials}`\n }\n break\n }\n\n return result\n}\n\n/**\n * Construye la URL final con query parameters.\n */\nfunction buildUrl(baseUrl: string, query?: Record<string, string>): string {\n const url = new URL(baseUrl)\n\n if (query) {\n for (const [key, value] of Object.entries(query)) {\n url.searchParams.set(key, value)\n }\n }\n\n return url.toString()\n}\n\n/**\n * Ejecuta un HTTP request y retorna la respuesta con métricas de timing.\n */\nexport async function executeRequest(config: RequestConfig): Promise<RequestResponse> {\n const timeout = config.timeout ?? DEFAULT_TIMEOUT\n\n // Construir URL con query params\n const url = buildUrl(config.url, config.query)\n\n // Preparar headers\n let headers: Record<string, string> = { ...config.headers }\n\n // Aplicar auth\n if (config.auth) {\n headers = applyAuth(headers, config.auth)\n }\n\n // Preparar body\n let body: string | undefined\n if (config.body !== undefined && config.body !== null) {\n if (typeof config.body === 'string') {\n body = config.body\n } else {\n body = JSON.stringify(config.body)\n // Solo añadir Content-Type si no está definido\n if (!headers['Content-Type'] && !headers['content-type']) {\n headers['Content-Type'] = 'application/json'\n }\n }\n }\n\n // AbortController para timeout\n const controller = new AbortController()\n const timeoutId = setTimeout(() => controller.abort(), timeout)\n\n // Medir timing\n const startTime = performance.now()\n\n try {\n const response = await fetch(url, {\n method: config.method,\n headers,\n body,\n signal: controller.signal,\n })\n\n const endTime = performance.now()\n const totalMs = Math.round((endTime - startTime) * 100) / 100\n\n // Parsear response body\n const responseText = await response.text()\n let responseBody: unknown\n try {\n responseBody = JSON.parse(responseText)\n } catch {\n responseBody = responseText\n }\n\n // Convertir headers a Record\n const responseHeaders: Record<string, string> = {}\n response.headers.forEach((value, key) => {\n responseHeaders[key] = value\n })\n\n // Calcular tamaño\n const sizeBytes =\n Number(response.headers.get('content-length')) ||\n Buffer.byteLength(responseText, 'utf-8')\n\n return {\n status: response.status,\n statusText: response.statusText,\n headers: responseHeaders,\n body: responseBody,\n timing: { total_ms: totalMs },\n size_bytes: sizeBytes,\n }\n } catch (error) {\n if (error instanceof Error && error.name === 'AbortError') {\n throw new Error(`Request timeout: superado el límite de ${timeout}ms`)\n }\n throw error\n } finally {\n clearTimeout(timeoutId)\n }\n}\n","import type { RequestConfig } from './types.js'\n\nconst VARIABLE_PATTERN = /\\{\\{(\\w+)\\}\\}/g\n\n/**\n * Resuelve todas las ocurrencias de {{variable}} en un string.\n * Las variables no encontradas se dejan intactas.\n */\nexport function interpolateString(\n template: string,\n variables: Record<string, string>,\n): string {\n return template.replace(VARIABLE_PATTERN, (match, varName: string) => {\n return varName in variables ? variables[varName] : match\n })\n}\n\n/**\n * Interpola {{variables}} recursivamente en un valor.\n * - string → interpolateString\n * - object → interpola cada valor (recursivo)\n * - array → interpola cada elemento\n * - otros tipos → retorna sin cambios\n */\nfunction interpolateValue(value: unknown, variables: Record<string, string>): unknown {\n if (typeof value === 'string') {\n return interpolateString(value, variables)\n }\n\n if (Array.isArray(value)) {\n return value.map((item) => interpolateValue(item, variables))\n }\n\n if (value !== null && typeof value === 'object') {\n const result: Record<string, unknown> = {}\n for (const [key, val] of Object.entries(value)) {\n result[key] = interpolateValue(val, variables)\n }\n return result\n }\n\n return value\n}\n\n/**\n * Interpola un Record<string, string> (headers, query params).\n * Solo interpola los valores, no las keys.\n */\nfunction interpolateRecord(\n record: Record<string, string> | undefined,\n variables: Record<string, string>,\n): Record<string, string> | undefined {\n if (!record) return undefined\n\n const result: Record<string, string> = {}\n for (const [key, value] of Object.entries(record)) {\n result[key] = interpolateString(value, variables)\n }\n return result\n}\n\n/**\n * Resuelve {{variables}} en todos los campos de un RequestConfig:\n * url, headers (valores), body (recursivo), query params (valores).\n */\nexport function interpolateRequest(\n config: RequestConfig,\n variables: Record<string, string>,\n): RequestConfig {\n return {\n ...config,\n url: interpolateString(config.url, variables),\n headers: interpolateRecord(config.headers, variables),\n query: interpolateRecord(config.query, variables),\n body: config.body !== undefined ? interpolateValue(config.body, variables) : undefined,\n auth: config.auth\n ? (interpolateValue(config.auth, variables) as RequestConfig['auth'])\n : undefined,\n }\n}\n","/**\n * Auto-prepend BASE_URL para URLs relativas (que empiezan con /).\n * Quita trailing slash de BASE_URL para evitar doble slash.\n */\nexport function resolveUrl(url: string, variables: Record<string, string>): string {\n if (url.startsWith('/') && variables.BASE_URL) {\n const baseUrl = variables.BASE_URL.replace(/\\/+$/, '')\n return `${baseUrl}${url}`\n }\n return url\n}\n","import { z } from 'zod'\n\nexport const HttpMethodSchema = z.enum([\n 'GET',\n 'POST',\n 'PUT',\n 'PATCH',\n 'DELETE',\n 'HEAD',\n 'OPTIONS',\n])\n\nexport const AuthSchema = z.object({\n type: z.enum(['bearer', 'api-key', 'basic']).describe('Tipo de autenticación'),\n token: z.string().optional().describe('Token para Bearer auth'),\n key: z.string().optional().describe('API key value'),\n header: z.string().optional().describe('Header name para API key (default: X-API-Key)'),\n username: z.string().optional().describe('Username para Basic auth'),\n password: z.string().optional().describe('Password para Basic auth'),\n})\n\n/**\n * Shape (raw properties) del AuthSchema para usar con server.tool()\n * que espera raw Zod shapes, no z.object().\n */\nexport const AuthSchemaShape = AuthSchema.shape\n","import { z } from 'zod'\nimport type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'\nimport type { Storage } from '../lib/storage.js'\nimport { AuthSchemaShape } from '../lib/schemas.js'\nimport type { SavedRequest } from '../lib/types.js'\n\nexport function registerCollectionTools(server: McpServer, storage: Storage): void {\n // ── collection_save ──\n server.tool(\n 'collection_save',\n 'Guarda un request en la colección local. Si ya existe un request con el mismo nombre, lo sobreescribe.',\n {\n name: z.string().describe('Nombre único del request guardado'),\n request: z\n .object({\n method: z.enum(['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'HEAD', 'OPTIONS']),\n url: z.string(),\n headers: z.record(z.string()).optional(),\n body: z.any().optional(),\n query: z.record(z.string()).optional(),\n auth: z.object(AuthSchemaShape).optional(),\n })\n .describe('Configuración del request a guardar'),\n tags: z\n .array(z.string())\n .optional()\n .describe('Tags para organizar (ej: [\"auth\", \"users\"])'),\n },\n async (params) => {\n try {\n const now = new Date().toISOString()\n const existing = await storage.getCollection(params.name)\n\n const saved: SavedRequest = {\n name: params.name,\n request: params.request,\n tags: params.tags,\n createdAt: existing?.createdAt ?? now,\n updatedAt: now,\n }\n\n await storage.saveCollection(saved)\n\n return {\n content: [\n {\n type: 'text' as const,\n text: `Request '${params.name}' guardado (${params.request.method} ${params.request.url})`,\n },\n ],\n }\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error)\n return {\n content: [{ type: 'text' as const, text: `Error: ${message}` }],\n isError: true,\n }\n }\n },\n )\n\n // ── collection_list ──\n server.tool(\n 'collection_list',\n 'Lista todos los requests guardados en la colección. Opcionalmente filtra por tag.',\n {\n tag: z.string().optional().describe('Filtrar por tag'),\n },\n async (params) => {\n try {\n const items = await storage.listCollections(params.tag)\n\n if (items.length === 0) {\n const msg = params.tag\n ? `No hay requests con tag '${params.tag}'`\n : 'La colección está vacía'\n return { content: [{ type: 'text' as const, text: msg }] }\n }\n\n return {\n content: [\n {\n type: 'text' as const,\n text: JSON.stringify(items, null, 2),\n },\n ],\n }\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error)\n return {\n content: [{ type: 'text' as const, text: `Error: ${message}` }],\n isError: true,\n }\n }\n },\n )\n\n // ── collection_get ──\n server.tool(\n 'collection_get',\n 'Obtiene los detalles completos de un request guardado por su nombre.',\n {\n name: z.string().describe('Nombre del request guardado'),\n },\n async (params) => {\n try {\n const saved = await storage.getCollection(params.name)\n\n if (!saved) {\n return {\n content: [\n {\n type: 'text' as const,\n text: `Request '${params.name}' no encontrado`,\n },\n ],\n isError: true,\n }\n }\n\n return {\n content: [\n {\n type: 'text' as const,\n text: JSON.stringify(saved, null, 2),\n },\n ],\n }\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error)\n return {\n content: [{ type: 'text' as const, text: `Error: ${message}` }],\n isError: true,\n }\n }\n },\n )\n\n // ── collection_delete ──\n server.tool(\n 'collection_delete',\n 'Elimina un request guardado de la colección.',\n {\n name: z.string().describe('Nombre del request a eliminar'),\n },\n async (params) => {\n try {\n const deleted = await storage.deleteCollection(params.name)\n\n if (!deleted) {\n return {\n content: [\n {\n type: 'text' as const,\n text: `Request '${params.name}' no encontrado`,\n },\n ],\n isError: true,\n }\n }\n\n return {\n content: [\n {\n type: 'text' as const,\n text: `Request '${params.name}' eliminado`,\n },\n ],\n }\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error)\n return {\n content: [{ type: 'text' as const, text: `Error: ${message}` }],\n isError: true,\n }\n }\n },\n )\n}\n","import { z } from 'zod'\nimport type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'\nimport type { Storage } from '../lib/storage.js'\nimport type { Environment } from '../lib/types.js'\n\nexport function registerEnvironmentTools(server: McpServer, storage: Storage): void {\n // ── env_create ──\n server.tool(\n 'env_create',\n 'Crea un nuevo entorno (ej: dev, staging, prod) con variables opcionales.',\n {\n name: z.string().describe('Nombre del entorno (ej: dev, staging, prod)'),\n variables: z\n .record(z.string())\n .optional()\n .describe('Variables iniciales como key-value'),\n spec: z\n .string()\n .optional()\n .describe('Nombre del spec API asociado (ej: \"cocaxcode-api\")'),\n },\n async (params) => {\n try {\n const now = new Date().toISOString()\n const env: Environment = {\n name: params.name,\n variables: params.variables ?? {},\n spec: params.spec,\n createdAt: now,\n updatedAt: now,\n }\n\n await storage.createEnvironment(env)\n\n const varCount = Object.keys(env.variables).length\n const specMsg = params.spec ? ` — spec: '${params.spec}'` : ''\n return {\n content: [\n {\n type: 'text' as const,\n text: `Entorno '${params.name}' creado con ${varCount} variable(s)${specMsg}`,\n },\n ],\n }\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error)\n return {\n content: [{ type: 'text' as const, text: `Error: ${message}` }],\n isError: true,\n }\n }\n },\n )\n\n // ── env_list ──\n server.tool(\n 'env_list',\n 'Lista todos los entornos disponibles e indica cuál está activo.',\n {},\n async () => {\n try {\n const items = await storage.listEnvironments()\n\n if (items.length === 0) {\n return {\n content: [{ type: 'text' as const, text: 'No hay entornos configurados' }],\n }\n }\n\n return {\n content: [\n {\n type: 'text' as const,\n text: JSON.stringify(items, null, 2),\n },\n ],\n }\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error)\n return {\n content: [{ type: 'text' as const, text: `Error: ${message}` }],\n isError: true,\n }\n }\n },\n )\n\n // ── env_set ──\n server.tool(\n 'env_set',\n 'Establece una variable en un entorno. Si no se especifica entorno, usa el activo.',\n {\n key: z.string().describe('Nombre de la variable'),\n value: z.string().describe('Valor de la variable'),\n environment: z\n .string()\n .optional()\n .describe('Entorno destino (default: entorno activo)'),\n },\n async (params) => {\n try {\n // Determinar entorno destino\n const envName = params.environment ?? (await storage.getActiveEnvironment())\n\n if (!envName) {\n return {\n content: [\n {\n type: 'text' as const,\n text: 'No hay entorno activo. Usa env_create para crear uno y env_switch para activarlo.',\n },\n ],\n isError: true,\n }\n }\n\n await storage.updateEnvironment(envName, { [params.key]: params.value })\n\n return {\n content: [\n {\n type: 'text' as const,\n text: `Variable '${params.key}' establecida en entorno '${envName}'`,\n },\n ],\n }\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error)\n return {\n content: [{ type: 'text' as const, text: `Error: ${message}` }],\n isError: true,\n }\n }\n },\n )\n\n // ── env_get ──\n server.tool(\n 'env_get',\n 'Obtiene una variable específica o todas las variables de un entorno.',\n {\n key: z\n .string()\n .optional()\n .describe('Variable específica. Si se omite, retorna todas'),\n environment: z\n .string()\n .optional()\n .describe('Entorno a consultar (default: entorno activo)'),\n },\n async (params) => {\n try {\n const envName = params.environment ?? (await storage.getActiveEnvironment())\n\n if (!envName) {\n return {\n content: [\n {\n type: 'text' as const,\n text: 'No hay entorno activo. Usa env_switch para activar uno.',\n },\n ],\n isError: true,\n }\n }\n\n const env = await storage.getEnvironment(envName)\n if (!env) {\n return {\n content: [\n { type: 'text' as const, text: `Entorno '${envName}' no encontrado` },\n ],\n isError: true,\n }\n }\n\n if (params.key) {\n const value = env.variables[params.key]\n if (value === undefined) {\n return {\n content: [\n {\n type: 'text' as const,\n text: `Variable '${params.key}' no encontrada en entorno '${envName}'`,\n },\n ],\n isError: true,\n }\n }\n return {\n content: [\n {\n type: 'text' as const,\n text: JSON.stringify({ key: params.key, value, environment: envName }, null, 2),\n },\n ],\n }\n }\n\n return {\n content: [\n {\n type: 'text' as const,\n text: JSON.stringify(\n { environment: envName, variables: env.variables },\n null,\n 2,\n ),\n },\n ],\n }\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error)\n return {\n content: [{ type: 'text' as const, text: `Error: ${message}` }],\n isError: true,\n }\n }\n },\n )\n\n // ── env_spec ──\n server.tool(\n 'env_spec',\n 'Asocia o desasocia un spec API a un entorno. Si no se especifica entorno, usa el activo.',\n {\n spec: z\n .string()\n .optional()\n .describe('Nombre del spec a asociar. Si se omite, desasocia el spec actual'),\n environment: z\n .string()\n .optional()\n .describe('Entorno destino (default: entorno activo)'),\n },\n async (params) => {\n try {\n const envName = params.environment ?? (await storage.getActiveEnvironment())\n\n if (!envName) {\n return {\n content: [\n {\n type: 'text' as const,\n text: 'No hay entorno activo. Usa env_switch para activar uno.',\n },\n ],\n isError: true,\n }\n }\n\n await storage.setEnvironmentSpec(envName, params.spec ?? null)\n\n const message = params.spec\n ? `Spec '${params.spec}' asociado al entorno '${envName}'`\n : `Spec desasociado del entorno '${envName}'`\n\n return {\n content: [{ type: 'text' as const, text: message }],\n }\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error)\n return {\n content: [{ type: 'text' as const, text: `Error: ${message}` }],\n isError: true,\n }\n }\n },\n )\n\n // ── env_rename ──\n server.tool(\n 'env_rename',\n 'Renombra un entorno existente. Si es el entorno activo, actualiza la referencia.',\n {\n name: z.string().describe('Nombre actual del entorno'),\n new_name: z.string().describe('Nuevo nombre para el entorno'),\n },\n async (params) => {\n try {\n await storage.renameEnvironment(params.name, params.new_name)\n\n return {\n content: [\n {\n type: 'text' as const,\n text: `Entorno '${params.name}' renombrado a '${params.new_name}'`,\n },\n ],\n }\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error)\n return {\n content: [{ type: 'text' as const, text: `Error: ${message}` }],\n isError: true,\n }\n }\n },\n )\n\n // ── env_delete ──\n server.tool(\n 'env_delete',\n 'Elimina un entorno y todas sus variables. Si es el entorno activo, lo desactiva.',\n {\n name: z.string().describe('Nombre del entorno a eliminar'),\n },\n async (params) => {\n try {\n await storage.deleteEnvironment(params.name)\n\n return {\n content: [\n {\n type: 'text' as const,\n text: `Entorno '${params.name}' eliminado`,\n },\n ],\n }\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error)\n return {\n content: [{ type: 'text' as const, text: `Error: ${message}` }],\n isError: true,\n }\n }\n },\n )\n\n // ── env_switch ──\n server.tool(\n 'env_switch',\n 'Cambia el entorno activo. Si se especifica project, solo aplica a ese directorio de proyecto.',\n {\n name: z.string().describe('Nombre del entorno a activar'),\n project: z\n .string()\n .optional()\n .describe('Ruta del proyecto (ej: C:/cocaxcode). Si se omite, cambia el entorno global'),\n },\n async (params) => {\n try {\n await storage.setActiveEnvironment(params.name, params.project)\n\n const scope = params.project\n ? ` para proyecto '${params.project}'`\n : ' (global)'\n return {\n content: [\n {\n type: 'text' as const,\n text: `Entorno activo cambiado a '${params.name}'${scope}`,\n },\n ],\n }\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error)\n return {\n content: [{ type: 'text' as const, text: `Error: ${message}` }],\n isError: true,\n }\n }\n },\n )\n\n // ── env_project_clear ──\n server.tool(\n 'env_project_clear',\n 'Elimina la asociación de entorno específico de un proyecto. El proyecto usará el entorno global.',\n {\n project: z\n .string()\n .describe('Ruta del proyecto del que eliminar la asociación'),\n },\n async (params) => {\n try {\n const removed = await storage.clearProjectEnvironment(params.project)\n\n if (!removed) {\n return {\n content: [\n {\n type: 'text' as const,\n text: `No hay entorno específico para el proyecto '${params.project}'`,\n },\n ],\n }\n }\n\n return {\n content: [\n {\n type: 'text' as const,\n text: `Entorno específico eliminado para proyecto '${params.project}'. Usará el entorno global.`,\n },\n ],\n }\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error)\n return {\n content: [{ type: 'text' as const, text: `Error: ${message}` }],\n isError: true,\n }\n }\n },\n )\n\n // ── env_project_list ──\n server.tool(\n 'env_project_list',\n 'Lista todos los proyectos con entornos específicos asignados.',\n {},\n async () => {\n try {\n const projectEnvs = await storage.listProjectEnvironments()\n const entries = Object.entries(projectEnvs)\n\n if (entries.length === 0) {\n return {\n content: [\n {\n type: 'text' as const,\n text: 'No hay entornos específicos por proyecto. Todos usan el entorno global.',\n },\n ],\n }\n }\n\n return {\n content: [\n {\n type: 'text' as const,\n text: JSON.stringify(\n entries.map(([project, env]) => ({ project, environment: env })),\n null,\n 2,\n ),\n },\n ],\n }\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error)\n return {\n content: [{ type: 'text' as const, text: `Error: ${message}` }],\n isError: true,\n }\n }\n },\n )\n}\n","import { z } from 'zod'\nimport type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'\nimport type { Storage } from '../lib/storage.js'\nimport { parseOpenApiSpec } from '../lib/openapi-parser.js'\nimport { readFile } from 'node:fs/promises'\n\n/**\n * Resuelve el nombre del spec a usar:\n * 1. Si se pasa explícitamente, lo usa\n * 2. Si hay un entorno activo con spec asociado, lo usa\n * 3. Si solo hay un spec importado, lo usa\n * 4. Si hay múltiples, pide al usuario que elija\n */\nasync function resolveSpecName(\n name: string | undefined,\n storage: Storage,\n): Promise<{ name: string; error?: never } | { name?: never; error: string }> {\n if (name) return { name }\n\n // Try active environment spec\n const activeSpec = await storage.getActiveSpec()\n if (activeSpec) return { name: activeSpec }\n\n // Fallback to single spec\n const specs = await storage.listSpecs()\n if (specs.length === 0) {\n return { error: 'No hay specs importados. Usa api_import para importar uno.' }\n }\n if (specs.length === 1) {\n return { name: specs[0].name }\n }\n return {\n error: `Hay ${specs.length} specs importados. Especifica cuál usar: ${specs.map((s) => s.name).join(', ')}`,\n }\n}\n\nexport function registerApiSpecTools(server: McpServer, storage: Storage): void {\n // ── api_import ──\n\n server.tool(\n 'api_import',\n 'Importa un spec OpenAPI/Swagger desde una URL o archivo local. Guarda los endpoints y schemas para consulta.',\n {\n name: z\n .string()\n .describe('Nombre para identificar este API (ej: \"mi-backend\", \"cocaxcode-api\")'),\n source: z\n .string()\n .describe(\n 'URL del spec OpenAPI JSON (ej: http://localhost:3001/api-docs-json) o ruta a archivo local',\n ),\n },\n async (params) => {\n try {\n let rawDoc: Record<string, unknown>\n\n if (params.source.startsWith('http://') || params.source.startsWith('https://')) {\n // Fetch from URL\n const controller = new AbortController()\n const timeout = setTimeout(() => controller.abort(), 30000)\n\n try {\n const response = await fetch(params.source, { signal: controller.signal })\n if (!response.ok) {\n return {\n content: [\n {\n type: 'text' as const,\n text: `Error: No se pudo descargar el spec. Status: ${response.status} ${response.statusText}`,\n },\n ],\n isError: true,\n }\n }\n rawDoc = (await response.json()) as Record<string, unknown>\n } finally {\n clearTimeout(timeout)\n }\n } else {\n // Read from local file\n try {\n const content = await readFile(params.source, 'utf-8')\n rawDoc = JSON.parse(content) as Record<string, unknown>\n } catch {\n return {\n content: [\n {\n type: 'text' as const,\n text: `Error: No se pudo leer el archivo '${params.source}'. Verifica que existe y es JSON válido.`,\n },\n ],\n isError: true,\n }\n }\n }\n\n // Validate it looks like OpenAPI\n if (!rawDoc.openapi && !rawDoc.swagger) {\n return {\n content: [\n {\n type: 'text' as const,\n text: 'Error: El documento no parece ser un spec OpenAPI/Swagger válido. Falta la propiedad \"openapi\" o \"swagger\".',\n },\n ],\n isError: true,\n }\n }\n\n // Parse and save\n const spec = parseOpenApiSpec(rawDoc, params.name, params.source)\n await storage.saveSpec(spec)\n\n // Auto-associate with active environment\n const activeEnv = await storage.getActiveEnvironment()\n if (activeEnv) {\n await storage.setEnvironmentSpec(activeEnv, params.name)\n }\n\n // Build summary\n const tagCounts: Record<string, number> = {}\n for (const ep of spec.endpoints) {\n for (const tag of ep.tags ?? ['sin-tag']) {\n tagCounts[tag] = (tagCounts[tag] ?? 0) + 1\n }\n }\n\n const tagSummary = Object.entries(tagCounts)\n .map(([tag, count]) => ` - ${tag}: ${count} endpoints`)\n .join('\\n')\n\n const schemaCount = Object.keys(spec.schemas).length\n\n return {\n content: [\n {\n type: 'text' as const,\n text: [\n `API '${params.name}' importada correctamente.`,\n '',\n `Versión: ${spec.version ?? 'no especificada'}`,\n `Endpoints: ${spec.endpoints.length}`,\n `Schemas: ${schemaCount}`,\n '',\n 'Endpoints por tag:',\n tagSummary,\n '',\n activeEnv ? `Asociado al entorno '${activeEnv}'.` : '',\n 'Usa api_endpoints para ver los endpoints disponibles.',\n 'Usa api_endpoint_detail para ver el detalle de un endpoint específico.',\n ].join('\\n'),\n },\n ],\n }\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error)\n return {\n content: [{ type: 'text' as const, text: `Error: ${message}` }],\n isError: true,\n }\n }\n },\n )\n\n // ── api_spec_list ──\n\n server.tool(\n 'api_spec_list',\n 'Lista todos los specs de API importados. Úsalo para descubrir qué APIs están disponibles.',\n {},\n async () => {\n try {\n const items = await storage.listSpecs()\n\n if (items.length === 0) {\n return {\n content: [\n {\n type: 'text' as const,\n text: 'No hay specs importados. Usa api_import para importar uno.',\n },\n ],\n }\n }\n\n return {\n content: [\n {\n type: 'text' as const,\n text: JSON.stringify(items, null, 2),\n },\n ],\n }\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error)\n return {\n content: [{ type: 'text' as const, text: `Error: ${message}` }],\n isError: true,\n }\n }\n },\n )\n\n // ── api_endpoints ──\n\n server.tool(\n 'api_endpoints',\n 'Lista los endpoints de un API importada. Filtra por tag, método o path. Si no se especifica nombre y solo hay un spec importado, lo usa automáticamente.',\n {\n name: z\n .string()\n .optional()\n .describe('Nombre del API importada. Si se omite y solo hay un spec, lo usa automáticamente'),\n tag: z\n .string()\n .optional()\n .describe('Filtrar por tag (ej: \"blog\", \"auth\", \"users\")'),\n method: z\n .enum(['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'HEAD', 'OPTIONS'])\n .optional()\n .describe('Filtrar por método HTTP'),\n path: z\n .string()\n .optional()\n .describe('Filtrar por path (búsqueda parcial, ej: \"/blog\" muestra todos los que contienen /blog)'),\n },\n async (params) => {\n try {\n const resolved = await resolveSpecName(params.name, storage)\n if (resolved.error) {\n return {\n content: [{ type: 'text' as const, text: resolved.error }],\n isError: true,\n }\n }\n\n const resolvedName = resolved.name as string\n const spec = await storage.getSpec(resolvedName)\n if (!spec) {\n return {\n content: [\n {\n type: 'text' as const,\n text: `Error: API '${resolvedName}' no encontrada. Usa api_import para importarla primero.`,\n },\n ],\n isError: true,\n }\n }\n\n let endpoints = spec.endpoints\n\n // Apply filters\n if (params.tag) {\n endpoints = endpoints.filter((ep) =>\n (ep.tags ?? []).some((t) => t.toLowerCase() === params.tag!.toLowerCase()),\n )\n }\n if (params.method) {\n endpoints = endpoints.filter((ep) => ep.method === params.method)\n }\n if (params.path) {\n const search = params.path.toLowerCase()\n endpoints = endpoints.filter((ep) => ep.path.toLowerCase().includes(search))\n }\n\n if (endpoints.length === 0) {\n return {\n content: [\n {\n type: 'text' as const,\n text: 'No se encontraron endpoints con los filtros aplicados.',\n },\n ],\n }\n }\n\n // Format output\n const lines = endpoints.map((ep) => {\n const tags = ep.tags?.length ? ` [${ep.tags.join(', ')}]` : ''\n const summary = ep.summary ? ` — ${ep.summary}` : ''\n return `${ep.method.padEnd(7)} ${ep.path}${summary}${tags}`\n })\n\n return {\n content: [\n {\n type: 'text' as const,\n text: [\n `API: ${spec.name} (${endpoints.length} endpoints)`,\n '',\n ...lines,\n '',\n 'Usa api_endpoint_detail para ver parámetros, body y respuestas de un endpoint.',\n ].join('\\n'),\n },\n ],\n }\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error)\n return {\n content: [{ type: 'text' as const, text: `Error: ${message}` }],\n isError: true,\n }\n }\n },\n )\n\n // ── api_endpoint_detail ──\n\n server.tool(\n 'api_endpoint_detail',\n 'Muestra el detalle completo de un endpoint: parámetros, body schema, y respuestas. Útil para saber qué datos enviar.',\n {\n name: z\n .string()\n .optional()\n .describe('Nombre del API importada. Si se omite y solo hay un spec, lo usa automáticamente'),\n method: z\n .enum(['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'HEAD', 'OPTIONS'])\n .describe('Método HTTP del endpoint'),\n path: z\n .string()\n .describe('Path exacto del endpoint (ej: \"/blog\", \"/auth/login\")'),\n },\n async (params) => {\n try {\n const resolved = await resolveSpecName(params.name, storage)\n if (resolved.error) {\n return {\n content: [{ type: 'text' as const, text: resolved.error }],\n isError: true,\n }\n }\n\n const resolvedName = resolved.name as string\n const spec = await storage.getSpec(resolvedName)\n if (!spec) {\n return {\n content: [\n {\n type: 'text' as const,\n text: `Error: API '${resolvedName}' no encontrada. Usa api_import para importarla primero.`,\n },\n ],\n isError: true,\n }\n }\n\n const endpoint = spec.endpoints.find(\n (ep) => ep.method === params.method && ep.path === params.path,\n )\n\n if (!endpoint) {\n // Try partial match\n const similar = spec.endpoints.filter((ep) =>\n ep.path.includes(params.path) || params.path.includes(ep.path),\n )\n\n const suggestion = similar.length > 0\n ? `\\n\\nEndpoints similares:\\n${similar.map((ep) => ` ${ep.method} ${ep.path}`).join('\\n')}`\n : ''\n\n return {\n content: [\n {\n type: 'text' as const,\n text: `Error: Endpoint ${params.method} ${params.path} no encontrado.${suggestion}`,\n },\n ],\n isError: true,\n }\n }\n\n // Build detailed output\n const sections: string[] = []\n\n // Header\n sections.push(`## ${endpoint.method} ${endpoint.path}`)\n if (endpoint.summary) sections.push(`**${endpoint.summary}**`)\n if (endpoint.description) sections.push(endpoint.description)\n if (endpoint.tags?.length) sections.push(`Tags: ${endpoint.tags.join(', ')}`)\n\n // Parameters\n if (endpoint.parameters?.length) {\n sections.push('')\n sections.push('### Parámetros')\n for (const param of endpoint.parameters) {\n const required = param.required ? ' (requerido)' : ' (opcional)'\n const type = param.schema?.type ?? 'string'\n const desc = param.description ? ` — ${param.description}` : ''\n sections.push(`- **${param.name}** [${param.in}] ${type}${required}${desc}`)\n }\n }\n\n // Request body\n if (endpoint.requestBody) {\n sections.push('')\n sections.push('### Body')\n const required = endpoint.requestBody.required ? ' (requerido)' : ' (opcional)'\n sections.push(`Body${required}`)\n\n if (endpoint.requestBody.content) {\n for (const [contentType, media] of Object.entries(endpoint.requestBody.content)) {\n sections.push(`\\nContent-Type: ${contentType}`)\n if (media.schema) {\n sections.push('```json')\n sections.push(formatSchema(media.schema))\n sections.push('```')\n }\n }\n }\n }\n\n // Responses\n if (endpoint.responses) {\n sections.push('')\n sections.push('### Respuestas')\n for (const [status, resp] of Object.entries(endpoint.responses)) {\n const desc = resp.description ? ` — ${resp.description}` : ''\n sections.push(`\\n**${status}**${desc}`)\n\n if (resp.content) {\n for (const [, media] of Object.entries(resp.content)) {\n if (media.schema) {\n sections.push('```json')\n sections.push(formatSchema(media.schema))\n sections.push('```')\n }\n }\n }\n }\n }\n\n return {\n content: [\n {\n type: 'text' as const,\n text: sections.join('\\n'),\n },\n ],\n }\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error)\n return {\n content: [{ type: 'text' as const, text: `Error: ${message}` }],\n isError: true,\n }\n }\n },\n )\n}\n\n/**\n * Formatea un schema como ejemplo JSON legible.\n * Genera un ejemplo basado en los tipos y propiedades del schema.\n */\nfunction formatSchema(schema: { type?: string; properties?: Record<string, unknown>; items?: unknown; required?: string[]; enum?: unknown[]; example?: unknown; format?: string; description?: string }, depth = 0): string {\n if (depth > 5) return '\"...\"'\n\n const indent = ' '.repeat(depth)\n const innerIndent = ' '.repeat(depth + 1)\n\n if (schema.example !== undefined) {\n return JSON.stringify(schema.example, null, 2)\n .split('\\n')\n .map((line, i) => (i === 0 ? line : indent + line))\n .join('\\n')\n }\n\n if (schema.enum) {\n return JSON.stringify(schema.enum[0])\n }\n\n if (schema.type === 'object' && schema.properties) {\n const props = Object.entries(schema.properties as Record<string, Record<string, unknown>>)\n if (props.length === 0) return '{}'\n\n const requiredFields = new Set(schema.required ?? [])\n const lines: string[] = ['{']\n\n for (const [key, prop] of props) {\n const isRequired = requiredFields.has(key)\n const comment = []\n if (prop.description) comment.push(prop.description as string)\n if (!isRequired) comment.push('opcional')\n const commentStr = comment.length > 0 ? ` // ${comment.join(' — ')}` : ''\n\n const value = formatSchema(prop as typeof schema, depth + 1)\n lines.push(`${innerIndent}\"${key}\": ${value},${commentStr}`)\n }\n\n lines.push(`${indent}}`)\n return lines.join('\\n')\n }\n\n if (schema.type === 'array' && schema.items) {\n const itemValue = formatSchema(schema.items as typeof schema, depth + 1)\n return `[${itemValue}]`\n }\n\n // Primitive types\n switch (schema.type) {\n case 'string':\n if (schema.format === 'date-time') return '\"2024-01-01T00:00:00Z\"'\n if (schema.format === 'email') return '\"user@example.com\"'\n if (schema.format === 'uri' || schema.format === 'url') return '\"https://example.com\"'\n return '\"string\"'\n case 'number':\n case 'integer':\n return '0'\n case 'boolean':\n return 'true'\n default:\n return 'null'\n }\n}\n","import type {\n HttpMethod,\n ApiSpecEndpoint,\n ApiSpecSchema,\n ApiSpec,\n} from './types.js'\n\nconst VALID_METHODS: HttpMethod[] = ['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'HEAD', 'OPTIONS']\n\n/**\n * Resuelve $ref references en un schema OpenAPI.\n * Soporta refs tipo \"#/components/schemas/MyModel\".\n */\nfunction resolveRef(\n ref: string,\n root: Record<string, unknown>,\n): ApiSpecSchema | undefined {\n const parts = ref.replace(/^#\\//, '').split('/')\n let current: unknown = root\n\n for (const part of parts) {\n if (current && typeof current === 'object' && part in current) {\n current = (current as Record<string, unknown>)[part]\n } else {\n return undefined\n }\n }\n\n return current as ApiSpecSchema\n}\n\n/**\n * Resuelve recursivamente todos los $ref en un schema.\n */\nfunction resolveSchema(\n schema: ApiSpecSchema | undefined,\n root: Record<string, unknown>,\n depth = 0,\n): ApiSpecSchema | undefined {\n if (!schema || depth > 10) return schema\n\n if (schema.$ref) {\n const resolved = resolveRef(schema.$ref, root)\n if (resolved) {\n return resolveSchema(resolved, root, depth + 1)\n }\n return { type: 'object', description: `Unresolved: ${schema.$ref}` }\n }\n\n const result: ApiSpecSchema = { ...schema }\n\n // Resolve allOf — merge all schemas into one\n const rawAllOf = (schema as Record<string, unknown>).allOf as ApiSpecSchema[] | undefined\n if (rawAllOf && Array.isArray(rawAllOf)) {\n const merged: ApiSpecSchema = { type: 'object' }\n const mergedProps: Record<string, ApiSpecSchema> = {}\n const mergedRequired: string[] = []\n\n for (const sub of rawAllOf) {\n const resolved = resolveSchema(sub, root, depth + 1)\n if (resolved?.properties) {\n Object.assign(mergedProps, resolved.properties)\n }\n if (resolved?.required) {\n mergedRequired.push(...resolved.required)\n }\n if (resolved?.description && !merged.description) {\n merged.description = resolved.description\n }\n }\n\n merged.properties = { ...(result.properties ?? {}), ...mergedProps }\n if (mergedRequired.length > 0) {\n merged.required = [...new Set([...(result.required ?? []), ...mergedRequired])]\n }\n\n return merged\n }\n\n // Resolve oneOf/anyOf — pick the first schema as representative\n const rawOneOf = (schema as Record<string, unknown>).oneOf as ApiSpecSchema[] | undefined\n const rawAnyOf = (schema as Record<string, unknown>).anyOf as ApiSpecSchema[] | undefined\n const unionSchemas = rawOneOf ?? rawAnyOf\n if (unionSchemas && Array.isArray(unionSchemas) && unionSchemas.length > 0) {\n return resolveSchema(unionSchemas[0], root, depth + 1)\n }\n\n // Resolve properties recursively\n if (result.properties) {\n const resolvedProps: Record<string, ApiSpecSchema> = {}\n for (const [key, prop] of Object.entries(result.properties)) {\n resolvedProps[key] = resolveSchema(prop, root, depth + 1) ?? prop\n }\n result.properties = resolvedProps\n }\n\n // Resolve array items\n if (result.items) {\n result.items = resolveSchema(result.items, root, depth + 1) ?? result.items\n }\n\n return result\n}\n\n/**\n * Parsea un documento OpenAPI 3.x y extrae endpoints y schemas.\n */\nexport function parseOpenApiSpec(\n doc: Record<string, unknown>,\n name: string,\n source: string,\n): ApiSpec {\n const info = doc.info as Record<string, unknown> | undefined\n const paths = doc.paths as Record<string, Record<string, unknown>> | undefined\n const components = doc.components as Record<string, unknown> | undefined\n const rawSchemas = (components?.schemas ?? {}) as Record<string, ApiSpecSchema>\n\n // Resolve all schemas\n const schemas: Record<string, ApiSpecSchema> = {}\n for (const [schemaName, schema] of Object.entries(rawSchemas)) {\n schemas[schemaName] = resolveSchema(schema, doc, 0) ?? schema\n }\n\n const endpoints: ApiSpecEndpoint[] = []\n\n if (paths) {\n for (const [path, pathItem] of Object.entries(paths)) {\n for (const [method, operation] of Object.entries(pathItem)) {\n const upperMethod = method.toUpperCase() as HttpMethod\n if (!VALID_METHODS.includes(upperMethod)) continue\n\n const op = operation as Record<string, unknown>\n\n // Parse parameters\n const rawParams = (op.parameters ?? []) as Array<Record<string, unknown>>\n const parameters = rawParams.map((p) => ({\n name: p.name as string,\n in: p.in as 'path' | 'query' | 'header' | 'cookie',\n required: p.required as boolean | undefined,\n description: p.description as string | undefined,\n schema: resolveSchema(p.schema as ApiSpecSchema | undefined, doc),\n }))\n\n // Parse request body\n const rawBody = op.requestBody as Record<string, unknown> | undefined\n let requestBody = undefined\n if (rawBody) {\n const bodyContent = rawBody.content as Record<string, Record<string, unknown>> | undefined\n const resolvedContent: Record<string, { schema?: ApiSpecSchema }> = {}\n\n if (bodyContent) {\n for (const [contentType, mediaType] of Object.entries(bodyContent)) {\n resolvedContent[contentType] = {\n schema: resolveSchema(mediaType.schema as ApiSpecSchema | undefined, doc),\n }\n }\n }\n\n requestBody = {\n required: rawBody.required as boolean | undefined,\n description: rawBody.description as string | undefined,\n content: resolvedContent,\n }\n }\n\n // Parse responses\n const rawResponses = (op.responses ?? {}) as Record<string, Record<string, unknown>>\n const responses: Record<string, { description?: string; content?: Record<string, { schema?: ApiSpecSchema }> }> = {}\n\n for (const [statusCode, resp] of Object.entries(rawResponses)) {\n const respContent = resp.content as Record<string, Record<string, unknown>> | undefined\n const resolvedRespContent: Record<string, { schema?: ApiSpecSchema }> = {}\n\n if (respContent) {\n for (const [contentType, mediaType] of Object.entries(respContent)) {\n resolvedRespContent[contentType] = {\n schema: resolveSchema(mediaType.schema as ApiSpecSchema | undefined, doc),\n }\n }\n }\n\n responses[statusCode] = {\n description: resp.description as string | undefined,\n content: respContent ? resolvedRespContent : undefined,\n }\n }\n\n endpoints.push({\n method: upperMethod,\n path,\n summary: op.summary as string | undefined,\n description: op.description as string | undefined,\n tags: op.tags as string[] | undefined,\n parameters,\n requestBody,\n responses,\n })\n }\n }\n }\n\n const now = new Date().toISOString()\n\n return {\n name,\n source,\n version: info?.version as string | undefined,\n endpoints,\n schemas,\n importedAt: now,\n updatedAt: now,\n }\n}\n","import { z } from 'zod'\nimport type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'\nimport type { Storage } from '../lib/storage.js'\nimport { executeRequest } from '../lib/http-client.js'\nimport { interpolateRequest } from '../lib/interpolation.js'\nimport { resolveUrl } from '../lib/url.js'\nimport { getByPath } from '../lib/path.js'\nimport { AuthSchema } from '../lib/schemas.js'\nimport type { RequestConfig, RequestResponse } from '../lib/types.js'\n\nconst AssertionSchema = z.object({\n path: z\n .string()\n .describe(\n 'JSONPath al valor a validar: \"status\", \"body.data.id\", \"headers.content-type\", \"timing.total_ms\"',\n ),\n operator: z\n .enum(['eq', 'neq', 'gt', 'gte', 'lt', 'lte', 'contains', 'not_contains', 'exists', 'type'])\n .describe(\n 'Operador: eq (igual), neq (no igual), gt/gte/lt/lte (numéricos), contains/not_contains (strings/arrays), exists (campo existe), type (typeof)',\n ),\n expected: z.any().optional().describe('Valor esperado (no necesario para \"exists\")'),\n})\n\n/**\n * Evalúa una aserción contra una respuesta.\n */\nfunction evaluateAssertion(\n response: RequestResponse,\n assertion: { path: string; operator: string; expected?: unknown },\n): { pass: boolean; message: string } {\n const actual = getByPath(response, assertion.path)\n\n switch (assertion.operator) {\n case 'eq':\n return {\n pass: actual === assertion.expected,\n message: actual === assertion.expected\n ? `${assertion.path} === ${JSON.stringify(assertion.expected)}`\n : `${assertion.path}: esperado ${JSON.stringify(assertion.expected)}, recibido ${JSON.stringify(actual)}`,\n }\n\n case 'neq':\n return {\n pass: actual !== assertion.expected,\n message: actual !== assertion.expected\n ? `${assertion.path} !== ${JSON.stringify(assertion.expected)}`\n : `${assertion.path}: no debería ser ${JSON.stringify(assertion.expected)}`,\n }\n\n case 'gt':\n return {\n pass: typeof actual === 'number' && actual > (assertion.expected as number),\n message: `${assertion.path}: ${actual} > ${assertion.expected} → ${typeof actual === 'number' && actual > (assertion.expected as number)}`,\n }\n\n case 'gte':\n return {\n pass: typeof actual === 'number' && actual >= (assertion.expected as number),\n message: `${assertion.path}: ${actual} >= ${assertion.expected} → ${typeof actual === 'number' && actual >= (assertion.expected as number)}`,\n }\n\n case 'lt':\n return {\n pass: typeof actual === 'number' && actual < (assertion.expected as number),\n message: `${assertion.path}: ${actual} < ${assertion.expected} → ${typeof actual === 'number' && actual < (assertion.expected as number)}`,\n }\n\n case 'lte':\n return {\n pass: typeof actual === 'number' && actual <= (assertion.expected as number),\n message: `${assertion.path}: ${actual} <= ${assertion.expected} → ${typeof actual === 'number' && actual <= (assertion.expected as number)}`,\n }\n\n case 'contains': {\n let pass = false\n if (typeof actual === 'string') {\n pass = actual.includes(String(assertion.expected))\n } else if (Array.isArray(actual)) {\n pass = actual.includes(assertion.expected)\n }\n return {\n pass,\n message: pass\n ? `${assertion.path} contiene ${JSON.stringify(assertion.expected)}`\n : `${assertion.path}: no contiene ${JSON.stringify(assertion.expected)}`,\n }\n }\n\n case 'not_contains': {\n let pass = true\n if (typeof actual === 'string') {\n pass = !actual.includes(String(assertion.expected))\n } else if (Array.isArray(actual)) {\n pass = !actual.includes(assertion.expected)\n }\n return {\n pass,\n message: pass\n ? `${assertion.path} no contiene ${JSON.stringify(assertion.expected)}`\n : `${assertion.path}: contiene ${JSON.stringify(assertion.expected)} (no debería)`,\n }\n }\n\n case 'exists':\n return {\n pass: actual !== undefined && actual !== null,\n message: actual !== undefined && actual !== null\n ? `${assertion.path} existe`\n : `${assertion.path}: no existe`,\n }\n\n case 'type':\n return {\n pass: typeof actual === assertion.expected,\n message: typeof actual === assertion.expected\n ? `${assertion.path} es tipo ${assertion.expected}`\n : `${assertion.path}: esperado tipo ${assertion.expected}, recibido ${typeof actual}`,\n }\n\n default:\n return { pass: false, message: `Operador desconocido: ${assertion.operator}` }\n }\n}\n\nexport function registerAssertTool(server: McpServer, storage: Storage): void {\n server.tool(\n 'assert',\n 'Ejecuta un request y valida la respuesta con assertions. Retorna resultado pass/fail por cada assertion.',\n {\n method: z\n .enum(['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'HEAD', 'OPTIONS'])\n .describe('HTTP method'),\n url: z.string().describe('URL del endpoint (soporta /relativa y {{variables}})'),\n headers: z.record(z.string()).optional().describe('Headers HTTP'),\n body: z.any().optional().describe('Body del request (JSON)'),\n query: z.record(z.string()).optional().describe('Query parameters'),\n auth: AuthSchema.optional().describe('Autenticación'),\n assertions: z\n .array(AssertionSchema)\n .describe('Lista de assertions a validar contra la respuesta'),\n },\n async (params) => {\n try {\n const variables = await storage.getActiveVariables()\n const resolvedUrl = resolveUrl(params.url, variables)\n\n const config: RequestConfig = {\n method: params.method,\n url: resolvedUrl,\n headers: params.headers,\n body: params.body,\n query: params.query,\n auth: params.auth,\n }\n\n const interpolated = interpolateRequest(config, variables)\n const response = await executeRequest(interpolated)\n\n // Evaluate assertions\n const results = params.assertions.map((assertion) => {\n const result = evaluateAssertion(response, assertion)\n return { ...result, assertion }\n })\n\n const passed = results.filter((r) => r.pass).length\n const failed = results.filter((r) => !r.pass).length\n const allPassed = failed === 0\n\n const lines: string[] = [\n `${allPassed ? '✅ PASS' : '❌ FAIL'} — ${passed}/${results.length} assertions passed`,\n `${params.method} ${params.url} → ${response.status} ${response.statusText} (${response.timing.total_ms}ms)`,\n '',\n ]\n\n for (const r of results) {\n const icon = r.pass ? '✅' : '❌'\n lines.push(`${icon} ${r.message}`)\n }\n\n return {\n content: [{ type: 'text' as const, text: lines.join('\\n') }],\n isError: !allPassed,\n }\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error)\n return {\n content: [{ type: 'text' as const, text: `Error: ${message}` }],\n isError: true,\n }\n }\n },\n )\n}\n","/**\n * Accede a un valor en un objeto usando dot notation.\n * Soporta acceso a arrays por índice numérico (ej: \"data.0.id\").\n *\n * Ej: getByPath({ body: { data: [{ id: 1 }] } }, \"body.data.0.id\") → 1\n */\nexport function getByPath(obj: unknown, path: string): unknown {\n const parts = path.split('.')\n let current: unknown = obj\n\n for (const part of parts) {\n if (current === null || current === undefined) return undefined\n if (typeof current === 'object') {\n if (Array.isArray(current) && /^\\d+$/.test(part)) {\n current = current[parseInt(part)]\n } else {\n current = (current as Record<string, unknown>)[part]\n }\n } else {\n return undefined\n }\n }\n\n return current\n}\n","import { z } from 'zod'\nimport type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'\nimport type { Storage } from '../lib/storage.js'\nimport { executeRequest } from '../lib/http-client.js'\nimport { interpolateRequest } from '../lib/interpolation.js'\nimport { resolveUrl } from '../lib/url.js'\nimport { getByPath } from '../lib/path.js'\nimport { AuthSchema } from '../lib/schemas.js'\nimport type { RequestConfig, RequestResponse } from '../lib/types.js'\n\nconst FlowStepSchema = z.object({\n name: z.string().describe('Nombre del paso (ej: \"login\", \"crear-post\")'),\n method: z\n .enum(['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'HEAD', 'OPTIONS'])\n .describe('HTTP method'),\n url: z.string().describe('URL del endpoint'),\n headers: z.record(z.string()).optional().describe('Headers HTTP'),\n body: z.any().optional().describe('Body del request'),\n query: z.record(z.string()).optional().describe('Query parameters'),\n auth: AuthSchema.optional().describe('Autenticación'),\n extract: z\n .record(z.string())\n .optional()\n .describe(\n 'Variables a extraer de la respuesta para pasos siguientes. Key = nombre variable, value = path (ej: { \"TOKEN\": \"body.token\", \"USER_ID\": \"body.data.id\" })',\n ),\n})\n\nexport function registerFlowTool(server: McpServer, storage: Storage): void {\n server.tool(\n 'flow_run',\n 'Ejecuta una secuencia de requests en orden. Extrae variables de cada respuesta para usar en pasos siguientes con {{variable}}.',\n {\n steps: z.array(FlowStepSchema).describe('Pasos a ejecutar en orden'),\n stop_on_error: z\n .boolean()\n .optional()\n .describe('Detener al primer error (default: true)'),\n },\n async (params) => {\n try {\n const stopOnError = params.stop_on_error ?? true\n const envVariables = await storage.getActiveVariables()\n const flowVariables: Record<string, string> = { ...envVariables }\n const results: Array<{\n name: string\n status: number\n timing: number\n extracted: Record<string, string>\n error?: string\n }> = []\n\n for (const step of params.steps) {\n try {\n const resolvedUrl = resolveUrl(step.url, flowVariables)\n\n const config: RequestConfig = {\n method: step.method,\n url: resolvedUrl,\n headers: step.headers,\n body: step.body,\n query: step.query,\n auth: step.auth,\n }\n\n const interpolated = interpolateRequest(config, flowVariables)\n const response: RequestResponse = await executeRequest(interpolated)\n\n // Extract variables from response\n const extracted: Record<string, string> = {}\n if (step.extract) {\n for (const [varName, path] of Object.entries(step.extract)) {\n const value = getByPath(response, path)\n if (value !== undefined && value !== null) {\n extracted[varName] = String(value)\n flowVariables[varName] = String(value)\n }\n }\n }\n\n results.push({\n name: step.name,\n status: response.status,\n timing: response.timing.total_ms,\n extracted,\n })\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error)\n results.push({\n name: step.name,\n status: 0,\n timing: 0,\n extracted: {},\n error: message,\n })\n\n if (stopOnError) break\n }\n }\n\n // Build output\n const allOk = results.every((r) => !r.error && r.status >= 200 && r.status < 400)\n const lines: string[] = [\n `${allOk ? '✅ FLOW COMPLETO' : '❌ FLOW CON ERRORES'} — ${results.length}/${params.steps.length} pasos ejecutados`,\n '',\n ]\n\n for (let i = 0; i < results.length; i++) {\n const r = results[i]\n const icon = r.error ? '❌' : r.status >= 200 && r.status < 400 ? '✅' : '⚠️'\n lines.push(`${icon} Paso ${i + 1}: ${r.name}`)\n\n if (r.error) {\n lines.push(` Error: ${r.error}`)\n } else {\n lines.push(` Status: ${r.status} | Tiempo: ${r.timing}ms`)\n }\n\n if (Object.keys(r.extracted).length > 0) {\n const vars = Object.entries(r.extracted)\n .map(([k, v]) => `${k}=${v.length > 50 ? v.substring(0, 50) + '...' : v}`)\n .join(', ')\n lines.push(` Extraído: ${vars}`)\n }\n\n lines.push('')\n }\n\n return {\n content: [{ type: 'text' as const, text: lines.join('\\n') }],\n isError: !allOk,\n }\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error)\n return {\n content: [{ type: 'text' as const, text: `Error: ${message}` }],\n isError: true,\n }\n }\n },\n )\n}\n","import { z } from 'zod'\nimport type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'\nimport type { Storage } from '../lib/storage.js'\nimport { executeRequest } from '../lib/http-client.js'\nimport { interpolateRequest } from '../lib/interpolation.js'\nimport { resolveUrl } from '../lib/url.js'\nimport { AuthSchema } from '../lib/schemas.js'\nimport type { RequestConfig } from '../lib/types.js'\n\nexport function registerUtilityTools(server: McpServer, storage: Storage): void {\n // ── export_curl ──\n\n server.tool(\n 'export_curl',\n 'Genera un comando cURL a partir de un request guardado en la colección. Listo para copiar y pegar.',\n {\n name: z.string().describe('Nombre del request guardado en la colección'),\n resolve_variables: z\n .boolean()\n .optional()\n .describe('Resolver {{variables}} del entorno activo (default: true)'),\n },\n async (params) => {\n try {\n const saved = await storage.getCollection(params.name)\n if (!saved) {\n return {\n content: [\n {\n type: 'text' as const,\n text: `Error: Request '${params.name}' no encontrado en la colección.`,\n },\n ],\n isError: true,\n }\n }\n\n let config = saved.request\n const resolveVars = params.resolve_variables ?? true\n\n if (resolveVars) {\n const variables = await storage.getActiveVariables()\n const resolvedUrl = resolveUrl(config.url, variables)\n config = { ...config, url: resolvedUrl }\n config = interpolateRequest(config, variables)\n }\n\n // Build cURL command\n const parts: string[] = ['curl']\n\n if (config.method !== 'GET') {\n parts.push(`-X ${config.method}`)\n }\n\n let url = config.url\n if (config.query && Object.keys(config.query).length > 0) {\n const queryStr = Object.entries(config.query)\n .map(([k, v]) => `${encodeURIComponent(k)}=${encodeURIComponent(v)}`)\n .join('&')\n url += (url.includes('?') ? '&' : '?') + queryStr\n }\n parts.push(`'${url}'`)\n\n if (config.headers) {\n for (const [key, value] of Object.entries(config.headers)) {\n parts.push(`-H '${key}: ${value}'`)\n }\n }\n\n if (config.auth) {\n switch (config.auth.type) {\n case 'bearer':\n if (config.auth.token) {\n parts.push(`-H 'Authorization: Bearer ${config.auth.token}'`)\n }\n break\n case 'api-key':\n if (config.auth.key) {\n const header = config.auth.header ?? 'X-API-Key'\n parts.push(`-H '${header}: ${config.auth.key}'`)\n }\n break\n case 'basic':\n if (config.auth.username && config.auth.password) {\n parts.push(`-u '${config.auth.username}:${config.auth.password}'`)\n }\n break\n }\n }\n\n if (config.body !== undefined && config.body !== null) {\n const bodyStr =\n typeof config.body === 'string' ? config.body : JSON.stringify(config.body)\n parts.push(`-H 'Content-Type: application/json'`)\n parts.push(`-d '${bodyStr}'`)\n }\n\n const curlCommand = parts.join(' \\\\\\n ')\n\n return {\n content: [\n {\n type: 'text' as const,\n text: `cURL para '${params.name}':\\n\\n${curlCommand}`,\n },\n ],\n }\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error)\n return {\n content: [{ type: 'text' as const, text: `Error: ${message}` }],\n isError: true,\n }\n }\n },\n )\n\n // ── diff_responses ──\n\n const DiffRequestSchema = z.object({\n label: z.string().optional().describe('Etiqueta (ej: \"antes\", \"dev\", \"v1\")'),\n method: z.enum(['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'HEAD', 'OPTIONS']),\n url: z.string(),\n headers: z.record(z.string()).optional(),\n body: z.any().optional(),\n query: z.record(z.string()).optional(),\n auth: AuthSchema.optional(),\n })\n\n server.tool(\n 'diff_responses',\n 'Ejecuta dos requests y compara sus respuestas. Útil para detectar regresiones o comparar entornos.',\n {\n request_a: DiffRequestSchema.describe('Primer request'),\n request_b: DiffRequestSchema.describe('Segundo request'),\n },\n async (params) => {\n try {\n const variables = await storage.getActiveVariables()\n\n const executeOne = async (req: z.infer<typeof DiffRequestSchema>) => {\n const resolvedUrl = resolveUrl(req.url, variables)\n\n const config: RequestConfig = {\n method: req.method,\n url: resolvedUrl,\n headers: req.headers,\n body: req.body,\n query: req.query,\n auth: req.auth,\n }\n\n return executeRequest(interpolateRequest(config, variables))\n }\n\n const [responseA, responseB] = await Promise.all([\n executeOne(params.request_a),\n executeOne(params.request_b),\n ])\n\n const labelA = params.request_a.label ?? 'A'\n const labelB = params.request_b.label ?? 'B'\n\n const diffs: string[] = []\n\n if (responseA.status !== responseB.status) {\n diffs.push(\n `Status: ${labelA}=${responseA.status} vs ${labelB}=${responseB.status}`,\n )\n }\n\n const timingDiff = Math.abs(responseA.timing.total_ms - responseB.timing.total_ms)\n if (timingDiff > 100) {\n diffs.push(\n `Timing: ${labelA}=${responseA.timing.total_ms}ms vs ${labelB}=${responseB.timing.total_ms}ms (Δ${Math.round(timingDiff)}ms)`,\n )\n }\n\n const bodyA = JSON.stringify(responseA.body, null, 2)\n const bodyB = JSON.stringify(responseB.body, null, 2)\n\n if (bodyA !== bodyB) {\n diffs.push('Body: diferente')\n\n if (\n typeof responseA.body === 'object' &&\n typeof responseB.body === 'object' &&\n responseA.body &&\n responseB.body\n ) {\n const keysA = new Set(Object.keys(responseA.body as Record<string, unknown>))\n const keysB = new Set(Object.keys(responseB.body as Record<string, unknown>))\n\n const onlyInA = [...keysA].filter((k) => !keysB.has(k))\n const onlyInB = [...keysB].filter((k) => !keysA.has(k))\n const common = [...keysA].filter((k) => keysB.has(k))\n\n if (onlyInA.length > 0) diffs.push(` Solo en ${labelA}: ${onlyInA.join(', ')}`)\n if (onlyInB.length > 0) diffs.push(` Solo en ${labelB}: ${onlyInB.join(', ')}`)\n\n for (const key of common) {\n const valA = JSON.stringify(\n (responseA.body as Record<string, unknown>)[key],\n )\n const valB = JSON.stringify(\n (responseB.body as Record<string, unknown>)[key],\n )\n if (valA !== valB) {\n const shortA = valA.length > 50 ? valA.substring(0, 50) + '...' : valA\n const shortB = valB.length > 50 ? valB.substring(0, 50) + '...' : valB\n diffs.push(` ${key}: ${labelA}=${shortA} vs ${labelB}=${shortB}`)\n }\n }\n }\n }\n\n const sizeDiff = Math.abs(responseA.size_bytes - responseB.size_bytes)\n if (sizeDiff > 0) {\n diffs.push(\n `Size: ${labelA}=${responseA.size_bytes}B vs ${labelB}=${responseB.size_bytes}B`,\n )\n }\n\n const identical = diffs.length === 0\n\n const lines: string[] = [\n identical ? '✅ IDÉNTICAS' : `⚠️ ${diffs.length} DIFERENCIAS ENCONTRADAS`,\n '',\n `${labelA}: ${params.request_a.method} ${params.request_a.url} → ${responseA.status} (${responseA.timing.total_ms}ms)`,\n `${labelB}: ${params.request_b.method} ${params.request_b.url} → ${responseB.status} (${responseB.timing.total_ms}ms)`,\n ]\n\n if (!identical) {\n lines.push('')\n lines.push('Diferencias:')\n for (const diff of diffs) {\n lines.push(` ${diff}`)\n }\n }\n\n return {\n content: [{ type: 'text' as const, text: lines.join('\\n') }],\n }\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error)\n return {\n content: [{ type: 'text' as const, text: `Error: ${message}` }],\n isError: true,\n }\n }\n },\n )\n\n // ── bulk_test ──\n\n server.tool(\n 'bulk_test',\n 'Ejecuta todos los requests guardados en la colección y reporta resultados. Filtrable por tag.',\n {\n tag: z.string().optional().describe('Filtrar por tag'),\n expected_status: z\n .number()\n .optional()\n .describe('Status HTTP esperado para todos (default: cualquier 2xx)'),\n },\n async (params) => {\n try {\n const collections = await storage.listCollections(params.tag)\n if (collections.length === 0) {\n return {\n content: [\n {\n type: 'text' as const,\n text: params.tag\n ? `No hay requests guardados con tag '${params.tag}'.`\n : 'No hay requests guardados en la colección.',\n },\n ],\n }\n }\n\n const variables = await storage.getActiveVariables()\n const results: Array<{\n name: string\n method: string\n url: string\n status: number\n timing: number\n pass: boolean\n error?: string\n }> = []\n\n for (const item of collections) {\n const saved = await storage.getCollection(item.name)\n if (!saved) continue\n\n try {\n let config = saved.request\n const resolvedUrl = resolveUrl(config.url, variables)\n config = { ...config, url: resolvedUrl }\n const interpolated = interpolateRequest(config, variables)\n const response = await executeRequest(interpolated)\n\n const pass = params.expected_status\n ? response.status === params.expected_status\n : response.status >= 200 && response.status < 300\n\n results.push({\n name: item.name,\n method: config.method,\n url: item.url,\n status: response.status,\n timing: response.timing.total_ms,\n pass,\n })\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error)\n results.push({\n name: item.name,\n method: item.method,\n url: item.url,\n status: 0,\n timing: 0,\n pass: false,\n error: message,\n })\n }\n }\n\n const passed = results.filter((r) => r.pass).length\n const failed = results.filter((r) => !r.pass).length\n const totalTime = Math.round(results.reduce((sum, r) => sum + r.timing, 0) * 100) / 100\n\n const lines: string[] = [\n `${failed === 0 ? '✅' : '❌'} BULK TEST — ${passed}/${results.length} passed | ${totalTime}ms total`,\n '',\n ]\n\n for (const r of results) {\n const icon = r.pass ? '✅' : '❌'\n if (r.error) {\n lines.push(`${icon} ${r.name} — ERROR: ${r.error}`)\n } else {\n lines.push(`${icon} ${r.name} — ${r.method} ${r.url} → ${r.status} (${r.timing}ms)`)\n }\n }\n\n return {\n content: [{ type: 'text' as const, text: lines.join('\\n') }],\n isError: failed > 0,\n }\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error)\n return {\n content: [{ type: 'text' as const, text: `Error: ${message}` }],\n isError: true,\n }\n }\n },\n )\n}\n","import { z } from 'zod'\nimport type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'\nimport type { Storage } from '../lib/storage.js'\nimport type { ApiSpecSchema } from '../lib/types.js'\n\n/**\n * Genera datos fake basándose en un schema OpenAPI.\n */\nfunction generateMockData(schema: ApiSpecSchema, depth = 0): unknown {\n if (depth > 8) return null\n\n // If example exists, use it\n if (schema.example !== undefined) return schema.example\n\n // If enum, pick first value\n if (schema.enum && schema.enum.length > 0) {\n return schema.enum[Math.floor(Math.random() * schema.enum.length)]\n }\n\n switch (schema.type) {\n case 'object': {\n if (!schema.properties) return {}\n const obj: Record<string, unknown> = {}\n for (const [key, propSchema] of Object.entries(schema.properties)) {\n obj[key] = generateMockData(propSchema, depth + 1)\n }\n return obj\n }\n\n case 'array': {\n if (!schema.items) return []\n const count = Math.floor(Math.random() * 3) + 1 // 1-3 items\n return Array.from({ length: count }, () =>\n generateMockData(schema.items!, depth + 1),\n )\n }\n\n case 'string': {\n switch (schema.format) {\n case 'date-time':\n return new Date().toISOString()\n case 'date':\n return new Date().toISOString().split('T')[0]\n case 'email':\n return `user${Math.floor(Math.random() * 1000)}@example.com`\n case 'uri':\n case 'url':\n return 'https://example.com/resource'\n case 'uuid':\n return crypto.randomUUID()\n case 'ipv4':\n return `192.168.${Math.floor(Math.random() * 255)}.${Math.floor(Math.random() * 255)}`\n default: {\n // Use description or key name for smarter generation\n const desc = (schema.description ?? '').toLowerCase()\n if (desc.includes('name') || desc.includes('nombre'))\n return `Test User ${Math.floor(Math.random() * 100)}`\n if (desc.includes('title') || desc.includes('título'))\n return `Test Title ${Math.floor(Math.random() * 100)}`\n if (desc.includes('description') || desc.includes('descripción'))\n return 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.'\n if (desc.includes('password') || desc.includes('contraseña'))\n return 'TestPass123!'\n if (desc.includes('slug'))\n return `test-slug-${Math.floor(Math.random() * 1000)}`\n if (desc.includes('phone') || desc.includes('teléfono'))\n return '+34612345678'\n return `mock-string-${Math.floor(Math.random() * 10000)}`\n }\n }\n }\n\n case 'number':\n case 'integer':\n return Math.floor(Math.random() * 1000)\n\n case 'boolean':\n return Math.random() > 0.5\n\n default:\n return null\n }\n}\n\nexport function registerMockTool(server: McpServer, storage: Storage): void {\n server.tool(\n 'mock',\n 'Genera datos mock/fake para un endpoint basándose en su spec OpenAPI importada. Útil para frontend sin backend.',\n {\n name: z.string().describe('Nombre del API importada'),\n method: z\n .enum(['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'HEAD', 'OPTIONS'])\n .describe('Método HTTP del endpoint'),\n path: z.string().describe('Path del endpoint (ej: \"/users\", \"/blog\")'),\n target: z\n .enum(['request', 'response'])\n .optional()\n .describe('Generar mock del body de request o de la response (default: response)'),\n status: z\n .string()\n .optional()\n .describe('Status code de la respuesta a mockear (default: \"200\" o \"201\")'),\n count: z\n .number()\n .optional()\n .describe('Número de items mock a generar si el schema es un array (default: 3)'),\n },\n async (params) => {\n try {\n const spec = await storage.getSpec(params.name)\n if (!spec) {\n return {\n content: [\n {\n type: 'text' as const,\n text: `Error: API '${params.name}' no encontrada. Usa api_import para importarla primero.`,\n },\n ],\n isError: true,\n }\n }\n\n const endpoint = spec.endpoints.find(\n (ep) => ep.method === params.method && ep.path === params.path,\n )\n\n if (!endpoint) {\n return {\n content: [\n {\n type: 'text' as const,\n text: `Error: Endpoint ${params.method} ${params.path} no encontrado en '${params.name}'.`,\n },\n ],\n isError: true,\n }\n }\n\n const target = params.target ?? 'response'\n let schema: ApiSpecSchema | undefined\n\n if (target === 'request') {\n // Get request body schema\n const content = endpoint.requestBody?.content\n if (content) {\n const jsonContent = content['application/json']\n schema = jsonContent?.schema\n }\n\n if (!schema) {\n return {\n content: [\n {\n type: 'text' as const,\n text: `Error: El endpoint ${params.method} ${params.path} no tiene un body schema definido.`,\n },\n ],\n isError: true,\n }\n }\n } else {\n // Get response body schema\n const statusCode = params.status ?? (params.method === 'POST' ? '201' : '200')\n const response = endpoint.responses?.[statusCode]\n\n if (!response) {\n // Try to find any 2xx response\n const twoXX = Object.keys(endpoint.responses ?? {}).find((s) => s.startsWith('2'))\n if (twoXX && endpoint.responses) {\n const fallbackResp = endpoint.responses[twoXX]\n const content = fallbackResp?.content\n if (content) {\n const jsonContent = content['application/json']\n schema = jsonContent?.schema\n }\n }\n } else {\n const content = response.content\n if (content) {\n const jsonContent = content['application/json']\n schema = jsonContent?.schema\n }\n }\n\n if (!schema) {\n return {\n content: [\n {\n type: 'text' as const,\n text: `Error: No se encontró un schema de respuesta para ${params.method} ${params.path}.`,\n },\n ],\n isError: true,\n }\n }\n }\n\n // Generate mock data\n let mockData: unknown\n\n if (schema.type === 'array' && params.count) {\n // Generate specific number of items\n mockData = Array.from({ length: params.count }, () =>\n generateMockData(schema!.items ?? { type: 'object' }),\n )\n } else {\n mockData = generateMockData(schema)\n }\n\n const label = target === 'request' ? 'REQUEST BODY' : 'RESPONSE'\n\n return {\n content: [\n {\n type: 'text' as const,\n text: [\n `Mock ${label} para ${params.method} ${params.path}:`,\n '',\n '```json',\n JSON.stringify(mockData, null, 2),\n '```',\n '',\n 'Datos generados automáticamente desde el spec OpenAPI.',\n target === 'request'\n ? 'Puedes usar estos datos directamente en un request.'\n : 'Estos son datos de ejemplo que devolvería el endpoint.',\n ].join('\\n'),\n },\n ],\n }\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error)\n return {\n content: [{ type: 'text' as const, text: `Error: ${message}` }],\n isError: true,\n }\n }\n },\n )\n}\n","import { z } from 'zod'\nimport type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'\nimport type { Storage } from '../lib/storage.js'\nimport { executeRequest } from '../lib/http-client.js'\nimport { interpolateRequest } from '../lib/interpolation.js'\nimport { resolveUrl } from '../lib/url.js'\nimport { AuthSchema } from '../lib/schemas.js'\nimport type { RequestConfig } from '../lib/types.js'\n\nexport function registerLoadTestTool(server: McpServer, storage: Storage): void {\n server.tool(\n 'load_test',\n 'Lanza N requests concurrentes al mismo endpoint y mide tiempos promedio, percentiles y tasa de errores.',\n {\n method: z\n .enum(['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'HEAD', 'OPTIONS'])\n .describe('HTTP method'),\n url: z.string().describe('URL del endpoint'),\n headers: z.record(z.string()).optional().describe('Headers HTTP'),\n body: z.any().optional().describe('Body del request'),\n query: z.record(z.string()).optional().describe('Query parameters'),\n auth: AuthSchema.optional().describe('Autenticación'),\n concurrent: z\n .number()\n .describe('Número de requests concurrentes a lanzar (max: 100)'),\n timeout: z\n .number()\n .optional()\n .describe('Timeout por request en ms (default: 30000)'),\n },\n async (params) => {\n try {\n const concurrentCount = Math.min(Math.max(params.concurrent, 1), 100)\n const variables = await storage.getActiveVariables()\n const resolvedUrl = resolveUrl(params.url, variables)\n\n const baseConfig: RequestConfig = {\n method: params.method,\n url: resolvedUrl,\n headers: params.headers,\n body: params.body,\n query: params.query,\n auth: params.auth,\n timeout: params.timeout,\n }\n\n const interpolated = interpolateRequest(baseConfig, variables)\n\n const startTotal = performance.now()\n\n const promises = Array.from({ length: concurrentCount }, () =>\n executeRequest(interpolated)\n .then((response) => ({\n status: response.status,\n timing: response.timing.total_ms,\n error: undefined as string | undefined,\n }))\n .catch((error) => ({\n status: 0,\n timing: 0,\n error: error instanceof Error ? error.message : String(error),\n })),\n )\n\n const results = await Promise.all(promises)\n const endTotal = performance.now()\n const wallTime = Math.round((endTotal - startTotal) * 100) / 100\n\n const successful = results.filter((r) => !r.error)\n const failed = results.filter((r) => r.error)\n const timings = successful.map((r) => r.timing).sort((a, b) => a - b)\n\n const statusCounts: Record<number, number> = {}\n for (const r of successful) {\n statusCounts[r.status] = (statusCounts[r.status] ?? 0) + 1\n }\n\n const avg = timings.length > 0\n ? Math.round((timings.reduce((s, t) => s + t, 0) / timings.length) * 100) / 100\n : 0\n const min = timings.length > 0 ? timings[0] : 0\n const max = timings.length > 0 ? timings[timings.length - 1] : 0\n const p50 = timings.length > 0 ? timings[Math.floor(timings.length * 0.5)] : 0\n const p95 = timings.length > 0 ? timings[Math.floor(timings.length * 0.95)] : 0\n const p99 = timings.length > 0 ? timings[Math.floor(timings.length * 0.99)] : 0\n\n const rps = wallTime > 0\n ? Math.round((successful.length / (wallTime / 1000)) * 100) / 100\n : 0\n\n const lines: string[] = [\n `📊 LOAD TEST — ${params.method} ${params.url}`,\n '',\n `Requests: ${concurrentCount} concurrentes`,\n `Exitosos: ${successful.length} | Fallidos: ${failed.length}`,\n `Tiempo total: ${wallTime}ms`,\n `Requests/segundo: ${rps}`,\n '',\n '⏱️ Tiempos de respuesta:',\n ` Min: ${min}ms`,\n ` Avg: ${avg}ms`,\n ` p50: ${p50}ms`,\n ` p95: ${p95}ms`,\n ` p99: ${p99}ms`,\n ` Max: ${max}ms`,\n ]\n\n if (Object.keys(statusCounts).length > 0) {\n lines.push('')\n lines.push('📋 Status codes:')\n for (const [status, count] of Object.entries(statusCounts)) {\n const pct = Math.round((count / concurrentCount) * 100)\n lines.push(` ${status}: ${count} (${pct}%)`)\n }\n }\n\n if (failed.length > 0) {\n lines.push('')\n lines.push('❌ Errores:')\n const errorCounts: Record<string, number> = {}\n for (const r of failed) {\n const errMsg = r.error ?? 'Unknown'\n errorCounts[errMsg] = (errorCounts[errMsg] ?? 0) + 1\n }\n for (const [err, count] of Object.entries(errorCounts)) {\n lines.push(` ${err}: ${count}x`)\n }\n }\n\n return {\n content: [{ type: 'text' as const, text: lines.join('\\n') }],\n isError: failed.length > successful.length,\n }\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error)\n return {\n content: [{ type: 'text' as const, text: `Error: ${message}` }],\n isError: true,\n }\n }\n },\n )\n}\n"],"mappings":"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","names":["z","z","z","z","z","z","readFile","z","z","z","z","z","z","z","z","z","z"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/server.ts","../src/lib/storage.ts","../src/tools/request.ts","../src/lib/http-client.ts","../src/lib/interpolation.ts","../src/lib/url.ts","../src/lib/schemas.ts","../src/tools/collection.ts","../src/tools/environment.ts","../src/tools/api-spec.ts","../src/lib/openapi-parser.ts","../src/tools/assert.ts","../src/lib/path.ts","../src/tools/flow.ts","../src/tools/utilities.ts","../src/tools/mock.ts","../src/tools/load-test.ts"],"sourcesContent":["import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'\nimport { createServer } from './server.js'\n\nasync function main() {\n const server = createServer()\n const transport = new StdioServerTransport()\n await server.connect(transport)\n console.error('api-testing-mcp server running on stdio')\n}\n\nmain().catch((error) => {\n console.error('Fatal:', error)\n process.exit(1)\n})\n","import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'\nimport { Storage } from './lib/storage.js'\nimport { registerRequestTool } from './tools/request.js'\nimport { registerCollectionTools } from './tools/collection.js'\nimport { registerEnvironmentTools } from './tools/environment.js'\nimport { registerApiSpecTools } from './tools/api-spec.js'\nimport { registerAssertTool } from './tools/assert.js'\nimport { registerFlowTool } from './tools/flow.js'\nimport { registerUtilityTools } from './tools/utilities.js'\nimport { registerMockTool } from './tools/mock.js'\nimport { registerLoadTestTool } from './tools/load-test.js'\n\n// Leer version del package.json en build time no es posible con ESM fácilmente,\n// así que la definimos como constante sincronizada manualmente.\nconst VERSION = '0.8.0'\n\n/**\n * Crea y configura el MCP server con todos los tools registrados.\n * Exportada como factory para testabilidad con InMemoryTransport.\n */\nexport function createServer(storageDir?: string): McpServer {\n const server = new McpServer({\n name: 'api-testing-mcp',\n version: VERSION,\n })\n\n const storage = new Storage(storageDir)\n\n // Registrar tools\n registerRequestTool(server, storage)\n registerCollectionTools(server, storage)\n registerEnvironmentTools(server, storage)\n registerApiSpecTools(server, storage)\n registerAssertTool(server, storage)\n registerFlowTool(server, storage)\n registerUtilityTools(server, storage)\n registerMockTool(server, storage)\n registerLoadTestTool(server, storage)\n\n return server\n}\n","import { mkdir, readFile, writeFile, readdir, unlink } from 'node:fs/promises'\nimport { homedir } from 'node:os'\nimport { join } from 'node:path'\nimport type {\n SavedRequest,\n CollectionListItem,\n Environment,\n EnvironmentListItem,\n ApiSpec,\n ApiSpecListItem,\n} from './types.js'\n\nexport class Storage {\n private readonly baseDir: string\n private readonly collectionsDir: string\n private readonly environmentsDir: string\n private readonly specsDir: string\n private readonly activeEnvFile: string\n private readonly projectEnvsFile: string\n\n constructor(baseDir?: string) {\n this.baseDir = baseDir ?? process.env.API_TESTING_DIR ?? join(homedir(), '.api-testing')\n this.collectionsDir = join(this.baseDir, 'collections')\n this.environmentsDir = join(this.baseDir, 'environments')\n this.specsDir = join(this.baseDir, 'specs')\n this.activeEnvFile = join(this.baseDir, 'active-env')\n this.projectEnvsFile = join(this.baseDir, 'project-envs.json')\n }\n\n // ── Collections ──\n\n async saveCollection(saved: SavedRequest): Promise<void> {\n await this.ensureDir('collections')\n const filePath = join(this.collectionsDir, `${this.sanitizeName(saved.name)}.json`)\n await this.writeJson(filePath, saved)\n }\n\n async getCollection(name: string): Promise<SavedRequest | null> {\n const filePath = join(this.collectionsDir, `${this.sanitizeName(name)}.json`)\n return this.readJson<SavedRequest>(filePath)\n }\n\n async listCollections(tag?: string): Promise<CollectionListItem[]> {\n await this.ensureDir('collections')\n const files = await this.listJsonFiles(this.collectionsDir)\n\n const allSaved = await Promise.all(\n files.map((file) => this.readJson<SavedRequest>(join(this.collectionsDir, file))),\n )\n\n return allSaved\n .filter((saved): saved is SavedRequest => {\n if (!saved) return false\n if (tag && !(saved.tags ?? []).includes(tag)) return false\n return true\n })\n .map((saved) => ({\n name: saved.name,\n method: saved.request.method,\n url: saved.request.url,\n tags: saved.tags ?? [],\n }))\n }\n\n async deleteCollection(name: string): Promise<boolean> {\n const filePath = join(this.collectionsDir, `${this.sanitizeName(name)}.json`)\n try {\n await unlink(filePath)\n return true\n } catch {\n return false\n }\n }\n\n // ── Environments ──\n\n async createEnvironment(env: Environment): Promise<void> {\n await this.ensureDir('environments')\n const filePath = join(this.environmentsDir, `${this.sanitizeName(env.name)}.json`)\n await this.writeJson(filePath, env)\n }\n\n async getEnvironment(name: string): Promise<Environment | null> {\n const filePath = join(this.environmentsDir, `${this.sanitizeName(name)}.json`)\n return this.readJson<Environment>(filePath)\n }\n\n async listEnvironments(): Promise<EnvironmentListItem[]> {\n await this.ensureDir('environments')\n const files = await this.listJsonFiles(this.environmentsDir)\n const activeEnv = await this.getActiveEnvironment()\n\n const allEnvs = await Promise.all(\n files.map((file) => this.readJson<Environment>(join(this.environmentsDir, file))),\n )\n\n return allEnvs\n .filter((env): env is Environment => env !== null)\n .map((env) => ({\n name: env.name,\n active: env.name === activeEnv,\n variableCount: Object.keys(env.variables).length,\n spec: env.spec,\n }))\n }\n\n async updateEnvironment(name: string, variables: Record<string, string>): Promise<void> {\n const env = await this.getEnvironment(name)\n if (!env) {\n throw new Error(`Entorno '${name}' no encontrado`)\n }\n\n env.variables = { ...env.variables, ...variables }\n env.updatedAt = new Date().toISOString()\n\n const filePath = join(this.environmentsDir, `${this.sanitizeName(name)}.json`)\n await this.writeJson(filePath, env)\n }\n\n async getActiveEnvironment(project?: string): Promise<string | null> {\n // Primero buscar entorno específico del proyecto\n const projectPath = project ?? process.cwd()\n const projectEnvs = await this.getProjectEnvs()\n const projectEnv = projectEnvs[projectPath]\n if (projectEnv) {\n // Verificar que el entorno aún existe\n const env = await this.getEnvironment(projectEnv)\n if (env) return projectEnv\n }\n\n // Fallback al entorno global\n try {\n const content = await readFile(this.activeEnvFile, 'utf-8')\n return content.trim() || null\n } catch {\n return null\n }\n }\n\n async setActiveEnvironment(name: string, project?: string): Promise<void> {\n // Verificar que el entorno existe\n const env = await this.getEnvironment(name)\n if (!env) {\n throw new Error(`Entorno '${name}' no encontrado`)\n }\n\n if (project) {\n // Guardar como entorno específico del proyecto\n const projectEnvs = await this.getProjectEnvs()\n projectEnvs[project] = name\n await this.ensureDir('')\n await this.writeJson(this.projectEnvsFile, projectEnvs)\n } else {\n // Guardar como entorno global\n await this.ensureDir('')\n await writeFile(this.activeEnvFile, name, 'utf-8')\n }\n }\n\n async clearProjectEnvironment(project: string): Promise<boolean> {\n const projectEnvs = await this.getProjectEnvs()\n if (!(project in projectEnvs)) return false\n delete projectEnvs[project]\n await this.writeJson(this.projectEnvsFile, projectEnvs)\n return true\n }\n\n async listProjectEnvironments(): Promise<Record<string, string>> {\n return this.getProjectEnvs()\n }\n\n private async getProjectEnvs(): Promise<Record<string, string>> {\n return (await this.readJson<Record<string, string>>(this.projectEnvsFile)) ?? {}\n }\n\n async setEnvironmentSpec(envName: string, specName: string | null): Promise<void> {\n const env = await this.getEnvironment(envName)\n if (!env) {\n throw new Error(`Entorno '${envName}' no encontrado`)\n }\n\n env.spec = specName ?? undefined\n env.updatedAt = new Date().toISOString()\n\n const filePath = join(this.environmentsDir, `${this.sanitizeName(envName)}.json`)\n await this.writeJson(filePath, env)\n }\n\n async getActiveSpec(): Promise<string | null> {\n const activeName = await this.getActiveEnvironment()\n if (!activeName) return null\n\n const env = await this.getEnvironment(activeName)\n return env?.spec ?? null\n }\n\n async renameEnvironment(oldName: string, newName: string): Promise<void> {\n const env = await this.getEnvironment(oldName)\n if (!env) {\n throw new Error(`Entorno '${oldName}' no encontrado`)\n }\n\n // Verificar que el nuevo nombre no exista\n const existing = await this.getEnvironment(newName)\n if (existing) {\n throw new Error(`Ya existe un entorno con el nombre '${newName}'`)\n }\n\n // Crear con nuevo nombre y eliminar el anterior\n env.name = newName\n env.updatedAt = new Date().toISOString()\n await this.createEnvironment(env)\n await unlink(join(this.environmentsDir, `${this.sanitizeName(oldName)}.json`))\n\n // Actualizar active-env global si era el activo\n try {\n const globalActive = await readFile(this.activeEnvFile, 'utf-8')\n if (globalActive.trim() === oldName) {\n await writeFile(this.activeEnvFile, newName, 'utf-8')\n }\n } catch {\n // No hay active-env global\n }\n\n // Actualizar project-envs\n const projectEnvs = await this.getProjectEnvs()\n let changed = false\n for (const [project, envName] of Object.entries(projectEnvs)) {\n if (envName === oldName) {\n projectEnvs[project] = newName\n changed = true\n }\n }\n if (changed) {\n await this.writeJson(this.projectEnvsFile, projectEnvs)\n }\n }\n\n async deleteEnvironment(name: string): Promise<void> {\n const env = await this.getEnvironment(name)\n if (!env) {\n throw new Error(`Entorno '${name}' no encontrado`)\n }\n\n await unlink(join(this.environmentsDir, `${this.sanitizeName(name)}.json`))\n\n // Limpiar active-env global si era el activo\n try {\n const globalActive = await readFile(this.activeEnvFile, 'utf-8')\n if (globalActive.trim() === name) {\n await unlink(this.activeEnvFile)\n }\n } catch {\n // No hay active-env global\n }\n\n // Limpiar project-envs\n const projectEnvs = await this.getProjectEnvs()\n let changed = false\n for (const [project, envName] of Object.entries(projectEnvs)) {\n if (envName === name) {\n delete projectEnvs[project]\n changed = true\n }\n }\n if (changed) {\n await this.writeJson(this.projectEnvsFile, projectEnvs)\n }\n }\n\n /**\n * Carga las variables del entorno activo.\n * Retorna objeto vacío si no hay entorno activo.\n */\n async getActiveVariables(): Promise<Record<string, string>> {\n const activeName = await this.getActiveEnvironment()\n if (!activeName) return {}\n\n const env = await this.getEnvironment(activeName)\n return env?.variables ?? {}\n }\n\n // ── API Specs ──\n\n async saveSpec(spec: ApiSpec): Promise<void> {\n await this.ensureDir('specs')\n const filePath = join(this.specsDir, `${this.sanitizeName(spec.name)}.json`)\n await this.writeJson(filePath, spec)\n }\n\n async getSpec(name: string): Promise<ApiSpec | null> {\n const filePath = join(this.specsDir, `${this.sanitizeName(name)}.json`)\n return this.readJson<ApiSpec>(filePath)\n }\n\n async listSpecs(): Promise<ApiSpecListItem[]> {\n await this.ensureDir('specs')\n const files = await this.listJsonFiles(this.specsDir)\n\n const allSpecs = await Promise.all(\n files.map((file) => this.readJson<ApiSpec>(join(this.specsDir, file))),\n )\n\n return allSpecs\n .filter((spec): spec is ApiSpec => spec !== null)\n .map((spec) => ({\n name: spec.name,\n source: spec.source,\n endpointCount: spec.endpoints.length,\n version: spec.version,\n }))\n }\n\n async deleteSpec(name: string): Promise<boolean> {\n const filePath = join(this.specsDir, `${this.sanitizeName(name)}.json`)\n try {\n await unlink(filePath)\n return true\n } catch {\n return false\n }\n }\n\n // ── Internal ──\n\n private async ensureDir(subdir: string): Promise<void> {\n const dir = subdir ? join(this.baseDir, subdir) : this.baseDir\n await mkdir(dir, { recursive: true })\n }\n\n private async readJson<T>(filePath: string): Promise<T | null> {\n try {\n const content = await readFile(filePath, 'utf-8')\n return JSON.parse(content) as T\n } catch {\n return null\n }\n }\n\n private async writeJson(filePath: string, data: unknown): Promise<void> {\n await writeFile(filePath, JSON.stringify(data, null, 2), 'utf-8')\n }\n\n private async listJsonFiles(dir: string): Promise<string[]> {\n try {\n const entries = await readdir(dir)\n return entries.filter((f) => f.endsWith('.json')).sort()\n } catch {\n return []\n }\n }\n\n /**\n * Sanitiza un nombre para usarlo como nombre de archivo.\n * Reemplaza caracteres no alfanuméricos por guiones.\n */\n private sanitizeName(name: string): string {\n const sanitized = name\n .toLowerCase()\n .replace(/[^a-z0-9_-]/g, '-')\n .replace(/-+/g, '-')\n .replace(/^-|-$/g, '')\n\n if (!sanitized) {\n throw new Error(`Nombre inválido: '${name}'`)\n }\n\n return sanitized\n }\n}\n","import { z } from 'zod'\nimport type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'\nimport type { Storage } from '../lib/storage.js'\nimport { executeRequest } from '../lib/http-client.js'\nimport { interpolateRequest } from '../lib/interpolation.js'\nimport { resolveUrl } from '../lib/url.js'\nimport { AuthSchemaShape } from '../lib/schemas.js'\nimport type { RequestConfig } from '../lib/types.js'\n\nexport function registerRequestTool(server: McpServer, storage: Storage): void {\n server.tool(\n 'request',\n 'Ejecuta un HTTP request. URLs relativas (/path) usan BASE_URL del entorno activo. Soporta {{variables}}.',\n {\n method: z\n .enum(['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'HEAD', 'OPTIONS'])\n .describe('HTTP method'),\n url: z\n .string()\n .describe(\n 'URL del endpoint. Si empieza con / se antepone BASE_URL del entorno activo. Soporta {{variables}}.',\n ),\n headers: z\n .record(z.string())\n .optional()\n .describe('Headers HTTP como key-value pairs'),\n body: z.any().optional().describe('Body del request (JSON). Soporta {{variables}}'),\n query: z\n .record(z.string())\n .optional()\n .describe('Query parameters como key-value pairs'),\n timeout: z.number().optional().describe('Timeout en milisegundos (default: 30000)'),\n auth: z\n .object(AuthSchemaShape)\n .optional()\n .describe('Configuración de autenticación'),\n },\n async (params) => {\n try {\n const variables = await storage.getActiveVariables()\n const resolvedUrl = resolveUrl(params.url, variables)\n\n const config: RequestConfig = {\n method: params.method,\n url: resolvedUrl,\n headers: params.headers,\n body: params.body,\n query: params.query,\n timeout: params.timeout,\n auth: params.auth,\n }\n\n const interpolated = interpolateRequest(config, variables)\n const response = await executeRequest(interpolated)\n\n return {\n content: [\n {\n type: 'text' as const,\n text: JSON.stringify(response, null, 2),\n },\n ],\n }\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error)\n return {\n content: [{ type: 'text' as const, text: `Error: ${message}` }],\n isError: true,\n }\n }\n },\n )\n}\n","import type { RequestConfig, RequestResponse, AuthConfig } from './types.js'\n\nconst DEFAULT_TIMEOUT = 30_000\n\n/**\n * Aplica la configuración de auth a los headers del request.\n */\nfunction applyAuth(\n headers: Record<string, string>,\n auth: AuthConfig,\n): Record<string, string> {\n const result = { ...headers }\n\n switch (auth.type) {\n case 'bearer':\n if (auth.token) {\n result['Authorization'] = `Bearer ${auth.token}`\n }\n break\n\n case 'api-key':\n if (auth.key) {\n const headerName = auth.header ?? 'X-API-Key'\n result[headerName] = auth.key\n }\n break\n\n case 'basic':\n if (auth.username && auth.password) {\n const credentials = Buffer.from(`${auth.username}:${auth.password}`).toString('base64')\n result['Authorization'] = `Basic ${credentials}`\n }\n break\n }\n\n return result\n}\n\n/**\n * Construye la URL final con query parameters.\n */\nfunction buildUrl(baseUrl: string, query?: Record<string, string>): string {\n const url = new URL(baseUrl)\n\n if (query) {\n for (const [key, value] of Object.entries(query)) {\n url.searchParams.set(key, value)\n }\n }\n\n return url.toString()\n}\n\n/**\n * Ejecuta un HTTP request y retorna la respuesta con métricas de timing.\n */\nexport async function executeRequest(config: RequestConfig): Promise<RequestResponse> {\n const timeout = config.timeout ?? DEFAULT_TIMEOUT\n\n // Construir URL con query params\n const url = buildUrl(config.url, config.query)\n\n // Preparar headers\n let headers: Record<string, string> = { ...config.headers }\n\n // Aplicar auth\n if (config.auth) {\n headers = applyAuth(headers, config.auth)\n }\n\n // Preparar body\n let body: string | undefined\n if (config.body !== undefined && config.body !== null) {\n if (typeof config.body === 'string') {\n body = config.body\n } else {\n body = JSON.stringify(config.body)\n // Solo añadir Content-Type si no está definido\n if (!headers['Content-Type'] && !headers['content-type']) {\n headers['Content-Type'] = 'application/json'\n }\n }\n }\n\n // AbortController para timeout\n const controller = new AbortController()\n const timeoutId = setTimeout(() => controller.abort(), timeout)\n\n // Medir timing\n const startTime = performance.now()\n\n try {\n const response = await fetch(url, {\n method: config.method,\n headers,\n body,\n signal: controller.signal,\n })\n\n const endTime = performance.now()\n const totalMs = Math.round((endTime - startTime) * 100) / 100\n\n // Parsear response body\n const responseText = await response.text()\n let responseBody: unknown\n try {\n responseBody = JSON.parse(responseText)\n } catch {\n responseBody = responseText\n }\n\n // Convertir headers a Record\n const responseHeaders: Record<string, string> = {}\n response.headers.forEach((value, key) => {\n responseHeaders[key] = value\n })\n\n // Calcular tamaño\n const sizeBytes =\n Number(response.headers.get('content-length')) ||\n Buffer.byteLength(responseText, 'utf-8')\n\n return {\n status: response.status,\n statusText: response.statusText,\n headers: responseHeaders,\n body: responseBody,\n timing: { total_ms: totalMs },\n size_bytes: sizeBytes,\n }\n } catch (error) {\n if (error instanceof Error && error.name === 'AbortError') {\n throw new Error(`Request timeout: superado el límite de ${timeout}ms`)\n }\n throw error\n } finally {\n clearTimeout(timeoutId)\n }\n}\n","import type { RequestConfig } from './types.js'\n\nconst VARIABLE_PATTERN = /\\{\\{(\\w+)\\}\\}/g\n\n/**\n * Resuelve todas las ocurrencias de {{variable}} en un string.\n * Las variables no encontradas se dejan intactas.\n */\nexport function interpolateString(\n template: string,\n variables: Record<string, string>,\n): string {\n return template.replace(VARIABLE_PATTERN, (match, varName: string) => {\n return varName in variables ? variables[varName] : match\n })\n}\n\n/**\n * Interpola {{variables}} recursivamente en un valor.\n * - string → interpolateString\n * - object → interpola cada valor (recursivo)\n * - array → interpola cada elemento\n * - otros tipos → retorna sin cambios\n */\nfunction interpolateValue(value: unknown, variables: Record<string, string>): unknown {\n if (typeof value === 'string') {\n return interpolateString(value, variables)\n }\n\n if (Array.isArray(value)) {\n return value.map((item) => interpolateValue(item, variables))\n }\n\n if (value !== null && typeof value === 'object') {\n const result: Record<string, unknown> = {}\n for (const [key, val] of Object.entries(value)) {\n result[key] = interpolateValue(val, variables)\n }\n return result\n }\n\n return value\n}\n\n/**\n * Interpola un Record<string, string> (headers, query params).\n * Solo interpola los valores, no las keys.\n */\nfunction interpolateRecord(\n record: Record<string, string> | undefined,\n variables: Record<string, string>,\n): Record<string, string> | undefined {\n if (!record) return undefined\n\n const result: Record<string, string> = {}\n for (const [key, value] of Object.entries(record)) {\n result[key] = interpolateString(value, variables)\n }\n return result\n}\n\n/**\n * Resuelve {{variables}} en todos los campos de un RequestConfig:\n * url, headers (valores), body (recursivo), query params (valores).\n */\nexport function interpolateRequest(\n config: RequestConfig,\n variables: Record<string, string>,\n): RequestConfig {\n return {\n ...config,\n url: interpolateString(config.url, variables),\n headers: interpolateRecord(config.headers, variables),\n query: interpolateRecord(config.query, variables),\n body: config.body !== undefined ? interpolateValue(config.body, variables) : undefined,\n auth: config.auth\n ? (interpolateValue(config.auth, variables) as RequestConfig['auth'])\n : undefined,\n }\n}\n","/**\n * Auto-prepend BASE_URL para URLs relativas (que empiezan con /).\n * Quita trailing slash de BASE_URL para evitar doble slash.\n */\nexport function resolveUrl(url: string, variables: Record<string, string>): string {\n if (url.startsWith('/') && variables.BASE_URL) {\n const baseUrl = variables.BASE_URL.replace(/\\/+$/, '')\n return `${baseUrl}${url}`\n }\n return url\n}\n","import { z } from 'zod'\n\nexport const HttpMethodSchema = z.enum([\n 'GET',\n 'POST',\n 'PUT',\n 'PATCH',\n 'DELETE',\n 'HEAD',\n 'OPTIONS',\n])\n\nexport const AuthSchema = z.object({\n type: z.enum(['bearer', 'api-key', 'basic']).describe('Tipo de autenticación'),\n token: z.string().optional().describe('Token para Bearer auth'),\n key: z.string().optional().describe('API key value'),\n header: z.string().optional().describe('Header name para API key (default: X-API-Key)'),\n username: z.string().optional().describe('Username para Basic auth'),\n password: z.string().optional().describe('Password para Basic auth'),\n})\n\n/**\n * Shape (raw properties) del AuthSchema para usar con server.tool()\n * que espera raw Zod shapes, no z.object().\n */\nexport const AuthSchemaShape = AuthSchema.shape\n","import { z } from 'zod'\nimport type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'\nimport type { Storage } from '../lib/storage.js'\nimport { AuthSchemaShape } from '../lib/schemas.js'\nimport type { SavedRequest } from '../lib/types.js'\n\nexport function registerCollectionTools(server: McpServer, storage: Storage): void {\n // ── collection_save ──\n server.tool(\n 'collection_save',\n 'Guarda un request en la colección local. Si ya existe un request con el mismo nombre, lo sobreescribe.',\n {\n name: z.string().describe('Nombre único del request guardado'),\n request: z\n .object({\n method: z.enum(['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'HEAD', 'OPTIONS']),\n url: z.string(),\n headers: z.record(z.string()).optional(),\n body: z.any().optional(),\n query: z.record(z.string()).optional(),\n auth: z.object(AuthSchemaShape).optional(),\n })\n .describe('Configuración del request a guardar'),\n tags: z\n .array(z.string())\n .optional()\n .describe('Tags para organizar (ej: [\"auth\", \"users\"])'),\n },\n async (params) => {\n try {\n const now = new Date().toISOString()\n const existing = await storage.getCollection(params.name)\n\n const saved: SavedRequest = {\n name: params.name,\n request: params.request,\n tags: params.tags,\n createdAt: existing?.createdAt ?? now,\n updatedAt: now,\n }\n\n await storage.saveCollection(saved)\n\n return {\n content: [\n {\n type: 'text' as const,\n text: `Request '${params.name}' guardado (${params.request.method} ${params.request.url})`,\n },\n ],\n }\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error)\n return {\n content: [{ type: 'text' as const, text: `Error: ${message}` }],\n isError: true,\n }\n }\n },\n )\n\n // ── collection_list ──\n server.tool(\n 'collection_list',\n 'Lista todos los requests guardados en la colección. Opcionalmente filtra por tag.',\n {\n tag: z.string().optional().describe('Filtrar por tag'),\n },\n async (params) => {\n try {\n const items = await storage.listCollections(params.tag)\n\n if (items.length === 0) {\n const msg = params.tag\n ? `No hay requests con tag '${params.tag}'`\n : 'La colección está vacía'\n return { content: [{ type: 'text' as const, text: msg }] }\n }\n\n return {\n content: [\n {\n type: 'text' as const,\n text: JSON.stringify(items, null, 2),\n },\n ],\n }\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error)\n return {\n content: [{ type: 'text' as const, text: `Error: ${message}` }],\n isError: true,\n }\n }\n },\n )\n\n // ── collection_get ──\n server.tool(\n 'collection_get',\n 'Obtiene los detalles completos de un request guardado por su nombre.',\n {\n name: z.string().describe('Nombre del request guardado'),\n },\n async (params) => {\n try {\n const saved = await storage.getCollection(params.name)\n\n if (!saved) {\n return {\n content: [\n {\n type: 'text' as const,\n text: `Request '${params.name}' no encontrado`,\n },\n ],\n isError: true,\n }\n }\n\n return {\n content: [\n {\n type: 'text' as const,\n text: JSON.stringify(saved, null, 2),\n },\n ],\n }\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error)\n return {\n content: [{ type: 'text' as const, text: `Error: ${message}` }],\n isError: true,\n }\n }\n },\n )\n\n // ── collection_delete ──\n server.tool(\n 'collection_delete',\n 'Elimina un request guardado de la colección.',\n {\n name: z.string().describe('Nombre del request a eliminar'),\n },\n async (params) => {\n try {\n const deleted = await storage.deleteCollection(params.name)\n\n if (!deleted) {\n return {\n content: [\n {\n type: 'text' as const,\n text: `Request '${params.name}' no encontrado`,\n },\n ],\n isError: true,\n }\n }\n\n return {\n content: [\n {\n type: 'text' as const,\n text: `Request '${params.name}' eliminado`,\n },\n ],\n }\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error)\n return {\n content: [{ type: 'text' as const, text: `Error: ${message}` }],\n isError: true,\n }\n }\n },\n )\n}\n","import { z } from 'zod'\nimport type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'\nimport type { Storage } from '../lib/storage.js'\nimport type { Environment } from '../lib/types.js'\n\nexport function registerEnvironmentTools(server: McpServer, storage: Storage): void {\n // ── env_create ──\n server.tool(\n 'env_create',\n 'Crea un nuevo entorno (ej: dev, staging, prod) con variables opcionales.',\n {\n name: z.string().describe('Nombre del entorno (ej: dev, staging, prod)'),\n variables: z\n .record(z.string())\n .optional()\n .describe('Variables iniciales como key-value'),\n spec: z\n .string()\n .optional()\n .describe('Nombre del spec API asociado (ej: \"cocaxcode-api\")'),\n },\n async (params) => {\n try {\n const now = new Date().toISOString()\n const env: Environment = {\n name: params.name,\n variables: params.variables ?? {},\n spec: params.spec,\n createdAt: now,\n updatedAt: now,\n }\n\n await storage.createEnvironment(env)\n\n const varCount = Object.keys(env.variables).length\n const specMsg = params.spec ? ` — spec: '${params.spec}'` : ''\n return {\n content: [\n {\n type: 'text' as const,\n text: `Entorno '${params.name}' creado con ${varCount} variable(s)${specMsg}`,\n },\n ],\n }\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error)\n return {\n content: [{ type: 'text' as const, text: `Error: ${message}` }],\n isError: true,\n }\n }\n },\n )\n\n // ── env_list ──\n server.tool(\n 'env_list',\n 'Lista todos los entornos disponibles e indica cuál está activo.',\n {},\n async () => {\n try {\n const items = await storage.listEnvironments()\n\n if (items.length === 0) {\n return {\n content: [{ type: 'text' as const, text: 'No hay entornos configurados' }],\n }\n }\n\n return {\n content: [\n {\n type: 'text' as const,\n text: JSON.stringify(items, null, 2),\n },\n ],\n }\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error)\n return {\n content: [{ type: 'text' as const, text: `Error: ${message}` }],\n isError: true,\n }\n }\n },\n )\n\n // ── env_set ──\n server.tool(\n 'env_set',\n 'Establece una variable en un entorno. Si no se especifica entorno, usa el activo.',\n {\n key: z.string().describe('Nombre de la variable'),\n value: z.string().describe('Valor de la variable'),\n environment: z\n .string()\n .optional()\n .describe('Entorno destino (default: entorno activo)'),\n },\n async (params) => {\n try {\n // Determinar entorno destino\n const envName = params.environment ?? (await storage.getActiveEnvironment())\n\n if (!envName) {\n return {\n content: [\n {\n type: 'text' as const,\n text: 'No hay entorno activo. Usa env_create para crear uno y env_switch para activarlo.',\n },\n ],\n isError: true,\n }\n }\n\n await storage.updateEnvironment(envName, { [params.key]: params.value })\n\n return {\n content: [\n {\n type: 'text' as const,\n text: `Variable '${params.key}' establecida en entorno '${envName}'`,\n },\n ],\n }\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error)\n return {\n content: [{ type: 'text' as const, text: `Error: ${message}` }],\n isError: true,\n }\n }\n },\n )\n\n // ── env_get ──\n server.tool(\n 'env_get',\n 'Obtiene una variable específica o todas las variables de un entorno.',\n {\n key: z\n .string()\n .optional()\n .describe('Variable específica. Si se omite, retorna todas'),\n environment: z\n .string()\n .optional()\n .describe('Entorno a consultar (default: entorno activo)'),\n },\n async (params) => {\n try {\n const envName = params.environment ?? (await storage.getActiveEnvironment())\n\n if (!envName) {\n return {\n content: [\n {\n type: 'text' as const,\n text: 'No hay entorno activo. Usa env_switch para activar uno.',\n },\n ],\n isError: true,\n }\n }\n\n const env = await storage.getEnvironment(envName)\n if (!env) {\n return {\n content: [\n { type: 'text' as const, text: `Entorno '${envName}' no encontrado` },\n ],\n isError: true,\n }\n }\n\n if (params.key) {\n const value = env.variables[params.key]\n if (value === undefined) {\n return {\n content: [\n {\n type: 'text' as const,\n text: `Variable '${params.key}' no encontrada en entorno '${envName}'`,\n },\n ],\n isError: true,\n }\n }\n return {\n content: [\n {\n type: 'text' as const,\n text: JSON.stringify({ key: params.key, value, environment: envName }, null, 2),\n },\n ],\n }\n }\n\n return {\n content: [\n {\n type: 'text' as const,\n text: JSON.stringify(\n { environment: envName, variables: env.variables },\n null,\n 2,\n ),\n },\n ],\n }\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error)\n return {\n content: [{ type: 'text' as const, text: `Error: ${message}` }],\n isError: true,\n }\n }\n },\n )\n\n // ── env_spec ──\n server.tool(\n 'env_spec',\n 'Asocia o desasocia un spec API a un entorno. Si no se especifica entorno, usa el activo.',\n {\n spec: z\n .string()\n .optional()\n .describe('Nombre del spec a asociar. Si se omite, desasocia el spec actual'),\n environment: z\n .string()\n .optional()\n .describe('Entorno destino (default: entorno activo)'),\n },\n async (params) => {\n try {\n const envName = params.environment ?? (await storage.getActiveEnvironment())\n\n if (!envName) {\n return {\n content: [\n {\n type: 'text' as const,\n text: 'No hay entorno activo. Usa env_switch para activar uno.',\n },\n ],\n isError: true,\n }\n }\n\n await storage.setEnvironmentSpec(envName, params.spec ?? null)\n\n const message = params.spec\n ? `Spec '${params.spec}' asociado al entorno '${envName}'`\n : `Spec desasociado del entorno '${envName}'`\n\n return {\n content: [{ type: 'text' as const, text: message }],\n }\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error)\n return {\n content: [{ type: 'text' as const, text: `Error: ${message}` }],\n isError: true,\n }\n }\n },\n )\n\n // ── env_rename ──\n server.tool(\n 'env_rename',\n 'Renombra un entorno existente. Si es el entorno activo, actualiza la referencia.',\n {\n name: z.string().describe('Nombre actual del entorno'),\n new_name: z.string().describe('Nuevo nombre para el entorno'),\n },\n async (params) => {\n try {\n await storage.renameEnvironment(params.name, params.new_name)\n\n return {\n content: [\n {\n type: 'text' as const,\n text: `Entorno '${params.name}' renombrado a '${params.new_name}'`,\n },\n ],\n }\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error)\n return {\n content: [{ type: 'text' as const, text: `Error: ${message}` }],\n isError: true,\n }\n }\n },\n )\n\n // ── env_delete ──\n server.tool(\n 'env_delete',\n 'Elimina un entorno y todas sus variables. Si es el entorno activo, lo desactiva.',\n {\n name: z.string().describe('Nombre del entorno a eliminar'),\n },\n async (params) => {\n try {\n await storage.deleteEnvironment(params.name)\n\n return {\n content: [\n {\n type: 'text' as const,\n text: `Entorno '${params.name}' eliminado`,\n },\n ],\n }\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error)\n return {\n content: [{ type: 'text' as const, text: `Error: ${message}` }],\n isError: true,\n }\n }\n },\n )\n\n // ── env_switch ──\n server.tool(\n 'env_switch',\n 'Cambia el entorno activo. Si se especifica project, solo aplica a ese directorio de proyecto.',\n {\n name: z.string().describe('Nombre del entorno a activar'),\n project: z\n .string()\n .optional()\n .describe('Ruta del proyecto (ej: C:/cocaxcode). Si se omite, cambia el entorno global'),\n },\n async (params) => {\n try {\n await storage.setActiveEnvironment(params.name, params.project)\n\n const scope = params.project\n ? ` para proyecto '${params.project}'`\n : ' (global)'\n return {\n content: [\n {\n type: 'text' as const,\n text: `Entorno activo cambiado a '${params.name}'${scope}`,\n },\n ],\n }\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error)\n return {\n content: [{ type: 'text' as const, text: `Error: ${message}` }],\n isError: true,\n }\n }\n },\n )\n\n // ── env_project_clear ──\n server.tool(\n 'env_project_clear',\n 'Elimina la asociación de entorno específico de un proyecto. El proyecto usará el entorno global.',\n {\n project: z\n .string()\n .describe('Ruta del proyecto del que eliminar la asociación'),\n },\n async (params) => {\n try {\n const removed = await storage.clearProjectEnvironment(params.project)\n\n if (!removed) {\n return {\n content: [\n {\n type: 'text' as const,\n text: `No hay entorno específico para el proyecto '${params.project}'`,\n },\n ],\n }\n }\n\n return {\n content: [\n {\n type: 'text' as const,\n text: `Entorno específico eliminado para proyecto '${params.project}'. Usará el entorno global.`,\n },\n ],\n }\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error)\n return {\n content: [{ type: 'text' as const, text: `Error: ${message}` }],\n isError: true,\n }\n }\n },\n )\n\n // ── env_project_list ──\n server.tool(\n 'env_project_list',\n 'Lista todos los proyectos con entornos específicos asignados.',\n {},\n async () => {\n try {\n const projectEnvs = await storage.listProjectEnvironments()\n const entries = Object.entries(projectEnvs)\n\n if (entries.length === 0) {\n return {\n content: [\n {\n type: 'text' as const,\n text: 'No hay entornos específicos por proyecto. Todos usan el entorno global.',\n },\n ],\n }\n }\n\n return {\n content: [\n {\n type: 'text' as const,\n text: JSON.stringify(\n entries.map(([project, env]) => ({ project, environment: env })),\n null,\n 2,\n ),\n },\n ],\n }\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error)\n return {\n content: [{ type: 'text' as const, text: `Error: ${message}` }],\n isError: true,\n }\n }\n },\n )\n}\n","import { z } from 'zod'\nimport type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'\nimport type { Storage } from '../lib/storage.js'\nimport { parseOpenApiSpec } from '../lib/openapi-parser.js'\nimport { readFile } from 'node:fs/promises'\n\n/**\n * Resuelve el nombre del spec a usar:\n * 1. Si se pasa explícitamente, lo usa\n * 2. Si hay un entorno activo con spec asociado, lo usa\n * 3. Si solo hay un spec importado, lo usa\n * 4. Si hay múltiples, pide al usuario que elija\n */\nasync function resolveSpecName(\n name: string | undefined,\n storage: Storage,\n): Promise<{ name: string; error?: never } | { name?: never; error: string }> {\n if (name) return { name }\n\n // Try active environment spec\n const activeSpec = await storage.getActiveSpec()\n if (activeSpec) return { name: activeSpec }\n\n // Fallback to single spec\n const specs = await storage.listSpecs()\n if (specs.length === 0) {\n return { error: 'No hay specs importados. Usa api_import para importar uno.' }\n }\n if (specs.length === 1) {\n return { name: specs[0].name }\n }\n return {\n error: `Hay ${specs.length} specs importados. Especifica cuál usar: ${specs.map((s) => s.name).join(', ')}`,\n }\n}\n\nexport function registerApiSpecTools(server: McpServer, storage: Storage): void {\n // ── api_import ──\n\n server.tool(\n 'api_import',\n 'Importa un spec OpenAPI/Swagger desde una URL o archivo local. Guarda los endpoints y schemas para consulta.',\n {\n name: z\n .string()\n .describe('Nombre para identificar este API (ej: \"mi-backend\", \"cocaxcode-api\")'),\n source: z\n .string()\n .describe(\n 'URL del spec OpenAPI JSON (ej: http://localhost:3001/api-docs-json) o ruta a archivo local',\n ),\n },\n async (params) => {\n try {\n let rawDoc: Record<string, unknown>\n\n if (params.source.startsWith('http://') || params.source.startsWith('https://')) {\n // Fetch from URL\n const controller = new AbortController()\n const timeout = setTimeout(() => controller.abort(), 30000)\n\n try {\n const response = await fetch(params.source, { signal: controller.signal })\n if (!response.ok) {\n return {\n content: [\n {\n type: 'text' as const,\n text: `Error: No se pudo descargar el spec. Status: ${response.status} ${response.statusText}`,\n },\n ],\n isError: true,\n }\n }\n rawDoc = (await response.json()) as Record<string, unknown>\n } finally {\n clearTimeout(timeout)\n }\n } else {\n // Read from local file\n try {\n const content = await readFile(params.source, 'utf-8')\n rawDoc = JSON.parse(content) as Record<string, unknown>\n } catch {\n return {\n content: [\n {\n type: 'text' as const,\n text: `Error: No se pudo leer el archivo '${params.source}'. Verifica que existe y es JSON válido.`,\n },\n ],\n isError: true,\n }\n }\n }\n\n // Validate it looks like OpenAPI\n if (!rawDoc.openapi && !rawDoc.swagger) {\n return {\n content: [\n {\n type: 'text' as const,\n text: 'Error: El documento no parece ser un spec OpenAPI/Swagger válido. Falta la propiedad \"openapi\" o \"swagger\".',\n },\n ],\n isError: true,\n }\n }\n\n // Parse and save\n const spec = parseOpenApiSpec(rawDoc, params.name, params.source)\n await storage.saveSpec(spec)\n\n // Auto-associate with active environment\n const activeEnv = await storage.getActiveEnvironment()\n if (activeEnv) {\n await storage.setEnvironmentSpec(activeEnv, params.name)\n }\n\n // Build summary\n const tagCounts: Record<string, number> = {}\n for (const ep of spec.endpoints) {\n for (const tag of ep.tags ?? ['sin-tag']) {\n tagCounts[tag] = (tagCounts[tag] ?? 0) + 1\n }\n }\n\n const tagSummary = Object.entries(tagCounts)\n .map(([tag, count]) => ` - ${tag}: ${count} endpoints`)\n .join('\\n')\n\n const schemaCount = Object.keys(spec.schemas).length\n\n return {\n content: [\n {\n type: 'text' as const,\n text: [\n `API '${params.name}' importada correctamente.`,\n '',\n `Versión: ${spec.version ?? 'no especificada'}`,\n `Endpoints: ${spec.endpoints.length}`,\n `Schemas: ${schemaCount}`,\n '',\n 'Endpoints por tag:',\n tagSummary,\n '',\n activeEnv ? `Asociado al entorno '${activeEnv}'.` : '',\n 'Usa api_endpoints para ver los endpoints disponibles.',\n 'Usa api_endpoint_detail para ver el detalle de un endpoint específico.',\n ].join('\\n'),\n },\n ],\n }\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error)\n return {\n content: [{ type: 'text' as const, text: `Error: ${message}` }],\n isError: true,\n }\n }\n },\n )\n\n // ── api_spec_list ──\n\n server.tool(\n 'api_spec_list',\n 'Lista todos los specs de API importados. Úsalo para descubrir qué APIs están disponibles.',\n {},\n async () => {\n try {\n const items = await storage.listSpecs()\n\n if (items.length === 0) {\n return {\n content: [\n {\n type: 'text' as const,\n text: 'No hay specs importados. Usa api_import para importar uno.',\n },\n ],\n }\n }\n\n return {\n content: [\n {\n type: 'text' as const,\n text: JSON.stringify(items, null, 2),\n },\n ],\n }\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error)\n return {\n content: [{ type: 'text' as const, text: `Error: ${message}` }],\n isError: true,\n }\n }\n },\n )\n\n // ── api_endpoints ──\n\n server.tool(\n 'api_endpoints',\n 'Lista los endpoints de un API importada. Filtra por tag, método o path. Si no se especifica nombre y solo hay un spec importado, lo usa automáticamente.',\n {\n name: z\n .string()\n .optional()\n .describe('Nombre del API importada. Si se omite y solo hay un spec, lo usa automáticamente'),\n tag: z\n .string()\n .optional()\n .describe('Filtrar por tag (ej: \"blog\", \"auth\", \"users\")'),\n method: z\n .enum(['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'HEAD', 'OPTIONS'])\n .optional()\n .describe('Filtrar por método HTTP'),\n path: z\n .string()\n .optional()\n .describe('Filtrar por path (búsqueda parcial, ej: \"/blog\" muestra todos los que contienen /blog)'),\n },\n async (params) => {\n try {\n const resolved = await resolveSpecName(params.name, storage)\n if (resolved.error) {\n return {\n content: [{ type: 'text' as const, text: resolved.error }],\n isError: true,\n }\n }\n\n const resolvedName = resolved.name as string\n const spec = await storage.getSpec(resolvedName)\n if (!spec) {\n return {\n content: [\n {\n type: 'text' as const,\n text: `Error: API '${resolvedName}' no encontrada. Usa api_import para importarla primero.`,\n },\n ],\n isError: true,\n }\n }\n\n let endpoints = spec.endpoints\n\n // Apply filters\n if (params.tag) {\n endpoints = endpoints.filter((ep) =>\n (ep.tags ?? []).some((t) => t.toLowerCase() === params.tag!.toLowerCase()),\n )\n }\n if (params.method) {\n endpoints = endpoints.filter((ep) => ep.method === params.method)\n }\n if (params.path) {\n const search = params.path.toLowerCase()\n endpoints = endpoints.filter((ep) => ep.path.toLowerCase().includes(search))\n }\n\n if (endpoints.length === 0) {\n return {\n content: [\n {\n type: 'text' as const,\n text: 'No se encontraron endpoints con los filtros aplicados.',\n },\n ],\n }\n }\n\n // Format output\n const lines = endpoints.map((ep) => {\n const tags = ep.tags?.length ? ` [${ep.tags.join(', ')}]` : ''\n const summary = ep.summary ? ` — ${ep.summary}` : ''\n return `${ep.method.padEnd(7)} ${ep.path}${summary}${tags}`\n })\n\n return {\n content: [\n {\n type: 'text' as const,\n text: [\n `API: ${spec.name} (${endpoints.length} endpoints)`,\n '',\n ...lines,\n '',\n 'Usa api_endpoint_detail para ver parámetros, body y respuestas de un endpoint.',\n ].join('\\n'),\n },\n ],\n }\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error)\n return {\n content: [{ type: 'text' as const, text: `Error: ${message}` }],\n isError: true,\n }\n }\n },\n )\n\n // ── api_endpoint_detail ──\n\n server.tool(\n 'api_endpoint_detail',\n 'Muestra el detalle completo de un endpoint: parámetros, body schema, y respuestas. Útil para saber qué datos enviar.',\n {\n name: z\n .string()\n .optional()\n .describe('Nombre del API importada. Si se omite y solo hay un spec, lo usa automáticamente'),\n method: z\n .enum(['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'HEAD', 'OPTIONS'])\n .describe('Método HTTP del endpoint'),\n path: z\n .string()\n .describe('Path exacto del endpoint (ej: \"/blog\", \"/auth/login\")'),\n },\n async (params) => {\n try {\n const resolved = await resolveSpecName(params.name, storage)\n if (resolved.error) {\n return {\n content: [{ type: 'text' as const, text: resolved.error }],\n isError: true,\n }\n }\n\n const resolvedName = resolved.name as string\n const spec = await storage.getSpec(resolvedName)\n if (!spec) {\n return {\n content: [\n {\n type: 'text' as const,\n text: `Error: API '${resolvedName}' no encontrada. Usa api_import para importarla primero.`,\n },\n ],\n isError: true,\n }\n }\n\n const endpoint = spec.endpoints.find(\n (ep) => ep.method === params.method && ep.path === params.path,\n )\n\n if (!endpoint) {\n // Try partial match\n const similar = spec.endpoints.filter((ep) =>\n ep.path.includes(params.path) || params.path.includes(ep.path),\n )\n\n const suggestion = similar.length > 0\n ? `\\n\\nEndpoints similares:\\n${similar.map((ep) => ` ${ep.method} ${ep.path}`).join('\\n')}`\n : ''\n\n return {\n content: [\n {\n type: 'text' as const,\n text: `Error: Endpoint ${params.method} ${params.path} no encontrado.${suggestion}`,\n },\n ],\n isError: true,\n }\n }\n\n // Build detailed output\n const sections: string[] = []\n\n // Header\n sections.push(`## ${endpoint.method} ${endpoint.path}`)\n if (endpoint.summary) sections.push(`**${endpoint.summary}**`)\n if (endpoint.description) sections.push(endpoint.description)\n if (endpoint.tags?.length) sections.push(`Tags: ${endpoint.tags.join(', ')}`)\n\n // Parameters\n if (endpoint.parameters?.length) {\n sections.push('')\n sections.push('### Parámetros')\n for (const param of endpoint.parameters) {\n const required = param.required ? ' (requerido)' : ' (opcional)'\n const type = param.schema?.type ?? 'string'\n const desc = param.description ? ` — ${param.description}` : ''\n sections.push(`- **${param.name}** [${param.in}] ${type}${required}${desc}`)\n }\n }\n\n // Request body\n if (endpoint.requestBody) {\n sections.push('')\n sections.push('### Body')\n const required = endpoint.requestBody.required ? ' (requerido)' : ' (opcional)'\n sections.push(`Body${required}`)\n\n if (endpoint.requestBody.content) {\n for (const [contentType, media] of Object.entries(endpoint.requestBody.content)) {\n sections.push(`\\nContent-Type: ${contentType}`)\n if (media.schema) {\n sections.push('```json')\n sections.push(formatSchema(media.schema))\n sections.push('```')\n }\n }\n }\n }\n\n // Responses\n if (endpoint.responses) {\n sections.push('')\n sections.push('### Respuestas')\n for (const [status, resp] of Object.entries(endpoint.responses)) {\n const desc = resp.description ? ` — ${resp.description}` : ''\n sections.push(`\\n**${status}**${desc}`)\n\n if (resp.content) {\n for (const [, media] of Object.entries(resp.content)) {\n if (media.schema) {\n sections.push('```json')\n sections.push(formatSchema(media.schema))\n sections.push('```')\n }\n }\n }\n }\n }\n\n return {\n content: [\n {\n type: 'text' as const,\n text: sections.join('\\n'),\n },\n ],\n }\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error)\n return {\n content: [{ type: 'text' as const, text: `Error: ${message}` }],\n isError: true,\n }\n }\n },\n )\n}\n\n/**\n * Formatea un schema como ejemplo JSON legible.\n * Genera un ejemplo basado en los tipos y propiedades del schema.\n */\nfunction formatSchema(schema: { type?: string; properties?: Record<string, unknown>; items?: unknown; required?: string[]; enum?: unknown[]; example?: unknown; format?: string; description?: string }, depth = 0): string {\n if (depth > 5) return '\"...\"'\n\n const indent = ' '.repeat(depth)\n const innerIndent = ' '.repeat(depth + 1)\n\n if (schema.example !== undefined) {\n return JSON.stringify(schema.example, null, 2)\n .split('\\n')\n .map((line, i) => (i === 0 ? line : indent + line))\n .join('\\n')\n }\n\n if (schema.enum) {\n return JSON.stringify(schema.enum[0])\n }\n\n if (schema.type === 'object' && schema.properties) {\n const props = Object.entries(schema.properties as Record<string, Record<string, unknown>>)\n if (props.length === 0) return '{}'\n\n const requiredFields = new Set(schema.required ?? [])\n const lines: string[] = ['{']\n\n for (const [key, prop] of props) {\n const isRequired = requiredFields.has(key)\n const comment = []\n if (prop.description) comment.push(prop.description as string)\n if (!isRequired) comment.push('opcional')\n const commentStr = comment.length > 0 ? ` // ${comment.join(' — ')}` : ''\n\n const value = formatSchema(prop as typeof schema, depth + 1)\n lines.push(`${innerIndent}\"${key}\": ${value},${commentStr}`)\n }\n\n lines.push(`${indent}}`)\n return lines.join('\\n')\n }\n\n if (schema.type === 'array' && schema.items) {\n const itemValue = formatSchema(schema.items as typeof schema, depth + 1)\n return `[${itemValue}]`\n }\n\n // Primitive types\n switch (schema.type) {\n case 'string':\n if (schema.format === 'date-time') return '\"2024-01-01T00:00:00Z\"'\n if (schema.format === 'email') return '\"user@example.com\"'\n if (schema.format === 'uri' || schema.format === 'url') return '\"https://example.com\"'\n return '\"string\"'\n case 'number':\n case 'integer':\n return '0'\n case 'boolean':\n return 'true'\n default:\n return 'null'\n }\n}\n","import type {\n HttpMethod,\n ApiSpecEndpoint,\n ApiSpecSchema,\n ApiSpec,\n} from './types.js'\n\nconst VALID_METHODS: HttpMethod[] = ['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'HEAD', 'OPTIONS']\n\n/**\n * Resuelve $ref references en un schema OpenAPI.\n * Soporta refs tipo \"#/components/schemas/MyModel\".\n */\nfunction resolveRef(\n ref: string,\n root: Record<string, unknown>,\n): ApiSpecSchema | undefined {\n const parts = ref.replace(/^#\\//, '').split('/')\n let current: unknown = root\n\n for (const part of parts) {\n if (current && typeof current === 'object' && part in current) {\n current = (current as Record<string, unknown>)[part]\n } else {\n return undefined\n }\n }\n\n return current as ApiSpecSchema\n}\n\n/**\n * Resuelve recursivamente todos los $ref en un schema.\n */\nfunction resolveSchema(\n schema: ApiSpecSchema | undefined,\n root: Record<string, unknown>,\n depth = 0,\n): ApiSpecSchema | undefined {\n if (!schema || depth > 10) return schema\n\n if (schema.$ref) {\n const resolved = resolveRef(schema.$ref, root)\n if (resolved) {\n return resolveSchema(resolved, root, depth + 1)\n }\n return { type: 'object', description: `Unresolved: ${schema.$ref}` }\n }\n\n const result: ApiSpecSchema = { ...schema }\n\n // Resolve allOf — merge all schemas into one\n const rawAllOf = (schema as Record<string, unknown>).allOf as ApiSpecSchema[] | undefined\n if (rawAllOf && Array.isArray(rawAllOf)) {\n const merged: ApiSpecSchema = { type: 'object' }\n const mergedProps: Record<string, ApiSpecSchema> = {}\n const mergedRequired: string[] = []\n\n for (const sub of rawAllOf) {\n const resolved = resolveSchema(sub, root, depth + 1)\n if (resolved?.properties) {\n Object.assign(mergedProps, resolved.properties)\n }\n if (resolved?.required) {\n mergedRequired.push(...resolved.required)\n }\n if (resolved?.description && !merged.description) {\n merged.description = resolved.description\n }\n }\n\n merged.properties = { ...(result.properties ?? {}), ...mergedProps }\n if (mergedRequired.length > 0) {\n merged.required = [...new Set([...(result.required ?? []), ...mergedRequired])]\n }\n\n return merged\n }\n\n // Resolve oneOf/anyOf — pick the first schema as representative\n const rawOneOf = (schema as Record<string, unknown>).oneOf as ApiSpecSchema[] | undefined\n const rawAnyOf = (schema as Record<string, unknown>).anyOf as ApiSpecSchema[] | undefined\n const unionSchemas = rawOneOf ?? rawAnyOf\n if (unionSchemas && Array.isArray(unionSchemas) && unionSchemas.length > 0) {\n return resolveSchema(unionSchemas[0], root, depth + 1)\n }\n\n // Resolve properties recursively\n if (result.properties) {\n const resolvedProps: Record<string, ApiSpecSchema> = {}\n for (const [key, prop] of Object.entries(result.properties)) {\n resolvedProps[key] = resolveSchema(prop, root, depth + 1) ?? prop\n }\n result.properties = resolvedProps\n }\n\n // Resolve array items\n if (result.items) {\n result.items = resolveSchema(result.items, root, depth + 1) ?? result.items\n }\n\n return result\n}\n\n/**\n * Parsea un documento OpenAPI 3.x y extrae endpoints y schemas.\n */\nexport function parseOpenApiSpec(\n doc: Record<string, unknown>,\n name: string,\n source: string,\n): ApiSpec {\n const info = doc.info as Record<string, unknown> | undefined\n const paths = doc.paths as Record<string, Record<string, unknown>> | undefined\n const components = doc.components as Record<string, unknown> | undefined\n const rawSchemas = (components?.schemas ?? {}) as Record<string, ApiSpecSchema>\n\n // Resolve all schemas\n const schemas: Record<string, ApiSpecSchema> = {}\n for (const [schemaName, schema] of Object.entries(rawSchemas)) {\n schemas[schemaName] = resolveSchema(schema, doc, 0) ?? schema\n }\n\n const endpoints: ApiSpecEndpoint[] = []\n\n if (paths) {\n for (const [path, pathItem] of Object.entries(paths)) {\n for (const [method, operation] of Object.entries(pathItem)) {\n const upperMethod = method.toUpperCase() as HttpMethod\n if (!VALID_METHODS.includes(upperMethod)) continue\n\n const op = operation as Record<string, unknown>\n\n // Parse parameters\n const rawParams = (op.parameters ?? []) as Array<Record<string, unknown>>\n const parameters = rawParams.map((p) => ({\n name: p.name as string,\n in: p.in as 'path' | 'query' | 'header' | 'cookie',\n required: p.required as boolean | undefined,\n description: p.description as string | undefined,\n schema: resolveSchema(p.schema as ApiSpecSchema | undefined, doc),\n }))\n\n // Parse request body\n const rawBody = op.requestBody as Record<string, unknown> | undefined\n let requestBody = undefined\n if (rawBody) {\n const bodyContent = rawBody.content as Record<string, Record<string, unknown>> | undefined\n const resolvedContent: Record<string, { schema?: ApiSpecSchema }> = {}\n\n if (bodyContent) {\n for (const [contentType, mediaType] of Object.entries(bodyContent)) {\n resolvedContent[contentType] = {\n schema: resolveSchema(mediaType.schema as ApiSpecSchema | undefined, doc),\n }\n }\n }\n\n requestBody = {\n required: rawBody.required as boolean | undefined,\n description: rawBody.description as string | undefined,\n content: resolvedContent,\n }\n }\n\n // Parse responses\n const rawResponses = (op.responses ?? {}) as Record<string, Record<string, unknown>>\n const responses: Record<string, { description?: string; content?: Record<string, { schema?: ApiSpecSchema }> }> = {}\n\n for (const [statusCode, resp] of Object.entries(rawResponses)) {\n const respContent = resp.content as Record<string, Record<string, unknown>> | undefined\n const resolvedRespContent: Record<string, { schema?: ApiSpecSchema }> = {}\n\n if (respContent) {\n for (const [contentType, mediaType] of Object.entries(respContent)) {\n resolvedRespContent[contentType] = {\n schema: resolveSchema(mediaType.schema as ApiSpecSchema | undefined, doc),\n }\n }\n }\n\n responses[statusCode] = {\n description: resp.description as string | undefined,\n content: respContent ? resolvedRespContent : undefined,\n }\n }\n\n endpoints.push({\n method: upperMethod,\n path,\n summary: op.summary as string | undefined,\n description: op.description as string | undefined,\n tags: op.tags as string[] | undefined,\n parameters,\n requestBody,\n responses,\n })\n }\n }\n }\n\n const now = new Date().toISOString()\n\n return {\n name,\n source,\n version: info?.version as string | undefined,\n endpoints,\n schemas,\n importedAt: now,\n updatedAt: now,\n }\n}\n","import { z } from 'zod'\nimport type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'\nimport type { Storage } from '../lib/storage.js'\nimport { executeRequest } from '../lib/http-client.js'\nimport { interpolateRequest } from '../lib/interpolation.js'\nimport { resolveUrl } from '../lib/url.js'\nimport { getByPath } from '../lib/path.js'\nimport { AuthSchema } from '../lib/schemas.js'\nimport type { RequestConfig, RequestResponse } from '../lib/types.js'\n\nconst AssertionSchema = z.object({\n path: z\n .string()\n .describe(\n 'JSONPath al valor a validar: \"status\", \"body.data.id\", \"headers.content-type\", \"timing.total_ms\"',\n ),\n operator: z\n .enum(['eq', 'neq', 'gt', 'gte', 'lt', 'lte', 'contains', 'not_contains', 'exists', 'type'])\n .describe(\n 'Operador: eq (igual), neq (no igual), gt/gte/lt/lte (numéricos), contains/not_contains (strings/arrays), exists (campo existe), type (typeof)',\n ),\n expected: z.any().optional().describe('Valor esperado (no necesario para \"exists\")'),\n})\n\n/**\n * Evalúa una aserción contra una respuesta.\n */\nfunction evaluateAssertion(\n response: RequestResponse,\n assertion: { path: string; operator: string; expected?: unknown },\n): { pass: boolean; message: string } {\n const actual = getByPath(response, assertion.path)\n\n switch (assertion.operator) {\n case 'eq':\n return {\n pass: actual === assertion.expected,\n message: actual === assertion.expected\n ? `${assertion.path} === ${JSON.stringify(assertion.expected)}`\n : `${assertion.path}: esperado ${JSON.stringify(assertion.expected)}, recibido ${JSON.stringify(actual)}`,\n }\n\n case 'neq':\n return {\n pass: actual !== assertion.expected,\n message: actual !== assertion.expected\n ? `${assertion.path} !== ${JSON.stringify(assertion.expected)}`\n : `${assertion.path}: no debería ser ${JSON.stringify(assertion.expected)}`,\n }\n\n case 'gt':\n return {\n pass: typeof actual === 'number' && actual > (assertion.expected as number),\n message: `${assertion.path}: ${actual} > ${assertion.expected} → ${typeof actual === 'number' && actual > (assertion.expected as number)}`,\n }\n\n case 'gte':\n return {\n pass: typeof actual === 'number' && actual >= (assertion.expected as number),\n message: `${assertion.path}: ${actual} >= ${assertion.expected} → ${typeof actual === 'number' && actual >= (assertion.expected as number)}`,\n }\n\n case 'lt':\n return {\n pass: typeof actual === 'number' && actual < (assertion.expected as number),\n message: `${assertion.path}: ${actual} < ${assertion.expected} → ${typeof actual === 'number' && actual < (assertion.expected as number)}`,\n }\n\n case 'lte':\n return {\n pass: typeof actual === 'number' && actual <= (assertion.expected as number),\n message: `${assertion.path}: ${actual} <= ${assertion.expected} → ${typeof actual === 'number' && actual <= (assertion.expected as number)}`,\n }\n\n case 'contains': {\n let pass = false\n if (typeof actual === 'string') {\n pass = actual.includes(String(assertion.expected))\n } else if (Array.isArray(actual)) {\n pass = actual.includes(assertion.expected)\n }\n return {\n pass,\n message: pass\n ? `${assertion.path} contiene ${JSON.stringify(assertion.expected)}`\n : `${assertion.path}: no contiene ${JSON.stringify(assertion.expected)}`,\n }\n }\n\n case 'not_contains': {\n let pass = true\n if (typeof actual === 'string') {\n pass = !actual.includes(String(assertion.expected))\n } else if (Array.isArray(actual)) {\n pass = !actual.includes(assertion.expected)\n }\n return {\n pass,\n message: pass\n ? `${assertion.path} no contiene ${JSON.stringify(assertion.expected)}`\n : `${assertion.path}: contiene ${JSON.stringify(assertion.expected)} (no debería)`,\n }\n }\n\n case 'exists':\n return {\n pass: actual !== undefined && actual !== null,\n message: actual !== undefined && actual !== null\n ? `${assertion.path} existe`\n : `${assertion.path}: no existe`,\n }\n\n case 'type':\n return {\n pass: typeof actual === assertion.expected,\n message: typeof actual === assertion.expected\n ? `${assertion.path} es tipo ${assertion.expected}`\n : `${assertion.path}: esperado tipo ${assertion.expected}, recibido ${typeof actual}`,\n }\n\n default:\n return { pass: false, message: `Operador desconocido: ${assertion.operator}` }\n }\n}\n\nexport function registerAssertTool(server: McpServer, storage: Storage): void {\n server.tool(\n 'assert',\n 'Ejecuta un request y valida la respuesta con assertions. Retorna resultado pass/fail por cada assertion.',\n {\n method: z\n .enum(['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'HEAD', 'OPTIONS'])\n .describe('HTTP method'),\n url: z.string().describe('URL del endpoint (soporta /relativa y {{variables}})'),\n headers: z.record(z.string()).optional().describe('Headers HTTP'),\n body: z.any().optional().describe('Body del request (JSON)'),\n query: z.record(z.string()).optional().describe('Query parameters'),\n auth: AuthSchema.optional().describe('Autenticación'),\n assertions: z\n .array(AssertionSchema)\n .describe('Lista de assertions a validar contra la respuesta'),\n },\n async (params) => {\n try {\n const variables = await storage.getActiveVariables()\n const resolvedUrl = resolveUrl(params.url, variables)\n\n const config: RequestConfig = {\n method: params.method,\n url: resolvedUrl,\n headers: params.headers,\n body: params.body,\n query: params.query,\n auth: params.auth,\n }\n\n const interpolated = interpolateRequest(config, variables)\n const response = await executeRequest(interpolated)\n\n // Evaluate assertions\n const results = params.assertions.map((assertion) => {\n const result = evaluateAssertion(response, assertion)\n return { ...result, assertion }\n })\n\n const passed = results.filter((r) => r.pass).length\n const failed = results.filter((r) => !r.pass).length\n const allPassed = failed === 0\n\n const lines: string[] = [\n `${allPassed ? '✅ PASS' : '❌ FAIL'} — ${passed}/${results.length} assertions passed`,\n `${params.method} ${params.url} → ${response.status} ${response.statusText} (${response.timing.total_ms}ms)`,\n '',\n ]\n\n for (const r of results) {\n const icon = r.pass ? '✅' : '❌'\n lines.push(`${icon} ${r.message}`)\n }\n\n return {\n content: [{ type: 'text' as const, text: lines.join('\\n') }],\n isError: !allPassed,\n }\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error)\n return {\n content: [{ type: 'text' as const, text: `Error: ${message}` }],\n isError: true,\n }\n }\n },\n )\n}\n","/**\n * Accede a un valor en un objeto usando dot notation.\n * Soporta acceso a arrays por índice numérico (ej: \"data.0.id\").\n *\n * Ej: getByPath({ body: { data: [{ id: 1 }] } }, \"body.data.0.id\") → 1\n */\nexport function getByPath(obj: unknown, path: string): unknown {\n const parts = path.split('.')\n let current: unknown = obj\n\n for (const part of parts) {\n if (current === null || current === undefined) return undefined\n if (typeof current === 'object') {\n if (Array.isArray(current) && /^\\d+$/.test(part)) {\n current = current[parseInt(part)]\n } else {\n current = (current as Record<string, unknown>)[part]\n }\n } else {\n return undefined\n }\n }\n\n return current\n}\n","import { z } from 'zod'\nimport type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'\nimport type { Storage } from '../lib/storage.js'\nimport { executeRequest } from '../lib/http-client.js'\nimport { interpolateRequest } from '../lib/interpolation.js'\nimport { resolveUrl } from '../lib/url.js'\nimport { getByPath } from '../lib/path.js'\nimport { AuthSchema } from '../lib/schemas.js'\nimport type { RequestConfig, RequestResponse } from '../lib/types.js'\n\nconst FlowStepSchema = z.object({\n name: z.string().describe('Nombre del paso (ej: \"login\", \"crear-post\")'),\n method: z\n .enum(['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'HEAD', 'OPTIONS'])\n .describe('HTTP method'),\n url: z.string().describe('URL del endpoint'),\n headers: z.record(z.string()).optional().describe('Headers HTTP'),\n body: z.any().optional().describe('Body del request'),\n query: z.record(z.string()).optional().describe('Query parameters'),\n auth: AuthSchema.optional().describe('Autenticación'),\n extract: z\n .record(z.string())\n .optional()\n .describe(\n 'Variables a extraer de la respuesta para pasos siguientes. Key = nombre variable, value = path (ej: { \"TOKEN\": \"body.token\", \"USER_ID\": \"body.data.id\" })',\n ),\n})\n\nexport function registerFlowTool(server: McpServer, storage: Storage): void {\n server.tool(\n 'flow_run',\n 'Ejecuta una secuencia de requests en orden. Extrae variables de cada respuesta para usar en pasos siguientes con {{variable}}.',\n {\n steps: z.array(FlowStepSchema).describe('Pasos a ejecutar en orden'),\n stop_on_error: z\n .boolean()\n .optional()\n .describe('Detener al primer error (default: true)'),\n },\n async (params) => {\n try {\n const stopOnError = params.stop_on_error ?? true\n const envVariables = await storage.getActiveVariables()\n const flowVariables: Record<string, string> = { ...envVariables }\n const results: Array<{\n name: string\n status: number\n timing: number\n extracted: Record<string, string>\n error?: string\n }> = []\n\n for (const step of params.steps) {\n try {\n const resolvedUrl = resolveUrl(step.url, flowVariables)\n\n const config: RequestConfig = {\n method: step.method,\n url: resolvedUrl,\n headers: step.headers,\n body: step.body,\n query: step.query,\n auth: step.auth,\n }\n\n const interpolated = interpolateRequest(config, flowVariables)\n const response: RequestResponse = await executeRequest(interpolated)\n\n // Extract variables from response\n const extracted: Record<string, string> = {}\n if (step.extract) {\n for (const [varName, path] of Object.entries(step.extract)) {\n const value = getByPath(response, path)\n if (value !== undefined && value !== null) {\n extracted[varName] = String(value)\n flowVariables[varName] = String(value)\n }\n }\n }\n\n results.push({\n name: step.name,\n status: response.status,\n timing: response.timing.total_ms,\n extracted,\n })\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error)\n results.push({\n name: step.name,\n status: 0,\n timing: 0,\n extracted: {},\n error: message,\n })\n\n if (stopOnError) break\n }\n }\n\n // Build output\n const allOk = results.every((r) => !r.error && r.status >= 200 && r.status < 400)\n const lines: string[] = [\n `${allOk ? '✅ FLOW COMPLETO' : '❌ FLOW CON ERRORES'} — ${results.length}/${params.steps.length} pasos ejecutados`,\n '',\n ]\n\n for (let i = 0; i < results.length; i++) {\n const r = results[i]\n const icon = r.error ? '❌' : r.status >= 200 && r.status < 400 ? '✅' : '⚠️'\n lines.push(`${icon} Paso ${i + 1}: ${r.name}`)\n\n if (r.error) {\n lines.push(` Error: ${r.error}`)\n } else {\n lines.push(` Status: ${r.status} | Tiempo: ${r.timing}ms`)\n }\n\n if (Object.keys(r.extracted).length > 0) {\n const vars = Object.entries(r.extracted)\n .map(([k, v]) => `${k}=${v.length > 50 ? v.substring(0, 50) + '...' : v}`)\n .join(', ')\n lines.push(` Extraído: ${vars}`)\n }\n\n lines.push('')\n }\n\n return {\n content: [{ type: 'text' as const, text: lines.join('\\n') }],\n isError: !allOk,\n }\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error)\n return {\n content: [{ type: 'text' as const, text: `Error: ${message}` }],\n isError: true,\n }\n }\n },\n )\n}\n","import { z } from 'zod'\nimport { mkdir, writeFile } from 'node:fs/promises'\nimport { join } from 'node:path'\nimport type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'\nimport type { Storage } from '../lib/storage.js'\nimport { executeRequest } from '../lib/http-client.js'\nimport { interpolateRequest } from '../lib/interpolation.js'\nimport { resolveUrl } from '../lib/url.js'\nimport { AuthSchema } from '../lib/schemas.js'\nimport type { RequestConfig, AuthConfig, SavedRequest } from '../lib/types.js'\n\nexport function registerUtilityTools(server: McpServer, storage: Storage): void {\n // ── export_curl ──\n\n server.tool(\n 'export_curl',\n 'Genera un comando cURL a partir de un request guardado en la colección. Listo para copiar y pegar.',\n {\n name: z.string().describe('Nombre del request guardado en la colección'),\n resolve_variables: z\n .boolean()\n .optional()\n .describe('Resolver {{variables}} del entorno activo (default: true)'),\n },\n async (params) => {\n try {\n const saved = await storage.getCollection(params.name)\n if (!saved) {\n return {\n content: [\n {\n type: 'text' as const,\n text: `Error: Request '${params.name}' no encontrado en la colección.`,\n },\n ],\n isError: true,\n }\n }\n\n let config = saved.request\n const resolveVars = params.resolve_variables ?? true\n\n if (resolveVars) {\n const variables = await storage.getActiveVariables()\n const resolvedUrl = resolveUrl(config.url, variables)\n config = { ...config, url: resolvedUrl }\n config = interpolateRequest(config, variables)\n }\n\n // Build cURL command\n const parts: string[] = ['curl']\n\n if (config.method !== 'GET') {\n parts.push(`-X ${config.method}`)\n }\n\n let url = config.url\n if (config.query && Object.keys(config.query).length > 0) {\n const queryStr = Object.entries(config.query)\n .map(([k, v]) => `${encodeURIComponent(k)}=${encodeURIComponent(v)}`)\n .join('&')\n url += (url.includes('?') ? '&' : '?') + queryStr\n }\n parts.push(`'${url}'`)\n\n if (config.headers) {\n for (const [key, value] of Object.entries(config.headers)) {\n parts.push(`-H '${key}: ${value}'`)\n }\n }\n\n if (config.auth) {\n switch (config.auth.type) {\n case 'bearer':\n if (config.auth.token) {\n parts.push(`-H 'Authorization: Bearer ${config.auth.token}'`)\n }\n break\n case 'api-key':\n if (config.auth.key) {\n const header = config.auth.header ?? 'X-API-Key'\n parts.push(`-H '${header}: ${config.auth.key}'`)\n }\n break\n case 'basic':\n if (config.auth.username && config.auth.password) {\n parts.push(`-u '${config.auth.username}:${config.auth.password}'`)\n }\n break\n }\n }\n\n if (config.body !== undefined && config.body !== null) {\n const bodyStr =\n typeof config.body === 'string' ? config.body : JSON.stringify(config.body)\n parts.push(`-H 'Content-Type: application/json'`)\n parts.push(`-d '${bodyStr}'`)\n }\n\n const curlCommand = parts.join(' \\\\\\n ')\n\n return {\n content: [\n {\n type: 'text' as const,\n text: `cURL para '${params.name}':\\n\\n${curlCommand}`,\n },\n ],\n }\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error)\n return {\n content: [{ type: 'text' as const, text: `Error: ${message}` }],\n isError: true,\n }\n }\n },\n )\n\n // ── diff_responses ──\n\n const DiffRequestSchema = z.object({\n label: z.string().optional().describe('Etiqueta (ej: \"antes\", \"dev\", \"v1\")'),\n method: z.enum(['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'HEAD', 'OPTIONS']),\n url: z.string(),\n headers: z.record(z.string()).optional(),\n body: z.any().optional(),\n query: z.record(z.string()).optional(),\n auth: AuthSchema.optional(),\n })\n\n server.tool(\n 'diff_responses',\n 'Ejecuta dos requests y compara sus respuestas. Útil para detectar regresiones o comparar entornos.',\n {\n request_a: DiffRequestSchema.describe('Primer request'),\n request_b: DiffRequestSchema.describe('Segundo request'),\n },\n async (params) => {\n try {\n const variables = await storage.getActiveVariables()\n\n const executeOne = async (req: z.infer<typeof DiffRequestSchema>) => {\n const resolvedUrl = resolveUrl(req.url, variables)\n\n const config: RequestConfig = {\n method: req.method,\n url: resolvedUrl,\n headers: req.headers,\n body: req.body,\n query: req.query,\n auth: req.auth,\n }\n\n return executeRequest(interpolateRequest(config, variables))\n }\n\n const [responseA, responseB] = await Promise.all([\n executeOne(params.request_a),\n executeOne(params.request_b),\n ])\n\n const labelA = params.request_a.label ?? 'A'\n const labelB = params.request_b.label ?? 'B'\n\n const diffs: string[] = []\n\n if (responseA.status !== responseB.status) {\n diffs.push(\n `Status: ${labelA}=${responseA.status} vs ${labelB}=${responseB.status}`,\n )\n }\n\n const timingDiff = Math.abs(responseA.timing.total_ms - responseB.timing.total_ms)\n if (timingDiff > 100) {\n diffs.push(\n `Timing: ${labelA}=${responseA.timing.total_ms}ms vs ${labelB}=${responseB.timing.total_ms}ms (Δ${Math.round(timingDiff)}ms)`,\n )\n }\n\n const bodyA = JSON.stringify(responseA.body, null, 2)\n const bodyB = JSON.stringify(responseB.body, null, 2)\n\n if (bodyA !== bodyB) {\n diffs.push('Body: diferente')\n\n if (\n typeof responseA.body === 'object' &&\n typeof responseB.body === 'object' &&\n responseA.body &&\n responseB.body\n ) {\n const keysA = new Set(Object.keys(responseA.body as Record<string, unknown>))\n const keysB = new Set(Object.keys(responseB.body as Record<string, unknown>))\n\n const onlyInA = [...keysA].filter((k) => !keysB.has(k))\n const onlyInB = [...keysB].filter((k) => !keysA.has(k))\n const common = [...keysA].filter((k) => keysB.has(k))\n\n if (onlyInA.length > 0) diffs.push(` Solo en ${labelA}: ${onlyInA.join(', ')}`)\n if (onlyInB.length > 0) diffs.push(` Solo en ${labelB}: ${onlyInB.join(', ')}`)\n\n for (const key of common) {\n const valA = JSON.stringify(\n (responseA.body as Record<string, unknown>)[key],\n )\n const valB = JSON.stringify(\n (responseB.body as Record<string, unknown>)[key],\n )\n if (valA !== valB) {\n const shortA = valA.length > 50 ? valA.substring(0, 50) + '...' : valA\n const shortB = valB.length > 50 ? valB.substring(0, 50) + '...' : valB\n diffs.push(` ${key}: ${labelA}=${shortA} vs ${labelB}=${shortB}`)\n }\n }\n }\n }\n\n const sizeDiff = Math.abs(responseA.size_bytes - responseB.size_bytes)\n if (sizeDiff > 0) {\n diffs.push(\n `Size: ${labelA}=${responseA.size_bytes}B vs ${labelB}=${responseB.size_bytes}B`,\n )\n }\n\n const identical = diffs.length === 0\n\n const lines: string[] = [\n identical ? '✅ IDÉNTICAS' : `⚠️ ${diffs.length} DIFERENCIAS ENCONTRADAS`,\n '',\n `${labelA}: ${params.request_a.method} ${params.request_a.url} → ${responseA.status} (${responseA.timing.total_ms}ms)`,\n `${labelB}: ${params.request_b.method} ${params.request_b.url} → ${responseB.status} (${responseB.timing.total_ms}ms)`,\n ]\n\n if (!identical) {\n lines.push('')\n lines.push('Diferencias:')\n for (const diff of diffs) {\n lines.push(` ${diff}`)\n }\n }\n\n return {\n content: [{ type: 'text' as const, text: lines.join('\\n') }],\n }\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error)\n return {\n content: [{ type: 'text' as const, text: `Error: ${message}` }],\n isError: true,\n }\n }\n },\n )\n\n // ── bulk_test ──\n\n server.tool(\n 'bulk_test',\n 'Ejecuta todos los requests guardados en la colección y reporta resultados. Filtrable por tag.',\n {\n tag: z.string().optional().describe('Filtrar por tag'),\n expected_status: z\n .number()\n .optional()\n .describe('Status HTTP esperado para todos (default: cualquier 2xx)'),\n },\n async (params) => {\n try {\n const collections = await storage.listCollections(params.tag)\n if (collections.length === 0) {\n return {\n content: [\n {\n type: 'text' as const,\n text: params.tag\n ? `No hay requests guardados con tag '${params.tag}'.`\n : 'No hay requests guardados en la colección.',\n },\n ],\n }\n }\n\n const variables = await storage.getActiveVariables()\n const results: Array<{\n name: string\n method: string\n url: string\n status: number\n timing: number\n pass: boolean\n error?: string\n }> = []\n\n for (const item of collections) {\n const saved = await storage.getCollection(item.name)\n if (!saved) continue\n\n try {\n let config = saved.request\n const resolvedUrl = resolveUrl(config.url, variables)\n config = { ...config, url: resolvedUrl }\n const interpolated = interpolateRequest(config, variables)\n const response = await executeRequest(interpolated)\n\n const pass = params.expected_status\n ? response.status === params.expected_status\n : response.status >= 200 && response.status < 300\n\n results.push({\n name: item.name,\n method: config.method,\n url: item.url,\n status: response.status,\n timing: response.timing.total_ms,\n pass,\n })\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error)\n results.push({\n name: item.name,\n method: item.method,\n url: item.url,\n status: 0,\n timing: 0,\n pass: false,\n error: message,\n })\n }\n }\n\n const passed = results.filter((r) => r.pass).length\n const failed = results.filter((r) => !r.pass).length\n const totalTime = Math.round(results.reduce((sum, r) => sum + r.timing, 0) * 100) / 100\n\n const lines: string[] = [\n `${failed === 0 ? '✅' : '❌'} BULK TEST — ${passed}/${results.length} passed | ${totalTime}ms total`,\n '',\n ]\n\n for (const r of results) {\n const icon = r.pass ? '✅' : '❌'\n if (r.error) {\n lines.push(`${icon} ${r.name} — ERROR: ${r.error}`)\n } else {\n lines.push(`${icon} ${r.name} — ${r.method} ${r.url} → ${r.status} (${r.timing}ms)`)\n }\n }\n\n return {\n content: [{ type: 'text' as const, text: lines.join('\\n') }],\n isError: failed > 0,\n }\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error)\n return {\n content: [{ type: 'text' as const, text: `Error: ${message}` }],\n isError: true,\n }\n }\n },\n )\n\n // ── export_postman_collection ──\n\n server.tool(\n 'export_postman_collection',\n 'Exporta los requests guardados como una Postman Collection v2.1 (JSON). Escribe el archivo en disco, importable directamente en Postman.',\n {\n name: z\n .string()\n .optional()\n .describe('Nombre de la colección (default: \"API Testing Collection\")'),\n tag: z.string().optional().describe('Filtrar requests por tag'),\n output_dir: z\n .string()\n .optional()\n .describe('Directorio donde guardar el archivo (default: ./postman/)'),\n resolve_variables: z\n .boolean()\n .optional()\n .describe('Resolver {{variables}} del entorno activo (default: false)'),\n },\n async (params) => {\n try {\n const collections = await storage.listCollections(params.tag)\n if (collections.length === 0) {\n return {\n content: [\n {\n type: 'text' as const,\n text: params.tag\n ? `No hay requests guardados con tag '${params.tag}'.`\n : 'No hay requests guardados en la colección.',\n },\n ],\n }\n }\n\n const resolveVars = params.resolve_variables ?? false\n const variables = resolveVars ? await storage.getActiveVariables() : {}\n\n // Load full requests\n const savedRequests: SavedRequest[] = []\n for (const item of collections) {\n const saved = await storage.getCollection(item.name)\n if (saved) savedRequests.push(saved)\n }\n\n // Group by tags for folder structure\n const tagged = new Map<string, SavedRequest[]>()\n const untagged: SavedRequest[] = []\n\n for (const saved of savedRequests) {\n if (saved.tags && saved.tags.length > 0) {\n const tag = saved.tags[0]\n if (!tagged.has(tag)) tagged.set(tag, [])\n tagged.get(tag)!.push(saved)\n } else {\n untagged.push(saved)\n }\n }\n\n // Build Postman items\n const items: unknown[] = []\n\n for (const [tag, requests] of tagged) {\n items.push({\n name: tag,\n item: requests.map((r) => buildPostmanItem(r, variables, resolveVars)),\n })\n }\n\n for (const saved of untagged) {\n items.push(buildPostmanItem(saved, variables, resolveVars))\n }\n\n // Include environment variables as collection variables\n const activeVars = await storage.getActiveVariables()\n const collectionVars = Object.entries(activeVars).map(([key, value]) => ({\n key,\n value,\n type: 'string',\n }))\n\n const collectionName = params.name ?? 'API Testing Collection'\n\n const postmanCollection = {\n info: {\n name: collectionName,\n schema: 'https://schema.getpostman.com/json/collection/v2.1.0/collection.json',\n },\n item: items,\n variable: collectionVars,\n }\n\n const json = JSON.stringify(postmanCollection, null, 2)\n\n // Write to file\n const outputDir = params.output_dir ?? join(process.cwd(), 'postman')\n await mkdir(outputDir, { recursive: true })\n const fileName = collectionName.toLowerCase().replace(/[^a-z0-9]+/g, '-').replace(/^-|-$/g, '') + '.postman_collection.json'\n const filePath = join(outputDir, fileName)\n await writeFile(filePath, json, 'utf-8')\n\n return {\n content: [\n {\n type: 'text' as const,\n text: `Postman Collection v2.1 exportada (${savedRequests.length} requests).\\n\\nArchivo: ${filePath}\\n\\nImporta este archivo en Postman: File → Import → selecciona el archivo.`,\n },\n ],\n }\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error)\n return {\n content: [{ type: 'text' as const, text: `Error: ${message}` }],\n isError: true,\n }\n }\n },\n )\n\n // ── export_postman_environment ──\n\n server.tool(\n 'export_postman_environment',\n 'Exporta un entorno como Postman Environment (JSON). Escribe el archivo en disco, importable directamente en Postman.',\n {\n name: z\n .string()\n .optional()\n .describe('Nombre del entorno a exportar (default: entorno activo)'),\n output_dir: z\n .string()\n .optional()\n .describe('Directorio donde guardar el archivo (default: ./postman/)'),\n },\n async (params) => {\n try {\n let envName = params.name\n if (!envName) {\n envName = (await storage.getActiveEnvironment()) ?? undefined\n if (!envName) {\n return {\n content: [\n {\n type: 'text' as const,\n text: 'No hay entorno activo. Especifica un nombre con el parámetro \"name\".',\n },\n ],\n isError: true,\n }\n }\n }\n\n const env = await storage.getEnvironment(envName)\n if (!env) {\n return {\n content: [\n {\n type: 'text' as const,\n text: `Entorno '${envName}' no encontrado.`,\n },\n ],\n isError: true,\n }\n }\n\n const postmanEnv = {\n name: env.name,\n values: Object.entries(env.variables).map(([key, value]) => ({\n key,\n value,\n type: 'default',\n enabled: true,\n })),\n _postman_variable_scope: 'environment',\n }\n\n const json = JSON.stringify(postmanEnv, null, 2)\n\n // Write to file\n const outputDir = params.output_dir ?? join(process.cwd(), 'postman')\n await mkdir(outputDir, { recursive: true })\n const fileName = env.name.toLowerCase().replace(/[^a-z0-9]+/g, '-').replace(/^-|-$/g, '') + '.postman_environment.json'\n const filePath = join(outputDir, fileName)\n await writeFile(filePath, json, 'utf-8')\n\n return {\n content: [\n {\n type: 'text' as const,\n text: `Postman Environment \"${env.name}\" exportado (${Object.keys(env.variables).length} variables).\\n\\nArchivo: ${filePath}\\n\\nImporta este archivo en Postman: File → Import → selecciona el archivo.`,\n },\n ],\n }\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error)\n return {\n content: [{ type: 'text' as const, text: `Error: ${message}` }],\n isError: true,\n }\n }\n },\n )\n}\n\n// ── Postman helpers ──\n\nfunction buildPostmanItem(\n saved: SavedRequest,\n variables: Record<string, string>,\n resolveVars: boolean,\n): unknown {\n let config = saved.request\n if (resolveVars) {\n const resolvedUrl = resolveUrl(config.url, variables)\n config = { ...config, url: resolvedUrl }\n config = interpolateRequest(config, variables)\n }\n\n const item: Record<string, unknown> = {\n name: saved.name,\n request: buildPostmanRequest(config),\n }\n\n return item\n}\n\nfunction buildPostmanRequest(config: RequestConfig): unknown {\n const request: Record<string, unknown> = {\n method: config.method,\n header: buildPostmanHeaders(config.headers),\n url: buildPostmanUrl(config.url, config.query),\n }\n\n if (config.body !== undefined && config.body !== null) {\n request.body = {\n mode: 'raw',\n raw: typeof config.body === 'string' ? config.body : JSON.stringify(config.body, null, 2),\n options: { raw: { language: 'json' } },\n }\n // Add Content-Type header if not already present\n const headers = request.header as Array<{ key: string; value: string }>\n if (!headers.some((h) => h.key.toLowerCase() === 'content-type')) {\n headers.push({ key: 'Content-Type', value: 'application/json' })\n }\n }\n\n if (config.auth) {\n request.auth = buildPostmanAuth(config.auth)\n }\n\n return request\n}\n\nfunction buildPostmanHeaders(\n headers?: Record<string, string>,\n): Array<{ key: string; value: string }> {\n if (!headers) return []\n return Object.entries(headers).map(([key, value]) => ({ key, value }))\n}\n\nfunction buildPostmanUrl(\n rawUrl: string,\n query?: Record<string, string>,\n): Record<string, unknown> {\n const url: Record<string, unknown> = { raw: rawUrl }\n\n // Parse protocol, host, path\n const match = rawUrl.match(/^(https?):\\/\\/([^/]+)(\\/.*)?$/)\n if (match) {\n url.protocol = match[1]\n url.host = match[2].split('.')\n url.path = match[3] ? match[3].slice(1).split('/') : []\n }\n\n if (query && Object.keys(query).length > 0) {\n url.query = Object.entries(query).map(([key, value]) => ({ key, value }))\n // Append query to raw URL\n const queryStr = Object.entries(query)\n .map(([k, v]) => `${k}=${v}`)\n .join('&')\n url.raw = rawUrl + (rawUrl.includes('?') ? '&' : '?') + queryStr\n }\n\n return url\n}\n\nfunction buildPostmanAuth(auth: AuthConfig): Record<string, unknown> {\n switch (auth.type) {\n case 'bearer':\n return {\n type: 'bearer',\n bearer: [{ key: 'token', value: auth.token ?? '', type: 'string' }],\n }\n case 'api-key':\n return {\n type: 'apikey',\n apikey: [\n { key: 'key', value: auth.key ?? '', type: 'string' },\n { key: 'value', value: auth.header ?? 'X-API-Key', type: 'string' },\n { key: 'in', value: 'header', type: 'string' },\n ],\n }\n case 'basic':\n return {\n type: 'basic',\n basic: [\n { key: 'username', value: auth.username ?? '', type: 'string' },\n { key: 'password', value: auth.password ?? '', type: 'string' },\n ],\n }\n }\n}\n","import { z } from 'zod'\nimport type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'\nimport type { Storage } from '../lib/storage.js'\nimport type { ApiSpecSchema } from '../lib/types.js'\n\n/**\n * Genera datos fake basándose en un schema OpenAPI.\n */\nfunction generateMockData(schema: ApiSpecSchema, depth = 0): unknown {\n if (depth > 8) return null\n\n // If example exists, use it\n if (schema.example !== undefined) return schema.example\n\n // If enum, pick first value\n if (schema.enum && schema.enum.length > 0) {\n return schema.enum[Math.floor(Math.random() * schema.enum.length)]\n }\n\n switch (schema.type) {\n case 'object': {\n if (!schema.properties) return {}\n const obj: Record<string, unknown> = {}\n for (const [key, propSchema] of Object.entries(schema.properties)) {\n obj[key] = generateMockData(propSchema, depth + 1)\n }\n return obj\n }\n\n case 'array': {\n if (!schema.items) return []\n const count = Math.floor(Math.random() * 3) + 1 // 1-3 items\n return Array.from({ length: count }, () =>\n generateMockData(schema.items!, depth + 1),\n )\n }\n\n case 'string': {\n switch (schema.format) {\n case 'date-time':\n return new Date().toISOString()\n case 'date':\n return new Date().toISOString().split('T')[0]\n case 'email':\n return `user${Math.floor(Math.random() * 1000)}@example.com`\n case 'uri':\n case 'url':\n return 'https://example.com/resource'\n case 'uuid':\n return crypto.randomUUID()\n case 'ipv4':\n return `192.168.${Math.floor(Math.random() * 255)}.${Math.floor(Math.random() * 255)}`\n default: {\n // Use description or key name for smarter generation\n const desc = (schema.description ?? '').toLowerCase()\n if (desc.includes('name') || desc.includes('nombre'))\n return `Test User ${Math.floor(Math.random() * 100)}`\n if (desc.includes('title') || desc.includes('título'))\n return `Test Title ${Math.floor(Math.random() * 100)}`\n if (desc.includes('description') || desc.includes('descripción'))\n return 'Lorem ipsum dolor sit amet, consectetur adipiscing elit.'\n if (desc.includes('password') || desc.includes('contraseña'))\n return 'TestPass123!'\n if (desc.includes('slug'))\n return `test-slug-${Math.floor(Math.random() * 1000)}`\n if (desc.includes('phone') || desc.includes('teléfono'))\n return '+34612345678'\n return `mock-string-${Math.floor(Math.random() * 10000)}`\n }\n }\n }\n\n case 'number':\n case 'integer':\n return Math.floor(Math.random() * 1000)\n\n case 'boolean':\n return Math.random() > 0.5\n\n default:\n return null\n }\n}\n\nexport function registerMockTool(server: McpServer, storage: Storage): void {\n server.tool(\n 'mock',\n 'Genera datos mock/fake para un endpoint basándose en su spec OpenAPI importada. Útil para frontend sin backend.',\n {\n name: z.string().describe('Nombre del API importada'),\n method: z\n .enum(['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'HEAD', 'OPTIONS'])\n .describe('Método HTTP del endpoint'),\n path: z.string().describe('Path del endpoint (ej: \"/users\", \"/blog\")'),\n target: z\n .enum(['request', 'response'])\n .optional()\n .describe('Generar mock del body de request o de la response (default: response)'),\n status: z\n .string()\n .optional()\n .describe('Status code de la respuesta a mockear (default: \"200\" o \"201\")'),\n count: z\n .number()\n .optional()\n .describe('Número de items mock a generar si el schema es un array (default: 3)'),\n },\n async (params) => {\n try {\n const spec = await storage.getSpec(params.name)\n if (!spec) {\n return {\n content: [\n {\n type: 'text' as const,\n text: `Error: API '${params.name}' no encontrada. Usa api_import para importarla primero.`,\n },\n ],\n isError: true,\n }\n }\n\n const endpoint = spec.endpoints.find(\n (ep) => ep.method === params.method && ep.path === params.path,\n )\n\n if (!endpoint) {\n return {\n content: [\n {\n type: 'text' as const,\n text: `Error: Endpoint ${params.method} ${params.path} no encontrado en '${params.name}'.`,\n },\n ],\n isError: true,\n }\n }\n\n const target = params.target ?? 'response'\n let schema: ApiSpecSchema | undefined\n\n if (target === 'request') {\n // Get request body schema\n const content = endpoint.requestBody?.content\n if (content) {\n const jsonContent = content['application/json']\n schema = jsonContent?.schema\n }\n\n if (!schema) {\n return {\n content: [\n {\n type: 'text' as const,\n text: `Error: El endpoint ${params.method} ${params.path} no tiene un body schema definido.`,\n },\n ],\n isError: true,\n }\n }\n } else {\n // Get response body schema\n const statusCode = params.status ?? (params.method === 'POST' ? '201' : '200')\n const response = endpoint.responses?.[statusCode]\n\n if (!response) {\n // Try to find any 2xx response\n const twoXX = Object.keys(endpoint.responses ?? {}).find((s) => s.startsWith('2'))\n if (twoXX && endpoint.responses) {\n const fallbackResp = endpoint.responses[twoXX]\n const content = fallbackResp?.content\n if (content) {\n const jsonContent = content['application/json']\n schema = jsonContent?.schema\n }\n }\n } else {\n const content = response.content\n if (content) {\n const jsonContent = content['application/json']\n schema = jsonContent?.schema\n }\n }\n\n if (!schema) {\n return {\n content: [\n {\n type: 'text' as const,\n text: `Error: No se encontró un schema de respuesta para ${params.method} ${params.path}.`,\n },\n ],\n isError: true,\n }\n }\n }\n\n // Generate mock data\n let mockData: unknown\n\n if (schema.type === 'array' && params.count) {\n // Generate specific number of items\n mockData = Array.from({ length: params.count }, () =>\n generateMockData(schema!.items ?? { type: 'object' }),\n )\n } else {\n mockData = generateMockData(schema)\n }\n\n const label = target === 'request' ? 'REQUEST BODY' : 'RESPONSE'\n\n return {\n content: [\n {\n type: 'text' as const,\n text: [\n `Mock ${label} para ${params.method} ${params.path}:`,\n '',\n '```json',\n JSON.stringify(mockData, null, 2),\n '```',\n '',\n 'Datos generados automáticamente desde el spec OpenAPI.',\n target === 'request'\n ? 'Puedes usar estos datos directamente en un request.'\n : 'Estos son datos de ejemplo que devolvería el endpoint.',\n ].join('\\n'),\n },\n ],\n }\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error)\n return {\n content: [{ type: 'text' as const, text: `Error: ${message}` }],\n isError: true,\n }\n }\n },\n )\n}\n","import { z } from 'zod'\nimport type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'\nimport type { Storage } from '../lib/storage.js'\nimport { executeRequest } from '../lib/http-client.js'\nimport { interpolateRequest } from '../lib/interpolation.js'\nimport { resolveUrl } from '../lib/url.js'\nimport { AuthSchema } from '../lib/schemas.js'\nimport type { RequestConfig } from '../lib/types.js'\n\nexport function registerLoadTestTool(server: McpServer, storage: Storage): void {\n server.tool(\n 'load_test',\n 'Lanza N requests concurrentes al mismo endpoint y mide tiempos promedio, percentiles y tasa de errores.',\n {\n method: z\n .enum(['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'HEAD', 'OPTIONS'])\n .describe('HTTP method'),\n url: z.string().describe('URL del endpoint'),\n headers: z.record(z.string()).optional().describe('Headers HTTP'),\n body: z.any().optional().describe('Body del request'),\n query: z.record(z.string()).optional().describe('Query parameters'),\n auth: AuthSchema.optional().describe('Autenticación'),\n concurrent: z\n .number()\n .describe('Número de requests concurrentes a lanzar (max: 100)'),\n timeout: z\n .number()\n .optional()\n .describe('Timeout por request en ms (default: 30000)'),\n },\n async (params) => {\n try {\n const concurrentCount = Math.min(Math.max(params.concurrent, 1), 100)\n const variables = await storage.getActiveVariables()\n const resolvedUrl = resolveUrl(params.url, variables)\n\n const baseConfig: RequestConfig = {\n method: params.method,\n url: resolvedUrl,\n headers: params.headers,\n body: params.body,\n query: params.query,\n auth: params.auth,\n timeout: params.timeout,\n }\n\n const interpolated = interpolateRequest(baseConfig, variables)\n\n const startTotal = performance.now()\n\n const promises = Array.from({ length: concurrentCount }, () =>\n executeRequest(interpolated)\n .then((response) => ({\n status: response.status,\n timing: response.timing.total_ms,\n error: undefined as string | undefined,\n }))\n .catch((error) => ({\n status: 0,\n timing: 0,\n error: error instanceof Error ? error.message : String(error),\n })),\n )\n\n const results = await Promise.all(promises)\n const endTotal = performance.now()\n const wallTime = Math.round((endTotal - startTotal) * 100) / 100\n\n const successful = results.filter((r) => !r.error)\n const failed = results.filter((r) => r.error)\n const timings = successful.map((r) => r.timing).sort((a, b) => a - b)\n\n const statusCounts: Record<number, number> = {}\n for (const r of successful) {\n statusCounts[r.status] = (statusCounts[r.status] ?? 0) + 1\n }\n\n const avg = timings.length > 0\n ? Math.round((timings.reduce((s, t) => s + t, 0) / timings.length) * 100) / 100\n : 0\n const min = timings.length > 0 ? timings[0] : 0\n const max = timings.length > 0 ? timings[timings.length - 1] : 0\n const p50 = timings.length > 0 ? timings[Math.floor(timings.length * 0.5)] : 0\n const p95 = timings.length > 0 ? timings[Math.floor(timings.length * 0.95)] : 0\n const p99 = timings.length > 0 ? timings[Math.floor(timings.length * 0.99)] : 0\n\n const rps = wallTime > 0\n ? Math.round((successful.length / (wallTime / 1000)) * 100) / 100\n : 0\n\n const lines: string[] = [\n `📊 LOAD TEST — ${params.method} ${params.url}`,\n '',\n `Requests: ${concurrentCount} concurrentes`,\n `Exitosos: ${successful.length} | Fallidos: ${failed.length}`,\n `Tiempo total: ${wallTime}ms`,\n `Requests/segundo: ${rps}`,\n '',\n '⏱️ Tiempos de respuesta:',\n ` Min: ${min}ms`,\n ` Avg: ${avg}ms`,\n ` p50: ${p50}ms`,\n ` p95: ${p95}ms`,\n ` p99: ${p99}ms`,\n ` Max: ${max}ms`,\n ]\n\n if (Object.keys(statusCounts).length > 0) {\n lines.push('')\n lines.push('📋 Status codes:')\n for (const [status, count] of Object.entries(statusCounts)) {\n const pct = Math.round((count / concurrentCount) * 100)\n lines.push(` ${status}: ${count} (${pct}%)`)\n }\n }\n\n if (failed.length > 0) {\n lines.push('')\n lines.push('❌ Errores:')\n const errorCounts: Record<string, number> = {}\n for (const r of failed) {\n const errMsg = r.error ?? 'Unknown'\n errorCounts[errMsg] = (errorCounts[errMsg] ?? 0) + 1\n }\n for (const [err, count] of Object.entries(errorCounts)) {\n lines.push(` ${err}: ${count}x`)\n }\n }\n\n return {\n content: [{ type: 'text' as const, text: lines.join('\\n') }],\n isError: failed.length > successful.length,\n }\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error)\n return {\n content: [{ type: 'text' as const, text: `Error: ${message}` }],\n isError: true,\n }\n }\n },\n )\n}\n"],"mappings":"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","names":["z","z","z","z","z","z","readFile","z","z","z","z","z","z","mkdir","writeFile","join","z","join","mkdir","writeFile","z","z","z"]}