# MCP resources

A resource is a document a client can read by URI; a prompt is a reusable instruction template a person can invoke by name. Neither is a function call. Connect publishes four resources — its llms.txt, documentation manifest, capability status and A2A agent card — and two prompts.

- **Status:** Reference
- **Audience:** developer
- **Last verified:** 2026-09-10
- **Canonical:** https://connectbyjbrh.com/docs/protocols/mcp-resources/

## Three primitives, three different controllers

MCP separates what a server offers by who decides to use it, and that is the distinction that makes the three primitives worth keeping apart.

| Primitive | Who invokes it | Shape |
|---|---|---|
| Tool | The model, mid-reasoning | A function with arguments and a result |
| Resource | The client, usually on a person's instruction | A document at a URI, with a MIME type |
| Prompt | A person, explicitly | A named template that expands into messages |

The consequence is practical. A tool is the right shape when the answer depends on arguments the model works out — a search query, a page id. A resource is the right shape when the thing is a whole document that does not change per caller, because it can be fetched once, cached, and shown to a person before it reaches the model. A prompt is the right shape when the useful thing is not data at all but a way of asking.

## When a resource beats a tool

- **The whole document is the answer.** A manifest of every page has no sensible arguments. Wrapping it in `get_manifest()` adds a call and removes the client's ability to cache it by URI.
- **A person should see it first.** Client interfaces show resources as attachable context. That review step disappears if the same bytes arrive as a tool result the model requested on its own.
- **It is already public at a URL.** A resource URI can be the public URL, so there is one address for the document rather than two representations that can drift.
- **You want it cached.** Resources are addressed, so a client can hold one and re-read it without another round trip.

The inverse also holds. If the caller must supply a query, a filter or an identifier, a resource forces you to invent a URI template for what is obviously a function call — and Connect's search is exactly that case, which is why it is a tool.

## Does Connect use MCP resources and prompts?

Yes, both, and they are deliberately small. `resources/list` returns four entries and `resources/read` serves each one; `resources/templates/list` returns an empty list, because no resource here takes parameters.

| Name | URI | What it carries |
|---|---|---|
| llms.txt | `/llms.txt` | A short map of the documentation and every machine interface |
| docs-manifest | `/docs-manifest.json` | Every public page: id, URL, title, summary, status |
| capability-status | `/docs-data/status.json` | The status of every documented capability |
| agent-card | `/.well-known/agent-card.json` | Connect's public A2A card |

Two prompts are published. `explain_connect` takes a question and expands into an instruction to answer it from the public documentation, cite the page URL used, and say plainly when a capability is `foundation` or `not_yet` rather than describing it as available. `check_capability` takes a claim and expands into an instruction to check it against `get_product_status` before repeating it.

Both prompts exist for one reason: the most common way an assistant gets Connect wrong is by describing a foundation capability as a usable feature. A prompt that puts the status check in front of the answer costs nothing and removes the most likely error.

> **Note** `subscribe` is `false` and `listChanged` is `false` on all three primitives. Nothing here changes between requests without a release, so a client that polls for change notifications gets none, correctly.

## Reading one, and what can go wrong

1. Call `resources/list`.
   - Result: Four descriptors, each with a `uri`, `name`, `title`, `description` and `mimeType`.
2. Call `resources/read` with one of those exact URIs.
   - Result: A `contents` array with the text and its MIME type.
3. Call `resources/read` with a URI that is not on the list.
   - Result: JSON-RPC `-32601` naming the unknown resource. There is no wildcard and no path traversal: the list is the whole surface.

One quiet failure is worth knowing about. If the generated files are missing from a deployment — a checkout that has not run the machine artefact generator — a resource read returns an empty string rather than an error, because an empty document is a more honest answer than a fabricated one. On the live site the files are present; if you see empty content, you are pointed at something that is not production.

## Questions

### Should I fetch llms.txt as a resource or just request the URL?

Either. It is the same file, and the resource URI is the public URL. Reading it through MCP is convenient when your client already holds the connection and shows resources for a person to attach; a plain HTTP GET is fine otherwise.

### Why are there only two prompts?

Because a prompt is worth publishing only when it encodes something a caller would otherwise get wrong. Two behaviours qualify here: answer from the documentation and cite it, and check a claimed capability against the status manifest first. A longer list would be padding.

### Can a resource change without me being told?

It changes when Connect publishes a release, and `listChanged` is false so there is no notification. Each document carries its own generated date; if freshness matters, read that rather than assuming a cached copy is current.

## Related

- [Model Context Protocol](https://connectbyjbrh.com/docs/protocols/mcp/)
- [MCP tools](https://connectbyjbrh.com/docs/protocols/mcp-tools/)
- [llms.txt](https://connectbyjbrh.com/docs/protocols/llms-txt/)
- [The machine-readable documentation](https://connectbyjbrh.com/developers/machine-manifests/)
- [The product status manifest](https://connectbyjbrh.com/developers/status-manifest/)

## What this page is based on

- https://modelcontextprotocol.io/specification/2026-07-28
- `backend/app/mcp_server.py` — RESOURCES, PROMPTS and the read handlers
- `docs-source/facts.py` — CAPABILITY_STATUS['docs_manifests']
