mock_endpoint
Set up a mock HTTP endpoint by providing method, path, and response. No OpenAPI spec required.
Instructions
Quickly mock a single HTTP endpoint without writing an OpenAPI spec. Pass method (default GET), path (the EXACT HTTP path the user described, including all segments), and the response body (object → JSON, string → text). The bridge writes the response into a managed static dir at ~/.cache/mockzilla-mcp/mocks/ and (re)starts a single shared mockzilla server pointing at it.
Pass path AS IS. Do NOT prepend or duplicate any segment. The bridge derives the service name from the first segment for internal grouping, but it does not change the URL the user hits. Examples:
• User says GET /pets/{id} → call mock_endpoint with path=/pets/{id} → URL is http://HOST:PORT/pets/{id}
• User says POST /orders → path=/orders → URL is http://HOST:PORT/orders
• User says GET /v1/users/me → path=/v1/users/me → URL is http://HOST:PORT/v1/users/me
Path placeholders like {id} are stored as literal directory names — by default ALL placeholder values share the same response. To return different responses for specific values, call mock_endpoint again with a literal value (e.g. /pets/123).
Calling this multiple times accumulates endpoints in the same server — adding POST /pets after GET /pets/{id} keeps both. Mutually exclusive with serve_locally: stop any ad-hoc server first. See mockzilla_docs_search('static directory') for the underlying convention.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| method | No | GET | |
| path | Yes | Path beginning with /. First segment is the service name. | |
| response | No | Response body. Object → JSON. String → text. Default {}. | |
| status | No | ||
| content_type | No | Override content type. Inferred from response type if omitted (object → application/json, string → text/plain). |
Implementation Reference
- lib/local.js:113-186 (handler)The mockEndpoint function is the core handler for the mock_endpoint tool. It validates inputs (method, path, status, response, content_type), writes the response into a static file under ~/.cache/mockzilla-mcp/mocks/static/<service>/<subPath>/<method>/index.<ext>, kills any running managed server, and spawns a fresh managed server pointing at the mocks root. Returns the resulting URL, service info, file path, and admin URLs.
export async function mockEndpoint(args) { const method = String(args.method || "GET").toUpperCase(); if (!ALLOWED_METHODS.has(method)) { throw new Error(`Unsupported method: ${method}`); } const rawPath = args.path; if (typeof rawPath !== "string" || !rawPath.startsWith("/")) { throw new Error("`path` must be a string starting with /"); } const segments = rawPath.split("/").filter(Boolean); if (segments.length === 0) { throw new Error("`path` must include at least one segment after /"); } const service = segments[0]; const subPath = segments.slice(1); const status = Number.isInteger(args.status) ? args.status : 200; const response = args.response !== undefined && args.response !== null ? args.response : {}; const contentType = typeof args.content_type === "string" ? args.content_type : typeof response === "string" ? "text/plain" : "application/json"; const ext = extensionFor(contentType); refuseIfBusy("managed"); // Write the file BEFORE (re)starting the server. Empty MOCKS_ROOT // would cause mockzilla to bail with "no specs found"; we want at // least the just-written endpoint to be present on first launch. const dir = path.join( MOCKS_STATIC_DIR, service, ...subPath, method.toLowerCase(), ); const file = path.join(dir, `index.${ext}`); await mkdir(dir, { recursive: true }); const body = typeof response === "string" ? response : JSON.stringify(response, null, 2); await writeFile(file, body); // Restart-on-write: portable mode does NOT hot-reload new files into // the spec set, so we kill the running managed server (if any) and // start fresh pointing at MOCKS_ROOT. ~1s round trip. await killManaged(); const stamp = await spawnManagedServer(); const url = `${stamp.url.replace(/\/$/, "")}/${service}${ subPath.length > 0 ? "/" + subPath.join("/") : "" }`; const hasPlaceholder = /\{[^}]+\}/.test(rawPath); return { method, path: rawPath, service, url, status, file_path: file, server_url: stamp.url, admin: adminUrls(stamp.port), notes: hasPlaceholder ? `Path contains placeholder(s) like {id}; ALL values share this response. ` + `For per-value responses, call mock_endpoint with literal values ` + `(e.g. ${rawPath.replace(/\{[^}]+\}/g, "123")}).` : null, }; } - lib/tools.js:146-203 (schema)Registration and input schema for the mock_endpoint tool. Defines the tool's description (how to use it, examples), inputSchema with properties: method (enum of HTTP verbs), path (required string), response, status (integer 100-599), content_type (string override). The schema is defined in the LOCAL_TOOLS registry.
mock_endpoint: { description: "Quickly mock a single HTTP endpoint without writing an OpenAPI " + "spec. Pass `method` (default GET), `path` (the EXACT HTTP path " + "the user described, including all segments), and the `response` " + "body (object → JSON, string → text). The bridge writes the " + "response into a managed static dir at ~/.cache/mockzilla-mcp/mocks/ " + "and (re)starts a single shared mockzilla server pointing at it.\n\n" + "Pass `path` AS IS. Do NOT prepend or duplicate any segment. The " + "bridge derives the service name from the first segment for " + "internal grouping, but it does not change the URL the user hits. " + "Examples:\n" + " • User says `GET /pets/{id}` → call mock_endpoint with path=`/pets/{id}` → URL is http://HOST:PORT/pets/{id}\n" + " • User says `POST /orders` → path=`/orders` → URL is http://HOST:PORT/orders\n" + " • User says `GET /v1/users/me` → path=`/v1/users/me` → URL is http://HOST:PORT/v1/users/me\n\n" + "Path placeholders like `{id}` are stored as literal directory " + "names — by default ALL placeholder values share the same " + "response. To return different responses for specific values, " + "call mock_endpoint again with a literal value (e.g. /pets/123).\n\n" + "Calling this multiple times accumulates endpoints in the same " + "server — adding `POST /pets` after `GET /pets/{id}` keeps both. " + "Mutually exclusive with `serve_locally`: stop any ad-hoc server " + "first. See `mockzilla_docs_search('static directory')` for the " + "underlying convention.", inputSchema: { type: "object", properties: { method: { type: "string", enum: ["GET", "POST", "PUT", "PATCH", "DELETE", "HEAD", "OPTIONS"], default: "GET", }, path: { type: "string", description: "Path beginning with /. First segment is the service name.", }, response: { description: "Response body. Object → JSON. String → text. Default {}.", }, status: { type: "integer", minimum: 100, maximum: 599, default: 200, }, content_type: { type: "string", description: "Override content type. Inferred from response type if omitted (object → application/json, string → text/plain).", }, }, required: ["path"], additionalProperties: false, }, handler: mockEndpoint, }, - lib/tools.js:202-203 (registration)The mock_endpoint tool is registered in the LOCAL_TOOLS object with handler: mockEndpoint (imported from ./local.js). This registration makes the tool available to the MCP agent.
handler: mockEndpoint, }, - lib/local.js:594-601 (helper)The extensionFor() helper maps content types (json, html, xml, yaml) to file extensions for the mock response files. Used by mockEndpoint to determine the file extension when writing the response body.
function extensionFor(contentType) { const ct = contentType.toLowerCase(); if (ct.includes("json")) return "json"; if (ct.includes("html")) return "html"; if (ct.includes("xml")) return "xml"; if (ct.includes("yaml") || ct.includes("yml")) return "yaml"; return "txt"; } - lib/local.js:22-52 (helper)Constants used by mockEndpoint: MOCKS_ROOT (~/.cache/mockzilla-mcp/mocks), MOCKS_STATIC_DIR (mocks/static), ALLOWED_METHODS (set of HTTP methods), MANAGED_DEFAULT_PORT (2200), lastManagedPort (sticky port tracking). These define where mock responses are stored and how the managed server is configured.
const MOCKS_ROOT = path.join(homedir(), ".cache", "mockzilla-mcp", "mocks"); const MOCKS_STATIC_DIR = path.join(MOCKS_ROOT, "static"); const ALLOWED_METHODS = new Set([ "GET", "POST", "PUT", "PATCH", "DELETE", "HEAD", "OPTIONS", ]); // In-flight portable processes keyed by PID. Entries carry a `kind` // tag — "adhoc" (started via serve_locally with user-supplied input) // or "managed" (started by mock_endpoint, points at MOCKS_ROOT). The // two are mutually exclusive: only one server runs at a time, and // each tool refuses if the wrong kind is up. const localServers = new Map(); let starting = false; // Sticky port for the managed (mock_endpoint) server. mockzilla's // default is 2200; we try that first, then keep whatever port we // actually got bound across all subsequent restarts in this bridge // session. Without this, every mock_endpoint call lands on a fresh // kernel-picked port and the user's terminal curls go stale. const MANAGED_DEFAULT_PORT = parseInt( process.env.MOCKZILLA_MANAGED_PORT || "2200", 10, ); let lastManagedPort = null;