> Connect an AI agent to your Pylo data over the Model Context Protocol

# MCP

Pylo runs a remote MCP server, so an agent client like Claude can read your data. The connection is
read-only and scoped to one customer.

[Connect an app](/mcp/connect-an-app) has the setup steps for Claude, Claude Code, ChatGPT, Codex,
Cursor, VS Code, Gemini and any other MCP client.

## The endpoint

The endpoint comes in two forms. With the bare `https://<your-pylo-mcp-host>/mcp` you pick the
customer at consent time. `https://<your-pylo-mcp-host>/mcp/<customer-id>` names the customer up
front, so consent skips that step.

[Settings > Connect Pylo](https://app.pyloapp.com/p/settings/connected-apps) in the admin panel
shows the second form, with the id already filled in.

A customer id that is not a valid UUID returns a 404 from the MCP server. A well-formed but unknown
id fails the OAuth handshake with `invalid_target`.

## Authorization

The OAuth handshake runs on first use: your browser opens and you approve. With the bare URL you
also pick the customer the agent may read. Either way, the customer stays fixed for the life of the
grant.

Pylo implements OAuth 2.1 with dynamic client registration, so a client that supports it needs no
credentials from you.

[Settings > Connect Pylo](https://app.pyloapp.com/p/settings/connected-apps) lists every app you
have authorized, with the host it connects from, when you connected it, and when it last called the
API. Revoke access there. The app loses access immediately and has to run the handshake again to
reconnect.

Grants are read-only: the MCP surface registers read tools only, so an agent cannot change your
data. A grant also inherits the permissions of the user who approved it, so an agent reads exactly
what that user may read.

## Tools

| Tool                   | Purpose                                                                      |
| ---------------------- | ---------------------------------------------------------------------------- |
| `pylo_list_entities`   | Every entity this user may read, with its shortcode and readable field count |
| `pylo_describe_entity` | One entity's fields, enum values, relations and supported operations         |
| `pylo_query`           | Rows of one entity, filtered and sorted, up to 100 per call                  |
| `pylo_get`             | A single record by id                                                        |
| `pylo_aggregate`       | Counts, sums, averages, minima and maxima, grouped by field or time bucket   |
| `pylo_me`              | The Pylo user this connection is authenticated as                            |
| `pylo_docs`            | This documentation, as markdown                                              |

`pylo_docs` takes no argument for an index of every page, or a page slug for the full text, for
example `data/filtering-and-sorting`.

## What the agent knows

The agent starts out knowing nothing about your schema. Entity and field names are yours, so it
calls `pylo_list_entities` and `pylo_describe_entity` before it queries anything. Enum values come
from the schema too, and the agent reads them rather than guessing.

Reference material like filter operators, relation paths, and aggregation lives in the
[Data](/data/overview) section. The agent reaches it through `pylo_docs`, so it can look things up
mid-conversation without you pasting anything in.
