How to fix: Set the top-level tool.title to a short human-readable label (for example, "Search catalog"). Claude directory submission requires tool titles; annotations.title remains accepted only as a legacy fallback.
Add a human-readable title so users do not have to interpret the tool identifier.
Description88/100
List all schema recommendations for a database. Each schema recommendation is based on production data from the users database. If you have access to the code base generating the queries, evaluate the code in the context of the recommendation to determine the best steps forward for the specific application. Use schema recommendations as a data point for improvement, not a directive.
Suggestions include adding indexes, removing redundant indexes, preventing primary key exhaustion, unused tables and other general performance improvements. See https://planetscale.com/docs/postgres/monitoring/schema-recommendations for a full list as well as warnings of possible risks when making schema changes.
Set `state` to "open" to retrieve only open recommendations.
Describe the returned information so the agent knows whether it will answer the request.
Inputs95/100
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
pathParameters › database
Database name slug from `list_databases`. Example: `app-db`.
Clear enough to supply this argument.
pathParameters › organization
Organization name slug from `list_organizations`. Example: `acme`.
Clear enough to supply this argument.
queryParameters › page
If provided, specifies the page offset of returned results
Clear enough to supply this argument.
queryParameters › state
Filter by recommendation state
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
queryParameters › per_page
If provided, specifies the number of returned results
No output schema is declared. Add one for structured results so clients can interpret returned fields.
Not declared
Original tool metadata
{
"name": "planetscale_list_schema_recommendations",
"description": "List all schema recommendations for a database. Each schema recommendation is based on production data from the users database. If you have access to the code base generating the queries, evaluate the code in the context of the recommendation to determine the best steps forward for the specific application. Use schema recommendations as a data point for improvement, not a directive.\n\nSuggestions include adding indexes, removing redundant indexes, preventing primary key exhaustion, unused tables and other general performance improvements. See https://planetscale.com/docs/postgres/monitoring/schema-recommendations for a full list as well as warnings of possible risks when making schema changes.\n\nSet `state` to \"open\" to retrieve only open recommendations.",
"inputSchema": {
"type": "object",
"required": [
"pathParameters"
],
"properties": {
"pathParameters": {
"type": "object",
"required": [
"organization",
"database"
],
"properties": {
"database": {
"type": "string",
"description": "Database name slug from `list_databases`. Example: `app-db`."
},
"organization": {
"type": "string",
"description": "Organization name slug from `list_organizations`. Example: `acme`."
}
},
"additionalProperties": false
},
"queryParameters": {
"type": "object",
"properties": {
"page": {
"type": "integer",
"default": 1,
"description": "If provided, specifies the page offset of returned results"
},
"state": {
"enum": [
"open",
"closed"
],
"type": "string",
"description": "Filter by recommendation state"
},
"per_page": {
"type": "integer",
"default": 25,
"description": "If provided, specifies the number of returned results"
}
},
"additionalProperties": false
}
},
"additionalProperties": false
},
"annotations": {
"readOnlyHint": true,
"openWorldHint": true,
"idempotentHint": false,
"destructiveHint": false
}
}
Add a human-readable title so users do not have to interpret the tool identifier.
Description95/100
Search across PlanetScale documentation and blog posts to find relevant information, code examples, API references, and guides. Use this tool when you need to answer questions about PlanetScale, find specific documentation, understand how features work, or locate implementation details. The search returns contextual content with titles and direct links to documentation pages and /blog posts.
The description explains the capability, when to use it, and what to expect.
Inputs85/100
Input documentation gives an agent enough context to populate the arguments.
No output schema is declared. Add one for structured results so clients can interpret returned fields.
Not declared
Original tool metadata
{
"name": "planetscale_search_documentation",
"description": "Search across PlanetScale documentation and blog posts to find relevant information, code examples, API references, and guides. Use this tool when you need to answer questions about PlanetScale, find specific documentation, understand how features work, or locate implementation details. The search returns contextual content with titles and direct links to documentation pages and /blog posts.",
"inputSchema": {
"type": "object",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"required": [
"query"
],
"properties": {
"query": {
"type": "string",
"description": "Search query for PlanetScale docs and blog posts"
}
},
"additionalProperties": false
},
"annotations": {
"readOnlyHint": true,
"openWorldHint": true,
"idempotentHint": false,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description97/100
Break query statistics on a PlanetScale database branch down by query tag value -- total time, latency, rows read, and errors per application, route, job, or user. This is the tool that answers 'which part of my app is causing this load', as opposed to `get_insights`, which answers 'which query'. Pass one or more tag `id` values from `list_query_tags` in `tags`; several ids group by the combination of their values. Each row's `dimensions` maps the grouped tag ids to that row's values. Rows are sorted descending by `sort_by` (default 'totalTime'). A curated set of metrics is requested by default; `fields` widens or narrows it, and the response echoes the effective set as a map from each requested name to the key it is serialized under, since the two differ (`count` arrives as `query_count`). Metrics outside that set are stripped, so a 0 on a returned metric is a real measurement rather than an unrequested field. The `sort_by` metric is always included, whether or not it was asked for. `dimension_counts` reports how many matched queries had the grouping tag's value collapsed (`collapsed_count`) out of the total (`total_count`) -- those queries carry the tag, but their value was never recorded and cannot be recovered. Data comes from PlanetScale Insights. Default time window is the last 24 hours; from/to reaches back up to 365 days, but a range wider than 25 hours must be hour-aligned -- see the from/to descriptions.
The description explains the capability, when to use it, and what to expect.
Inputs87/100
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
to
End of time range (ISO 8601 format). Defaults to now. For a range wider than 25 hours it must land on an hour boundary -- either the top of an hour or its last second ('T13:00:00Z' or 'T12:59:59Z') -- so the simplest way to ask for a wide window is to omit it, which covers everything through the current hour.
Clear enough to supply this argument.
from
Start of time range (ISO 8601 format). Defaults to 24 hours ago. A range wider than 25 hours must start on the hour (e.g. '2026-08-19T00:00:00Z') and span at most 365 days; a wide range that is not hour-aligned is rejected, not narrowed.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
tags
Tag ids to group by, taken from the `id` values returned by `list_query_tags` with their prefix intact, e.g. ['Sapp'] or ['Sapp', 'Broute']. Several ids group by the combination of their values. An id missing its 'S'/'B' prefix is rejected.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
limit
Maximum number of summary rows to return (default: 25, max: 100). This endpoint does not paginate, so when a response reports truncated: true, raise this limit or narrow the time window, tags, or query.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
query
Filter the query statistics being summarized. This is a structured search, not a plain substring: supported terms include `fingerprint:<hash>`, `keyspace:<name>`, `tag:<key>:<value>` (or `tag:<key>` for any value), `user:<name>`, `statement_type:<type>`, `table:<name>`, `index:<name>`, and comparisons like `p99:>100`, while a bare word matches the normalized SQL. Prefix a term with '!' to negate it. This is also the only way to restrict these summaries to one fingerprint or keyspace -- unlike `list_query_tags`, this endpoint has no separate fingerprint or keyspace filter.
Clear enough to supply this argument.
branch
Branch name (e.g., 'main')
Clear enough to supply this argument.
fields
Metric fields to return. Defaults to a curated set (dimensions, count, errorCount, totalTime, percentTime, p50Latency, p99Latency, rowsRead, rowsReadPerReturned, rowsAffected, egressBytes, lastRun), because omitting this server-side returns all 43 metrics and most of them will be zero-fill for any one question. 'dimensions' is always included, since without it the rows cannot be told apart. The response echoes the effective set as `fields`, mapping each requested name to the key it is serialized under (`count` arrives as `query_count`); metrics outside that set are stripped, so a 0 on a returned metric is a real measurement.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
period
Shorthand for a recent time window ending at now. Cannot be combined with from/to.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
sort_by
Metric to sort rows by, descending. Defaults to 'totalTime'. Accepts any name listed under `fields`.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
database
Database name
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
tablet_type
Filter by tablet type: 'primary', 'replica', or 'rdonly'.
No output schema is declared. Add one for structured results so clients can interpret returned fields.
Not declared
Original tool metadata
{
"name": "planetscale_list_query_tag_summaries",
"description": "Break query statistics on a PlanetScale database branch down by query tag value -- total time, latency, rows read, and errors per application, route, job, or user. This is the tool that answers 'which part of my app is causing this load', as opposed to `get_insights`, which answers 'which query'. Pass one or more tag `id` values from `list_query_tags` in `tags`; several ids group by the combination of their values. Each row's `dimensions` maps the grouped tag ids to that row's values. Rows are sorted descending by `sort_by` (default 'totalTime'). A curated set of metrics is requested by default; `fields` widens or narrows it, and the response echoes the effective set as a map from each requested name to the key it is serialized under, since the two differ (`count` arrives as `query_count`). Metrics outside that set are stripped, so a 0 on a returned metric is a real measurement rather than an unrequested field. The `sort_by` metric is always included, whether or not it was asked for. `dimension_counts` reports how many matched queries had the grouping tag's value collapsed (`collapsed_count`) out of the total (`total_count`) -- those queries carry the tag, but their value was never recorded and cannot be recovered. Data comes from PlanetScale Insights. Default time window is the last 24 hours; from/to reaches back up to 365 days, but a range wider than 25 hours must be hour-aligned -- see the from/to descriptions.",
"inputSchema": {
"type": "object",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"required": [
"organization",
"database",
"branch",
"tags"
],
"properties": {
"to": {
"type": "string",
"description": "End of time range (ISO 8601 format). Defaults to now. For a range wider than 25 hours it must land on an hour boundary -- either the top of an hour or its last second ('T13:00:00Z' or 'T12:59:59Z') -- so the simplest way to ask for a wide window is to omit it, which covers everything through the current hour."
},
"from": {
"type": "string",
"description": "Start of time range (ISO 8601 format). Defaults to 24 hours ago. A range wider than 25 hours must start on the hour (e.g. '2026-08-19T00:00:00Z') and span at most 365 days; a wide range that is not hour-aligned is rejected, not narrowed."
},
"tags": {
"type": "array",
"items": {
"type": "string"
},
"minItems": 1,
"description": "Tag ids to group by, taken from the `id` values returned by `list_query_tags` with their prefix intact, e.g. ['Sapp'] or ['Sapp', 'Broute']. Several ids group by the combination of their values. An id missing its 'S'/'B' prefix is rejected."
},
"limit": {
"type": "number",
"description": "Maximum number of summary rows to return (default: 25, max: 100). This endpoint does not paginate, so when a response reports truncated: true, raise this limit or narrow the time window, tags, or query."
},
"query": {
"type": "string",
"description": "Filter the query statistics being summarized. This is a structured search, not a plain substring: supported terms include `fingerprint:<hash>`, `keyspace:<name>`, `tag:<key>:<value>` (or `tag:<key>` for any value), `user:<name>`, `statement_type:<type>`, `table:<name>`, `index:<name>`, and comparisons like `p99:>100`, while a bare word matches the normalized SQL. Prefix a term with '!' to negate it. This is also the only way to restrict these summaries to one fingerprint or keyspace -- unlike `list_query_tags`, this endpoint has no separate fingerprint or keyspace filter."
},
"branch": {
"type": "string",
"description": "Branch name (e.g., 'main')"
},
"fields": {
"type": "array",
"items": {
"enum": [
"dimensions",
"lastRun",
"count",
"errorCount",
"rowsRead",
"rowsAffected",
"rowsReturned",
"rowsReadPerReturned",
"rowsReadPerQuery",
"rowsReturnedPerQuery",
"rowsAffectedPerQuery",
"totalTime",
"cpuTime",
"ioTime",
"percentTime",
"percentCpuTime",
"percentIoTime",
"sumShardQueries",
"maxShardQueries",
"avgShardQueries",
"avgParallelWorkers",
"table",
"qualifiedTable",
"tableKeyspace",
"indexes",
"routingIndexes",
"p50Latency",
"p99Latency",
"maxLatency",
"egressBytes",
"egressBytesPerQuery",
"maxEgressBytes",
"ingressBytes",
"ingressBytesPerQuery",
"maxIngressBytes",
"blocksRead",
"blocksHit",
"blockCacheHitRatio",
"blocksDirtied",
"blocksWritten",
"trafficControlWarnings",
"trafficControlThrottled",
"trafficControlChecked"
],
"type": "string"
},
"minItems": 1,
"description": "Metric fields to return. Defaults to a curated set (dimensions, count, errorCount, totalTime, percentTime, p50Latency, p99Latency, rowsRead, rowsReadPerReturned, rowsAffected, egressBytes, lastRun), because omitting this server-side returns all 43 metrics and most of them will be zero-fill for any one question. 'dimensions' is always included, since without it the rows cannot be told apart. The response echoes the effective set as `fields`, mapping each requested name to the key it is serialized under (`count` arrives as `query_count`); metrics outside that set are stripped, so a 0 on a returned metric is a real measurement."
},
"period": {
"enum": [
"15m",
"1h",
"3h",
"6h",
"12h",
"1d",
"2d",
"7d",
"8d"
],
"type": "string",
"description": "Shorthand for a recent time window ending at now. Cannot be combined with from/to."
},
"sort_by": {
"enum": [
"dimensions",
"lastRun",
"count",
"errorCount",
"rowsRead",
"rowsAffected",
"rowsReturned",
"rowsReadPerReturned",
"rowsReadPerQuery",
"rowsReturnedPerQuery",
"rowsAffectedPerQuery",
"totalTime",
"cpuTime",
"ioTime",
"percentTime",
"percentCpuTime",
"percentIoTime",
"sumShardQueries",
"maxShardQueries",
"avgShardQueries",
"avgParallelWorkers",
"table",
"qualifiedTable",
"tableKeyspace",
"indexes",
"routingIndexes",
"p50Latency",
"p99Latency",
"maxLatency",
"egressBytes",
"egressBytesPerQuery",
"maxEgressBytes",
"ingressBytes",
"ingressBytesPerQuery",
"maxIngressBytes",
"blocksRead",
"blocksHit",
"blockCacheHitRatio",
"blocksDirtied",
"blocksWritten",
"trafficControlWarnings",
"trafficControlThrottled",
"trafficControlChecked"
],
"type": "string",
"description": "Metric to sort rows by, descending. Defaults to 'totalTime'. Accepts any name listed under `fields`."
},
"database": {
"type": "string",
"description": "Database name"
},
"tablet_type": {
"enum": [
"primary",
"replica",
"rdonly"
],
"type": "string",
"description": "Filter by tablet type: 'primary', 'replica', or 'rdonly'."
},
"organization": {
"type": "string",
"description": "PlanetScale organization name"
},
"statement_type": {
"enum": [
"SELECT",
"INSERT",
"UPDATE",
"DELETE"
],
"type": "string",
"description": "Only summarize queries of this statement type."
}
},
"additionalProperties": false
},
"annotations": {
"readOnlyHint": true,
"openWorldHint": false,
"idempotentHint": false,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description94/100
Fetch one query tag on a PlanetScale database branch, with its values and their query counts. Pass the `id` from `list_query_tags`, prefix included -- an unprefixed or unknown id returns a not-found error. Value entries carry the same `kind` ('literal', 'overflow', 'collapsed') as the listing. Use this to re-read a single tag's values under different filters -- a narrower time window, a specific fingerprint or keyspace, or `literal_values_only` -- without listing every tag on the branch again. Data comes from PlanetScale Insights. Default time window is the last 24 hours; from/to reaches back up to 365 days, but a range wider than 25 hours must be hour-aligned -- see the from/to descriptions.
The description explains the capability, when to use it, and what to expect.
Inputs95/100
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
to
End of time range (ISO 8601 format). Defaults to now. For a range wider than 25 hours it must land on an hour boundary -- either the top of an hour or its last second ('T13:00:00Z' or 'T12:59:59Z') -- so the simplest way to ask for a wide window is to omit it, which covers everything through the current hour.
Clear enough to supply this argument.
tag
The tag id to fetch, e.g. 'Sapp' or 'Busername'. Use an `id` value from `list_query_tags`, keeping its 'S'/'B' prefix. A tag whose name contains a '.' cannot be fetched here, because the API's route splits the path on it.
Clear enough to supply this argument.
from
Start of time range (ISO 8601 format). Defaults to 24 hours ago. A range wider than 25 hours must start on the hour (e.g. '2026-08-19T00:00:00Z') and span at most 365 days; a wide range that is not hour-aligned is rejected, not narrowed.
Clear enough to supply this argument.
branch
Branch name (e.g., 'main')
Clear enough to supply this argument.
period
Shorthand for a recent time window ending at now. Cannot be combined with from/to.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
database
Database name
Clear enough to supply this argument.
keyspace
Only include tags that appear on queries against this keyspace.
Clear enough to supply this argument.
fingerprint
Only include tags that appear on queries with this fingerprint. Get one from `get_insights`.
Clear enough to supply this argument.
tablet_type
Filter by tablet type: 'primary', 'replica', or 'rdonly'.
Clear enough to supply this argument.
organization
PlanetScale organization name
Clear enough to supply this argument.
values_limit
Maximum number of literal values returned per tag (default: 25, max: 100). Values outside that range are clamped. The 'Other' and 'Collapsed' buckets are counted separately and still returned.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
literal_values_only
Return only real recorded values, dropping the synthetic 'Other' (overflow) and 'Collapsed' entries. Note that 'Other' is the only signal that values beyond `values_limit` exist, so dropping it leaves no indication that the value list is partial -- the response's `truncated` field counts tags, not values.
No output schema is declared. Add one for structured results so clients can interpret returned fields.
Not declared
Original tool metadata
{
"name": "planetscale_get_query_tag",
"description": "Fetch one query tag on a PlanetScale database branch, with its values and their query counts. Pass the `id` from `list_query_tags`, prefix included -- an unprefixed or unknown id returns a not-found error. Value entries carry the same `kind` ('literal', 'overflow', 'collapsed') as the listing. Use this to re-read a single tag's values under different filters -- a narrower time window, a specific fingerprint or keyspace, or `literal_values_only` -- without listing every tag on the branch again. Data comes from PlanetScale Insights. Default time window is the last 24 hours; from/to reaches back up to 365 days, but a range wider than 25 hours must be hour-aligned -- see the from/to descriptions.",
"inputSchema": {
"type": "object",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"required": [
"organization",
"database",
"branch",
"tag"
],
"properties": {
"to": {
"type": "string",
"description": "End of time range (ISO 8601 format). Defaults to now. For a range wider than 25 hours it must land on an hour boundary -- either the top of an hour or its last second ('T13:00:00Z' or 'T12:59:59Z') -- so the simplest way to ask for a wide window is to omit it, which covers everything through the current hour."
},
"tag": {
"type": "string",
"description": "The tag id to fetch, e.g. 'Sapp' or 'Busername'. Use an `id` value from `list_query_tags`, keeping its 'S'/'B' prefix. A tag whose name contains a '.' cannot be fetched here, because the API's route splits the path on it."
},
"from": {
"type": "string",
"description": "Start of time range (ISO 8601 format). Defaults to 24 hours ago. A range wider than 25 hours must start on the hour (e.g. '2026-08-19T00:00:00Z') and span at most 365 days; a wide range that is not hour-aligned is rejected, not narrowed."
},
"branch": {
"type": "string",
"description": "Branch name (e.g., 'main')"
},
"period": {
"enum": [
"15m",
"1h",
"3h",
"6h",
"12h",
"1d",
"2d",
"7d",
"8d"
],
"type": "string",
"description": "Shorthand for a recent time window ending at now. Cannot be combined with from/to."
},
"database": {
"type": "string",
"description": "Database name"
},
"keyspace": {
"type": "string",
"description": "Only include tags that appear on queries against this keyspace."
},
"fingerprint": {
"type": "string",
"description": "Only include tags that appear on queries with this fingerprint. Get one from `get_insights`."
},
"tablet_type": {
"enum": [
"primary",
"replica",
"rdonly"
],
"type": "string",
"description": "Filter by tablet type: 'primary', 'replica', or 'rdonly'."
},
"organization": {
"type": "string",
"description": "PlanetScale organization name"
},
"values_limit": {
"type": "number",
"description": "Maximum number of literal values returned per tag (default: 25, max: 100). Values outside that range are clamped. The 'Other' and 'Collapsed' buckets are counted separately and still returned."
},
"literal_values_only": {
"type": "boolean",
"description": "Return only real recorded values, dropping the synthetic 'Other' (overflow) and 'Collapsed' entries. Note that 'Other' is the only signal that values beyond `values_limit` exist, so dropping it leaves no indication that the value list is partial -- the response's `truncated` field counts tags, not values."
}
},
"additionalProperties": false
},
"annotations": {
"readOnlyHint": true,
"openWorldHint": false,
"idempotentHint": false,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description97/100
List the query tags seen on a PlanetScale database branch's queries, with their values and query counts. Query tags are SQLCommenter-style annotations an application attaches in SQL comments (e.g. 'app', 'controller', 'route'), plus dimensions Insights derives from the connection itself (e.g. 'username', 'application_name'). Start here: the `id` values this returns are the only way to reach `get_query_tag` and `list_query_tag_summaries`, which is where query load actually gets attributed to a tag value. Each `id` keeps a one-character origin prefix -- 'S' for a tag the application submitted in a SQL comment (source: 'sql'), 'B' for one Insights captured itself (source: 'system') -- and `name` is the same id with the prefix stripped. Each value entry carries a `kind`: 'literal' is a real recorded value; 'overflow' is the synthetic 'Other' bucket aggregating values ranked beyond `values_limit`; 'collapsed' is the synthetic 'Collapsed' bucket counting queries where Insights had stopped recording this tag's values because it saw too many distinct ones, so those values are unrecoverable rather than zero. Data comes from PlanetScale Insights. Default time window is the last 24 hours; from/to reaches back up to 365 days, but a range wider than 25 hours must be hour-aligned -- see the from/to descriptions.
The description explains the capability, when to use it, and what to expect.
Inputs88/100
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
to
End of time range (ISO 8601 format). Defaults to now. For a range wider than 25 hours it must land on an hour boundary -- either the top of an hour or its last second ('T13:00:00Z' or 'T12:59:59Z') -- so the simplest way to ask for a wide window is to omit it, which covers everything through the current hour.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
from
Start of time range (ISO 8601 format). Defaults to 24 hours ago. A range wider than 25 hours must start on the hour (e.g. '2026-08-19T00:00:00Z') and span at most 365 days; a wide range that is not hour-aligned is rejected, not narrowed.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
branch
Branch name (e.g., 'main')
Clear enough to supply this argument.
period
Shorthand for a recent time window ending at now. Cannot be combined with from/to.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
database
Database name
Clear enough to supply this argument.
keyspace
Only include tags that appear on queries against this keyspace.
Clear enough to supply this argument.
fingerprint
Only include tags that appear on queries with this fingerprint. Get one from `get_insights`.
Clear enough to supply this argument.
tablet_type
Filter by tablet type: 'primary', 'replica', or 'rdonly'.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
name_pattern
Filter tags by a SQL LIKE pattern matched against the prefixed id. Wildcards are not added for you, so a bare word like 'app' matches nothing: use '%app%' to find 'Sapp', where '%' matches any run of characters and '_' matches exactly one (so '_app' matches both 'Sapp' and 'Bapp').
Clear enough to supply this argument.
organization
PlanetScale organization name
Clear enough to supply this argument.
values_limit
Maximum number of literal values returned per tag (default: 25, max: 100). Values outside that range are clamped. The 'Other' and 'Collapsed' buckets are counted separately and still returned.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
literal_values_only
Return only real recorded values, dropping the synthetic 'Other' (overflow) and 'Collapsed' entries. Note that 'Other' is the only signal that values beyond `values_limit` exist, so dropping it leaves no indication that the value list is partial -- the response's `truncated` field counts tags, not values.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
No output schema is declared. Add one for structured results so clients can interpret returned fields.
Not declared
Original tool metadata
{
"name": "planetscale_list_query_tags",
"description": "List the query tags seen on a PlanetScale database branch's queries, with their values and query counts. Query tags are SQLCommenter-style annotations an application attaches in SQL comments (e.g. 'app', 'controller', 'route'), plus dimensions Insights derives from the connection itself (e.g. 'username', 'application_name'). Start here: the `id` values this returns are the only way to reach `get_query_tag` and `list_query_tag_summaries`, which is where query load actually gets attributed to a tag value. Each `id` keeps a one-character origin prefix -- 'S' for a tag the application submitted in a SQL comment (source: 'sql'), 'B' for one Insights captured itself (source: 'system') -- and `name` is the same id with the prefix stripped. Each value entry carries a `kind`: 'literal' is a real recorded value; 'overflow' is the synthetic 'Other' bucket aggregating values ranked beyond `values_limit`; 'collapsed' is the synthetic 'Collapsed' bucket counting queries where Insights had stopped recording this tag's values because it saw too many distinct ones, so those values are unrecoverable rather than zero. Data comes from PlanetScale Insights. Default time window is the last 24 hours; from/to reaches back up to 365 days, but a range wider than 25 hours must be hour-aligned -- see the from/to descriptions.",
"inputSchema": {
"type": "object",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"required": [
"organization",
"database",
"branch"
],
"properties": {
"to": {
"type": "string",
"description": "End of time range (ISO 8601 format). Defaults to now. For a range wider than 25 hours it must land on an hour boundary -- either the top of an hour or its last second ('T13:00:00Z' or 'T12:59:59Z') -- so the simplest way to ask for a wide window is to omit it, which covers everything through the current hour."
},
"from": {
"type": "string",
"description": "Start of time range (ISO 8601 format). Defaults to 24 hours ago. A range wider than 25 hours must start on the hour (e.g. '2026-08-19T00:00:00Z') and span at most 365 days; a wide range that is not hour-aligned is rejected, not narrowed."
},
"branch": {
"type": "string",
"description": "Branch name (e.g., 'main')"
},
"period": {
"enum": [
"15m",
"1h",
"3h",
"6h",
"12h",
"1d",
"2d",
"7d",
"8d"
],
"type": "string",
"description": "Shorthand for a recent time window ending at now. Cannot be combined with from/to."
},
"database": {
"type": "string",
"description": "Database name"
},
"keyspace": {
"type": "string",
"description": "Only include tags that appear on queries against this keyspace."
},
"fingerprint": {
"type": "string",
"description": "Only include tags that appear on queries with this fingerprint. Get one from `get_insights`."
},
"tablet_type": {
"enum": [
"primary",
"replica",
"rdonly"
],
"type": "string",
"description": "Filter by tablet type: 'primary', 'replica', or 'rdonly'."
},
"name_pattern": {
"type": "string",
"description": "Filter tags by a SQL LIKE pattern matched against the prefixed id. Wildcards are not added for you, so a bare word like 'app' matches nothing: use '%app%' to find 'Sapp', where '%' matches any run of characters and '_' matches exactly one (so '_app' matches both 'Sapp' and 'Bapp')."
},
"organization": {
"type": "string",
"description": "PlanetScale organization name"
},
"values_limit": {
"type": "number",
"description": "Maximum number of literal values returned per tag (default: 25, max: 100). Values outside that range are clamped. The 'Other' and 'Collapsed' buckets are counted separately and still returned."
},
"literal_values_only": {
"type": "boolean",
"description": "Return only real recorded values, dropping the synthetic 'Other' (overflow) and 'Collapsed' entries. Note that 'Other' is the only signal that values beyond `values_limit` exist, so dropping it leaves no indication that the value list is partial -- the response's `truncated` field counts tags, not values."
}
},
"additionalProperties": false
},
"annotations": {
"readOnlyHint": true,
"openWorldHint": false,
"idempotentHint": false,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description98/100
List the individual captured query executions that failed with a given error fingerprint on a PlanetScale database branch. Each execution includes the normalized SQL, tables, keyspace, user, row counts, duration, error message, and query tags. Get an `error_fingerprint` from `list_query_error_patterns` first. This endpoint cannot filter by tablet type, so executions from all tablet types are returned even when the fingerprint came from a tablet-filtered pattern list. Data comes from PlanetScale Insights. Default time window is the last 24 hours. These results describe individual query executions, so unlike `get_insights` and the query tag tools the window is capped at 25 hours: a wider from/to falls back to the default window server-side.
The description explains the capability, when to use it, and what to expect.
Inputs91/100
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
to
End of time range (ISO 8601 format). Defaults to now.
Clear enough to supply this argument.
from
Start of time range (ISO 8601 format). Defaults to 24 hours ago. These endpoints report individual query executions and do not serve the wide windows `get_insights` and the query tag tools do: a range longer than 25 hours falls back to the default window instead of being rejected, which makes recent data look like a wide-window answer.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
limit
Maximum number of results to return (default: 25, max: 100). These endpoints do not paginate, so when a response reports truncated: true, raise this limit or narrow the time window to see the rest.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
branch
Branch name (e.g., 'main')
Clear enough to supply this argument.
period
Shorthand for a recent time window ending at now. Cannot be combined with from/to.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
database
Database name
Clear enough to supply this argument.
organization
PlanetScale organization name
Clear enough to supply this argument.
error_fingerprint
Error fingerprint identifying the error to list executions for. Use the `error_fingerprint` value from `list_query_error_patterns`.
No output schema is declared. Add one for structured results so clients can interpret returned fields.
Not declared
Original tool metadata
{
"name": "planetscale_list_query_error_executions",
"description": "List the individual captured query executions that failed with a given error fingerprint on a PlanetScale database branch. Each execution includes the normalized SQL, tables, keyspace, user, row counts, duration, error message, and query tags. Get an `error_fingerprint` from `list_query_error_patterns` first. This endpoint cannot filter by tablet type, so executions from all tablet types are returned even when the fingerprint came from a tablet-filtered pattern list. Data comes from PlanetScale Insights. Default time window is the last 24 hours. These results describe individual query executions, so unlike `get_insights` and the query tag tools the window is capped at 25 hours: a wider from/to falls back to the default window server-side.",
"inputSchema": {
"type": "object",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"required": [
"organization",
"database",
"branch",
"error_fingerprint"
],
"properties": {
"to": {
"type": "string",
"description": "End of time range (ISO 8601 format). Defaults to now."
},
"from": {
"type": "string",
"description": "Start of time range (ISO 8601 format). Defaults to 24 hours ago. These endpoints report individual query executions and do not serve the wide windows `get_insights` and the query tag tools do: a range longer than 25 hours falls back to the default window instead of being rejected, which makes recent data look like a wide-window answer."
},
"limit": {
"type": "number",
"description": "Maximum number of results to return (default: 25, max: 100). These endpoints do not paginate, so when a response reports truncated: true, raise this limit or narrow the time window to see the rest."
},
"branch": {
"type": "string",
"description": "Branch name (e.g., 'main')"
},
"period": {
"enum": [
"15m",
"1h",
"3h",
"6h",
"12h",
"1d",
"2d",
"7d",
"8d"
],
"type": "string",
"description": "Shorthand for a recent time window ending at now. Cannot be combined with from/to."
},
"database": {
"type": "string",
"description": "Database name"
},
"organization": {
"type": "string",
"description": "PlanetScale organization name"
},
"error_fingerprint": {
"type": "string",
"description": "Error fingerprint identifying the error to list executions for. Use the `error_fingerprint` value from `list_query_error_patterns`."
}
},
"additionalProperties": false
},
"annotations": {
"readOnlyHint": true,
"openWorldHint": false,
"idempotentHint": false,
"destructiveHint": false
}
}
Add a human-readable title so users do not have to interpret the tool identifier.
Description96/100
List failing queries for a PlanetScale database branch, aggregated by error fingerprint. Each pattern reports the error message, how many times it occurred, when it was last seen, and total/average duration. Use `list_query_error_executions` with an `error_fingerprint` from these results to see the individual failed executions behind a pattern. Data comes from PlanetScale Insights. Default time window is the last 24 hours. These results describe individual query executions, so unlike `get_insights` and the query tag tools the window is capped at 25 hours: a wider from/to falls back to the default window server-side.
The description explains the capability, when to use it, and what to expect.
Inputs88/100
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
to
End of time range (ISO 8601 format). Defaults to now.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
from
Start of time range (ISO 8601 format). Defaults to 24 hours ago. These endpoints report individual query executions and do not serve the wide windows `get_insights` and the query tag tools do: a range longer than 25 hours falls back to the default window instead of being rejected, which makes recent data look like a wide-window answer.
Clear enough to supply this argument.
limit
Maximum number of results to return (default: 25, max: 100). These endpoints do not paginate, so when a response reports truncated: true, raise this limit or narrow the time window to see the rest.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
query
Search error patterns by error message text.
Clear enough to supply this argument.
branch
Branch name (e.g., 'main')
Clear enough to supply this argument.
period
Shorthand for a recent time window ending at now. Cannot be combined with from/to.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
sort_by
Sort error patterns by: 'count' (default, most frequent), 'lastRun' (most recent), 'error' (message), 'totalTime', or 'timePerQuery'.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
database
Database name
Clear enough to supply this argument.
tablet_type
Filter by tablet type: 'primary', 'replica', or 'rdonly'.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
No output schema is declared. Add one for structured results so clients can interpret returned fields.
Not declared
Original tool metadata
{
"name": "planetscale_list_query_error_patterns",
"description": "List failing queries for a PlanetScale database branch, aggregated by error fingerprint. Each pattern reports the error message, how many times it occurred, when it was last seen, and total/average duration. Use `list_query_error_executions` with an `error_fingerprint` from these results to see the individual failed executions behind a pattern. Data comes from PlanetScale Insights. Default time window is the last 24 hours. These results describe individual query executions, so unlike `get_insights` and the query tag tools the window is capped at 25 hours: a wider from/to falls back to the default window server-side.",
"inputSchema": {
"type": "object",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"required": [
"organization",
"database",
"branch"
],
"properties": {
"to": {
"type": "string",
"description": "End of time range (ISO 8601 format). Defaults to now."
},
"from": {
"type": "string",
"description": "Start of time range (ISO 8601 format). Defaults to 24 hours ago. These endpoints report individual query executions and do not serve the wide windows `get_insights` and the query tag tools do: a range longer than 25 hours falls back to the default window instead of being rejected, which makes recent data look like a wide-window answer."
},
"limit": {
"type": "number",
"description": "Maximum number of results to return (default: 25, max: 100). These endpoints do not paginate, so when a response reports truncated: true, raise this limit or narrow the time window to see the rest."
},
"query": {
"type": "string",
"description": "Search error patterns by error message text."
},
"branch": {
"type": "string",
"description": "Branch name (e.g., 'main')"
},
"period": {
"enum": [
"15m",
"1h",
"3h",
"6h",
"12h",
"1d",
"2d",
"7d",
"8d"
],
"type": "string",
"description": "Shorthand for a recent time window ending at now. Cannot be combined with from/to."
},
"sort_by": {
"enum": [
"error",
"lastRun",
"count",
"totalTime",
"timePerQuery"
],
"type": "string",
"description": "Sort error patterns by: 'count' (default, most frequent), 'lastRun' (most recent), 'error' (message), 'totalTime', or 'timePerQuery'."
},
"database": {
"type": "string",
"description": "Database name"
},
"tablet_type": {
"enum": [
"primary",
"replica",
"rdonly"
],
"type": "string",
"description": "Filter by tablet type: 'primary', 'replica', or 'rdonly'."
},
"organization": {
"type": "string",
"description": "PlanetScale organization name"
}
},
"additionalProperties": false
},
"annotations": {
"readOnlyHint": true,
"openWorldHint": false,
"idempotentHint": false,
"destructiveHint": false
}
}
Add a human-readable title so users do not have to interpret the tool identifier.
Description90/100
Get a Stripe Checkout payment method setup started by update_payment_method. Use the setup_id returned by that tool; it is not a payment method ID. This is a one-time check and does not wait. If pending, give checkout_url to the customer and call this tool again only after they finish Checkout. If completed, this tool also returns the saved card brand, last four digits, expiration, and cardholder name as confirmation. Failed or expired setups cannot be resumed. Requires full access to the organization's payment method to inspect the setup and return the saved card.
The description explains the capability, when to use it, and what to expect.
Inputs92/100
Input documentation gives an agent enough context to populate the arguments.
setup_id
Payment method setup ID returned by update_payment_method, not a card or payment method ID
No output schema is declared. Add one for structured results so clients can interpret returned fields.
Not declared
Original tool metadata
{
"name": "planetscale_get_payment_method_setup",
"description": "Get a Stripe Checkout payment method setup started by update_payment_method. Use the setup_id returned by that tool; it is not a payment method ID. This is a one-time check and does not wait. If pending, give checkout_url to the customer and call this tool again only after they finish Checkout. If completed, this tool also returns the saved card brand, last four digits, expiration, and cardholder name as confirmation. Failed or expired setups cannot be resumed. Requires full access to the organization's payment method to inspect the setup and return the saved card.",
"inputSchema": {
"type": "object",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"required": [
"organization",
"setup_id"
],
"properties": {
"setup_id": {
"type": "string",
"description": "Payment method setup ID returned by update_payment_method, not a card or payment method ID"
},
"organization": {
"type": "string",
"description": "PlanetScale organization name"
}
},
"additionalProperties": false
},
"annotations": {
"readOnlyHint": true,
"openWorldHint": true,
"idempotentHint": true,
"destructiveHint": false
}
}
Add a human-readable title so users do not have to interpret the tool identifier.
Description99/100
Start a secure Stripe Checkout session to add or replace an organization's billing card. Use when a customer asks to add, set, replace, or update their PlanetScale payment method. This tool never collects card details: return checkout_url to the customer and let them complete Stripe Checkout in their browser. It returns a setup_id; do not call this tool again while that setup is pending. After the customer finishes, call get_payment_method_setup with the same organization and setup_id. Requires full access to the organization's payment method.
The description explains the capability, when to use it, and what to expect.
Inputs85/100
Input documentation gives an agent enough context to populate the arguments.
No output schema is declared. Add one for structured results so clients can interpret returned fields.
Not declared
Original tool metadata
{
"name": "planetscale_update_payment_method",
"description": "Start a secure Stripe Checkout session to add or replace an organization's billing card. Use when a customer asks to add, set, replace, or update their PlanetScale payment method. This tool never collects card details: return checkout_url to the customer and let them complete Stripe Checkout in their browser. It returns a setup_id; do not call this tool again while that setup is pending. After the customer finishes, call get_payment_method_setup with the same organization and setup_id. Requires full access to the organization's payment method.",
"inputSchema": {
"type": "object",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"required": [
"organization"
],
"properties": {
"organization": {
"type": "string",
"description": "PlanetScale organization name"
}
},
"additionalProperties": false
},
"annotations": {
"readOnlyHint": false,
"openWorldHint": true,
"idempotentHint": false,
"destructiveHint": true
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description80/100
List available PlanetScale cluster sizes (SKUs) for an organization and database engine, including Neki-specific PS-*_NEKI sizes. PS-* sizes use autoscaling network-backed storage; M-* sizes use super fast NVMe storage drives. The rate field is for an HA cluster with 2 replicas; replica_rate is for a single instance. Single instance databases are only available for Postgres. Metal instances must be HA.
Describe the returned information so the agent knows whether it will answer the request.
Inputs67/100
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
type
Filter to only autoscaling (PS-*, network-backed) or metal (M-*, local storage) sizes
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
engine
Database engine to list SKUs for (default: mysql)
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
organization
PlanetScale organization name
Clarify units, where to obtain this value, or conventions not already expressed in the schema.
No output schema is declared. Add one for structured results so clients can interpret returned fields.
Not declared
Original tool metadata
{
"name": "planetscale_list_cluster_sizes",
"description": "List available PlanetScale cluster sizes (SKUs) for an organization and database engine, including Neki-specific PS-*_NEKI sizes. PS-* sizes use autoscaling network-backed storage; M-* sizes use super fast NVMe storage drives. The rate field is for an HA cluster with 2 replicas; replica_rate is for a single instance. Single instance databases are only available for Postgres. Metal instances must be HA.",
"inputSchema": {
"type": "object",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"required": [
"organization"
],
"properties": {
"type": {
"enum": [
"autoscaling",
"metal"
],
"type": "string",
"description": "Filter to only autoscaling (PS-*, network-backed) or metal (M-*, local storage) sizes"
},
"engine": {
"enum": [
"mysql",
"postgresql",
"neki"
],
"type": "string",
"description": "Database engine to list SKUs for (default: mysql)"
},
"organization": {
"type": "string",
"description": "PlanetScale organization name"
}
},
"additionalProperties": false
},
"annotations": {
"readOnlyHint": true,
"openWorldHint": true,
"idempotentHint": true,
"destructiveHint": false
}
}
Add a human-readable title so users do not have to interpret the tool identifier.
Description87/100
Fetch server logs for a PlanetScale Postgres or Neki database branch (not available for Vitess/MySQL databases). Returns recent log entries sorted newest first. Supports filtering by log level, time range, server role, and pod name, plus an optional raw LogsQL query for advanced filtering (e.g. word matching, field filters, and pipe stages like 'error | stats count()'). Default time window is the last hour.
Describe the returned information so the agent knows whether it will answer the request.
Inputs83/100
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
to
End of time range (ISO 8601). Must be used together with 'from'.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
from
Start of time range (ISO 8601, e.g. '2026-08-17T00:00:00Z'). Must be used together with 'to'.
Clear enough to supply this argument.
page
Page number for pagination (default: 1)
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
pods
Filter to specific pod names.
Clear enough to supply this argument.
role
Filter to servers in this role: 'primary' or 'replica'. Omit for all roles.
Clear enough to supply this argument.
limit
Number of log entries to return (default: 50, max: 1000)
Resolve the mismatch between this description and its schema constraints.
query
Optional LogsQL filter expression matched against log content (e.g. 'checkpoint', 'error AND connection'). May include pipe stages after '|'. The tool appends its own 'sort by (_time desc)' and pagination stages after any supplied here, so a custom 'sort by' stage is overridden. Defaults to '*' (all logs).
Clear enough to supply this argument.
branch
Branch name (e.g., 'main')
Clear enough to supply this argument.
levels
Filter to specific log levels: 'INFO', 'DEBUG', 'WARNING', 'ERROR'. Omit for all levels.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
period
Recent time window ending at now, written as number+unit with no spaces (units: ms, s, m, h, d, w, y), e.g. '5m', '30m', '1h', '6h', '24h', '7d'. Cannot be combined with from/to. Defaults to '1h' when no time range is given.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
No output schema is declared. Add one for structured results so clients can interpret returned fields.
Not declared
Original tool metadata
{
"name": "planetscale_get_postgres_logs",
"description": "Fetch server logs for a PlanetScale Postgres or Neki database branch (not available for Vitess/MySQL databases). Returns recent log entries sorted newest first. Supports filtering by log level, time range, server role, and pod name, plus an optional raw LogsQL query for advanced filtering (e.g. word matching, field filters, and pipe stages like 'error | stats count()'). Default time window is the last hour.",
"inputSchema": {
"type": "object",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"required": [
"organization",
"database",
"branch"
],
"properties": {
"to": {
"type": "string",
"description": "End of time range (ISO 8601). Must be used together with 'from'."
},
"from": {
"type": "string",
"description": "Start of time range (ISO 8601, e.g. '2026-08-17T00:00:00Z'). Must be used together with 'to'."
},
"page": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": -9007199254740991,
"description": "Page number for pagination (default: 1)"
},
"pods": {
"type": "array",
"items": {
"type": "string"
},
"description": "Filter to specific pod names."
},
"role": {
"enum": [
"primary",
"replica"
],
"type": "string",
"description": "Filter to servers in this role: 'primary' or 'replica'. Omit for all roles."
},
"limit": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": -9007199254740991,
"description": "Number of log entries to return (default: 50, max: 1000)"
},
"query": {
"type": "string",
"description": "Optional LogsQL filter expression matched against log content (e.g. 'checkpoint', 'error AND connection'). May include pipe stages after '|'. The tool appends its own 'sort by (_time desc)' and pagination stages after any supplied here, so a custom 'sort by' stage is overridden. Defaults to '*' (all logs)."
},
"branch": {
"type": "string",
"description": "Branch name (e.g., 'main')"
},
"levels": {
"type": "array",
"items": {
"enum": [
"INFO",
"DEBUG",
"WARNING",
"ERROR"
],
"type": "string"
},
"description": "Filter to specific log levels: 'INFO', 'DEBUG', 'WARNING', 'ERROR'. Omit for all levels."
},
"period": {
"type": "string",
"description": "Recent time window ending at now, written as number+unit with no spaces (units: ms, s, m, h, d, w, y), e.g. '5m', '30m', '1h', '6h', '24h', '7d'. Cannot be combined with from/to. Defaults to '1h' when no time range is given."
},
"database": {
"type": "string",
"description": "Database name"
},
"organization": {
"type": "string",
"description": "PlanetScale organization name"
}
},
"additionalProperties": false
},
"annotations": {
"readOnlyHint": true,
"openWorldHint": true,
"idempotentHint": false,
"destructiveHint": false
}
}
Add a human-readable title so users do not have to interpret the tool identifier.
Description95/100
Get query performance insights for a PlanetScale database branch. By default, aggregates the top queries across curated metrics (slowest, most time-consuming, most rows read, most inefficient, most rows affected, and highest egress) for a comprehensive view. Can also fetch queries sorted by a single metric. Supports filtering by tablet type (primary/replica). To drill down into a specific query pattern, first call without fingerprint to discover queries (each result includes a `fingerprint` and `keyspace`), then call again with both `fingerprint` and `keyspace` from that result to get the aggregated summary stats and individual executions. Note: egress_bytes and ingress_bytes values are raw bytes; the PlanetScale UI displays these as binary megabytes (1 MB = 2^20 bytes). Durations (sum_total_duration_millis) are in milliseconds. cpuTime is available for Postgres and Neki branches only; maxEgressBytes and ingressBytes/ingressBytesPerQuery/maxIngressBytes are available for MySQL/Vitess branches only. Default time window is the last 24 hours; from/to reaches back up to 365 days, but a range wider than 25 hours must be hour-aligned -- see the from/to descriptions. The individual executions in fingerprint mode are the exception: they are always limited to the last 25 hours, so a wider fingerprint call returns a full-range `summary` next to executions from the last 24 hours, and the response says so.
The description explains the capability, when to use it, and what to expect.
Inputs90/100
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
to
End of time range (ISO 8601 format). Defaults to now. For a range wider than 25 hours it must land on an hour boundary -- either the top of an hour or its last second ('T13:00:00Z' or 'T12:59:59Z') -- so the simplest way to ask for a wide window is to omit it, which covers everything through the current hour. Supported in both discovery and fingerprint modes.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
from
Start of time range (ISO 8601 format). Defaults to 24 hours ago. A range wider than 25 hours must start on the hour (e.g. '2026-08-19T00:00:00Z') and span at most 365 days; a wide range that is not hour-aligned is rejected, not narrowed. Supported in both discovery and fingerprint modes, though in fingerprint mode only the summary honours a wide range.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
limit
Number of results per metric (default: 5, max: 20)
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
query
Filter insights by search query. Supports plain text matching and structured filters: exact match with quotes ("select count"), statement_type:select|delete|update|insert, table:table_name, keyspace:keyspace_name, table_keyspace:keyspace_name, tag:tag_key:tag_value for queries carrying that tag with that value, tag:tag_key on its own for queries carrying the tag whatever its value (including ones whose value went unrecorded), where tag_key is the bare tag name without the 'S'/'B' prefix `list_query_tags` reports and a value containing spaces or colons needs quoting (tag:route:"GET /horses"), index:index_name or index:table.index_name, indexed:true|false, multishard:true|false, query_count:>N or query_count:<N, p99:>N or p50:<N (ms), max_latency:>N (ms). Any term can be negated by an immediately preceding '!' (!tag:app:web). Ignored when fingerprint is provided.
Clear enough to supply this argument.
branch
Branch name (e.g., 'main')
Clear enough to supply this argument.
fields
Request specific metric fields from the API (e.g. ['query', 'count', 'percentTime', 'totalTime', 'cpuTime', 'p50Latency', 'rowsRead', 'rowsReadPerQuery', 'rowsAffected', 'egressBytes', 'egressBytesPerQuery', 'maxEgressBytes', 'ingressBytes', 'ingressBytesPerQuery', 'maxIngressBytes', 'indexes', 'maxShardQueries']). 'cpuTime' is Postgres/Neki-only; 'maxEgressBytes' and ingress* are MySQL/Vitess-only. Ignored when fingerprint is provided.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
period
Shorthand for a recent time window ending at now. Cannot be combined with from/to — use one or the other. Only supported in discovery mode (ignored in fingerprint mode — use from/to instead).
Clear enough to supply this argument.
sort_by
Sort order: 'all' (default) aggregates curated API calls for a comprehensive view, or specify a single metric: 'count', 'percentTime', 'totalTime', 'cpuTime', 'p50Latency', 'p99Latency', 'rowsRead', 'rowsReadPerQuery', 'rowsReadPerReturned', 'rowsAffected', 'egressBytes', 'egressBytesPerQuery', 'maxEgressBytes', 'ingressBytes', 'ingressBytesPerQuery', 'maxIngressBytes'. 'cpuTime' is Postgres/Neki-only; 'maxEgressBytes' and ingress* are MySQL/Vitess-only. Ignored when fingerprint is provided.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
database
Database name
Clear enough to supply this argument.
keyspace
Keyspace for fingerprint drill-down. Required to get summary data. Use the `keyspace` value returned in insights results (e.g. 'my_keyspace' for MySQL/Vitess or 'postgres.public' for Postgres/Neki databases).
Clear enough to supply this argument.
fingerprint
Query fingerprint hash to drill down into a specific query pattern. Use the `fingerprint` value from an initial insights call. Always include `keyspace` (also from the initial results) to get summary data.
No output schema is declared. Add one for structured results so clients can interpret returned fields.
Not declared
Original tool metadata
{
"name": "planetscale_get_insights",
"description": "Get query performance insights for a PlanetScale database branch. By default, aggregates the top queries across curated metrics (slowest, most time-consuming, most rows read, most inefficient, most rows affected, and highest egress) for a comprehensive view. Can also fetch queries sorted by a single metric. Supports filtering by tablet type (primary/replica). To drill down into a specific query pattern, first call without fingerprint to discover queries (each result includes a `fingerprint` and `keyspace`), then call again with both `fingerprint` and `keyspace` from that result to get the aggregated summary stats and individual executions. Note: egress_bytes and ingress_bytes values are raw bytes; the PlanetScale UI displays these as binary megabytes (1 MB = 2^20 bytes). Durations (sum_total_duration_millis) are in milliseconds. cpuTime is available for Postgres and Neki branches only; maxEgressBytes and ingressBytes/ingressBytesPerQuery/maxIngressBytes are available for MySQL/Vitess branches only. Default time window is the last 24 hours; from/to reaches back up to 365 days, but a range wider than 25 hours must be hour-aligned -- see the from/to descriptions. The individual executions in fingerprint mode are the exception: they are always limited to the last 25 hours, so a wider fingerprint call returns a full-range `summary` next to executions from the last 24 hours, and the response says so.",
"inputSchema": {
"type": "object",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"required": [
"organization",
"database",
"branch"
],
"properties": {
"to": {
"type": "string",
"description": "End of time range (ISO 8601 format). Defaults to now. For a range wider than 25 hours it must land on an hour boundary -- either the top of an hour or its last second ('T13:00:00Z' or 'T12:59:59Z') -- so the simplest way to ask for a wide window is to omit it, which covers everything through the current hour. Supported in both discovery and fingerprint modes."
},
"from": {
"type": "string",
"description": "Start of time range (ISO 8601 format). Defaults to 24 hours ago. A range wider than 25 hours must start on the hour (e.g. '2026-08-19T00:00:00Z') and span at most 365 days; a wide range that is not hour-aligned is rejected, not narrowed. Supported in both discovery and fingerprint modes, though in fingerprint mode only the summary honours a wide range."
},
"limit": {
"type": "number",
"description": "Number of results per metric (default: 5, max: 20)"
},
"query": {
"type": "string",
"description": "Filter insights by search query. Supports plain text matching and structured filters: exact match with quotes (\"select count\"), statement_type:select|delete|update|insert, table:table_name, keyspace:keyspace_name, table_keyspace:keyspace_name, tag:tag_key:tag_value for queries carrying that tag with that value, tag:tag_key on its own for queries carrying the tag whatever its value (including ones whose value went unrecorded), where tag_key is the bare tag name without the 'S'/'B' prefix `list_query_tags` reports and a value containing spaces or colons needs quoting (tag:route:\"GET /horses\"), index:index_name or index:table.index_name, indexed:true|false, multishard:true|false, query_count:>N or query_count:<N, p99:>N or p50:<N (ms), max_latency:>N (ms). Any term can be negated by an immediately preceding '!' (!tag:app:web). Ignored when fingerprint is provided."
},
"branch": {
"type": "string",
"description": "Branch name (e.g., 'main')"
},
"fields": {
"type": "array",
"items": {
"type": "string"
},
"description": "Request specific metric fields from the API (e.g. ['query', 'count', 'percentTime', 'totalTime', 'cpuTime', 'p50Latency', 'rowsRead', 'rowsReadPerQuery', 'rowsAffected', 'egressBytes', 'egressBytesPerQuery', 'maxEgressBytes', 'ingressBytes', 'ingressBytesPerQuery', 'maxIngressBytes', 'indexes', 'maxShardQueries']). 'cpuTime' is Postgres/Neki-only; 'maxEgressBytes' and ingress* are MySQL/Vitess-only. Ignored when fingerprint is provided."
},
"period": {
"enum": [
"15m",
"1h",
"3h",
"6h",
"12h",
"1d",
"2d",
"7d",
"8d"
],
"type": "string",
"description": "Shorthand for a recent time window ending at now. Cannot be combined with from/to — use one or the other. Only supported in discovery mode (ignored in fingerprint mode — use from/to instead)."
},
"sort_by": {
"enum": [
"all",
"count",
"percentTime",
"totalTime",
"cpuTime",
"p50Latency",
"p99Latency",
"rowsRead",
"rowsReadPerQuery",
"rowsReadPerReturned",
"rowsAffected",
"egressBytes",
"egressBytesPerQuery",
"maxEgressBytes",
"ingressBytes",
"ingressBytesPerQuery",
"maxIngressBytes"
],
"type": "string",
"description": "Sort order: 'all' (default) aggregates curated API calls for a comprehensive view, or specify a single metric: 'count', 'percentTime', 'totalTime', 'cpuTime', 'p50Latency', 'p99Latency', 'rowsRead', 'rowsReadPerQuery', 'rowsReadPerReturned', 'rowsAffected', 'egressBytes', 'egressBytesPerQuery', 'maxEgressBytes', 'ingressBytes', 'ingressBytesPerQuery', 'maxIngressBytes'. 'cpuTime' is Postgres/Neki-only; 'maxEgressBytes' and ingress* are MySQL/Vitess-only. Ignored when fingerprint is provided."
},
"database": {
"type": "string",
"description": "Database name"
},
"keyspace": {
"type": "string",
"description": "Keyspace for fingerprint drill-down. Required to get summary data. Use the `keyspace` value returned in insights results (e.g. 'my_keyspace' for MySQL/Vitess or 'postgres.public' for Postgres/Neki databases)."
},
"fingerprint": {
"type": "string",
"description": "Query fingerprint hash to drill down into a specific query pattern. Use the `fingerprint` value from an initial insights call. Always include `keyspace` (also from the initial results) to get summary data."
},
"tablet_type": {
"enum": [
"primary",
"replica"
],
"type": "string",
"description": "Filter by tablet type: 'primary' or 'replica'"
},
"organization": {
"type": "string",
"description": "PlanetScale organization name"
}
},
"additionalProperties": false
},
"annotations": {
"readOnlyHint": true,
"openWorldHint": true,
"idempotentHint": false,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description85/100
Execute a write SQL query (INSERT, UPDATE, DELETE, or DDL) against a PlanetScale database. This tool creates short-lived credentials and executes the query securely. Queries have a maximum execution time of 50 seconds — if a query exceeds this limit it will be cancelled, so ensure queries are optimized. TRUNCATE is blocked. DELETE and UPDATE without WHERE clause are blocked. For Postgres and Neki only: use postgres_database_name when the user has created additional databases in the same cluster and wants to run the query against a non-default database. IMPORTANT: DELETE queries and DDL statements (CREATE, DROP, ALTER, RENAME) require human confirmation - you MUST ask the user for explicit approval before setting confirm_destructive: true. Never set confirm_destructive without first showing the user the exact query and getting their explicit 'yes' or approval.
Describe the returned information so the agent knows whether it will answer the request.
Inputs90/100
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
query
SQL INSERT/UPDATE/DELETE/DDL query to execute
Clear enough to supply this argument.
branch
Branch name (e.g., 'main')
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
database
Database name
Clear enough to supply this argument.
organization
PlanetScale organization name
Clear enough to supply this argument.
confirm_destructive
HUMAN CONFIRMATION REQUIRED: Only set to true after explicitly asking the user and receiving their approval. Show them the exact DELETE or DDL query first.
Clear enough to supply this argument.
postgres_database_name
Postgres and Neki only: target database name to connect to. Use when the user has created additional databases in the same cluster (e.g. via CREATE DATABASE). Omit to use the default database for the branch.
No output schema is declared. Add one for structured results so clients can interpret returned fields.
Not declared
Original tool metadata
{
"name": "planetscale_execute_write_query",
"description": "Execute a write SQL query (INSERT, UPDATE, DELETE, or DDL) against a PlanetScale database. This tool creates short-lived credentials and executes the query securely. Queries have a maximum execution time of 50 seconds — if a query exceeds this limit it will be cancelled, so ensure queries are optimized. TRUNCATE is blocked. DELETE and UPDATE without WHERE clause are blocked. For Postgres and Neki only: use postgres_database_name when the user has created additional databases in the same cluster and wants to run the query against a non-default database. IMPORTANT: DELETE queries and DDL statements (CREATE, DROP, ALTER, RENAME) require human confirmation - you MUST ask the user for explicit approval before setting confirm_destructive: true. Never set confirm_destructive without first showing the user the exact query and getting their explicit 'yes' or approval.",
"inputSchema": {
"type": "object",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"required": [
"organization",
"database",
"branch",
"query"
],
"properties": {
"query": {
"type": "string",
"description": "SQL INSERT/UPDATE/DELETE/DDL query to execute"
},
"branch": {
"type": "string",
"description": "Branch name (e.g., 'main')"
},
"database": {
"type": "string",
"description": "Database name"
},
"organization": {
"type": "string",
"description": "PlanetScale organization name"
},
"confirm_destructive": {
"type": "boolean",
"description": "HUMAN CONFIRMATION REQUIRED: Only set to true after explicitly asking the user and receiving their approval. Show them the exact DELETE or DDL query first."
},
"postgres_database_name": {
"type": "string",
"description": "Postgres and Neki only: target database name to connect to. Use when the user has created additional databases in the same cluster (e.g. via CREATE DATABASE). Omit to use the default database for the branch."
}
},
"additionalProperties": false
},
"annotations": {
"readOnlyHint": false,
"openWorldHint": true,
"idempotentHint": false,
"destructiveHint": true
}
}
Add a human-readable title so users do not have to interpret the tool identifier.
Description87/100
Execute a read-only SQL query against a PlanetScale database. Write operations are rejected by the database role. This tool creates short-lived credentials and executes the query securely. Queries have a maximum execution time of 50 seconds — if a query exceeds this limit it will be cancelled, so ensure queries are optimized. For Postgres and Neki, this tool uses an ephemeral pg_read_all_data role that does not bypass row-level security (RLS); zero-row or zero-count results on RLS-protected tables may mean rows are hidden by policy, and the response may include warnings when that risk is detected. For Postgres and Neki only: optionally specify postgres_database_name when the user wants to query a non-default database.
Describe the returned information so the agent knows whether it will answer the request.
Inputs88/100
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
query
Read-only SQL query to execute
Clear enough to supply this argument.
branch
Branch name (e.g., 'main')
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
database
Database name
Explain the meaning of this value, not just its name.
use_replica
Route read queries to a read replica when the branch has replicas. Defaults to true. Set false to force the primary.
Clear enough to supply this argument.
organization
PlanetScale organization name
Clear enough to supply this argument.
postgres_database_name
Postgres and Neki only: target database name to connect to. Use when the user has created additional databases in the same cluster (e.g. via CREATE DATABASE). Omit to use the default database for the branch.
No output schema is declared. Add one for structured results so clients can interpret returned fields.
Not declared
Original tool metadata
{
"name": "planetscale_execute_read_query",
"description": "Execute a read-only SQL query against a PlanetScale database. Write operations are rejected by the database role. This tool creates short-lived credentials and executes the query securely. Queries have a maximum execution time of 50 seconds — if a query exceeds this limit it will be cancelled, so ensure queries are optimized. For Postgres and Neki, this tool uses an ephemeral pg_read_all_data role that does not bypass row-level security (RLS); zero-row or zero-count results on RLS-protected tables may mean rows are hidden by policy, and the response may include warnings when that risk is detected. For Postgres and Neki only: optionally specify postgres_database_name when the user wants to query a non-default database.",
"inputSchema": {
"type": "object",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"required": [
"organization",
"database",
"branch",
"query"
],
"properties": {
"query": {
"type": "string",
"description": "Read-only SQL query to execute"
},
"branch": {
"type": "string",
"description": "Branch name (e.g., 'main')"
},
"database": {
"type": "string",
"description": "Database name"
},
"use_replica": {
"type": "boolean",
"description": "Route read queries to a read replica when the branch has replicas. Defaults to true. Set false to force the primary."
},
"organization": {
"type": "string",
"description": "PlanetScale organization name"
},
"postgres_database_name": {
"type": "string",
"description": "Postgres and Neki only: target database name to connect to. Use when the user has created additional databases in the same cluster (e.g. via CREATE DATABASE). Omit to use the default database for the branch."
}
},
"additionalProperties": false
},
"annotations": {
"readOnlyHint": true,
"openWorldHint": true,
"idempotentHint": false,
"destructiveHint": false
}
}
Loading score analytics…
Put your MCP to the test
A few tasks worth trying with this server, chosen from its reviewed tools. These have not been run.
01Planetscale search documentationSearch across PlanetScale documentation and blog posts to find relevant information, code examples, API references, and guides.
02Get details about a specific database
03List all databases within an organization
04List all PlanetScale organizations you have access to
05Get details about a specific organization
Want to run these tasks against your MCP server with us?
planetscale_list_organizationsplanetscale_list_databasesplanetscale_list_branchesplanetscale_get_organizationplanetscale_get_databaseplanetscale_get_branchplanetscale_get_branch_schemaplanetscale_execute_read_queryplanetscale_execute_write_queryplanetscale_get_insightsplanetscale_list_regions_for_organizationplanetscale_list_cluster_size_skus+3 more
Gram setup, tools, quality score, publishing readiness, and alternatives.
How do I add Gram to Claude, ChatGPT, or Cursor?
Add Gram to Claude, ChatGPT, or Cursor by connecting its remote MCP URL in each client's MCP settings. In Claude, add a custom connector. In ChatGPT, add an MCP app. In Cursor, add an MCP server under Settings. The MCP URL is https://mcp.pscale.dev/mcp/planetscale. This server requires OAuth, so complete the login prompt after you connect.
Is Gram MCP ready for ChatGPT and Claude?
As of October 6, 2026, Gram scores 94/100 on Manufact's MCP publishing checklist. The scan meets ChatGPT publishing checks and does not yet meet Claude publishing checks. Passing these checks does not guarantee marketplace approval.
How clear is Gram's MCP tool documentation?
As of October 6, 2026, Gram scores 70/100 in Manufact's review of tool titles, descriptions, input and output schemas, and behavior annotations. The review covers 25 of 25 discovered tools. The quality score measures documentation clarity; runtime behavior and marketplace readiness require separate checks.
What tools does the Gram MCP server provide?
Gram lists 15 MCP tools, including planetscale_list_organizations, planetscale_list_databases, planetscale_list_branches, planetscale_get_organization, planetscale_get_database, planetscale_get_branch, planetscale_get_branch_schema, planetscale_execute_read_query, planetscale_execute_write_query, planetscale_get_insights, planetscale_list_regions_for_organization, and planetscale_list_cluster_size_skus.
What are the best alternatives to Gram?
As of October 20, 2026, alternatives to Gram in data-analytics on the Manufact MCP leaderboard include Epicure, Newsflash, Point Topic, Pricing Optimizer AI, and StatCite.
Does Gram MCP require authentication?
Gram requires authentication. Connect it in Claude, ChatGPT, or Cursor and complete the OAuth login prompt.
How can Gram improve its MCP documentation?
planetscale_get_branch_schema is the lowest-scoring reviewed tool at 64/100. No output schema is declared. Add one for structured results so clients can interpret returned fields. Open its review for feedback and a copyable fix prompt, then rerun the documentation review after updating your tool metadata.
Who develops Gram?
Gram is developed by PlanetScale. It is listed as partner on the Claude connector directory.
Not your MCP?
Review any public or OAuth MCP server for protocol compatibility, tool documentation, and ChatGPT and Claude publishing readiness. No account required.