# flq MCP server

Run flq as a [Model Context Protocol](https://modelcontextprotocol.io) server
so AI agents like Claude Code can fetch and parse web pages directly, spending
80–90% fewer tokens than raw HTML.

## Setup

### 1. Build

```sh
cargo build --release
```

### 2. Register with Claude Code

```sh
claude mcp add flq -- /path/to/flq --mcp
```

Windows:

```sh
claude mcp add flq -- C:\path\to\flq.exe --mcp
```

### 3. Verify

```sh
claude mcp list
```

`flq` appearing in the list means it is wired up.

## Tools

### `fetch_page`

Fetch a web page and return it as lean, token-efficient text.

| Parameter    | Type   | Required | Description                                   |
| ------------ | ------ | -------- | --------------------------------------------- |
| `url`        | string | ✓        | URL to fetch                                  |
| `filter`     | string |          | Block filter (comma-separated)                |
| `select`     | string |          | Scope extraction with a CSS selector          |
| `max_tokens` | number |          | Token budget; the overflow is truncated       |
| `grep`       | string |          | Return only lines matching the pattern         |

`filter` values: `headings`, `code`, `tables`, `links`, `img`, `text`.

### `fetch_pages`

Fetch multiple URLs in one call. Results are separated by `===`.

| Parameter    | Type     | Required | Description                |
| ------------ | -------- | -------- | -------------------------- |
| `urls`       | string[] | ✓        | List of URLs               |
| `filter`     | string   |          | Block filter               |
| `max_tokens` | number   |          | Token budget per page      |

### `crawl_site`

Crawl same-host links starting from a seed URL.

| Parameter   | Type   | Required | Description                    |
| ----------- | ------ | -------- | ------------------------------ |
| `url`       | string | ✓        | Seed URL                       |
| `depth`     | number |          | Crawl depth (default: 1)       |
| `max_pages` | number |          | Max pages to fetch (default: 10) |
| `filter`    | string |          | Block filter                   |

### `head`

Return the HTTP response headers, like `curl -I`.

| Parameter | Type   | Required | Description |
| --------- | ------ | -------- | ----------- |
| `url`     | string | ✓        | URL         |

## Output format

```
title: Page Title
url: https://example.com
lang: en
desc: meta description
---
# heading
body text
- list item
> quote
@ https://link | link text
! https://img.png | alt text
table[3]{name,price}:
A,100
B,200
C,300
```

When a `filter` is set, the frontmatter is omitted and only the matching
blocks are returned.

## Usage examples

Typical exchanges inside Claude Code:

```
> Read and summarize https://docs.rs/tokio/latest/tokio/

→ the agent calls fetch_page, receives the flq format,
  and grasps the content while cutting token usage by 80–90%.
```

```
> Explore the whole tokio docs site

→ the agent calls crawl_site(url, depth=1, max_pages=10)
  and fetches multiple pages at once.
```

```
> Extract only the code samples from this page

→ the agent calls fetch_page(url, filter="code")
  and gets back just the code blocks.
```

## Notes

- flq does not use a headless browser. JavaScript-rendered content (SPAs)
  cannot be fetched.
- `crawl_site` only follows links on the same host as the seed URL.
- stdout is reserved for JSON-RPC; flq's own logs go to stderr.

## Troubleshooting

Tools not showing up in Claude Code:

```sh
# Check the registration
claude mcp list

# Smoke-test manually (a JSON-RPC initialize reply means it works)
echo '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-06-18","capabilities":{},"clientInfo":{"name":"test","version":"0"}}}' | flq --mcp
```

Tools work but pages come back empty:

- Possibly an SPA. Check the HTML source with `flq URL --raw | head` (CLI mode).
- Possibly blocked by User-Agent. Try a custom UA with `-A` (CLI mode).
