ax-mcp
This server provides a single MCP tool, scrape_web, which uses the fast, non-browser scraper yusukebe/ax to fetch and parse web content. It is exposed as a stateless Streamable HTTP service, suitable for stable remote connections and behind proxies.
Fetch full page as Markdown: Retrieve a URL and obtain a clean, readable Markdown representation (default when no CSS selector is specified and format is
"text").Extract specific elements: Use an optional CSS selector to precisely target and extract text from particular HTML elements.
Get a structured JSON report: Set
formatto"json"to receive a report containing status, response headers, timing, and body content.Set request timeout: Use the
waitparameter (seconds) to limit how long the scraper waits for a response.Error handling: Failed scrapes return an error with stderr for debugging.
Clean output: ANSI color codes are automatically removed for LLM-friendly text.
Limitations: The scraper does not execute JavaScript, so it is not suitable for JS-heavy single-page applications. For dynamic pages, a browser-based tool is recommended.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@ax-mcpScrape https://example.com and return as markdown"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Ax MCP — 遠端網頁爬蟲 MCP Server
💡 去 AI 味聲明:本專案文檔使用台灣在地化繁體中文去 AI 味工具 opencode-speak-human-tw 進行校對與語感微調,拒絕罐頭套話與空泛修辭。
基於 Node.js 的 MCP Server,封裝 yusukebe/ax(「AI 時代的 curl」),
透過 supergateway 橋接為 遠端 Streamable HTTP(/mcp) 介面,供 OpenCode Interpreter 呼叫(SSE 亦可)。
⚠️ 關於 ax 的重要說明:規格書假設 ax 是「Playwright 爬蟲」並有
--selector/--format/--wait參數。 實際上 ax 不是 Playwright 工具——它是用 Bun + linkedom 做的非瀏覽器快速爬蟲,不執行 JavaScript。 它的真實參數是--md(markdown)、--json、--row、--outline、positional selector、-m <secs>(逾時)等。 本專案已把規格的scrape_web介面對應到 ax 真實 CLI(見下方參數對照),因此可正常運作。 若你需要抓取 JS 重度渲染的 SPA,請改用瀏覽器型工具(Playwright / playwright-cli MCP),ax 不適用。
專案結構
├── src/
│ └── index.ts # MCP Server 核心邏輯
├── build/ # tsc 編譯產物(node build/index.js)
├── package.json # 依賴(@modelcontextprotocol/sdk, supergateway, zod)
├── tsconfig.json
├── Dockerfile # ax-mcp: node + bun + supergateway
├── docker-compose.yml # 單個 service: ax-mcp(3014)
└── README.mdRelated MCP server: Shark-no-Kari
工具:scrape_web
參數 | 類型 | 預設 | 說明 | 對應 ax |
| string (必填) | — | 目標網址 | positional |
| string (選填) | — | CSS selector 精確擷取 | positional + |
|
|
| 輸出格式 |
|
| number (選填) | — | 秒數預算 | 對應 ax |
有
selector:擷取該 selector 匹配元素的文字(--text)。無
selector+format:"text":整頁可讀 markdown(--md)。無
selector+format:"json":結構化抓取報告({status, ok, ms, headers, body})。輸出會經正則濾除 ANSI color codes,確保 LLM 收到純淨文字。
執行失敗回傳
{ isError: true, content: [...] }(含 stderr)。
傳輸協定與架構說明(SSE vs Streamable HTTP)
SSE (http://localhost:8000/sse) 與 Streamable HTTP (/mcp) 的底層差異
標準的 MCP 伺服器大多使用 SSE (Server-Sent Events) 傳輸。不過,當你在跨主機、遠端或 Homelab 叢集部署(例如讓 OpenCode Interpreter 跨網連線遠端 MCP)時,這兩種協定在底層運作上有決定性的差別:
http://localhost:8000/sse(標準 SSE 協定)缺點:標準 SSE 是有狀態(Stateful)的協定。當 OpenCode 這類用戶端連線時,必須維持一條長連線。一旦跨越外網或經過反向代理(如 Caddy、Nginx),這條長連線很容易因為逾時、網路抖動或代理伺服器的快取限制而斷線,造成 MCP 連線不穩定。
適用場景:完全在本地端(Localhost)跑 stdio 的開發環境,或用戶端與伺服器位於同一個安全且無代理阻擋的區域網路。
http://<host>:3014/mcp(Streamable HTTP 協定)優點:透過 supergateway,將 MCP 伺服器轉換為無狀態(Stateless)的標準 HTTP POST 請求。
特色:
穿透力強:每次工具呼叫都是獨立的短 HTTP 連線,能輕鬆穿透 CDN、反向代理、WAF 與 VPN,不會被防火牆或代理伺服器阻擋。
維護簡單:不需維持 TCP 長連線,自然沒有逾時斷連、需要重連的問題。這正是 OpenCode
type: "remote"的原生運作方式。專案定位:本專案直接將 supergateway 整合進 Docker,並預設輸出為
streamableHttp,提供跨主機、跨網段穩定的遠端連線配置範例。
Docker 部署
本專案支援兩種 Docker 部署方式:直接從 GitHub Registry 拉取預建映像檔(最快、免下載原始碼),或 Clone 專案本機編譯建置(適合客製化與二次開發)。
方式一:直接使用 GitHub Registry 部署(免 Clone)
若您僅需使用服務,無需下載專案原始碼,只需在主機的部署目錄(例如 $HOME/ax-mcp)建立一個 docker-compose.yml 檔案:
services:
ax-mcp:
image: ghcr.io/cawa0505/ax-mcp:latest
container_name: ax-mcp
restart: unless-stopped
ports:
- "3014:8000"並於該目錄執行以下指令拉取並啟動:
docker compose up -d方式二:Clone 專案本機編譯部署(適合二次開發)
如果您想自訂或擴充功能,可以進行二次開發:
調整爬蟲邏輯:希望自訂
ax的抓取細節或前處理規則。擴充 MCP 工具:在
src/index.ts內增加自訂的 MCP Tool。效能調優:修改
Dockerfile內的快取與編譯設定。
請複製本專案,並依以下步驟建置:
# 複製專案
git clone https://github.com/cawa0505/ax-mcp.git
cd ax-mcp
# 啟動並於本機編譯建置
docker compose up -d --build本機測試與偵錯步驟
如果不使用 Docker,想在本機直接編譯、修改與測試,請執行以下指令:
# 1. 安裝套件
npm install
# 2. 本地編譯(tsc -> build/index.js)
npm run build
# 3. 測試執行 stdio 協定(可供標準 MCP client 連線)
node build/index.js本地透過 supergateway 進行橋接與協定轉換測試:
# 預設啟動為 SSE(端點:http://localhost:8000/sse)
npx supergateway --stdio "node build/index.js" --port 8000
# 啟動為 Streamable HTTP(端點:http://localhost:8000/mcp,對應 OpenCode "type: remote")
npx supergateway --stdio "node build/index.js" --port 8000 --outputTransport streamableHttp服務說明
啟動後:
ax-mcp將於http://<host>:3014/mcp提供 Streamable HTTP 介面(容器內監聽 8000)。內部透過
supergateway將node build/index.js(stdio)包裝為遠端 MCP 介面。建置時已將
bunx快取預熱完畢(原生處理yusukebe/ax的 git 依賴),因此運行期無需額外聯網下載ax。
💡 關於瀏覽器型爬蟲 (Playwright):
由於 Playwright MCP 是微軟官方維護的成熟標準工具 (
@modelcontextprotocol/server-playwright/mcp/playwright),本專案定位是基於yusukebe/ax的輕量、超高速非瀏覽器 HTML/XML 擷取。若你仍需要動態網頁渲染 (SPA) 與瀏覽器自動化,建議直接使用 Microsoft 官方 Playwright MCP。你可透過
supergateway以--stateful模式橋接官方 stdio 程序以實現遠端 Streamable HTTP:npx supergateway --stdio "npx -y @modelcontextprotocol/server-playwright" --port 3015 --stateful
環境變數
變數 | 預設 | 說明 |
|
| 覆寫 ax 呼叫方式。允許 git fetch 的環境可用 |
OpenCode 連線
請在 OpenCode 設定檔 ~/.config/opencode/opencode.json 的 "mcp" 區段中加入本服務。本服務以 Streamable HTTP 暴露(路徑 /mcp),對應 OpenCode 的 type: "remote":
{
"mcp": {
"ax-mcp": {
"type": "remote",
"url": "http://<ax-mcp-host>:3014/mcp"
}
}
}本機部署將容器 8000 對應到 host 的 3014(8000 已被佔用)。若你改了
docker-compose.yml的 ports 對應,請同步修改此處的 port。
若 OpenCode 與容器不在同網段 / 需跨網,請在 docker-compose.yml 用 --cors 限制來源,
並視情況以反向代理(Caddy/Pangolin)加上 TLS 與驗證。
Available Tools
1 toolscrape_webScrape WebA
Fetch and parse a web page using yusukebe/ax. Returns clean text (markdown by default) or a JSON report. ax is a fast non-browser scraper (linkedom) and does NOT execute JavaScript; for JS-heavy SPAs use a browser tool.
| Name | Required | Description | Default |
|---|---|---|---|
| url | Yes | Target URL to scrape. | |
| wait | No | Seconds budget, mapped to ax -m (request timeout). ax has no browser wait. | |
| format | No | Output format: text (markdown/content) or json (structured report). | text |
| selector | No | Optional CSS selector for precise extraction. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden. It transparently discloses the key behavior: it does NOT execute JavaScript, uses linkedom, and returns markdown or JSON. It also explains the wait parameter maps to ax -m timeout. However, it omits details like redirect handling, cookies, or error behavior, which are secondary for a basic scraper.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is three sentences long, front-loaded with the core purpose, and each sentence earns its place. It includes essential details about return formats, the underlying library, and the limitation, with no redundant phrasing or filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's moderate complexity, no output schema, and no annotations, the description is complete. It covers the main functionality, the key limitation (no JS), the alternative for JS-heavy pages, and the return formats. All parameters are documented in both schema and description, and the description compensates for the lack of an output schema by explicitly stating what the tool returns.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Although schema coverage is 100%, the description adds significant meaning beyond the schema. It clarifies 'wait' as a seconds budget mapped to ax -m (request timeout) and notes ax has no browser wait, which is crucial for understanding the parameter. It also explains the 'format' enum values as text (markdown/content) or json (structured report), providing context the schema alone does not.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb+resource: 'Fetch and parse a web page using yusukebe/ax.' It clearly distinguishes itself from browser tools by noting it does not execute JavaScript and is a fast non-browser scraper, which differentiates it from potential alternatives.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives explicit guidance: 'for JS-heavy SPAs use a browser tool' clearly states when NOT to use this tool and suggests an alternative. The limitation about no JavaScript execution implies the appropriate use case is static or server-rendered pages.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
1 tool update
v1.0.0- First observed
scrape_web
TDQS
Scored across 1 tool
Only one tool exists, so there is no possibility of confusion between tools. The single tool's purpose is clearly described as scraping web pages.
The tool name 'scrape_web' follows a clear verb_noun pattern. Since there is only one tool, the naming is inherently consistent.
While one tool is on the low end of the typical range, it is appropriate for a narrowly focused server dedicated to a single scraping action. The tool is well-scoped and does not feel overly thin for its stated purpose.
The tool covers the core scraping workflow: fetching and parsing a page into clean text or JSON. The only notable gap is the lack of JavaScript execution, which is explicitly documented and hints at using a browser tool for SPAs, but that seems like a reasonable limitation rather than an incomplete surface.
Maintenance
Related MCP Connectors
Scrape, crawl and search the web for AI agents via MCP.
MCP server (stdio): fetch web pages as clean readable markdown via the AgentForge API
Docs: https://docs.keenable.ai/mcp-server Keenable is a free, remote MCP server that gives agents access to the web index. Search the web with ranked results and date/site filters, then fetch any indexed page as clean markdown. Works out of the box with no account or API key.
All HasData scraping tools in one MCP server: Google, TikTok, Instagram, maps, e-commerce and more.
Related MCP Servers
- AlicenseBqualityDmaintenanceA local web scraping MCP server with RAG capabilities that provides intelligent web search, content extraction, and screenshot tools without requiring API keys.47 npmMIT
- AlicenseNot gradedqualityAmaintenanceRemote MCP server for web scraping with anti-bot evasion. Provides stealth HTTP fetching, headless browser with Cloudflare bypass, CSS selectors, YouTube transcripts, and Markdown conversion.1MIT
- AlicenseAqualityBmaintenanceMCP server providing tools for web scraping, browser automation, computer vision, audio transcription, and RAG via API.91MIT
- AlicenseNot gradedqualityBmaintenanceA comprehensive web scraping MCP server with 26 tools for fetching, parsing, extracting, and assisting with web content, returning Markdown-formatted results.MIT