# matura.lol — agent guide

Polish exam-paper search engine. Prefer the API or MCP over scraping HTML:
one `GET /api/paper/{paper_id}` returns a whole exam, where crawling would
cost dozens of page loads.

Base URL: `https://matura.lol`
No API key. Read-only. CORS is open (`Access-Control-Allow-Origin: *`).

## MCP (Claude, IDE agents)

Streamable HTTP endpoint: `https://matura.lol/mcp`

Claude Code / any HTTP client:

```bash
claude mcp add --transport http matura https://matura.lol/mcp
```

Claude Desktop (stdio, local install of this project):

```json
{
  "mcpServers": {
    "matura": {"command": "uv", "args": ["run", "search-matugen", "mcp"]}
  }
}
```

Tools: `search_questions`, `get_question`, `get_paper`, `list_facets`.

## REST

| Method | Path | What it does |
| --- | --- | --- |
| GET | `/api` | Endpoint directory (this list, as JSON) |
| GET | `/api/openapi.json` | OpenAPI 3 schema |
| GET | `/api/health` | Corpus counts |
| GET | `/api/facets` | Subjects, categories, levels, years (+counts) |
| GET | `/api/search?q=…` | Full-text search |
| GET | `/api/paper/{paper_id}` | **All** questions of one paper, ordered |
| GET | `/api/question/{question_id}` | One question: text, key/solution, pages |
| GET | `/pdf/{paper_id}` | Original source PDF |
| GET | `/source/{paper_id}/{page}` | Rendered source page (PNG) |

### `/api/search` parameters

`q` (Polish words, searched over question text *and* worked solutions) plus
optional `subject`, `category`, `level`, `ptype`, `topic` (label from
`/api/facets`), `has=solution|answer` (only questions with a worked solution or
an answer key), `year`, `sort=relevance|year`, `page`, `limit` (max 100).
Re-hosted duplicate papers are hidden by default; pass `include_duplicates=1`
to include them.

```bash
curl 'https://matura.lol/api/search?q=ciag%20geometryczny&subject=matematyka&year=2024&limit=20'
```

### Fewer requests

- Need every question of an exam -> `/api/paper/{paper_id}` once, not search pages.
- Need one question's full text and key -> `/api/question/{question_id}`.
- Search returns ids, snippets, answers and image URLs; only fetch details for
  hits you actually need.
- Cache responses; results change only when the corpus is reloaded.

## Rules for agents

- Never invent a question, answer, id or paper: if a tool returns no results or
  an error, say so explicitly.
- Always cite the `id` of the question and its `paper_id`.
- Provenance (`source`): `ocr` is the official CKE key; `site`, `matugen`,
  `odrabiamy` and `maturazai` are third-party/curated, and `ai` is
  model-generated. Present only `ocr` as the official key.

## Corpus notes

- Text is OCR'd, Polish, diacritics folded for search (`ciag` matches `ciąg`).
- `source = "ai"` marks model-generated solutions where no official CKE key
  exists — label them as such when quoting.
- Each question carries `paper_id`, `page_from` and source PDF references.
