---
title: "Schema annotations"
description: "Attach human-written descriptions to your tables and columns and surface them to connected agents through the MCP schema catalog, so an agent gets curated context instead of guessing from names alone."
canonical: "https://pgbeam.com/docs/schema-annotations"
last-updated: "2026-09-09T11:37:53.000Z"
---

# Schema annotations

> Attach human-written descriptions to your tables and columns and surface them to connected agents through the MCP schema catalog, so an agent gets curated context instead of guessing from names alone.

URL: https://pgbeam.com/docs/schema-annotations

An agent reads your schema through the MCP `schema_catalog` and `describe_table` tools. By default the description it sees for a table or column is the DB-native comment (`COMMENT ON`, exposed as `pg_description`). Many databases have none, or have terse ones written for humans who already know the domain.

A schema annotation is a description you write for a specific table or column. When one exists, PgBeam surfaces it in the catalog in place of the DB-native comment, so the agent gets your curated wording. When none exists, the catalog falls back to the DB comment exactly as before. Annotations never change what data the agent can read: policy, masking, allowlists, and budgets are unchanged.

## Precedence

For each table and column the catalog picks the description in this order:

A schema-qualified annotation for that exact relation (for example `public.users`).

An unqualified annotation for the same table or column name (schema omitted).

The DB-native comment (`obj_description` / `col_description`).

The first one present wins. A qualified annotation always beats an unqualified one for the same relation.

## Attach an annotation

Annotations are keyed by `(schema_name, table_name, column_name)`. Omit `column_name` to describe the table itself. Omit `schema_name` to match the unqualified form. A `PUT` with an existing key replaces that annotation.

From the CLI, against the linked project:

Or over HTTP. Describe a table:

Describe a column:

## List and delete

From the CLI:

`annotations list` prints the key and the description; pass `--json` for the full records, including ids and timestamps. `annotations delete` prompts before removing, and `--yes` skips the prompt for scripts and CI.

Over HTTP, list every annotation for a project (cursor-paginated):

Delete one by its key. Pass the same `table_name`, plus `schema_name` and `column_name` when they were set:

## How it reaches the agent

Annotations are project configuration, streamed to the edge proxies on the same channel as your policies and honeytokens. A change propagates within seconds, so the next `schema_catalog` call reflects it. The proxy applies the annotation after policy filtering, so an annotation on a table the credential cannot see is never surfaced.

## Notes

Annotation names are matched case-insensitively, using the same normalization as the relation allowlist.

Writing an annotation needs the `schema_annotation:write` permission (held by owners, admins, security admins, and policy authors). Reading needs `schema_annotation:read`.

The CLI commands act on the linked project. Use `--project` to target another one without switching links.

Annotations are editable in the dashboard, on a project's **Schema** page under Policy and Safety. It lists the tables and columns the project can see, shows which columns a masking rule covers and with which mask kind, and lets you write or remove a description inline. The API stays available for scripted use. The same page can run a PII scan to mark the likely-PII columns no rule masks.