Model Context Protocol servers that give LLMs access to external data via tools and resources. Route MCP server web fetch requests through KnoxProxy to access geo-restricted content and avoid IP blocks when serving data to AI models.
Create a new TypeScript project and install the MCP SDK.
npm init -y
npm install @modelcontextprotocol/sdk undiciInstall undici for HTTP proxy support with the fetch API.
npm install undiciWrite an MCP server with tools that fetch web content through KnoxProxy.
Set KnoxProxy credentials via environment variables for the server process.
export KNOX_PROXY_USER="USER"
export KNOX_PROXY_PASS="PASS"Create MCP tools that accept a country parameter and route through the appropriate proxy endpoint.
Register the MCP server with Claude Desktop or your MCP client and test the proxied tools.
{
"mcpServers": {
"web-fetcher": {
"command": "npx",
"args": ["tsx", "server.ts"]
}
}
}import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import { z } from "zod";
import { ProxyAgent, fetch as undiciFetch } from "undici";
const PROXY_HOST = "gw.knoxproxy.com";
const PROXY_PORT = 7000;
const PROXY_USER = process.env.KNOX_PROXY_USER ?? "USER";
const PROXY_PASS = process.env.KNOX_PROXY_PASS ?? "PASS";
function buildProxyUrl(country?: string, sessionId?: string): string {
let username = PROXY_USER;
if (country) username += `-country-${country}`;
if (sessionId) username += `-session-${sessionId}`;
return `http://${username}:${PROXY_PASS}@${PROXY_HOST}:${PROXY_PORT}`;
}
async function proxiedFetch(
url: string,
country?: string,
sessionId?: string,
): Promise<string> {
const proxyUrl = buildProxyUrl(country, sessionId);
const dispatcher = new ProxyAgent(proxyUrl);
const response = await undiciFetch(url, { dispatcher });
if (!response.ok) {
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
}
return await response.text();
}
const server = new McpServer({
name: "web-fetcher",
version: "1.0.0",
});
server.tool(
"fetch_page",
"Fetch a web page through KnoxProxy with optional geo-targeting",
{
url: z.string().url().describe("URL to fetch"),
country: z.string().length(2).optional()
.describe("ISO country code for geo-targeting (e.g., us, de, jp)"),
},
async ({ url, country }) => {
const html = await proxiedFetch(url, country);
// Strip HTML tags for cleaner LLM consumption
const text = html.replace(/<[^>]*>/g, " ").replace(/\s+/g, " ").trim();
return {
content: [{ type: "text", text: text.slice(0, 50000) }],
};
},
);
server.tool(
"check_ip",
"Check the current proxy IP address and location",
{
country: z.string().length(2).optional()
.describe("ISO country code to verify geo-targeting"),
},
async ({ country }) => {
const result = await proxiedFetch("https://httpbin.org/ip", country);
return {
content: [{ type: "text", text: result }],
};
},
);
const transport = new StdioServerTransport();
await server.connect(transport);Each tool call gets a fresh proxy IP by default. For sticky sessions across multiple tool calls in one conversation, pass a sessionId parameter and use USER-session-{sessionId} in the proxy username.
| Problem | Fix |
|---|---|
| UND_ERR_CONNECT_TIMEOUT: proxy connection timeout | Verify outbound connectivity: curl -x http://USER:PASS@gw.knoxproxy.com:7000 https://httpbin.org/ip |
| FetchError: 407 Proxy Authentication Required | Check env vars are set in the MCP server process. For Claude Desktop, add env vars to the mcpServers config. |
| TypeError: fetch is not a function | Import fetch from undici: import { fetch as undiciFetch } from "undici". The native fetch does not support ProxyAgent. |
USER-country-de-city-berlin-session-profile07Order matters -- geo flags before the session flag. The session name is free text; use the profile ID so the mapping is self-documenting. Password stays as issued; no flags belong there. HTTP on :7000, SOCKS5 on :7001, same credentials.
Add the server to claude_desktop_config.json with env vars: {"command": "npx", "args": ["tsx", "server.ts"], "env": {"KNOX_PROXY_USER": "...", "KNOX_PROXY_PASS": "..."}}
Yes. Set HTTP_PROXY and HTTPS_PROXY as global environment variables for the server process. All outbound HTTP traffic will route through KnoxProxy.
Yes. The proxy configuration is for outbound requests from the server, which is independent of the MCP transport layer (stdio, SSE, or streamable HTTP).
Yes. Use undici SocksProxyAgent or the socks-proxy-agent package with gw.knoxproxy.com:7001.
Free trial on rotating residential -- 10 minutes setup, no credit card.