Endpoint Reachability Check
check_endpointProbe a public URL or API endpoint to verify it responds and inspect its HTTP status, content type, elapsed time, and response sample. Use this before recommending, documenting, or building on an endpoint.
Instructions
Perform one live, unauthenticated fetch against a public URL or API endpoint before you recommend it, document it, or build on top of it. Use this when the question is simply whether an endpoint currently responds and what kind of response it returns. It reports HTTP status, content type, elapsed time, likely auth/rate-limit signals, and a short response sample. Do not use it to validate authenticated flows, POST side effects, or deeper business logic.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| url | Yes | Public http(s) URL or bare domain to probe. Bare domains like google.com are accepted and normalized to https:// automatically. |
Output Schema
| Name | Required | Description | Default |
|---|---|---|---|
| inputUrl | No | Original user input when normalization changed it, for example when https:// was added. | |
| url | Yes | Normalized URL that was actually fetched. | |
| accessible | Yes | True when the endpoint returned a 2xx HTTP status. | |
| status | No | HTTP status code returned by the endpoint, when a response was received. | |
| contentType | No | Response Content-Type header, if present. | |
| responseTimeMs | No | Elapsed request time in milliseconds. | |
| authRequired | No | True when the server responded with 401 or 403, which usually means credentials are required. | |
| rateLimited | No | True when the server responded with 429 Too Many Requests. | |
| sampleResponse | No | First 1,000 characters of the response body for quick inspection. | |
| error | No | Validation or network error when the request could not be completed. |
Implementation Reference
- src/index.ts:574-670 (registration)Registration of the check_endpoint tool via McpServer.registerTool, including metadata about the free tier tool.
this.server.registerTool( "check_endpoint", { title: "Endpoint Reachability Check", description: "Perform one live, unauthenticated fetch against a public URL or API endpoint " + "before you recommend it, document it, or build on top of it. Use this when " + "the question is simply whether an endpoint currently responds and what kind " + "of response it returns. It reports HTTP status, content type, elapsed time, " + "likely auth/rate-limit signals, and a short response sample. A successful " + "result only proves basic reachability at fetch time. Do not use it to " + "validate authenticated flows, POST side effects, JavaScript execution, " + "or deeper business logic.", inputSchema: { url: z.string().trim().min(1).describe( "Public http(s) URL or bare domain to probe. Bare domains like google.com are accepted and normalized to https:// automatically.", ), }, outputSchema: { inputUrl: z.string().describe( "Original user input when normalization changed it, for example when https:// was added.", ).optional(), url: z.string().describe( "Normalized URL that was actually fetched.", ), accessible: z.boolean().describe( "True when the endpoint returned a 2xx HTTP status.", ), status: z.number().int().describe( "HTTP status code returned by the endpoint, when a response was received.", ).optional(), contentType: z.string().nullable().describe( "Response Content-Type header, if present.", ).optional(), responseTimeMs: z.number().int().nonnegative().describe( "Elapsed request time in milliseconds.", ).optional(), authRequired: z.boolean().describe( "True when the server responded with 401 or 403, which usually means credentials are required.", ).optional(), rateLimited: z.boolean().describe( "True when the server responded with 429 Too Many Requests.", ).optional(), sampleResponse: z.string().describe( "First 1,000 characters of the response body for quick inspection.", ).optional(), error: z.string().describe( "Validation or network error when the request could not be completed.", ).optional(), }, annotations: readOnlyNetworkToolAnnotations, }, async ({ url }) => { const normalizedUrl = normalizeHttpUrlInput(url); if (!normalizedUrl) { logUsage("check_endpoint", false); return structuredToolResult({ url, accessible: false, error: "Invalid URL. Use a public http(s) URL or a bare domain like google.com.", }); } const start = Date.now(); try { const resp = await fetch(normalizedUrl, { headers: { "User-Agent": "GroundTruth/0.3" }, }); const elapsed = Date.now() - start; const body = await resp.text(); const sample = body.slice(0, 1000); logUsage("check_endpoint", true); return structuredToolResult({ ...(normalizedUrl !== url ? { inputUrl: url } : {}), url: normalizedUrl, accessible: resp.ok, status: resp.status, contentType: resp.headers.get("content-type"), responseTimeMs: elapsed, authRequired: resp.status === 401 || resp.status === 403, rateLimited: resp.status === 429, sampleResponse: sample, }); } catch (e: unknown) { const message = e instanceof Error ? e.message : String(e); logUsage("check_endpoint", false); return structuredToolResult({ ...(normalizedUrl !== url ? { inputUrl: url } : {}), url: normalizedUrl, accessible: false, error: message, responseTimeMs: Date.now() - start, }); } } ); - src/index.ts:587-593 (schema)Input/output schema for check_endpoint using Zod validators. Input requires a URL string; output includes reachability, status, timing, auth/rate-limit signals, and a response sample.
inputSchema: { url: z.string().trim().min(1).describe( "Public http(s) URL or bare domain to probe. Bare domains like google.com are accepted and normalized to https:// automatically.", ), }, outputSchema: { inputUrl: z.string().describe( - src/index.ts:626-669 (handler)Handler function that executes the check_endpoint logic: normalizes URL, performs an HTTP GET, returns status/content-type/response time/auth/rate-limit signals and a sample of the response body.
async ({ url }) => { const normalizedUrl = normalizeHttpUrlInput(url); if (!normalizedUrl) { logUsage("check_endpoint", false); return structuredToolResult({ url, accessible: false, error: "Invalid URL. Use a public http(s) URL or a bare domain like google.com.", }); } const start = Date.now(); try { const resp = await fetch(normalizedUrl, { headers: { "User-Agent": "GroundTruth/0.3" }, }); const elapsed = Date.now() - start; const body = await resp.text(); const sample = body.slice(0, 1000); logUsage("check_endpoint", true); return structuredToolResult({ ...(normalizedUrl !== url ? { inputUrl: url } : {}), url: normalizedUrl, accessible: resp.ok, status: resp.status, contentType: resp.headers.get("content-type"), responseTimeMs: elapsed, authRequired: resp.status === 401 || resp.status === 403, rateLimited: resp.status === 429, sampleResponse: sample, }); } catch (e: unknown) { const message = e instanceof Error ? e.message : String(e); logUsage("check_endpoint", false); return structuredToolResult({ ...(normalizedUrl !== url ? { inputUrl: url } : {}), url: normalizedUrl, accessible: false, error: message, responseTimeMs: Date.now() - start, }); } } - src/index.ts:159-179 (helper)Helper used by the check_endpoint handler to normalize user input into a valid http(s) URL, including auto-prepending https:// for bare domains.
function normalizeHttpUrlInput(input: string): string | null { const trimmed = input.trim(); if (!trimmed) return null; const candidate = /^[a-zA-Z][a-zA-Z\d+.-]*:/.test(trimmed) ? trimmed : `https://${trimmed}`; try { const parsed = new URL(candidate); if (parsed.protocol !== "http:" && parsed.protocol !== "https:") { return null; } if (!parsed.hostname) { return null; } return parsed.toString(); } catch { return null; } } - src/index.ts:95-103 (helper)Helper function that wraps structured data into an MCP tool result with JSON text content, used by the check_endpoint handler to return its output.
function structuredToolResult<T extends Record<string, unknown>>(structuredContent: T) { return { content: [{ type: "text" as const, text: JSON.stringify(structuredContent, null, 2), }], structuredContent, }; }