---
title: "iammatthias.com developer documentation — API, GraphQL, MCP"
description: "HTTP endpoints, GraphQL, the MCP server, markdown twins, error shapes, and caching for iammatthias.com. Public, free, no key required."
canonical: https://iammatthias.com/developers.md
last-updated: 2026-08-21
---
# Developer notes

iammatthias.com publishes its content in machine-readable form. Everything here is public, unauthenticated, and free — see https://iammatthias.com/auth.md and https://iammatthias.com/pricing.md.

## Quickstart

```bash
# Search the site
curl "https://iammatthias.com/api/search.json?q=cloudflare+workers"

# List everything in one section
curl "https://iammatthias.com/api/content.json?section=recipes"

# Read one document as markdown
curl "https://iammatthias.com/posts/1779066375000-farfield.md"

# The whole corpus in a single request
curl "https://iammatthias.com/llms-full.txt"
```

## HTTP endpoints

### `GET /api/search-corpus.json`

Every searchable item on the site (documents and feed posts) as compact text, each carrying its Farfield content hash (cid). Intended for building your own index; the site's own search embeds this locally in the browser.

No parameters.

### `GET /api/search-vectors.json`

Precomputed embedding vectors for the corpus, keyed by cid, with the model name and dimension count. Built at deploy time with the ternlight model.

No parameters.

### `GET /api/content.json`

Every published document as structured JSON: title, section, tags, dates, content hash, canonical URL, and markdown URL. Filterable by section and tag.

- `section` — Restrict to one publication slug (art, posts, recipes, melange, open-source).
- `tag` — Restrict to documents carrying this tag.
- `limit` — Maximum number of items to return (default 100).

### `GET /api/search.json`

Ranked keyword search over titles, excerpts, tags, and body text of every published document and feed post. Returns canonical and markdown URLs per hit.

- `q` (required) — Search terms.
- `limit` — Maximum number of hits (default 10, max 50).

Full OpenAPI 3.1 specification: https://iammatthias.com/openapi.json

## MCP server

Streamable HTTP at `https://iammatthias.com/mcp`. No authentication. Tools:

- `search_site` — Search Matthias Jordan's writing, photography notes, and recipes by keyword. Returns titles, excerpts, and both HTML and markdown URLs.
- `get_document` — Fetch the full markdown source of one document by its path or slug, with front matter (title, dates, tags, content hash) and images resolved to public URLs.
- `list_sections` — List the site's publications (art, posts, recipes, melange, open-source) with descriptions and entry counts.
- `list_recent` — List the most recently published documents, newest first, optionally filtered to one section.

Add it to a client that speaks MCP:

```json
{ "mcpServers": { "iammatthias": { "url": "https://iammatthias.com/mcp" } } }
```

Preview it without connecting: https://iammatthias.com/.well-known/mcp/server-card.json

## Markdown twins

Every content URL has a markdown twin at the same path plus `.md`, carrying front matter (title, section, dates, tags, `cid`, canonical `html:` URL) with `blob://` and `series://` embeds resolved to public image URLs.

Section indexes: `/art.md`, `/melange.md`, `/open-source.md`, `/posts.md`, `/recipes.md`. Scoped context per section: `/<section>/llms.txt`.

## Errors

Errors are RFC 9457 problem documents with `code`, `detail`, and a `resolution` telling you how to retry:

```json
{
  "type": "https://iammatthias.com/developers#missing_query",
  "status": 400,
  "code": "missing_query",
  "detail": "The 'q' parameter is required and must not be empty.",
  "resolution": "Retry with a query, e.g. /api/search.json?q=cloudflare+workers."
}
```

## Test environment

There is no separate sandbox, because there is nothing to sandbox: every
endpoint is read-only. No request you can make will create, modify, or
delete anything, so production is safe to exercise directly — hammer it,
retry it, run it in CI. There is no key to obtain and no quota to burn.

If you want a fixed dataset to test against rather than live content,
https://iammatthias.com/llms-full.txt is a single immutable-per-build snapshot of
the whole corpus.

## Caching

Every record carries a `cid` — a CIDv1 content hash. Same `cid`, same bytes, forever. Cache against it and skip refetching unchanged documents.

## Source

The site is open source: https://github.com/iammatthias/com
