Skip to content

Commit 970eb84

Browse files
committed
README: MCP in the hero + full "set up in Claude" guide; add npm launcher
- Hero: add MCP + npm (npx tilion-mcp) badges. - The Fortress MCP section: rewritten as a proper setup guide — pip and npx runners, Claude Desktop config, Claude Code CLI (claude mcp add), Cursor / Cline / Windsurf, and a grouped tool overview. Reads clearer and higher-signal. - mcp/npm/: a `tilion-mcp` npm package — an npx shim that runs the Python MCP via uvx (falls back to pipx / console-script / python -m). So clients can spawn it with `npx -y tilion-mcp`. Install commands stay unpinned so they pull the latest engine.
1 parent 8acf175 commit 970eb84

4 files changed

Lines changed: 174 additions & 8 deletions

File tree

README.md

Lines changed: 41 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@ Stealth Chromium engine
99

1010
[![Chromium](https://img.shields.io/badge/chromium-151.0.7908.0-4285F4?logo=googlechrome&logoColor=white)](CHROMIUM_VERSION) [![pip](https://img.shields.io/badge/pip-3776AB?logo=pypi&logoColor=white)](https://pypi.org/project/tilion-fortress/) [![npm](https://img.shields.io/badge/npm-CB3837?logo=npm&logoColor=white)](https://www.npmjs.com/package/tilion-fortress) [![Docker pulls](https://img.shields.io/docker/pulls/tilion/fortress?logo=docker&logoColor=white&label=pulls)](https://hub.docker.com/r/tilion/fortress)<br/>
1111
[![CreepJS](https://img.shields.io/badge/CreepJS-0%25%20headless-2ea44f)](docs/GAUNTLET_RESULTS.md) [![Runtime.enable leak](https://img.shields.io/badge/Runtime.enable-no%20leak-2ea44f)](docs/GAUNTLET_RESULTS.md)<br/>
12-
[![Copy for agent](https://img.shields.io/badge/Copy%20for%20agent-24292f?logo=readme&logoColor=white)](https://raw.githubusercontent.com/tiliondev/fortress/main/AGENTS.md) [![llms.txt](https://img.shields.io/badge/llms.txt-24292f?logo=readme&logoColor=white)](https://raw.githubusercontent.com/tiliondev/fortress/main/llms.txt)
12+
[![Copy for agent](https://img.shields.io/badge/Copy%20for%20agent-24292f?logo=readme&logoColor=white)](https://raw.githubusercontent.com/tiliondev/fortress/main/AGENTS.md) [![llms.txt](https://img.shields.io/badge/llms.txt-24292f?logo=readme&logoColor=white)](https://raw.githubusercontent.com/tiliondev/fortress/main/llms.txt)<br/>
13+
[![MCP server](https://img.shields.io/badge/MCP-fortress%20·%2026%20tools-6E56CF?logo=modelcontextprotocol&logoColor=white)](mcp/) [![npm tilion-mcp](https://img.shields.io/npm/v/tilion-mcp?logo=npm&logoColor=white&label=npx%20tilion-mcp&color=CB3837)](https://www.npmjs.com/package/tilion-mcp)
1314

1415
**Fortress is a stealth Chromium engine that stops your scrapers and browser agents from getting blocked, with one line of code change.** Bot detectors flag automation by reading the browser fingerprint; Fortress corrects that fingerprint inside Chromium's C++, so the browser presents as an ordinary Chrome install. Scrapers finish their runs, agents reach the pages they were sent to, and CreepJS, Sannysoft, BrowserScan, and live Cloudflare Turnstile all read it as human. Point your existing Playwright or Puppeteer at Fortress over CDP, and nothing else in your code changes.
1516

@@ -272,26 +273,58 @@ Full guide: https://github.com/tiliondev/fortress/blob/main/AGENTS.md
272273

273274
## The Fortress MCP — stealth browsing as agent tools &nbsp;<sub>Beta</sub>
274275

275-
Beyond raw CDP, Fortress ships a **[Model Context Protocol](https://modelcontextprotocol.io) server** so an AI agent can reach for the stealth browser the moment a fetch gets blocked — no code, just tools. **26 tools**, local and free: `fetch_protected_page`, `extract_page`, `crawl_site`, `recon_site_apis`, `search_web`, `run_browser_task`, `save_profile`, `get_stealth_cdp_endpoint`, and more.
276+
Raw CDP is for code you write. The **Fortress MCP** is for agents that call **tools**: a [Model Context Protocol](https://modelcontextprotocol.io) server that hands Claude, Cursor, or any MCP client a stealth browser, so the moment a fetch is blocked it just calls a tool and gets the page. **26 tools, local and free** `fetch_protected_page`, `extract_page`, `crawl_site`, `recon_site_apis`, `search_web`, `run_browser_task`, `save_profile`, `get_stealth_cdp_endpoint`, and more.
276277

277278
<p align="center"><img src="mcp/demo.gif" alt="Same site, same prompt: a vanilla browser is blocked by PerimeterX while an agent with the Fortress MCP returns clean JSON" width="760"/></p>
278279

279-
<sub><i>Real, dated run against <b>stockx.com</b> (PerimeterX). A stock browser gets <b>HTTP 403 — “Access denied”</b>; an agent with the Fortress MCP returns clean JSON — same site, same prompt.</i></sub>
280+
<sub><i>Real, dated run against <b>stockx.com</b> (PerimeterX). A stock browser gets <b>HTTP 403 — “Access denied”</b>; an agent with the Fortress MCP returns clean JSON — same site, same prompt. Reproduce it from the framework repo.</i></sub>
281+
282+
### Set it up in 30 seconds
283+
284+
Two runners — pick one. `npx` needs Python on PATH; `pip` installs it directly:
280285

281286
```bash
282-
pip install "tilion[mcp]"
283-
tilion-mcp # stdio MCP server
287+
pip install "tilion[mcp]" # command: tilion-mcp
288+
# —or, zero-install—
289+
npx -y tilion-mcp # auto-runs the server via uv (no global install)
284290
```
285291

286-
**Claude Desktop / Cursor / Cline / Windsurf**add to the MCP config:
292+
**Claude Desktop**Settings → Developer → *Edit Config* (`claude_desktop_config.json`):
287293

288294
```json
289295
{ "mcpServers": { "fortress": { "command": "tilion-mcp" } } }
290296
```
297+
<sub>Prefer npx? Use <code>"command": "npx", "args": ["-y", "tilion-mcp"]</code>. Restart Claude, and the <b>fortress</b> tools appear.</sub>
298+
299+
**Claude Code** (CLI) — one line:
300+
301+
```bash
302+
claude mcp add fortress -- tilion-mcp # or: claude mcp add fortress -- npx -y tilion-mcp
303+
```
304+
305+
**Cursor** (`~/.cursor/mcp.json`) · **Cline / Windsurf** (VS Code → MCP servers) — same block:
306+
307+
```json
308+
{ "mcpServers": { "fortress": { "command": "tilion-mcp" } } }
309+
```
310+
311+
Then just ask your agent — *“get the price off this StockX page”* — and it calls `fetch_protected_page` on its own.
312+
313+
### What the agent gets
314+
315+
| | tools |
316+
|---|---|
317+
| **Get blocked pages** | `fetch_protected_page` · `read_page` · `get_page_html` · `search_web` |
318+
| **Structured data** | `extract_page` (schema-aware) · `extract_document` (PDF/DOCX/XLSX) |
319+
| **Whole sites** | `crawl_site` (auto-SPA) · `recon_site_apis` (find the private JSON API) |
320+
| **Drive a page** | `page_elements` · `click_button` · `fill_field` · `press_key` · `wait_for` · `evaluate_js` |
321+
| **Multi-step flows** | `run_browser_task` (login, paginate, infinite-scroll, checkout, …) |
322+
| **Capture / auth** | `screenshot_page` · `save_page` · `download_file` · `save_profile` / `load_profile` |
323+
| **Bring your own** | `get_stealth_cdp_endpoint` → a CDP url for Playwright / Puppeteer / browser-use |
291324

292-
The server is pre-warmed on startup (~100 ms first call), concurrency-safe, and timeout- and SSRF-guarded. A hosted/remote endpoint with residential egress is **coming soon**.
325+
Tools are annotated (reads auto-approve, writes gate), **pre-warmed** on startup (~100 ms first call), concurrency-safe, and timeout- and SSRF-guarded. A hosted endpoint with **residential egress is coming soon**.
293326

294-
→ Full tool table, benchmarks, and the agent skill: **[`mcp/`](mcp/README.md)**
327+
→ Full 26-tool table, benchmarks, and the agent skill: **[`mcp/`](mcp/README.md)**
295328

296329
---
297330

mcp/npm/README.md

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
# tilion-mcp
2+
3+
> A stealth-browser MCP for AI agents. When a fetch gets blocked — Cloudflare, DataDome,
4+
> PerimeterX, a 403, or a CAPTCHA — your agent calls these tools and gets the page, driving a
5+
> real, recompiled Chromium (**Fortress**) locally.
6+
7+
`npx tilion-mcp` runs the server. It launches the Python `tilion` MCP under the hood (via
8+
`uvx`, so nothing is permanently installed).
9+
10+
## Use it in a client
11+
12+
**Claude Desktop / Cursor / Cline / Windsurf** — add to the MCP config:
13+
14+
```json
15+
{ "mcpServers": { "fortress": { "command": "npx", "args": ["-y", "tilion-mcp"] } } }
16+
```
17+
18+
**Claude Code (CLI):**
19+
```bash
20+
claude mcp add fortress -- npx -y tilion-mcp
21+
```
22+
23+
Requires Python available on PATH (the shim prefers [`uv`](https://astral.sh/uv); falls back to
24+
`pipx`, a pre-installed `tilion-mcp`, or `python -m tilion.mcp`). Or install directly:
25+
`pip install "tilion[mcp]"`.
26+
27+
## What you get
28+
29+
26 tools: `fetch_protected_page`, `read_page`, `extract_page`, `crawl_site`,
30+
`recon_site_apis`, `search_web`, `run_browser_task`, `screenshot_page`, `save_page`,
31+
`save_profile` / `load_profile`, `get_stealth_cdp_endpoint`, and more. Pre-warmed,
32+
concurrency-safe, timeout- and SSRF-guarded.
33+
34+
Full docs: **https://github.com/tiliondev/fortress/tree/main/mcp**
35+
36+
BSD-3-Clause · hosted cloud with residential egress coming soon.

mcp/npm/cli.js

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
#!/usr/bin/env node
2+
"use strict";
3+
/**
4+
* tilion-mcp — npx launcher for the Fortress stealth-browser MCP.
5+
*
6+
* The server itself is Python (the `tilion` package). This shim finds the best
7+
* available runner and execs it, forwarding stdio transparently so MCP clients
8+
* (Claude Desktop, Cursor, Cline, Windsurf, …) can spawn it with `npx tilion-mcp`.
9+
*
10+
* Preference order:
11+
* 1. uvx — `uvx --from tilion tilion-mcp` (auto-installs, no persistent state)
12+
* 2. pipx — `pipx run --spec tilion tilion-mcp`
13+
* 3. a pre-installed `tilion-mcp` console script (pip install "tilion[mcp]")
14+
* 4. `python -m tilion.mcp` (requires tilion already installed)
15+
*/
16+
const { spawn, spawnSync } = require("child_process");
17+
18+
function has(cmd) {
19+
const finder = process.platform === "win32" ? "where" : "which";
20+
const r = spawnSync(finder, [cmd], { stdio: ["ignore", "ignore", "ignore"] });
21+
return r.status === 0;
22+
}
23+
24+
let cmd, args;
25+
if (has("uvx")) {
26+
cmd = "uvx"; args = ["--from", "tilion", "tilion-mcp"];
27+
} else if (has("pipx")) {
28+
cmd = "pipx"; args = ["run", "--spec", "tilion", "tilion-mcp"];
29+
} else if (has("tilion-mcp")) {
30+
cmd = "tilion-mcp"; args = [];
31+
} else if (has("python3") || has("python")) {
32+
cmd = has("python3") ? "python3" : "python"; args = ["-m", "tilion.mcp"];
33+
} else {
34+
process.stderr.write(
35+
"tilion-mcp: no Python runner found.\n" +
36+
" Install uv (https://astral.sh/uv) — recommended — or run:\n" +
37+
" pip install \"tilion[mcp]\"\n");
38+
process.exit(1);
39+
}
40+
41+
// forward any extra args, inherit stdio (this is an MCP stdio server)
42+
const child = spawn(cmd, args.concat(process.argv.slice(2)), { stdio: "inherit" });
43+
child.on("error", (e) => {
44+
process.stderr.write("tilion-mcp: failed to start (" + cmd + "): " + e.message + "\n");
45+
process.exit(1);
46+
});
47+
child.on("exit", (code, signal) => {
48+
if (signal) process.kill(process.pid, signal);
49+
else process.exit(code == null ? 1 : code);
50+
});

mcp/npm/package.json

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
{
2+
"name": "tilion-mcp",
3+
"version": "0.1.0",
4+
"description": "Stealth-browser MCP for AI agents — fetch pages behind Cloudflare / DataDome / PerimeterX / 403 / CAPTCHA, extract clean markdown & JSON, crawl sites, reverse-engineer private APIs, and drive a real undetected Chromium (Fortress). Local, no account, no key.",
5+
"bin": {
6+
"tilion-mcp": "cli.js"
7+
},
8+
"files": [
9+
"cli.js",
10+
"README.md"
11+
],
12+
"keywords": [
13+
"mcp",
14+
"model-context-protocol",
15+
"modelcontextprotocol",
16+
"stealth-browser",
17+
"undetected",
18+
"anti-bot",
19+
"bot-detection",
20+
"cloudflare",
21+
"datadome",
22+
"perimeterx",
23+
"captcha",
24+
"web-scraping",
25+
"browser-automation",
26+
"playwright",
27+
"fortress",
28+
"tilion",
29+
"agent",
30+
"claude",
31+
"cursor"
32+
],
33+
"repository": {
34+
"type": "git",
35+
"url": "git+https://github.com/tiliondev/fortress.git",
36+
"directory": "mcp/npm"
37+
},
38+
"homepage": "https://github.com/tiliondev/fortress/tree/main/mcp",
39+
"bugs": {
40+
"url": "https://github.com/tiliondev/fortress/issues"
41+
},
42+
"author": "Tilion",
43+
"license": "BSD-3-Clause",
44+
"engines": {
45+
"node": ">=16"
46+
}
47+
}

0 commit comments

Comments
 (0)