# A public API and an MCP server for a site with no login

> 23 Jul 2026 · Telemeter · 4 min read

telemeter.ai has no accounts, no dashboard, and no database of users — and a full REST API, an MCP server, and clean markdown for every page. Here's why building for agents came first.

telemeter.ai is, at the moment, a marketing site and a set of free tools. There
is no login, no account, and no user database. It is also fronted by a keyless
REST API, a read-only [Model Context Protocol](/docs) server, a clean-markdown
version of every page, and an `llms.txt`. That combination sounds backwards —
why build an agent-facing surface for a site that doesn't yet have a product? —
and this post is the argument that it isn't.

## The reader has changed

For most of the web's life, the thing reading a page was a person with a browser,
or a search crawler building an index for a person with a browser. That is no
longer the only reader that matters. Increasingly, the thing that visits a page
about "how much does GPT-4o cost" is an agent — a coding assistant, a research
tool, something acting on a person's behalf — and it is going to answer the
question whether or not the page was built for it to read cleanly.

If it has to scrape rendered HTML, it will, and it will do it badly: parsing
around navigation, guessing which number on the page is the price, occasionally
getting it wrong. The alternative is to hand it the same answer the human gets,
in a shape it can actually consume. That is the entire thesis behind the
agent-facing surface.

## One handler, three doors

The design rule that makes this affordable is that a tool is not its web page.
A tool is a **shared handler** — a pure function from validated input to a
result — and the web page is one of three doors onto it:

- the **web page**, for a human;
- a **REST endpoint** (`POST /api/tools/<slug>`), for a script;
- an **MCP tool**, for an agent that speaks the protocol.

All three call the same handler, so all three give the same answer, computed the
same way, from the same [sourced registry](/blog/prices-in-git-not-a-database).
There is no second, drifting implementation of the cost calculator for the API —
there is one calculator, wearing three interfaces. When the logic is fixed, it is
fixed everywhere at once.

## Meeting agents where they already are

Beyond the tools, the site publishes the passive surface an agent expects to
find:

- **Markdown twins.** Every tool and doc page has a `.md` version at a
  predictable URL — the same content, without the HTML chrome, so an agent that
  wants the text gets the text.
- **`llms.txt`.** A single map, at the root, pointing to the important pages,
  the API, and the MCP server — the convention agents look for to orient
  themselves.
- **Structured data.** Machine-readable JSON-LD on the pages, and an OpenAPI
  description of the REST surface, so a tool that prefers a schema to prose has
  one.

The honesty rule extends here too, and it matters more, not less, when the reader
is a machine. The MCP server carries the same verified/pending/stale distinction
the web tools do, and it is instructed to preserve it — a pending price stays
pending in a tool response, so an agent can't accidentally launder an uncertain
number into a confident one on its way to a user.

## Why first, and not later

The reason to build this before the paid product, rather than after, is that the
free tools are how the agent-facing surface gets *used and tested* under real
demand. Every tool that ships is another endpoint an agent can call, another page
it can read cleanly, another chance to find out whether the three doors really do
stay in sync. By the time there is a product with accounts behind it, the
discipline of "everything a human can do here, an agent can do too" is already
load-bearing, instead of a retrofit.

A site with no login was the cheapest possible place to get that discipline
right.

[Read on telemeter.ai](https://telemeter.ai/blog/public-api-and-mcp-for-a-site-with-no-login) · [Every tool and doc, machine-readable](https://telemeter.ai/llms.txt)
