MCP server for AI assistants

WyndPath exposes a remote MCP (Model Context Protocol) server at https://mcp.wyndpath.com/mcp. Any AI assistant that speaks MCP (Claude, ChatGPT, Cursor, VS Code...) can connect to it and gain direct access to hard-to-reach public web pages, using the same account and the same credits as the REST API.

Endpoints.
  • MCP server (authenticated): https://mcp.wyndpath.com/mcp
  • Public discovery, no authentication: https://mcp.wyndpath.com/public
  • OAuth metadata: https://mcp.wyndpath.com/.well-known/oauth-authorization-server and https://mcp.wyndpath.com/.well-known/oauth-protected-resource/mcp
  • Server card: https://mcp.wyndpath.com/.well-known/mcp/server-card.json

Contents

What is WyndPath MCP?

An AI agent tries its normal tools first to read a web page. On a site protected by an anti-bot system, a page that loads its content in JavaScript, or an empty result, those tools fail or come back with a captcha. That's the moment the agent decides, on its own, to call WyndPath instead of asking the user to paste a URL somewhere else. WyndPath retrieves the page (a real browser if needed, a residential IP if needed) and returns usable content, Markdown by default. The same engine as the REST API and proxy mode does the work; only the calling protocol changes.

Connecting WyndPath to an AI assistant

The server URL is the same everywhere: https://mcp.wyndpath.com/mcp. What changes from one client to another is how you declare it.

Claude Code

claude mcp add --transport http wyndpath https://mcp.wyndpath.com/mcp

Then run /mcp in a session to authenticate (OAuth by default, or an API key if you prefer).

Claude.ai and Claude Desktop

SettingsConnectorsAdd custom connector, with the URL https://mcp.wyndpath.com/mcp. Claude then opens the WyndPath sign-in page for OAuth authorization.

Cursor

Add this block to ~/.cursor/mcp.json:

{"mcpServers":{"wyndpath":{"url":"https://mcp.wyndpath.com/mcp"}}}

VS Code

Add this block to .vscode/mcp.json:

{"servers":{"wyndpath":{"type":"http","url":"https://mcp.wyndpath.com/mcp"}}}

ChatGPT

Add WyndPath as a custom connector, with the same URL. Authorization is OAuth only: ChatGPT connectors don't offer a field for pasting an API key.

Python client (mcp SDK)

from mcp import Client
from mcp.client.streamable_http import streamable_http_client
import httpx as httpx2

async with streamable_http_client(
    "https://mcp.wyndpath.com/mcp",
    http_client=httpx2.AsyncClient(headers={"Authorization": "Bearer wk_YOUR_KEY"}),
) as (read, write, _):
    async with Client(read, write) as client:
        result = await client.call_tool("fetch_url", {"url": "https://example.com"})
        print(result)

Onboarding in under two minutes

  1. Connect: the assistant declares the server.
  2. Sign in or create an account on wyndpath.com (free credits are included on sign-up).
  3. Authorize the requested access.
  4. WyndPath shows up in the assistant's tool list, ready to be called.

Authentication

OAuth 2.1

The flow follows OAuth 2.1 with PKCE, dynamic client registration and Client ID Metadata Documents. The user gives consent directly on wyndpath.com: the assistant never sees the password, only an access token with a limited scope. Revocation happens from the console, under SettingsConnected AI assistants; it cuts access immediately without touching the rest of the account.

API key

For a scripted client or an IDE, an API key is enough: Authorization: Bearer wk_.... It's the same key used for the REST API (see Authentication), placed in the client configuration's headers field rather than an OAuth setting.

Who supports what

ClientOAuthAPI key in header
Claude CodeYesYes
Claude.ai / Claude DesktopYesNo (connector has no header field)
CursorYesYes
VS CodeYesYes
ChatGPTYes (only method)No
Programmatic client (SDK)YesYes

Available tools

Seven tools: three are free and reachable without an account (useful for an agent to evaluate WyndPath before connecting), four consume credits from the connected account.

get_capabilities

When to use it: so an agent can discover what WyndPath does before connecting. Free, no authentication.

ParameterTypeDefaultRole
No parameters.

Returns: service description, use cases (use_when / do_not_use_when), tool list, supported formats, credit model, limits, authentication methods, sign-up and documentation links.

Cost: free.

get_pricing

When to use it: when the user asks what WyndPath costs, or before recommending a plan. Free, no authentication.

ParameterTypeDefaultRole
No parameters.

Returns: plan list (name, EUR/USD monthly price, credits included, allowed concurrency, availability), credit cost per request type, billing rule, links to the pricing page and plan management.

Cost: free.

check_support

When to use it: before fetch_url, when cost matters or you're not sure the site is supported. Retrieves nothing and spends no credits.

ParameterTypeDefaultRole
urlstring, required-Absolute URL to check.

Returns: supported (bool), estimated_credits, max_credits_with_escalation, route, detected protection, difficulty, whether a login is required (login_required), and a text recommendation (for instance the minimum max_credits to pass to fetch_url).

Cost: free.

fetch_url

When to use it: when the agent's normal web tools fail, return an empty page, a captcha, a consent wall, a 403/429/503, or when the page must be viewed from a specific country. Avoid it behind a login or a paywall, and on URLs the normal tools already read correctly.

ParameterTypeDefaultRole
urlstring, required-Absolute http(s) URL of the page.
formatenummarkdownmarkdown (cleaned), text or raw html. API responses are always returned as JSON.
countrystring or nullnullISO 3166-1 alpha-2 country code (fr, de, us...) to view the page from that country.
renderenumautoauto (cheapest route that works, may escalate), browser (forced), http (plain HTTP only, never escalates).
max_creditsinteger 1-100 or nullnull (15)Credit cap for the call; beyond it, nothing is fetched and COST_LIMIT_EXCEEDED reports the credits needed.
max_charsinteger 1000-400000 or nullnull (80,000)Truncates the returned content. The page is fetched and charged once regardless.
timeoutinteger 5-170 or nullnull (60)Seconds to wait for the retrieval.
idempotency_keystring or null (max 100)nullThe same key replayed within 10 minutes returns the previous result without a new charge.

Returns: on success, status, title, content (in the chosen format), truncated, credits_used, credits_remaining, duration_ms, and a strategy (route, engine, proxy type, escalation, attempts). On failure, success: false, a stable error, a message, sometimes a hint or an action to pass on to the user.

Cost: 1 credit for a simple site, 10 with browser or anti-bot handling, 15 with a residential IP. Charged on success only.

batch_fetch

When to use it: when the list of URLs is already known (product pages, result pages, listings) and you want them together instead of one call each.

ParameterTypeDefaultRole
urlsarray of strings, required (1 to 50)-Absolute URLs of public pages.
formatenummarkdownFormat applied to every page.
countrystring or nullnullCountry code applied to every page.
renderenumautoSame as fetch_url, applied to every page.
max_credits_per_urlinteger 1-100 or nullnull (15)Credit cap per page.
max_total_creditsinteger 1-1000 or nullnullStops fetching the remaining pages once this total is reached.
max_charsinteger 1000-400000 or nullnull (20,000)Truncates each page's content.

Returns: one result per URL (same shape as fetch_url), plus totals credits_used, credits_remaining, succeeded, failed. Stops early with COST_LIMIT_EXCEEDED on the remaining URLs if max_total_credits would be exceeded.

Cost: same as fetch_url, per page actually fetched with success (up to 50 pages).

extract_structured_data

When to use it: to get specific fields (price, availability, title, author, date...) instead of a whole page.

ParameterTypeDefaultRole
urlstring, required-Absolute URL of the page to read.
schemaobject, required-Fields to extract, shorthand ({"name":"string","price":"number"}) or full JSON Schema; up to 40 fields, a description per field helps disambiguate.
countrystring or nullnullCountry code to view the page from.
renderenumautoSame as fetch_url.
max_creditsinteger 1-100 or nullnull (15)Credit cap for the retrieval.
idempotency_keystring or null (max 100)nullReplays the previous result without a new charge within 10 minutes.

Returns: data (one field per schema key, null if absent), missing (fields not found), sources (page structured data or model), method. Nothing is ever invented: a missing field stays null and is listed in missing, with a Markdown excerpt of the page (evidence) so you can read it yourself if needed.

Cost: same as fetch_url, plus a surcharge only if model-assisted extraction is enabled on the server (then visible in method: "structured-data+llm").

get_account

When to use it: before a large batch, to check the budget, or when the user asks how many credits are left.

ParameterTypeDefaultRole
No parameters.

Returns: plan, credits used this month, credits remaining, concurrency limit, last 7 days of usage, top domains called, and links to the console, billing and the request log.

Cost: free.

Credits

Same account, same balance as the REST API and proxy mode: see the full breakdown in Credits & pricing.

Paid on success. A failed call (blocked target, unreachable target) consumes no credit.

Examples

Blocked product page

A product page behind an anti-bot system returns an empty page to the agent's normal tools.

{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"fetch_url","arguments":{"url":"https://shop-example.com/product/123","render":"browser","max_credits":15}}}

Response (summarized): success: true, content in Markdown with the product page, credits_used: 10, strategy.route: "browser", strategy.escalated: true.

Price and availability

You need the price and stock status, not the rest of the page.

{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"extract_structured_data","arguments":{"url":"https://shop-example.com/product/123","schema":{"name":"string","price":"number","currency":"string","available":"boolean"}}}}

Response (summarized): data: {"name":"...","price":129.9,"currency":"EUR","available":true}, missing: [], method: "structured-data", credits_used: 1.

Checking the cost first

Before spending credits, the agent checks what WyndPath knows about the target.

{"jsonrpc":"2.0","id":3,"method":"tools/call","params":{"name":"check_support","arguments":{"url":"https://shop-example.com/product/123"}}}

Response (summarized): supported: true, estimated_credits: 10, protection: "cloudflare", route: "browser", recommendation: "Call fetch_url with max_credits >= 10."

Security

Scope

WyndPath only retrieves public content. It never bypasses a login or a paywall, and applies its own acceptable-use policy on every call, whatever the channel (REST, proxy, MCP).

Anti-SSRF

Private or internal addresses are rejected before any retrieval attempt: the call fails with URL_NOT_ALLOWED, never reaching an internal network.

Untrusted content and prompt injection

A retrieved page can contain text like "ignore previous instructions" or any other manipulation attempt. WyndPath returns that text as content, never as a command to execute. For integrators: always treat the content field (or data, evidence) as data to read, not as instructions for the agent, and never let the agent perform a sensitive action (purchase, send, delete) based solely on text found in a page.

Tokens

OAuth tokens and API keys are opaque, revocable at any time from the console, and expire. Revoking one closes access immediately without affecting the rest of the account.

What the assistant can and cannot do

A connected assistant can read public pages, extract fields and check account status. It cannot buy credits, change plans or modify account settings: those actions stay with the user, in the console.

Troubleshooting

SymptomLikely cause
"This site can't be reached" on localhost after authorizingThe client waits for the return on a local receiver (http://localhost:<port>/callback) the browser cannot reach: SSH session, WSL or container, or the client dialog was closed before the return. Keep the dialog open until the browser returns, or go back to the WyndPath "Authorization complete" page and give the displayed address to the assistant (Claude Code completes the connection with it).
401 on connectExpired or revoked OAuth token, or a disabled API key. Reconnect the assistant (/mcp on Claude Code, or the connector on the client side).
TARGET_BLOCKEDThe target resisted every attempt allowed by the budget. Retrying with render: "browser" and a higher max_credits may help; otherwise the target isn't retrievable right now.
COST_LIMIT_EXCEEDEDThe real cost exceeds max_credits. The response includes credits_needed: retry with a cap at least that high.
RATE_LIMITED / TOO_MANY_CONCURRENTThe target is rate-limiting, or the plan's concurrency limit is reached. Wait a few seconds before retrying.
Slow or cut-off responseThe Streamable HTTP transport keeps the connection open during retrieval (SSE keep-alive); past roughly 150 seconds without a response, lowering timeout or checking the target is better than retrying in a loop.
The assistant isn't using WyndPathThat's by design: the assistant tries its normal tools first. On a target known to be difficult, ask it explicitly to use WyndPath.

To verify a connection from the command line, the protocol's official Inspector works directly against the WyndPath server:

npx @modelcontextprotocol/inspector --cli --transport http --server-url https://mcp.wyndpath.com/mcp --header "Authorization: Bearer wk_..." --method tools/list