SkillAgentSearch skills...

tls-fetch-mcp

A local MCP server written in Go that sends HTTP requests with browser-like TLS fingerprints using bogdanfinn/tls-client. The server communicates over MCP via `stdio` and uses the official modelcontextprotocol/go-sdk.

Install / Use

claude mcp add JakobAIOdev -- npx -y github:JakobAIOdev/tls-fetch-mcp

If the server publishes to npm under a different name, use that package instead — check the repo README.

About this skill
🔌

MCP Server

Model Context Protocol server

Quality Score

83/100

Supported Platforms

Claude Code
Claude Desktop
<div align="center">

TLS Fetch MCP

Browser-like HTTP requests for AI coding agents — implemented as a secure, local MCP server in Go.

CI Go MCP License

Features · Quick start · Codex setup · Tool reference · Security

</div>

TLS Fetch MCP gives Codex and other MCP clients a controlled HTTP client with browser-like TLS fingerprints. It is designed for web development, API inspection, debugging, and authorized scraping where a regular Go net/http.Client does not accurately resemble a modern browser.

It uses bogdanfinn/tls-client for TLS and HTTP fingerprinting and the official modelcontextprotocol/go-sdk for MCP.

Features

  • Browser TLS fingerprints — Chrome, Firefox, Safari, Brave, Opera, mobile applications, and every profile exposed by the installed tls-client version.
  • Intent-aware tools — read-only GET/HEAD traffic is isolated in tls_get; POST, PUT, PATCH, DELETE, and OPTIONS live in the explicitly mutating tls_request tool.
  • Accurate header behavior — sensible browser headers, matching user-agent versions, and optional explicit header ordering.
  • Managed cookie sessions — warm up regional homepages, preserve cookies across multi-step flows, inspect safe session metadata, and automatically expire idle sessions.
  • Large-response workflow — keep a bounded response out of the agent context, receive a short-lived response_id, then extract only the useful data, search it, or read it in byte ranges.
  • Structured extraction — run named CSS queries against HTML or RFC 9535 JSONPath queries against JSON without making another network request.
  • Proxy support — optional HTTP, HTTPS, SOCKS5, and SOCKS5H proxies.
  • Structured responses — status, HTTP version, final URL, redirect history, safe headers, content length, returned bytes, body encoding, timing, truncation state, selected profile, and session metadata.
  • Secret-safe outputSet-Cookie, authorization, and proxy authentication response headers are redacted. Cookie values are never returned; only cookie names and counts are exposed.
  • Binary-safe output — non-UTF-8 response bodies are returned as Base64.
  • Resource controls — server-side timeout, response-size, session-count, response-handle count, TTL, read-window, and redirect limits.
  • Secure by default — private networks, loopback, link-local ranges, multicast, unspecified addresses, and caller-supplied proxies are blocked unless the operator explicitly enables them.
  • DNS-rebinding protection — addresses are checked before the request and again immediately before the network connection.
  • Single local binary — no browser, Node.js runtime, or background daemon required.

How it works

flowchart LR
    A["Codex / MCP client"] -->|stdio| B["TLS Fetch MCP"]
    B --> C["URL and SSRF policy"]
    C --> D["Browser profile + headers"]
    D --> E["tls-client"]
    E -->|HTTP/1.1 or HTTP/2| F["Target website / API"]
    E <--> G["In-memory cookie session"]
    B <--> H["Bounded response store"]
    H --> I["CSS / JSONPath extraction"]

The MCP client starts the server as a local stdio process. Every requested URL passes through the host allowlist and IP policy. The server then builds a fingerprinted client, performs the request, redacts secret response headers, limits the body, and returns a typed MCP result. Cookie sessions and stored responses exist only in memory and expire automatically.

Quick start

Requirements

  • An MCP client with local stdio server support
  • Go 1.25 or newer when installing with Go or building from source

Homebrew

Homebrew is the recommended installation method on macOS and Linux:

brew install jakobaiodev/tap/tls-fetch-mcp

Find the absolute binary path for your MCP client configuration:

command -v tls-fetch-mcp

Install with Go

go install github.com/JakobAIOdev/tls-fetch-mcp/cmd/tls-fetch-mcp@latest

Build from source

git clone https://github.com/JakobAIOdev/tls-fetch-mcp.git
cd tls-fetch-mcp
make build

The binary is written to bin/tls-fetch-mcp.

You can also run it directly:

go run ./cmd/tls-fetch-mcp

Check a built binary:

./bin/tls-fetch-mcp --version

Update

Homebrew installations:

brew update
brew upgrade tls-fetch-mcp

Go installations:

go install github.com/JakobAIOdev/tls-fetch-mcp/cmd/tls-fetch-mcp@latest

Source installations:

git pull --ff-only
make build

Use with Codex

Codex can load an MCP server globally from ~/.codex/config.toml or only for a trusted repository from <project>/.codex/config.toml.

Project-scoped configuration

Create .codex/config.toml in the project where Codex should use the server:

[mcp_servers.tls_fetch]
command = "/absolute/path/to/tls-fetch-mcp"
enabled = true
required = true
enabled_tools = [
  "tls_get",
  "tls_request",
  "tls_profiles",
  "tls_session_warmup",
  "tls_session_info",
  "tls_session_clear",
  "tls_response_extract",
  "tls_response_read",
  "tls_response_search",
]
startup_timeout_sec = 10
tool_timeout_sec = 120
default_tools_approval_mode = "prompt"

[mcp_servers.tls_fetch.tools.tls_get]
approval_mode = "auto"

[mcp_servers.tls_fetch.tools.tls_profiles]
approval_mode = "auto"

[mcp_servers.tls_fetch.tools.tls_session_info]
approval_mode = "auto"

[mcp_servers.tls_fetch.tools.tls_response_extract]
approval_mode = "auto"

[mcp_servers.tls_fetch.tools.tls_response_read]
approval_mode = "auto"

[mcp_servers.tls_fetch.tools.tls_response_search]
approval_mode = "auto"

For local development targets such as localhost:3000, add:

[mcp_servers.tls_fetch.env]
MCP_TLS_FETCH_ALLOW_PRIVATE = "true"

Restart Codex or open a new task after changing the configuration. Use /mcp to verify that the tools are available. The legacy tls_fetch compatibility tool is intentionally omitted here so Codex naturally selects tls_get or tls_request.

Global CLI configuration

codex mcp add tls-fetch \
  -- /absolute/path/to/tls-fetch-mcp

To permit local development targets globally:

codex mcp add tls-fetch \
  --env MCP_TLS_FETCH_ALLOW_PRIVATE=true \
  -- /absolute/path/to/tls-fetch-mcp

Verify the configuration:

codex mcp list

Tool reference

tls_get

Sends a read-only, fingerprinted GET or HEAD request. This is the default tool for inspecting websites, discovering JSON endpoints, and authorized scraping.

| Input | Type | Default | Description | | --- | --- | --- | --- | | url | string | required | Absolute HTTP or HTTPS URL | | method | string | GET | GET or HEAD | | headers | object | browser defaults | Request header name-value pairs | | header_order | string[] | browser-like order | Explicit lower-case header order | | profile | string | chrome_146 | TLS profile returned by tls_profiles | | follow_redirects | boolean | true | Follow up to ten policy-checked redirects | | timeout_seconds | integer | 30 | Whole-request timeout, capped by server configuration | | max_response_bytes | integer | 524288 | Returned or stored body limit, capped by server configuration | | proxy_url | string | empty | Optional proxy; requires operator opt-in | | session_id | string | empty | Optional cookie-session identifier | | include_body | boolean | true | Include the bounded body directly in the result | | store_response | boolean | false | Return a temporary response_id for extract/search/read tools |

Example prompt:

Use tls_get with the chrome_146 profile to inspect https://example.com.
Return the status, final URL, content type, and HTML title.

For a large response:

Fetch the catalog with tls_get using store_response=true and include_body=false.
Use tls_response_extract on the returned response_id to get each item's title,
price.amount, and URL. Return at most 20 values per query. Only fall back to
tls_response_search or tls_response_read when the structure is unknown.

tls_request

Sends POST, PUT, PATCH, DELETE, or OPTIONS requests. It accepts the same options as tls_get, plus body. GET and HEAD are deliberately rejected so MCP clients can apply separate approval rules to read and write traffic.

Use tls_request to POST {"query":"mcp"} to
https://example.com/api/search. Set Content-Type to application/json.

tls_fetch

Compatibility alias for existing clients. It still accepts every supported method, but new integrations should prefer tls_get and tls_request.

tls_profiles

Returns the default profile and every fingerprint supported by the pinned tls-client version. Profile availability follows the dependency version rather than a hardcoded MCP schema enum.

tls_session_warmup

Fetches a bootstrap URL without returning its body and retains cookies in the provided session_id. This is useful when an API first returns 401, but the same request succeeds after visiting the regional homepage.

1. Warm up https://www.example.de/ as session "catalog-de".
2. Call tls_get for the catalog endpoint with session_id "catalog-de".
3. Inspect tls_session_info if authentication still fails.
4. Clear the session when the flow is finished.

tls_session_info

Returns existence, created/last-used/expiry timestamps, cookie count, and cookie names. Cookie values are never exposed.

tls_session_clear

Deletes one in-memory cookie session. Session IDs may contain letters, digits, dots, underscores, and hyphens and must not exceed 128 characters.

tls_response_extract

Extracts compact, structured values from a response created with store_response=true. It never performs a network request. format defaults to auto and uses the stored content type plus body detection.

For HTML, each named query accepts a CSS selector and one of four modes:

  • text (default) returns normalized descendant text.
  • inner_html returns the selected node's contents.
  • outer_html returns the complete selected node.
  • attribute returns one named attribute. Set resolve_urls=true to resolve URL attributes such as href or src against the response's final URL.
{
  "response_id": "resp_...",
  "format": "html",
  "queries": [
    {"name": "titles", "selector": "article h2"},
    {
      "name": "links",
      "selector": "article a",
      "mode": "attribute",
      "attribute": "href",
      "resolve_urls": true
    }
  ]
}

For JSON, selectors are RFC 9535 JSONPath expressions. Values are returned as compact JSON together with their normalized result path, so strings remain distinguishable from numbers, booleans, arrays, and objects.

{
  "response_id": "resp_...",
  "format": "json",
  "queries": [
    {"name": "titles", "selector": "$.items[*].title"},
    {"name": "affordable", "selector": "$.items[?@.price.amount < 20]"}
  ],
  "max_results": 20,
  "max_output_bytes": 65536
}

Each call accepts at most 16 named queries. max_results defaults to 20 per query and is capped at 100. Serialized output defaults to 64 KiB and is capped by MCP_TLS_FETCH_MAX_RESPONSE_READ_BYTES. Res

Truncated for display — read the full file on GitHub.

Related Skills

View on GitHub
GitHub Stars3
CategoryDevelopment
Updated16h ago
Forks0

Languages

Go

Security Score

92/100

Audited on Sep 13, 2026

1 low