A crawler for AI agents.
Scout, read, crawl.

Your agent can already search. Marrow is for the next step — get the page itself, clean. Scout a site cheaply, deep-read only what matters, cache as standard.

$ npx -y marrow-setup --email you@example.com
Marrow

Monitoring is withdrawn. Scheduled checks, webhooks, changeTracking and sections are frozen while the extraction design is reworked — those calls answer 410 monitoring-withdrawn. They are frozen rather than deleted, but there is no date for their return and no substitute endpoint. Everything else on this page works today.

Your agent already searches. So why Marrow?

🔐

It reaches past the login

Search stops at the wall. Marrow doesn't have to. You sign in — 2FA, CAPTCHA, SSO — and the agent works past it, in your own browser.

📦

Clean data, not snippets

Marrow returns clean markdown — humans can read it, and so can your AI.

🪙

Token-efficient & cheap

Scout → read: marrow_scout maps a page's links and structure, then marrow_read deep-reads it — fewer tokens burned. Cache is standard, so the second read is fast and cheap.

Marrow + your agent — a crawler for AI.

An agent rarely finds what it needs in one search. It loops — scout a page, read it, rephrase, read again — and the answer comes together across those turns, not in any single shot.

Marrow makes that loop cheap: re-reads are near-free from cache. So your agent can keep going until it has what it needs. Crawlers that bill per request do the opposite: every extra turn costs more. Marrow is designed for an agent to run the loop as many times as it needs.

Usage

1 · Scout, then read

Say "search with Marrow" and marrow_scout + marrow_read pull clean markdown.

2 · Crawl a slice

Bound it by depth and page count, and get the pages back as clean markdown — not a site dump.

3 · Behind a click

When the rows only appear after "show details", depth:"deep" renders and expands the page first.

Stop hauling the dirt. Get the marrow.

Most crawlers bulldoze through the whole rendered page — navs, ads, footers, related-product carousels and all. Marrow goes for the marrow: it scores the rendered page and keeps the part that carries the content, dropping the chrome around it. You get the nutritious core, not the bone. That's the whole point of the name.

PageTokens vs Firecrawl — same URL
Clean article (Wikipedia)On par — little chrome to strip
News article (BBC)~30% fewer
Heavy e-commerce (Shopify product)~75% fewer
The product feed behind that pageup to 26× smaller

The more clutter, the bigger the win. Measured head-to-head between Firecrawl and Marrow on the same URLs. And that's per pagescout → read saves even more tokens by skipping pages you don't need.

What you scrape stays yours.

The URLs you read are your strategy — competitor prices, hiring pages, policy changes. That's not for a crawler to know. Marrow is built so there's nothing to leak.

🔑

No account, no password

Your API key is your identity — like gh auth or stripe login. Nothing to sign up for, nothing to phish. Throw the key away and you're gone.

💳

Billing: Stripe

Card details go straight to Stripe — Marrow never sees them, and never stores your name or address. All we hold is an email handle and a credit balance.

🙈

No activity log

The extraction worker is stateless and the cache is content-addressed — it records that a page exists, not who asked for it. There's no dashboard of every URL you've ever pulled.

Most crawlers keep exactly that dashboard. What you read is a trade secret — Marrow doesn't hold it.

Install in your agent

One command — it gets you a free key and wires Marrow into every agent you use.

$ npx -y marrow-setup --email you@example.com

Or configure it manually

claude mcp add marrow \
  -e MARROW_API_KEY=mrw_xxx \
  -- npx -y @marrowdev/cloud-mcp
{
  "mcpServers": {
    "marrow": {
      "command": "npx",
      "args": ["-y", "@marrowdev/cloud-mcp"],
      "env": { "MARROW_API_KEY": "mrw_xxx" }
    }
  }
}
# ~/.codex/config.toml
[mcp_servers.marrow]
command = "npx"
args = ["-y", "@marrowdev/cloud-mcp"]
env = { MARROW_API_KEY = "mrw_xxx" }

Tools: marrow_scout · marrow_read · marrow_search · marrow_crawl · marrow_screenshot · marrow_usage

Or from your shell

Prefer your terminal? Use Marrow straight from shells, scripts and CI.

$ npm i -g @marrowdev/cli

marrow scout <url> · marrow read <url> · marrow search "…" · marrow crawl · marrow screenshot
Flux NDJSON out, --md for markdown. CLI docs →

Or call the API

Plain HTTP with a Bearer key. The REST API is Firecrawl-compatible.

import requests

BASE = "https://api.marrow.navii.online"
H = {"Authorization": "Bearer mrw_xxx", "Content-Type": "application/json"}

# Scout first — links and structure, cheap
s = requests.post(f"{BASE}/v1/scout", headers=H, json={
    "url": "https://example.com/pricing",
})
print(len(s.json()["data"]["links"]))

# Then read only what matters
r = requests.post(f"{BASE}/v1/scrape", headers=H, json={
    "url": "https://example.com/pricing",
    "formats": ["markdown"],
})
print(r.json()["data"]["data"]["body"][:500])
const BASE = "https://api.marrow.navii.online";
const H = { Authorization: "Bearer mrw_xxx", "Content-Type": "application/json" };

// Scout, then read
const scout = await fetch(`${BASE}/v1/scout`, {
  method: "POST", headers: H,
  body: JSON.stringify({ url: "https://example.com/pricing" }),
});
console.log((await scout.json()).data.links.length);

const res = await fetch(`${BASE}/v1/scrape`, {
  method: "POST", headers: H,
  body: JSON.stringify({
    url: "https://example.com/pricing",
    formats: ["markdown"],
  }),
});
const { data } = await res.json();
console.log(data.data.body.slice(0, 500));
# Scout, then read
curl -X POST https://api.marrow.navii.online/v1/scout \
  -H "Authorization: Bearer mrw_xxx" -H "Content-Type: application/json" \
  -d '{"url":"https://example.com/pricing"}'

curl -X POST https://api.marrow.navii.online/v1/scrape \
  -H "Authorization: Bearer mrw_xxx" -H "Content-Type: application/json" \
  -d '{"url":"https://example.com/pricing","formats":["markdown"]}'

Coming from Firecrawl?

The REST API is drop-in compatible — point your client at Marrow, keep your code.

- base_url = "https://api.firecrawl.dev"
+ base_url = "https://api.marrow.navii.online"

Still works untouched: /v1/scrape · /v1/crawl · /v1/search and formats: ["markdown"]. One line of your code changes. ⚠️ changeTracking is the exception — it answers 410 while that lane is frozen.

What you gain the moment you switch — re-reads at 0.1 credit, failed requests billed at zero, and no account — the key is the identity, and queries aren't logged.

Free key, no card — start testing with npx marrow-setup in seconds.

Pricing

Plan Monthly credits Daily rate
Free · $0500100 / dayStart free
Developer · $9.995,0002,000 / daySubscribe
Pro · $29.9950,00020,000 / dayComing soon

scrape/search 1 · scout 0.5 · crawl 2/page · screenshot 2 · Cache-hit 0.1 credits. Failed requests are free. Pro is coming soon.