# flq
Fetch the web as lean, token-efficient text. `HTML` → `.flq`
Raw HTML wastes 70-90% of LLM tokens on markup. flq strips a page down to
its content — headings, text, lists, tables, code — in a format that
tokenizes tight and reads clean.
## Install
```sh
cargo install flq
```
## Usage
```sh
flq https://example.com # fetch one page
flq https://example.com/1 https://example.com/2 # multiple (=== separated)
```
### curl-compatible flags
```sh
flq URL -o page.flq # output to file
flq URL -H "Authorization: Bearer x" # custom header
flq URL -A "my-agent/1.0" # user-agent
flq URL -m 10 # timeout (seconds; k/m suffix ok, e.g. 1k)
flq URL -b "session=abc" # cookies
flq URL -I # response headers only
flq URL -s # silent
```
### Extraction
```sh
flq URL -f headings # headings only
flq URL -f code # code blocks only
flq URL -f tables,links # combine filters
flq URL -g "install" # grep body lines
flq URL --select "article.post" # scope by CSS selector
flq URL --raw # raw HTML passthrough
```
Filters: `headings` `code` `tables` `links` `img` `text`
### Agent workflow
```sh
flq URL --max-tokens 2k # token budget (k/m suffix), truncates cleanly
flq URL --no-meta # body only, no frontmatter
flq URL -j # JSON: {title,url,body,tokens,truncated}
flq URL --cache # cache locally (~/.cache/flq)
flq URL --cache --cache-ttl 86400 # custom TTL
flq URL --diff # diff against cached version
```
## Format
```
title: Page Title
url: https://example.com
lang: ja
desc: meta description
---
# heading
paragraph text
- list item
- nested item
> quote
@ https://link | link text
! https://img.png | alt text
table[3]{name,price,stock}:
Widget A,1200,45
Widget B,800,120
Gadget C,500,300
```
Prose stays markdown — LLMs parse it natively and every marker is one
token. Tables use schema-once TOON-style headers: field names are
declared once, rows stream as CSV. Links (`@`) and images (`!`) are
off by default; enable with `-f links` / `-f img`.
## JSON output
```sh
flq https://example.com -j
```
```json
{
"title": "Page Title",
"url": "https://example.com",
"body": "# heading\nparagraph...",
"tokens": 142,
"truncated": false
}
```
`tokens` is an estimate (~4 ASCII chars or ~1.3 CJK chars per token).
## As a library
```rust
use flq::{Opts, process};
let opts = Opts {
max_tokens: Some(2000),
no_meta: true,
..Default::default()
};
let page = process("https://example.com", &opts)?;
println!("{} ({} tokens)", page.body, page.tokens);
```
## MCP server
flq doubles as a [Model Context Protocol](https://modelcontextprotocol.io)
server, so agents like Claude Code can fetch and parse the web directly.
```sh
flq --mcp # run as MCP server (stdio JSON-RPC)
claude mcp add flq -- flq --mcp # register with Claude Code
```
Tools: `fetch_page`, `fetch_pages`, `crawl_site`, `head`. See
[docs/mcp.md](docs/mcp.md) for the full tool reference and setup, and
[skills/flq/SKILL.md](skills/flq/SKILL.md) for an agent skill that teaches when
and how to reach for flq.
## License
MIT