> ## Documentation Index
> Fetch the complete documentation index at: https://docs.formation.texturehq.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Tool discovery

> Manage an optional MCP server directory while keeping setup available offline.

The **Add tool** directory uses bundled MCP server metadata and an optional local
catalog. Instance owners can enable online updates in **Settings → Tool
discovery** and supply a registry URL. Online discovery is off by default and
has no default URL. Custom MCP setup remains available independently of the
directory.

Directory entries suggest a server endpoint and authentication methods. They
never connect an account, copy credentials, change an existing endpoint, or
enable tools. Connecting remains an explicit action for the selected agent's
own account under the [identity guardrail](https://github.com/TextureHQ/formation/blob/main/docs/roadmap.md#agent-owned-acting-identities).

## Deployment settings and offline use

| Environment variable | Meaning |
| - | - |
| `MESH_TOOL_DISCOVERY_ENABLED` | Optional `true` or `false`. An explicit `false` prevents online catalog requests even if the saved instance setting enables them. |
| `MESH_MCP_REGISTRY_URL` | Optional public HTTPS URL for online catalog metadata. Supply it when enabling discovery. |
| `MESH_MCP_CATALOG_FILE` | Optional absolute path to a local JSON catalog, such as `/etc/mesh/mcp-servers.json`. Available with online discovery off. |

Setting either online environment variable makes the entire online section
environment-managed and read-only in the dashboard. Setting only a registry URL
keeps online discovery off; set both variables to enable it through deployment
configuration. Invalid configured URLs fail startup even when discovery is off;
startup validation performs no DNS lookup or HTTP request. Local-file
configuration is independent of that section.

An offline deployment can set `MESH_TOOL_DISCOVERY_ENABLED=false` and optionally
mount a local catalog. It makes no online registry requests, including after an
online catalog was previously cached. Metadata precedence is local file, online
catalog when enabled, then bundled entries. A stable ID or endpoint appears only
once; earlier sources win.

This directory does not change MCP transport policy. Private MCP destinations
still require the separately planned [internal trust policy](https://github.com/TextureHQ/formation/blob/main/docs/airgapped-deployment-plan.md#private-mcp-and-other-internal-tools).

## Publish or maintain a catalog

Bundled metadata lives in `internal/integration/mcp_presets.json`. Update that
single data file through the normal pull request process. Any operator can
publish the same JSON as a static HTTPS resource, for example at
`https://registry.example.com/v1/servers.json`, or copy it into an offline
installation. Hosting the resource is an operator deployment task.

The v1 catalog is a JSON array with this entry shape:

```json theme={null}
[
  {
    "id": "example.issues",
    "label": "Issue tracker",
    "description": "Read and manage issues.",
    "endpoint": "https://mcp.example.com/mcp",
    "auth_methods": ["oauth", "bearer"],
    "recommended_auth": "oauth"
  }
]
```

Version the distribution path, such as `/v1/servers.json`; there is no envelope
or `schema_version` field. This small curated format is not the official MCP
Registry API. An operator can transform another registry into this format.

IDs are stable lowercase letters, digits, dots, hyphens, or underscores, begin
with a letter or digit, and have at most 80 characters. IDs and endpoints must
be unique within each document. Labels have at most 80 characters and
descriptions at most 1,000. `auth_methods` lists `oauth`, `bearer`, or both,
without duplicates; `recommended_auth` must be one of those methods. Older
catalogs omitting the recommendation use the first method. `bearer` means an
API key or bearer token entered by the operator. Do not include credentials,
account identifiers, scripts, or tool schemas. Unknown fields are rejected.

Documents contain at most 200 entries and 1 MiB of JSON. Endpoints and registry
URLs use HTTPS without user information, query strings, fragments, or custom
ports. Online registry DNS answers must all be public addresses, checked and
pinned immediately before dialing. Fetches send no agent credential, cookie,
or account metadata and follow no redirects or environment proxies.

Online fetches have a five-second timeout. A successful document or HTTP `304`
is cached for one hour; failures retry after five minutes. ETags support
conditional refresh. Refreshes run in the background when a local or last-good
catalog is available, so those reads return immediately. A cold online read
without either source waits for the shared refresh, up to the fetch timeout;
canceling one reader leaves the bounded refresh available to other readers.
The next catalog read applies a changed registry URL or discovery-off setting:
it cancels the old refresh and prevents a late response from replacing the new
source. After a read with discovery off, re-enabling starts a fresh lookup on
the next read. A failed, oversized, or invalid update preserves the last
valid document and reports a warning. A malformed local file likewise preserves
the last valid local document. These caches are process-local: after a restart,
Formation uses the bundled catalog and configured local file until another valid
online response arrives. A catalog failure does not affect saved connections.

## Operator API

All responses require normal session or API-token authentication.

| Method | Path | Contract |
| - | - | - |
| `GET` | `/api/agents/{slug}/tool-catalog` | Agent access required. Returns `{servers, source, online_discovery, stale, warning?}`; each server has the entry shape above. Source is `bundled`, `remote`, or `local`. No connected-account state is returned. |
| `GET` | `/api/settings/tool-discovery` | Owner required. Returns `{config: {enabled, registry_url}, source, editable, local_catalog}`. Settings source is `unset`, `database`, or `environment`; `local_catalog` reports whether a local file is configured. |
| `PUT` | `/api/settings/tool-discovery` | Owner required. Accepts the complete `{config: {enabled, registry_url}}` document. Enabling requires a URL. Returns the saved settings view. Environment-managed sections return `409 tool_discovery_managed`. Saving performs no network request. |

The catalog API returns `Cache-Control: no-store`; server-side metadata caching
is independent of browser authentication. An agent operator cannot change
instance discovery settings or use another agent's catalog route without a
grant. New metadata fields do not confer authority on the remote publisher.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.