Overview
Theconfidential-websearch MCP server runs inside a Tinfoil secure enclave and exposes two tools: search (web search via Exa, a Zero Data Retention provider) and fetch (headless-browser page rendering via Cloudflare Browser Rendering). Both return results back into the enclave before being handed to the caller, so queries and page content are only ever decrypted inside attested code.
Use this guide when you want to drive the web-search tool loop yourself — for example, from a custom agent runtime or any MCP-compatible client. If you just want a model to search the web as part of a chat completion, prefer the higher-level Web search guide which wraps this same server behind web_search_options and the web_search Responses tool.
Optional safety filters run inside the same enclave:
- PII filter blocks outgoing search queries that contain sensitive identifiers before they reach Exa.
- Prompt-injection filter drops search results and fetched pages that contain instructions aimed at hijacking a downstream model.
Endpoint and transport
| Item | Value |
|---|---|
| Production host | websearch.tinfoil.sh |
| MCP endpoint | POST https://websearch.tinfoil.sh/mcp |
| Health check | GET https://websearch.tinfoil.sh/health |
| Transport | MCP Streamable HTTP |
| Source repo | tinfoilsh/confidential-websearch |
tools/list on the endpoint.
Authentication
Send your Tinfoil API key as a bearer token:Tools
search
Run a web search and return ranked results with titles, URLs, snippets, and publication dates.
Arguments
| Name | Type | Required | Default | Description |
|---|---|---|---|---|
query | string | yes | - | Natural language search query. Max ~400 characters. |
max_results | int | no | 8 | Number of results to return. The upstream provider applies its own ceiling. |
content_mode | string | no | highlights | highlights returns key excerpts relevant to the query. text returns the full page text as markdown. |
max_content_chars | int | no | 700 | Per-result character budget for the snippet or text returned in each hit. |
user_location_country | string | no | - | ISO 3166-1 alpha-2 country code (e.g. US, GB, DE) used to bias results toward that locale. |
allowed_domains | string[] | no | - | Only return results whose host matches one of these domains. |
excluded_domains | string[] | no | - | Drop results from these domains. |
category | string | no | - | Restrict to one of: company, people, research paper, news, personal site, financial report. company and people are incompatible with date filters and excluded_domains. |
start_published_date | string | no | - | ISO-8601 date. Only include results published at or after this instant. |
end_published_date | string | no | - | ISO-8601 date. Only include results published at or before this instant. |
max_age_hours | int | no | - | Cache freshness control. 0 forces a livecrawl on every result (freshest, slowest). -1 disables livecrawl (cache-only, fastest). Omit for the upstream default. |
Response
fetch
Fetch one or more web pages via Cloudflare Browser Rendering and return them as clean markdown. Use this after search when you need the full page beyond the returned snippet.
Arguments
| Name | Type | Required | Default | Description |
|---|---|---|---|---|
urls | string[] | yes | - | One or more HTTP/HTTPS URLs. Capped at 20 per request. |
allowed_domains | string[] | no | - | If set, reject any URL whose host is not in this list before it is sent to the renderer. |
Response
results preserves input order and includes both completed and failed fetches. pages is the convenience subset of results whose status is completed.
Per-request safety headers
The server’s safety filters have env-configured defaults, but an integrator can override them on a single request by forwarding either header on thePOST /mcp call. Missing, empty, or unparseable values fall back to the server default, so a malformed header cannot silently weaken filtering.
| Header | Values | Effect |
|---|---|---|
X-Tinfoil-Tool-PII-Check | true, false | Override the PII filter on outgoing search queries for this request only. |
X-Tinfoil-Tool-Injection-Check | true, false | Override the prompt-injection filter on search results and fetched pages for this request only. |
Calling from a Tinfoil SDK
Because the websearch server is an attested enclave, you should verify its attestation before trusting traffic to it. Every Tinfoil SDK exposes aSecureClient that does this for you: it verifies the enclave’s signed release against the tinfoilsh/confidential-websearch GitHub repo, pins the attested transport, and returns a verified HTTP client you can hand to any MCP client transport.
The example below pairs tinfoil-js with the TypeScript MCP SDK to call search. The same pattern works from the Python, Go, and Swift SDKs — point their SecureClient at websearch.tinfoil.sh with configRepo = tinfoilsh/confidential-websearch and plug the verified client into the MCP SDK of your choice.
ready() rejects before any request is sent. See the JavaScript SDK guide for transport-mode options (EHBP vs. TLS pinning) and proxying.
Limits and defaults
| Item | Value |
|---|---|
search.max_results default | 8 |
search.max_content_chars default | 700 |
fetch.urls per-call cap | 20 |
| Cloudflare per-URL timeout | 60s |
| Rendered markdown truncation | 50,000 characters |
See also
- Web search guide — the higher-level wrapper that drives this server for you on
/v1/chat/completionsand/v1/responses. tinfoilsh/confidential-websearch— source and release history for the MCP server itself.- JavaScript SDK — attested
SecureClientused in the example above.

