# Public MCP tools

Ten tools, all read-only, all reading the generated documentation corpus: `search_public_docs`, `fetch_public_doc`, `list_capabilities`, `get_capability`, `get_workflow`, `search_glossary`, `get_technology`, `get_protocol`, `get_product_status` and `get_changelog`. Each result carries both a text block and `structuredContent`, so a model reads prose and a program reads JSON.

- **Status:** Available
- **Audience:** developer
- **Last verified:** 2026-09-10
- **Canonical:** https://connectbyjbrh.com/developers/mcp-public-tools/

## The tools

| Tool | Required | Optional | Returns |
|---|---|---|---|
| `search_public_docs` | `query` | `limit` 1–25 (default 8), `kind`, `status`, `channel` | Ranked page summaries: id, url, title, description, summary, status, audiences, channels, updated, score |
| `fetch_public_doc` | `id_or_url` | `body` (default `true`) | One page, with its Markdown body and its `related` list |
| `list_capabilities` | — | `status`, `channel`, `audience`, `limit` 1–400 (default 200) | Capability pages in path order |
| `get_capability` | `id` | — | One capability page in full |
| `get_workflow` | — | `id` | One workflow page, or every workflow page when no id is given |
| `search_glossary` | — | `query`, `limit` 1–25 (default 8) | Matching glossary entries, or every defined term when no query is given |
| `get_technology` | — | `id` | One technology page, or the list of them |
| `get_protocol` | — | `id` | One protocol page, or the list plus the version of each protocol Connect implements |
| `get_product_status` | — | — | The status manifest: the five status words, every capability with its status, and the corpus counts |
| `get_changelog` | — | — | The published changelog of user-visible changes |

The `kind` filter accepts `capability`, `workflow`, `technology`, `protocol`, `troubleshooting`, `guide`, `glossary`, `comparison`, `research`, `developer` and `hub`. The `status` filter accepts the five status words. The `channel` filter accepts `email`, `phone`, `whatsapp`, `sms` and `softphone`. An empty string means no filter, which is why every enum includes one.

## What a result looks like

```json
{"jsonrpc": "2.0", "id": 7, "result": {
  "content": [{"type": "text", "text": "{ \"query\": \"held draft\", … }"}],
  "structuredContent": {
    "query": "held draft",
    "results": [
      {"id": "C0142", "kind": "capability",
       "url": "https://connectbyjbrh.com/docs/email/held-drafts/",
       "title": "Held drafts", "status": "available",
       "audiences": ["both"], "channels": ["email"],
       "updated": "2026-09-10", "score": 12.418}
    ]}}}
```

Both forms are always sent for a successful call. The text block exists so a model can read the answer without a parsing step; `structuredContent` exists so a program does not have to parse prose back into fields. They are generated from the same object, so they cannot disagree.

A tool that cannot answer returns a normal JSON-RPC *result* with `isError: true` and a sentence saying what to do instead — a missing `query`, or a reference that matches no page. That is a tool-level failure, not a protocol failure, and it is deliberately not a JSON-RPC error object: the model is meant to read it and try again. Protocol failures are on [MCP error shapes](/developers/mcp-errors/).

## Fetching by id or by path

`fetch_public_doc` takes a page id such as `C0142`, a site-relative path such as `/docs/phone/inbound-calls/`, or a full canonical URL. A missing trailing slash, a query string, a fragment and a trailing `index.md` are all normalised away, so the reference you copied out of a search result works whatever form it was in.

Ids are stable and opaque. Do not parse one: the letters and digits are an identifier, not a classification, and a page's kind is a field you can read directly. The body returned is the Markdown twin of the HTML page, generated from the same source, capped at 60,000 characters and carrying no navigation chrome for a model to mistake for content.

## Resources and prompts

Four resources are advertised, each a document already served from the website: `https://connectbyjbrh.com/llms.txt` (a map of the documentation), `/docs-manifest.json` (every public page as JSON), `/docs-data/status.json` (the status of every documented capability) and `/.well-known/agent-card.json` (the A2A card). `resources/read` returns them with their real content types; `resources/templates/list` returns an empty list, because there are no templated resources.

Two prompts are offered. `explain_connect` takes a `question` and asks the model to answer only from the documentation, cite the page URL, and say plainly when the status is `foundation` or `not_yet` rather than describing it as available. `check_capability` takes a `capability` and asks the model to check the claim against `get_product_status` before repeating it.

> **Note** Tool annotations are hints for a client's own interface, and a client is right to treat annotations from any server as untrusted. Here they happen to be exact: every public tool sets `readOnlyHint: true`, `destructiveHint: false`, `idempotentHint: true` and `openWorldHint: false`, because each one genuinely reads generated files and nothing else.

## Questions

### How do I find what Connect cannot do?

Call `list_capabilities` with `status` set to `foundation` or `not_yet`, or call `get_product_status` for the whole manifest. This is the most useful thing on the server: it is the difference between an agent that says Connect records calls and one that says the model exists but the live carrier does not enable it.

### Why does `search_public_docs` return at most 25 results?

Because the index caps a result set at 25 however large a `limit` you ask for. Search is ranked rather than paged — there is no cursor and no next link. Narrow the query, or use `list_capabilities` to walk a kind in order.

### Can a tool call change anything in a workspace?

No. There is no write tool, no workspace scope, and no credential that would grant one. See [Workspace MCP tools](/developers/mcp-workspace-tools/) for what that means in practice.

## Related

- [The Connect MCP server](https://connectbyjbrh.com/developers/mcp-server/)
- [MCP error shapes](https://connectbyjbrh.com/developers/mcp-errors/)
- [Workspace MCP tools](https://connectbyjbrh.com/developers/mcp-workspace-tools/)
- [The public data model](https://connectbyjbrh.com/developers/data-model-public/)
- [MCP tools](https://connectbyjbrh.com/docs/protocols/mcp-tools/)
- [MCP resources](https://connectbyjbrh.com/docs/protocols/mcp-resources/)

## What this page is based on

- `backend/app/mcp_server.py` — PUBLIC_TOOLS, RESOURCES, PROMPTS
- `backend/app/public_docs.py` — search, fetch, listing, data_file
- Connect capability registry (docs-source/facts.py)
