# Meridian MCP
This server exposes a developer's own Meridian organisation(s) and
app(s): plan builder, deploys, logs, webhooks, Shopify alerts,
databases, emails, automations, CRM definitions, and discounts.
- Every tool takes explicit ids (`organization_id`, `app_id`, ...). There is
no server-side "current app" or "current organization" state. Nothing is
remembered between calls.
- `apps_list` is how you discover the `app_id` (and `organization_id`) that
every other tool needs. Call it first when you don't already have an id.
- For Meridian product behaviour questions, call `docs_search` then
`docs_get` (or read `meridian://docs/{path}`). Those cover the same
public docs Answers uses. Do not invent platform behaviour from memory.
For live Plan Builder keys on a specific app, still use `features_list`
/ `events_list`. Docs explain how gating works; the catalog has the
real keys.
- `plans_list`, `features_list`, and `events_list` return an app's Plan
Builder catalog keyed by the app-local `key` your `@the-meridian/sdk`
`isEnabled()`/`track()` calls use. Read these before writing SDK
integration code. `events_create` and `feature_create` add events
and features to that catalog (snake_case keys, immutable);
`feature_update` renames a feature. `plan_create` makes a draft plan
(prices, trial, features, per-plan event terms) and `plan_update`
edits one; neither puts a plan live. `plan_activate` does, and only
with `confirm: true`: merchants can subscribe right after, so pass it
only once the developer has decided. A paid plan is refused until the
app can charge through Shopify (`SHOPIFY_BILLING_NOT_READY`).
`plan_deactivate` takes a plan off the pricing page again.
`entitlements_explain` resolves what a specific shop is currently
entitled to, for debugging. `discounts_list` / `discount_get`
read Plan Builder discounts; `discount_create` / `discount_update`
write them (deactivate with `status: inactive`). Leaving an
automa
Discoverability
0/6 passed0 of 6 passed0/100
Client listings and public setup information.
mcp.json or server-card.json
Either mcp.json or an MCP Server Card declaring this endpoint passes.
No matching mcp.json manifest or MCP Server Card was found at the checked URLs.
The title clearly communicates the tool’s action and subject. Keep it concise.
Description98/100
Returns the calling Meridian user's identity plus every organisation
they belong to (with their role and key permissions in each). Call
this first to orient yourself: it takes no arguments and its
`organizations[].organization_id` values are what you pass as
`organization_id` to other tools such as `apps_list`.
`organizations[].permissions` is a map of permission name to
boolean covering the permissions the other tools require
(`applications.view`, `applications.edit`, `hosting.view`,
`hosting.edit`, `hosting.promote`, `plan_builder.view`,
`plan_builder.edit`, `emails.view`, `emails.edit`,
`automations.view`, `automations.edit`, `crm.merchants.view`), so
you can tell before calling a tool whether it will be allowed.
The description explains the capability, when to use it, and what to expect.
Inputs100/100
This tool declares no inputs, so argument descriptions are not needed.
No input fields.
Annotations75/100
Declare idempotentHint based on the tool’s actual behavior.
No output schema is declared. Add one for structured results so clients can interpret returned fields.
Not declared
Original tool metadata
{
"name": "whoami",
"title": "Who Am I",
"description": "Returns the calling Meridian user's identity plus every organisation\nthey belong to (with their role and key permissions in each). Call\nthis first to orient yourself: it takes no arguments and its\n`organizations[].organization_id` values are what you pass as\n`organization_id` to other tools such as `apps_list`.\n\n`organizations[].permissions` is a map of permission name to\nboolean covering the permissions the other tools require\n(`applications.view`, `applications.edit`, `hosting.view`,\n`hosting.edit`, `hosting.promote`, `plan_builder.view`,\n`plan_builder.edit`, `emails.view`, `emails.edit`,\n`automations.view`, `automations.edit`, `crm.merchants.view`), so\nyou can tell before calling a tool whether it will be allowed.",
"inputSchema": {
"type": "object",
"properties": {}
},
"annotations": {
"readOnlyHint": true,
"openWorldHint": false,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description98/100
Lists the Meridian apps visible to the calling user, across all of
their organisations by default. Returns each app's `app_id`, the
identifier every other Meridian tool that targets a specific app
(e.g. `app_get`) requires. Use `whoami` first to discover an
`organization_id` if you want to narrow the search to one
organisation.
The description explains the capability, when to use it, and what to expect.
Inputs92/100
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
organization_id
An organisation uuid or slug, as returned by `whoami`. When omitted, every organisation the user belongs to is searched.
Clear enough to supply this argument.
search
Filters apps whose name contains this substring (case-insensitive).
Clear enough to supply this argument.
limit
Maximum number of apps to return. Default 20, maximum 100.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
Annotations75/100
Declare idempotentHint based on the tool’s actual behavior.
No output schema is declared. Add one for structured results so clients can interpret returned fields.
Not declared
Original tool metadata
{
"name": "apps_list",
"title": "List Apps",
"description": "Lists the Meridian apps visible to the calling user, across all of\ntheir organisations by default. Returns each app's `app_id`, the\nidentifier every other Meridian tool that targets a specific app\n(e.g. `app_get`) requires. Use `whoami` first to discover an\n`organization_id` if you want to narrow the search to one\norganisation.",
"inputSchema": {
"type": "object",
"properties": {
"limit": {
"type": "integer",
"description": "Maximum number of apps to return. Default 20, maximum 100."
},
"search": {
"type": "string",
"description": "Filters apps whose name contains this substring (case-insensitive)."
},
"organization_id": {
"type": "string",
"description": "An organisation uuid or slug, as returned by `whoami`. When omitted, every organisation the user belongs to is searched."
}
}
},
"annotations": {
"readOnlyHint": true,
"openWorldHint": false,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description98/100
Returns detail for a single Meridian app: its Shopify connection
state, its environments, and its plan feature entitlements. Takes
the `app_id` returned by `apps_list`. No secret values are ever
included, only metadata.
Each environment carries `base_url` (where the environment answers, the same as
`public_url`, null until the first runtime deploy), `platform_hostname`, `public_url`,
`domains` (the platform domain and each custom domain, with DNS and
certificate state), `database_status` and `database` (`status`,
`engine`, `error_code`, `error_message`, the database add-on first),
the same fields as `environments_list` without the scaling
configuration.
`environments` requires the `hosting.view` permission and
`entitlements` requires `plan_builder.view`. When the caller lacks
one, that block is `null` and `omitted` maps the block name to the
permission it needs (for example `{"environments": "requires
hosting.view"}`); `omitted` is an empty object when nothing was
withheld. Call `whoami` to see which permissions you hold.
The description explains the capability, when to use it, and what to expect.
Inputs96/100
Input documentation gives an agent enough context to populate the arguments.
app_id
The app uuid returned by `apps_list`.
Clear enough to supply this argument.
organization_id
An organisation uuid or slug. When supplied, `app_id` is resolved within that organisation and may be a slug instead of a uuid, mirroring the Meridian web app.
Clear enough to supply this argument.
Annotations75/100
Declare idempotentHint based on the tool’s actual behavior.
No output schema is declared. Add one for structured results so clients can interpret returned fields.
Not declared
Original tool metadata
{
"name": "app_get",
"title": "Get App",
"description": "Returns detail for a single Meridian app: its Shopify connection\nstate, its environments, and its plan feature entitlements. Takes\nthe `app_id` returned by `apps_list`. No secret values are ever\nincluded, only metadata.\n\nEach environment carries `base_url` (where the environment answers, the same as\n`public_url`, null until the first runtime deploy), `platform_hostname`, `public_url`,\n`domains` (the platform domain and each custom domain, with DNS and\ncertificate state), `database_status` and `database` (`status`,\n`engine`, `error_code`, `error_message`, the database add-on first),\nthe same fields as `environments_list` without the scaling\nconfiguration.\n\n`environments` requires the `hosting.view` permission and\n`entitlements` requires `plan_builder.view`. When the caller lacks\none, that block is `null` and `omitted` maps the block name to the\npermission it needs (for example `{\"environments\": \"requires\nhosting.view\"}`); `omitted` is an empty object when nothing was\nwithheld. Call `whoami` to see which permissions you hold.",
"inputSchema": {
"type": "object",
"required": [
"app_id"
],
"properties": {
"app_id": {
"type": "string",
"description": "The app uuid returned by `apps_list`."
},
"organization_id": {
"type": "string",
"description": "An organisation uuid or slug. When supplied, `app_id` is resolved within that organisation and may be a slug instead of a uuid, mirroring the Meridian web app."
}
}
},
"annotations": {
"readOnlyHint": true,
"openWorldHint": false,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description95/100
Searches Meridian's public product documentation (the same knowledge
base Answers uses) and returns ranked passages with path, title, URL,
heading, anchor, snippet, and relevance score. Use this to ground
answers about how Meridian behaves before writing code. No `app_id`.
Docs are not app-scoped. For Shopify Admin API, GraphQL, Polaris, or
theme questions, use Shopify's official developer docs instead. This
tool only covers Meridian. After a hit, call `docs_get` with the
returned `path` for the full page, and use `features_list` /
`events_list` for the caller's live Plan Builder keys.
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.
query
Natural-language question or search phrase about Meridian product behaviour.
Clear enough to supply this argument.
limit
Maximum number of passages to return (1–20). Defaults to the Answers retrieval top_k.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
Annotations75/100
Declare idempotentHint based on the tool’s actual behavior.
No output schema is declared. Add one for structured results so clients can interpret returned fields.
Not declared
Original tool metadata
{
"name": "docs_search",
"title": "Search Documentation",
"description": "Searches Meridian's public product documentation (the same knowledge\nbase Answers uses) and returns ranked passages with path, title, URL,\nheading, anchor, snippet, and relevance score. Use this to ground\nanswers about how Meridian behaves before writing code. No `app_id`.\nDocs are not app-scoped. For Shopify Admin API, GraphQL, Polaris, or\ntheme questions, use Shopify's official developer docs instead. This\ntool only covers Meridian. After a hit, call `docs_get` with the\nreturned `path` for the full page, and use `features_list` /\n`events_list` for the caller's live Plan Builder keys.",
"inputSchema": {
"type": "object",
"required": [
"query"
],
"properties": {
"limit": {
"type": "integer",
"maximum": 20,
"minimum": 1,
"description": "Maximum number of passages to return (1–20). Defaults to the Answers retrieval top_k."
},
"query": {
"type": "string",
"description": "Natural-language question or search phrase about Meridian product behaviour."
}
}
},
"annotations": {
"readOnlyHint": true,
"openWorldHint": false,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description98/100
Fetches one Meridian public product documentation page in full by
relative path (for example `mcp-server.mdx`, or a nested
`guides/some-page.mdx`). Use after `docs_search` when you
need the whole page. Paths match the `meridian://docs/{path}` resource
index. No `app_id`. These docs are not app-scoped. Returns path,
title, public URL, and markdown/MDX content.
The description explains the capability, when to use it, and what to expect.
Inputs94/100
Input documentation gives an agent enough context to populate the arguments.
path
Relative docs path ending in .md or .mdx, as listed by meridian://docs/ or returned by docs_search.
Clear enough to supply this argument.
Annotations75/100
Declare idempotentHint based on the tool’s actual behavior.
No output schema is declared. Add one for structured results so clients can interpret returned fields.
Not declared
Original tool metadata
{
"name": "docs_get",
"title": "Get Documentation Page",
"description": "Fetches one Meridian public product documentation page in full by\nrelative path (for example `mcp-server.mdx`, or a nested\n`guides/some-page.mdx`). Use after `docs_search` when you\nneed the whole page. Paths match the `meridian://docs/{path}` resource\nindex. No `app_id`. These docs are not app-scoped. Returns path,\ntitle, public URL, and markdown/MDX content.",
"inputSchema": {
"type": "object",
"required": [
"path"
],
"properties": {
"path": {
"type": "string",
"description": "Relative docs path ending in .md or .mdx, as listed by meridian://docs/ or returned by docs_search."
}
}
},
"annotations": {
"readOnlyHint": true,
"openWorldHint": false,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description97/100
Lists an app's Plan Builder plans: `plan_id`, `handle`, `name`,
`description`, `status` (`draft`/`active`), `price_monthly`/
`price_yearly`, `trial_days`, and the feature/event terms each plan
grants. Feature and event terms are keyed by their app-local `key`,
the exact string your `@the-meridian/sdk` calls use, e.g.
`isEnabled("<key>")` or `track({ eventKey: "<key>" })`, so you can
write correct SDK code directly from this output. Takes the `app_id`
returned by `apps_list`.
The description explains the capability, when to use it, and what to expect.
Inputs94/100
Input documentation gives an agent enough context to populate the arguments.
app_id
The app uuid returned by `apps_list`.
Clear enough to supply this argument.
organization_id
An organisation uuid or slug. When supplied, `app_id` is resolved within that organisation and may be a slug instead of a uuid, mirroring the Meridian web app.
Clear enough to supply this argument.
Annotations75/100
Declare idempotentHint based on the tool’s actual behavior.
No output schema is declared. Add one for structured results so clients can interpret returned fields.
Not declared
Original tool metadata
{
"name": "plans_list",
"title": "List Plans",
"description": "Lists an app's Plan Builder plans: `plan_id`, `handle`, `name`,\n`description`, `status` (`draft`/`active`), `price_monthly`/\n`price_yearly`, `trial_days`, and the feature/event terms each plan\ngrants. Feature and event terms are keyed by their app-local `key`,\nthe exact string your `@the-meridian/sdk` calls use, e.g.\n`isEnabled(\"<key>\")` or `track({ eventKey: \"<key>\" })`, so you can\nwrite correct SDK code directly from this output. Takes the `app_id`\nreturned by `apps_list`.",
"inputSchema": {
"type": "object",
"required": [
"app_id"
],
"properties": {
"app_id": {
"type": "string",
"description": "The app uuid returned by `apps_list`."
},
"organization_id": {
"type": "string",
"description": "An organisation uuid or slug. When supplied, `app_id` is resolved within that organisation and may be a slug instead of a uuid, mirroring the Meridian web app."
}
}
},
"annotations": {
"readOnlyHint": true,
"openWorldHint": false,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description94/100
Lists an app's Plan Builder feature catalog: `feature_id`, `handle`,
`key` (pass this to the `@the-meridian/sdk` `isEnabled("<key>")` call),
`name`, `description`, `type` (`boolean` or `number`), and which
plans grant the feature and with what value (a numeric limit for
`number`-type features, `null` for `boolean`-type). Takes the
`app_id` returned by `apps_list`.
The description explains the capability, when to use it, and what to expect.
Inputs93/100
Input documentation gives an agent enough context to populate the arguments.
app_id
The app uuid returned by `apps_list`.
Clear enough to supply this argument.
organization_id
An organisation uuid or slug. When supplied, `app_id` is resolved within that organisation and may be a slug instead of a uuid, mirroring the Meridian web app.
Clear enough to supply this argument.
Annotations75/100
Declare idempotentHint based on the tool’s actual behavior.
No output schema is declared. Add one for structured results so clients can interpret returned fields.
Not declared
Original tool metadata
{
"name": "features_list",
"title": "List Features",
"description": "Lists an app's Plan Builder feature catalog: `feature_id`, `handle`,\n`key` (pass this to the `@the-meridian/sdk` `isEnabled(\"<key>\")` call),\n`name`, `description`, `type` (`boolean` or `number`), and which\nplans grant the feature and with what value (a numeric limit for\n`number`-type features, `null` for `boolean`-type). Takes the\n`app_id` returned by `apps_list`.",
"inputSchema": {
"type": "object",
"required": [
"app_id"
],
"properties": {
"app_id": {
"type": "string",
"description": "The app uuid returned by `apps_list`."
},
"organization_id": {
"type": "string",
"description": "An organisation uuid or slug. When supplied, `app_id` is resolved within that organisation and may be a slug instead of a uuid, mirroring the Meridian web app."
}
}
},
"annotations": {
"readOnlyHint": true,
"openWorldHint": false,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description92/100
Lists an app's Plan Builder metered-usage event catalog:
`event_id`, `handle`, `key` (pass this as `eventKey` to the
`@the-meridian/sdk` `track({ eventKey: "<key>" })` call), `name`,
`unit`, `description`, the default metering terms
(`default_included_quantity`, `default_overage_rate`,
`default_overage_unit`, `default_capped_amount`), and the per-plan
terms that override those defaults. Takes the `app_id` returned by
`apps_list`.
The description explains the capability, when to use it, and what to expect.
Inputs95/100
Input documentation gives an agent enough context to populate the arguments.
app_id
The app uuid returned by `apps_list`.
Clear enough to supply this argument.
organization_id
An organisation uuid or slug. When supplied, `app_id` is resolved within that organisation and may be a slug instead of a uuid, mirroring the Meridian web app.
Clear enough to supply this argument.
Annotations75/100
Declare idempotentHint based on the tool’s actual behavior.
No output schema is declared. Add one for structured results so clients can interpret returned fields.
Not declared
Original tool metadata
{
"name": "events_list",
"title": "List Events",
"description": "Lists an app's Plan Builder metered-usage event catalog:\n`event_id`, `handle`, `key` (pass this as `eventKey` to the\n`@the-meridian/sdk` `track({ eventKey: \"<key>\" })` call), `name`,\n`unit`, `description`, the default metering terms\n(`default_included_quantity`, `default_overage_rate`,\n`default_overage_unit`, `default_capped_amount`), and the per-plan\nterms that override those defaults. Takes the `app_id` returned by\n`apps_list`.",
"inputSchema": {
"type": "object",
"required": [
"app_id"
],
"properties": {
"app_id": {
"type": "string",
"description": "The app uuid returned by `apps_list`."
},
"organization_id": {
"type": "string",
"description": "An organisation uuid or slug. When supplied, `app_id` is resolved within that organisation and may be a slug instead of a uuid, mirroring the Meridian web app."
}
}
},
"annotations": {
"readOnlyHint": true,
"openWorldHint": false,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description96/100
Adds a metered-usage event to an app's usage catalog. Requires `name`
and `key`; `key` is what `@the-meridian/sdk` `track({ eventKey: "<key>" })`
reports against, must be lowercase letters, digits and underscores, is
unique per app across both events and usage views, and cannot be
changed afterwards. Optional `unit`, `description`, and default
metering terms (`default_included_quantity`, `default_overage_rate`,
`default_overage_unit`, `default_capped_amount`); omitted terms fall
back to 0 / 0 / 1 / 0. Per-plan overrides are set in the Meridian
dashboard. Call `events_list` first to avoid duplicating a key. Takes
the `app_id` returned by `apps_list`. Returns the same shape as one
`events_list` entry.
The description explains the capability, when to use it, and what to expect.
Inputs85/100
Explain the meaning of this value, not just its name.
app_id
The app uuid returned by `apps_list`.
Clear enough to supply this argument.
organization_id
An organisation uuid or slug. When supplied, `app_id` is resolved within that organisation and may be a slug instead of a uuid, mirroring the Meridian web app.
Clear enough to supply this argument.
name
Display name for the event.
Clear enough to supply this argument.
key
App-local key the SDK reports usage against: lowercase letters, digits, underscores. Unique per app across events and usage views. Immutable.
Clear enough to supply this argument.
unit
Optional unit label, for example "call" or "order".
Clear enough to supply this argument.
description
Optional free-text description.
Explain the meaning of this value, not just its name.
default_included_quantity
Default included quantity per period (min 0, default 0).
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": "events_create",
"title": "Create Event",
"description": "Adds a metered-usage event to an app's usage catalog. Requires `name`\nand `key`; `key` is what `@the-meridian/sdk` `track({ eventKey: \"<key>\" })`\nreports against, must be lowercase letters, digits and underscores, is\nunique per app across both events and usage views, and cannot be\nchanged afterwards. Optional `unit`, `description`, and default\nmetering terms (`default_included_quantity`, `default_overage_rate`,\n`default_overage_unit`, `default_capped_amount`); omitted terms fall\nback to 0 / 0 / 1 / 0. Per-plan overrides are set in the Meridian\ndashboard. Call `events_list` first to avoid duplicating a key. Takes\nthe `app_id` returned by `apps_list`. Returns the same shape as one\n`events_list` entry.",
"inputSchema": {
"type": "object",
"required": [
"app_id",
"name",
"key"
],
"properties": {
"key": {
"type": "string",
"description": "App-local key the SDK reports usage against: lowercase letters, digits, underscores. Unique per app across events and usage views. Immutable."
},
"name": {
"type": "string",
"description": "Display name for the event."
},
"unit": {
"type": "string",
"description": "Optional unit label, for example \"call\" or \"order\"."
},
"app_id": {
"type": "string",
"description": "The app uuid returned by `apps_list`."
},
"description": {
"type": "string",
"description": "Optional free-text description."
},
"organization_id": {
"type": "string",
"description": "An organisation uuid or slug. When supplied, `app_id` is resolved within that organisation and may be a slug instead of a uuid, mirroring the Meridian web app."
},
"default_overage_rate": {
"type": "number",
"description": "Default per-unit overage price (min 0, default 0)."
},
"default_overage_unit": {
"type": "integer",
"description": "Default overage billing unit (min 1, default 1)."
},
"default_capped_amount": {
"type": "number",
"description": "Default overage cap per period (min 0, default 0)."
},
"default_included_quantity": {
"type": "integer",
"description": "Default included quantity per period (min 0, default 0)."
}
}
},
"annotations": {
"readOnlyHint": false,
"openWorldHint": false,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description97/100
Adds a feature to an app's Plan Builder catalog. Requires `name`, `key`
and `type`. `key` is what `@the-meridian/sdk` `isEnabled("<key>")`
checks: lowercase letters, digits and underscores, unique per app, and
it cannot be changed afterwards. `type` is `boolean` (on or off per
plan) or `number` (a limit per plan, such as 100 wishlists), and cannot
be changed either. Optional `description`. The feature is in no plan
yet: add it with `plan_create` or `plan_update`. Call `features_list`
first to avoid duplicating a key. Takes the `app_id` returned by
`apps_list`. Returns the same shape as one `features_list` entry.
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.
app_id
The app uuid returned by `apps_list`.
Clear enough to supply this argument.
organization_id
An organisation uuid or slug. When supplied, `app_id` is resolved within that organisation and may be a slug instead of a uuid, mirroring the Meridian web app.
Clear enough to supply this argument.
name
Display name of the feature.
Clear enough to supply this argument.
key
App-local key the SDK checks: lowercase letters, digits, underscores. Unique per app. Immutable.
Clear enough to supply this argument.
type
`boolean` (on or off per plan) or `number` (a limit per plan). Immutable.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
description
Optional free-text description.
Explain the meaning of this value, not just its name.
Annotations75/100
Declare idempotentHint based on the tool’s actual behavior.
No output schema is declared. Add one for structured results so clients can interpret returned fields.
Not declared
Original tool metadata
{
"name": "feature_create",
"title": "Create Feature",
"description": "Adds a feature to an app's Plan Builder catalog. Requires `name`, `key`\nand `type`. `key` is what `@the-meridian/sdk` `isEnabled(\"<key>\")`\nchecks: lowercase letters, digits and underscores, unique per app, and\nit cannot be changed afterwards. `type` is `boolean` (on or off per\nplan) or `number` (a limit per plan, such as 100 wishlists), and cannot\nbe changed either. Optional `description`. The feature is in no plan\nyet: add it with `plan_create` or `plan_update`. Call `features_list`\nfirst to avoid duplicating a key. Takes the `app_id` returned by\n`apps_list`. Returns the same shape as one `features_list` entry.",
"inputSchema": {
"type": "object",
"required": [
"app_id",
"name",
"key",
"type"
],
"properties": {
"key": {
"type": "string",
"description": "App-local key the SDK checks: lowercase letters, digits, underscores. Unique per app. Immutable."
},
"name": {
"type": "string",
"description": "Display name of the feature."
},
"type": {
"enum": [
"boolean",
"number"
],
"type": "string",
"description": "`boolean` (on or off per plan) or `number` (a limit per plan). Immutable."
},
"app_id": {
"type": "string",
"description": "The app uuid returned by `apps_list`."
},
"description": {
"type": "string",
"description": "Optional free-text description."
},
"organization_id": {
"type": "string",
"description": "An organisation uuid or slug. When supplied, `app_id` is resolved within that organisation and may be a slug instead of a uuid, mirroring the Meridian web app."
}
}
},
"annotations": {
"readOnlyHint": false,
"openWorldHint": false,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description97/100
Edits a Plan Builder feature's `name` or `description`. `feature_id`
is the uuid or handle from `features_list`. The `key` and `type` are
set at creation and cannot change: create another feature instead.
Which plans grant the feature, and its value in each, is set with
`plan_update`. Takes the `app_id` returned by `apps_list`. Returns the
same shape as one `features_list` entry.
The description explains the capability, when to use it, and what to expect.
Inputs91/100
Input documentation gives an agent enough context to populate the arguments.
app_id
The app uuid returned by `apps_list`.
Clear enough to supply this argument.
organization_id
An organisation uuid or slug. When supplied, `app_id` is resolved within that organisation and may be a slug instead of a uuid, mirroring the Meridian web app.
Clear enough to supply this argument.
feature_id
Feature uuid or handle from `features_list`.
Clear enough to supply this argument.
name
New display name.
Clear enough to supply this argument.
description
New description. Pass null to clear it.
Clear enough to supply this argument.
Annotations75/100
Declare idempotentHint based on the tool’s actual behavior.
No output schema is declared. Add one for structured results so clients can interpret returned fields.
Not declared
Original tool metadata
{
"name": "feature_update",
"title": "Update Feature",
"description": "Edits a Plan Builder feature's `name` or `description`. `feature_id`\nis the uuid or handle from `features_list`. The `key` and `type` are\nset at creation and cannot change: create another feature instead.\nWhich plans grant the feature, and its value in each, is set with\n`plan_update`. Takes the `app_id` returned by `apps_list`. Returns the\nsame shape as one `features_list` entry.",
"inputSchema": {
"type": "object",
"required": [
"app_id",
"feature_id"
],
"properties": {
"name": {
"type": "string",
"description": "New display name."
},
"app_id": {
"type": "string",
"description": "The app uuid returned by `apps_list`."
},
"feature_id": {
"type": "string",
"description": "Feature uuid or handle from `features_list`."
},
"description": {
"type": [
"string",
"null"
],
"description": "New description. Pass null to clear it."
},
"organization_id": {
"type": "string",
"description": "An organisation uuid or slug. When supplied, `app_id` is resolved within that organisation and may be a slug instead of a uuid, mirroring the Meridian web app."
}
}
},
"annotations": {
"readOnlyHint": false,
"openWorldHint": false,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description96/100
Creates a Plan Builder plan as a **draft**: merchants do not see it
until `plan_activate`. Requires `name` (unique per app) and
`price_monthly` in USD (0 for a free plan). Optional `description`,
`price_yearly` (needs a monthly price above 0, and no usage pricing),
`trial_days`, `features` (each `feature_id` from `features_list`, and
a `value` for a `number` feature) and `events` (per-plan usage terms
for events from `events_list`; at most one with an `overage_rate`
above 0). Takes the `app_id` returned by `apps_list`. Returns the same
shape as one `plans_list` entry.
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.
app_id
The app uuid returned by `apps_list`.
Clear enough to supply this argument.
organization_id
An organisation uuid or slug. When supplied, `app_id` is resolved within that organisation and may be a slug instead of a uuid, mirroring the Meridian web app.
Clear enough to supply this argument.
name
Plan name, unique among the app's plans.
Clear enough to supply this argument.
price_monthly
Monthly price in USD (min 0). 0 for a free plan.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
price_yearly
Optional yearly price in USD (min 0.01). Needs a monthly price above 0, and no usage pricing.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
trial_days
Optional free trial length in days (min 0).
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
description
Optional description shown with the plan.
Clear enough to supply this argument.
features › items › feature_id
The `feature_id` from `features_list` (or `feature_create`).
Clear enough to supply this argument.
features › items › value
For a `number` feature, the plan's limit. Leave it out for a `boolean` feature.
Clear enough to supply this argument.
events › items › event_id
The `event_id` from `events_list` (or `events_create`).
Clear enough to supply this argument.
events › items › included_quantity
Included per billing period (min 0).
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
events › items › overage_rate
Price per overage unit beyond the included quantity (min 0). Above 0, the plan charges for usage.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
events › items › overage_unit
How many units each overage price covers (min 1).
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
events › items › capped_amount
Most the plan charges for usage per period (min 0).
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
Annotations75/100
Declare idempotentHint based on the tool’s actual behavior.
No output schema is declared. Add one for structured results so clients can interpret returned fields.
Not declared
Original tool metadata
{
"name": "plan_create",
"title": "Create Plan",
"description": "Creates a Plan Builder plan as a **draft**: merchants do not see it\nuntil `plan_activate`. Requires `name` (unique per app) and\n`price_monthly` in USD (0 for a free plan). Optional `description`,\n`price_yearly` (needs a monthly price above 0, and no usage pricing),\n`trial_days`, `features` (each `feature_id` from `features_list`, and\na `value` for a `number` feature) and `events` (per-plan usage terms\nfor events from `events_list`; at most one with an `overage_rate`\nabove 0). Takes the `app_id` returned by `apps_list`. Returns the same\nshape as one `plans_list` entry.",
"inputSchema": {
"type": "object",
"required": [
"app_id",
"name",
"price_monthly"
],
"properties": {
"name": {
"type": "string",
"description": "Plan name, unique among the app's plans."
},
"app_id": {
"type": "string",
"description": "The app uuid returned by `apps_list`."
},
"events": {
"type": "array",
"items": {
"type": "object",
"required": [
"event_id",
"included_quantity",
"overage_rate",
"overage_unit",
"capped_amount"
],
"properties": {
"event_id": {
"type": "string",
"description": "The `event_id` from `events_list` (or `events_create`)."
},
"overage_rate": {
"type": "number",
"description": "Price per overage unit beyond the included quantity (min 0). Above 0, the plan charges for usage."
},
"overage_unit": {
"type": "integer",
"description": "How many units each overage price covers (min 1)."
},
"capped_amount": {
"type": "number",
"description": "Most the plan charges for usage per period (min 0)."
},
"included_quantity": {
"type": "integer",
"description": "Included per billing period (min 0)."
}
}
},
"description": "The plan's per-event usage terms. Replaces the plan's whole list. At most one event may have an overage rate above 0, and a plan that charges for usage cannot have a yearly price."
},
"features": {
"type": "array",
"items": {
"type": "object",
"required": [
"feature_id"
],
"properties": {
"value": {
"type": "integer",
"description": "For a `number` feature, the plan's limit. Leave it out for a `boolean` feature."
},
"feature_id": {
"type": "string",
"description": "The `feature_id` from `features_list` (or `feature_create`)."
}
}
},
"description": "The features this plan grants. Replaces the plan's whole list: send every feature the plan should keep. An empty list removes them all."
},
"trial_days": {
"type": "integer",
"description": "Optional free trial length in days (min 0)."
},
"description": {
"type": "string",
"description": "Optional description shown with the plan."
},
"price_yearly": {
"type": "number",
"description": "Optional yearly price in USD (min 0.01). Needs a monthly price above 0, and no usage pricing."
},
"price_monthly": {
"type": "number",
"description": "Monthly price in USD (min 0). 0 for a free plan."
},
"organization_id": {
"type": "string",
"description": "An organisation uuid or slug. When supplied, `app_id` is resolved within that organisation and may be a slug instead of a uuid, mirroring the Meridian web app."
}
}
},
"annotations": {
"readOnlyHint": false,
"openWorldHint": false,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description98/100
Edits a Plan Builder plan. `plan_id` is the uuid or handle from
`plans_list`. Send only what changes: `name`, `description`,
`price_monthly`, `price_yearly` (null removes it), `trial_days`,
`features`, `events`. `features` and `events` each replace the plan's
whole list, so send every entry the plan should keep. Refused when the
plan has live subscribers and the change would cost them more
(`PLAN_LOCKED`; make a new version in the Meridian dashboard), and
when it would price an active plan while the app cannot charge
through Shopify yet (`SHOPIFY_BILLING_NOT_READY`). An active plan's
changes reach new merchants at once. To put a draft live, use
`plan_activate`. Takes the `app_id` returned by `apps_list`. Returns
the same shape as one `plans_list` entry.
The description explains the capability, when to use it, and what to expect.
Inputs85/100
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
app_id
The app uuid returned by `apps_list`.
Clear enough to supply this argument.
organization_id
An organisation uuid or slug. When supplied, `app_id` is resolved within that organisation and may be a slug instead of a uuid, mirroring the Meridian web app.
Clear enough to supply this argument.
plan_id
Plan uuid or handle from `plans_list`.
Clear enough to supply this argument.
name
New plan name, unique among the app's plans.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
price_monthly
Monthly price in USD (min 0).
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
price_yearly
Yearly price in USD (min 0.01), or null to remove it.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
trial_days
Free trial length in days (min 0), or null for none.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
description
Description shown with the plan, or null to clear it.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
features › items › feature_id
The `feature_id` from `features_list` (or `feature_create`).
Clear enough to supply this argument.
features › items › value
For a `number` feature, the plan's limit. Leave it out for a `boolean` feature.
Clear enough to supply this argument.
events › items › event_id
The `event_id` from `events_list` (or `events_create`).
Clear enough to supply this argument.
events › items › included_quantity
Included per billing period (min 0).
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
events › items › overage_rate
Price per overage unit beyond the included quantity (min 0). Above 0, the plan charges for usage.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
events › items › overage_unit
How many units each overage price covers (min 1).
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
events › items › capped_amount
Most the plan charges for usage per period (min 0).
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
Annotations75/100
Declare idempotentHint based on the tool’s actual behavior.
No output schema is declared. Add one for structured results so clients can interpret returned fields.
Not declared
Original tool metadata
{
"name": "plan_update",
"title": "Update Plan",
"description": "Edits a Plan Builder plan. `plan_id` is the uuid or handle from\n`plans_list`. Send only what changes: `name`, `description`,\n`price_monthly`, `price_yearly` (null removes it), `trial_days`,\n`features`, `events`. `features` and `events` each replace the plan's\nwhole list, so send every entry the plan should keep. Refused when the\nplan has live subscribers and the change would cost them more\n(`PLAN_LOCKED`; make a new version in the Meridian dashboard), and\nwhen it would price an active plan while the app cannot charge\nthrough Shopify yet (`SHOPIFY_BILLING_NOT_READY`). An active plan's\nchanges reach new merchants at once. To put a draft live, use\n`plan_activate`. Takes the `app_id` returned by `apps_list`. Returns\nthe same shape as one `plans_list` entry.",
"inputSchema": {
"type": "object",
"required": [
"app_id",
"plan_id"
],
"properties": {
"name": {
"type": "string",
"description": "New plan name, unique among the app's plans."
},
"app_id": {
"type": "string",
"description": "The app uuid returned by `apps_list`."
},
"events": {
"type": "array",
"items": {
"type": "object",
"required": [
"event_id",
"included_quantity",
"overage_rate",
"overage_unit",
"capped_amount"
],
"properties": {
"event_id": {
"type": "string",
"description": "The `event_id` from `events_list` (or `events_create`)."
},
"overage_rate": {
"type": "number",
"description": "Price per overage unit beyond the included quantity (min 0). Above 0, the plan charges for usage."
},
"overage_unit": {
"type": "integer",
"description": "How many units each overage price covers (min 1)."
},
"capped_amount": {
"type": "number",
"description": "Most the plan charges for usage per period (min 0)."
},
"included_quantity": {
"type": "integer",
"description": "Included per billing period (min 0)."
}
}
},
"description": "The plan's per-event usage terms. Replaces the plan's whole list. At most one event may have an overage rate above 0, and a plan that charges for usage cannot have a yearly price."
},
"plan_id": {
"type": "string",
"description": "Plan uuid or handle from `plans_list`."
},
"features": {
"type": "array",
"items": {
"type": "object",
"required": [
"feature_id"
],
"properties": {
"value": {
"type": "integer",
"description": "For a `number` feature, the plan's limit. Leave it out for a `boolean` feature."
},
"feature_id": {
"type": "string",
"description": "The `feature_id` from `features_list` (or `feature_create`)."
}
}
},
"description": "The features this plan grants. Replaces the plan's whole list: send every feature the plan should keep. An empty list removes them all."
},
"trial_days": {
"type": [
"integer",
"null"
],
"description": "Free trial length in days (min 0), or null for none."
},
"description": {
"type": [
"string",
"null"
],
"description": "Description shown with the plan, or null to clear it."
},
"price_yearly": {
"type": [
"number",
"null"
],
"description": "Yearly price in USD (min 0.01), or null to remove it."
},
"price_monthly": {
"type": "number",
"description": "Monthly price in USD (min 0)."
},
"organization_id": {
"type": "string",
"description": "An organisation uuid or slug. When supplied, `app_id` is resolved within that organisation and may be a slug instead of a uuid, mirroring the Meridian web app."
}
}
},
"annotations": {
"readOnlyHint": false,
"openWorldHint": false,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description98/100
Puts a draft Plan Builder plan live: from then on it is on the app's
pricing page and merchants can subscribe to it, and pay for it if it
is paid. REQUIRES `confirm: true` in the same call; without it the
tool refuses and changes nothing. Only pass `confirm: true` once the
developer you act for has decided to offer this plan to merchants.
`plan_id` is the uuid or handle from `plans_list`. Refused for an
older version of a plan (activate the current one), and for a paid
plan while the app cannot charge through Shopify yet
(`SHOPIFY_BILLING_NOT_READY`, with what is missing and where to fix
it). A plan that is already active is returned unchanged. Takes the
`app_id` returned by `apps_list`. Returns the same shape as one
`plans_list` entry.
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.
app_id
The app uuid returned by `apps_list`.
Clear enough to supply this argument.
organization_id
An organisation uuid or slug. When supplied, `app_id` is resolved within that organisation and may be a slug instead of a uuid, mirroring the Meridian web app.
Clear enough to supply this argument.
plan_id
Plan uuid or handle from `plans_list`.
Clear enough to supply this argument.
confirm
Must be exactly `true`. Merchants can subscribe to the plan as soon as it is active; this tool refuses without explicit confirmation.
Clear enough to supply this argument.
Annotations75/100
Declare idempotentHint based on the tool’s actual behavior.
No output schema is declared. Add one for structured results so clients can interpret returned fields.
Not declared
Original tool metadata
{
"name": "plan_activate",
"title": "Activate Plan",
"description": "Puts a draft Plan Builder plan live: from then on it is on the app's\npricing page and merchants can subscribe to it, and pay for it if it\nis paid. REQUIRES `confirm: true` in the same call; without it the\ntool refuses and changes nothing. Only pass `confirm: true` once the\ndeveloper you act for has decided to offer this plan to merchants.\n`plan_id` is the uuid or handle from `plans_list`. Refused for an\nolder version of a plan (activate the current one), and for a paid\nplan while the app cannot charge through Shopify yet\n(`SHOPIFY_BILLING_NOT_READY`, with what is missing and where to fix\nit). A plan that is already active is returned unchanged. Takes the\n`app_id` returned by `apps_list`. Returns the same shape as one\n`plans_list` entry.",
"inputSchema": {
"type": "object",
"required": [
"app_id",
"plan_id",
"confirm"
],
"properties": {
"app_id": {
"type": "string",
"description": "The app uuid returned by `apps_list`."
},
"confirm": {
"type": "boolean",
"description": "Must be exactly `true`. Merchants can subscribe to the plan as soon as it is active; this tool refuses without explicit confirmation."
},
"plan_id": {
"type": "string",
"description": "Plan uuid or handle from `plans_list`."
},
"organization_id": {
"type": "string",
"description": "An organisation uuid or slug. When supplied, `app_id` is resolved within that organisation and may be a slug instead of a uuid, mirroring the Meridian web app."
}
}
},
"annotations": {
"readOnlyHint": false,
"openWorldHint": false,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description98/100
Takes an active Plan Builder plan off the app's pricing page by
switching it back to draft: new stores can no longer subscribe to it.
Stores already subscribed keep it, at the terms they approved.
`plan_id` is the uuid or handle from `plans_list`. A plan that is
already a draft is returned unchanged. Put it back with
`plan_activate`. Takes the `app_id` returned by `apps_list`. Returns
the same shape as one `plans_list` entry.
The description explains the capability, when to use it, and what to expect.
Inputs93/100
Input documentation gives an agent enough context to populate the arguments.
app_id
The app uuid returned by `apps_list`.
Clear enough to supply this argument.
organization_id
An organisation uuid or slug. When supplied, `app_id` is resolved within that organisation and may be a slug instead of a uuid, mirroring the Meridian web app.
Clear enough to supply this argument.
plan_id
Plan uuid or handle from `plans_list`.
Clear enough to supply this argument.
Annotations75/100
Declare idempotentHint based on the tool’s actual behavior.
No output schema is declared. Add one for structured results so clients can interpret returned fields.
Not declared
Original tool metadata
{
"name": "plan_deactivate",
"title": "Deactivate Plan",
"description": "Takes an active Plan Builder plan off the app's pricing page by\nswitching it back to draft: new stores can no longer subscribe to it.\nStores already subscribed keep it, at the terms they approved.\n`plan_id` is the uuid or handle from `plans_list`. A plan that is\nalready a draft is returned unchanged. Put it back with\n`plan_activate`. Takes the `app_id` returned by `apps_list`. Returns\nthe same shape as one `plans_list` entry.",
"inputSchema": {
"type": "object",
"required": [
"app_id",
"plan_id"
],
"properties": {
"app_id": {
"type": "string",
"description": "The app uuid returned by `apps_list`."
},
"plan_id": {
"type": "string",
"description": "Plan uuid or handle from `plans_list`."
},
"organization_id": {
"type": "string",
"description": "An organisation uuid or slug. When supplied, `app_id` is resolved within that organisation and may be a slug instead of a uuid, mirroring the Meridian web app."
}
}
},
"annotations": {
"readOnlyHint": false,
"openWorldHint": false,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description98/100
Resolves the Plan Builder entitlement snapshot for one shop of the
given app: the plan it is on, whether it is paused, its currency/FX
rate, and its feature/event terms, both objects keyed by the
app-local `key` your `@the-meridian/sdk` `isEnabled()`/`track()` calls
use. Unlike `plans_list`/`features_list`/`events_list`, the
feature/event entries here use the `@the-meridian/sdk` `Entitlements`
type's own field names verbatim (e.g. `enabled`, `limit`, `includedQuantity`,
`usedThisPeriod`) rather than this server's usual snake_case, because
this tool's whole purpose is showing exactly what the SDK's
`getEntitlements()` would return for that shop right now, without
calling Shopify. Never returns the shop's access token. Takes the
`app_id` returned by `apps_list` and the shop's `shop_domain` (e.g.
`demo.myshopify.com`). Requires both the `plan_builder.view` and
`crm.merchants.view` permissions on the app, because the result is
one merchant's subscription state.
The description explains the capability, when to use it, and what to expect.
Inputs93/100
Input documentation gives an agent enough context to populate the arguments.
app_id
The app uuid returned by `apps_list`.
Clear enough to supply this argument.
organization_id
An organisation uuid or slug. When supplied, `app_id` is resolved within that organisation and may be a slug instead of a uuid, mirroring the Meridian web app.
Clear enough to supply this argument.
shop_domain
The Shopify shop domain to resolve entitlements for, e.g. demo.myshopify.com.
Clear enough to supply this argument.
Annotations75/100
Declare idempotentHint based on the tool’s actual behavior.
No output schema is declared. Add one for structured results so clients can interpret returned fields.
Not declared
Original tool metadata
{
"name": "entitlements_explain",
"title": "Explain Shop Entitlements",
"description": "Resolves the Plan Builder entitlement snapshot for one shop of the\ngiven app: the plan it is on, whether it is paused, its currency/FX\nrate, and its feature/event terms, both objects keyed by the\napp-local `key` your `@the-meridian/sdk` `isEnabled()`/`track()` calls\nuse. Unlike `plans_list`/`features_list`/`events_list`, the\nfeature/event entries here use the `@the-meridian/sdk` `Entitlements`\ntype's own field names verbatim (e.g. `enabled`, `limit`, `includedQuantity`,\n`usedThisPeriod`) rather than this server's usual snake_case, because\nthis tool's whole purpose is showing exactly what the SDK's\n`getEntitlements()` would return for that shop right now, without\ncalling Shopify. Never returns the shop's access token. Takes the\n`app_id` returned by `apps_list` and the shop's `shop_domain` (e.g.\n`demo.myshopify.com`). Requires both the `plan_builder.view` and\n`crm.merchants.view` permissions on the app, because the result is\none merchant's subscription state.",
"inputSchema": {
"type": "object",
"required": [
"app_id",
"shop_domain"
],
"properties": {
"app_id": {
"type": "string",
"description": "The app uuid returned by `apps_list`."
},
"shop_domain": {
"type": "string",
"description": "The Shopify shop domain to resolve entitlements for, e.g. demo.myshopify.com."
},
"organization_id": {
"type": "string",
"description": "An organisation uuid or slug. When supplied, `app_id` is resolved within that organisation and may be a slug instead of a uuid, mirroring the Meridian web app."
}
}
},
"annotations": {
"readOnlyHint": true,
"openWorldHint": false,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description93/100
Lists an app's deploy-plane environments (development/staging/
production): each environment's `environment_id`, `type`, `region`,
`base_url`, `healthcheck_path`, Cloud Run scaling configuration
(`cpu`, `memory`, `min_instances`, `max_instances`, `concurrency`,
`timeout_seconds`), `config_pending_deploy` (true when settings changed
that only reach the app with the next deploy) with `config_changed_at`,
`database_status`, and when the managed database
failed to provision, sanitised `database_error_code` /
`database_error_message`. Takes the `app_id` returned by `apps_list`.
Use the returned `environment_id` with `deployments_list`,
`logs_tail`, or `deployment_create`.
`base_url` is where the environment answers once deployed (the same as
`public_url`), null until the first runtime deploy. `public_url` is
`https://` + `platform_hostname`, the Meridian hostname. `domains`
lists the
platform domain (`kind: "platform"`, `status` `active`,
`not_deployed` or `disabled` while hosting is off), then each custom
domain (`kind: "custom"`) with its `status` (`pending_dns`,
`provisioning`, `active`, `failed`, `deleting`), certificate state
`tls` (`active`, `provisioning`, `failed`, or null when Meridian
holds none), `dns_all_verified`, the `dns_records` to add,
`certificate_expires_at`, `ownership_expires_at` and
`error_message`.
`database` is the environment's database (`status`, `engine`,
`error_code`, `error_message`), or null when it has none: the
database add-on when there is one, else the legacy managed
database. `database_status` is its `status`: `pending`,
`provisioning`, `ready`, `failed`, `deleting` or `deleted`. Never a
host, user, database name or password.
The description explains the capability, when to use it, and what to expect.
Inputs95/100
Input documentation gives an agent enough context to populate the arguments.
app_id
The app uuid returned by `apps_list`.
Clear enough to supply this argument.
organization_id
An organisation uuid or slug. When supplied, `app_id` is resolved within that organisation and may be a slug instead of a uuid, mirroring the Meridian web app.
Clear enough to supply this argument.
Annotations75/100
Declare idempotentHint based on the tool’s actual behavior.
No output schema is declared. Add one for structured results so clients can interpret returned fields.
Not declared
Original tool metadata
{
"name": "environments_list",
"title": "List Environments",
"description": "Lists an app's deploy-plane environments (development/staging/\nproduction): each environment's `environment_id`, `type`, `region`,\n`base_url`, `healthcheck_path`, Cloud Run scaling configuration\n(`cpu`, `memory`, `min_instances`, `max_instances`, `concurrency`,\n`timeout_seconds`), `config_pending_deploy` (true when settings changed\nthat only reach the app with the next deploy) with `config_changed_at`,\n`database_status`, and when the managed database\nfailed to provision, sanitised `database_error_code` /\n`database_error_message`. Takes the `app_id` returned by `apps_list`.\nUse the returned `environment_id` with `deployments_list`,\n`logs_tail`, or `deployment_create`.\n\n`base_url` is where the environment answers once deployed (the same as\n`public_url`), null until the first runtime deploy. `public_url` is\n`https://` + `platform_hostname`, the Meridian hostname. `domains`\nlists the\nplatform domain (`kind: \"platform\"`, `status` `active`,\n`not_deployed` or `disabled` while hosting is off), then each custom\ndomain (`kind: \"custom\"`) with its `status` (`pending_dns`,\n`provisioning`, `active`, `failed`, `deleting`), certificate state\n`tls` (`active`, `provisioning`, `failed`, or null when Meridian\nholds none), `dns_all_verified`, the `dns_records` to add,\n`certificate_expires_at`, `ownership_expires_at` and\n`error_message`.\n\n`database` is the environment's database (`status`, `engine`,\n`error_code`, `error_message`), or null when it has none: the\ndatabase add-on when there is one, else the legacy managed\ndatabase. `database_status` is its `status`: `pending`,\n`provisioning`, `ready`, `failed`, `deleting` or `deleted`. Never a\nhost, user, database name or password.",
"inputSchema": {
"type": "object",
"required": [
"app_id"
],
"properties": {
"app_id": {
"type": "string",
"description": "The app uuid returned by `apps_list`."
},
"organization_id": {
"type": "string",
"description": "An organisation uuid or slug. When supplied, `app_id` is resolved within that organisation and may be a slug instead of a uuid, mirroring the Meridian web app."
}
}
},
"annotations": {
"readOnlyHint": true,
"openWorldHint": false,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description97/100
Checks whether an app is ready to deploy and run, in one call: the
Shopify client ID and secret (`SHOPIFY_API_KEY` / `SHOPIFY_API_SECRET`),
the Shopify Partner connection, the GitHub repository and its
Dockerfile, Plan Builder plans, whether Plan Builder billing has the
client secret it reads (only the one saved under Meridian SDK, never a
`SHOPIFY_API_SECRET` variable), and for the environment: its managed
database, Prisma session storage, Prisma migrations without a release
command, the variables a Shopify app reads at boot, `SCOPES` against
the access scopes of the repository's `shopify.app.toml` at the
commit, and its custom domains.
Returns `ready` (false when any check fails), a `summary` count, and
`checks`: each with `key`, `status` (`pass`, `warn`, `fail`), `code`
(the problem, such as `missing_shopify_client_secret`; null on a pass),
`message`, and `fix` (`location` in the Meridian dashboard and its
`url`). A `fail` is what makes a deploy fail in seconds, before its
build; a `warn` deploys but the app is likely to misbehave. The one
`fail` a deploy does not stop on is `shopify_billing`: merchants cannot
subscribe, but the app boots, so the deploy logs it as a warning.
Run it before `deployment_create`, and after a deployment failed with
`error_code` `invalid_config`. Takes the `app_id` from `apps_list` and
an optional `environment_id` from `environments_list` (default: the
production environment; an app with no environment yet gets the
app-level checks only). Values are never returned.
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.
app_id
The app uuid returned by `apps_list`.
Clear enough to supply this argument.
organization_id
An organisation uuid or slug. When supplied, `app_id` is resolved within that organisation and may be a slug instead of a uuid, mirroring the Meridian web app.
Clear enough to supply this argument.
environment_id
The environment to check, from `environments_list`. Defaults to the production environment.
Clear enough to supply this argument.
Annotations75/100
Declare idempotentHint based on the tool’s actual behavior.
No output schema is declared. Add one for structured results so clients can interpret returned fields.
Not declared
Original tool metadata
{
"name": "app_readiness_get",
"title": "Check App Readiness",
"description": "Checks whether an app is ready to deploy and run, in one call: the\nShopify client ID and secret (`SHOPIFY_API_KEY` / `SHOPIFY_API_SECRET`),\nthe Shopify Partner connection, the GitHub repository and its\nDockerfile, Plan Builder plans, whether Plan Builder billing has the\nclient secret it reads (only the one saved under Meridian SDK, never a\n`SHOPIFY_API_SECRET` variable), and for the environment: its managed\ndatabase, Prisma session storage, Prisma migrations without a release\ncommand, the variables a Shopify app reads at boot, `SCOPES` against\nthe access scopes of the repository's `shopify.app.toml` at the\ncommit, and its custom domains.\n\nReturns `ready` (false when any check fails), a `summary` count, and\n`checks`: each with `key`, `status` (`pass`, `warn`, `fail`), `code`\n(the problem, such as `missing_shopify_client_secret`; null on a pass),\n`message`, and `fix` (`location` in the Meridian dashboard and its\n`url`). A `fail` is what makes a deploy fail in seconds, before its\nbuild; a `warn` deploys but the app is likely to misbehave. The one\n`fail` a deploy does not stop on is `shopify_billing`: merchants cannot\nsubscribe, but the app boots, so the deploy logs it as a warning.\n\nRun it before `deployment_create`, and after a deployment failed with\n`error_code` `invalid_config`. Takes the `app_id` from `apps_list` and\nan optional `environment_id` from `environments_list` (default: the\nproduction environment; an app with no environment yet gets the\napp-level checks only). Values are never returned.",
"inputSchema": {
"type": "object",
"required": [
"app_id"
],
"properties": {
"app_id": {
"type": "string",
"description": "The app uuid returned by `apps_list`."
},
"environment_id": {
"type": "string",
"description": "The environment to check, from `environments_list`. Defaults to the production environment."
},
"organization_id": {
"type": "string",
"description": "An organisation uuid or slug. When supplied, `app_id` is resolved within that organisation and may be a slug instead of a uuid, mirroring the Meridian web app."
}
}
},
"annotations": {
"readOnlyHint": true,
"openWorldHint": false,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description98/100
Lists the environment variables Meridian itself injects into an
environment's runtime at deploy time: `SHOPIFY_API_KEY`,
`SHOPIFY_API_SECRET`, `SHOPIFY_APP_URL` (the environment's Meridian
address), `SCOPES` (the access scopes of the repository's
`shopify.app.toml`), the `MERIDIAN_*` platform identifiers, and the
managed database `DB_*` set. These are NOT in the app's repository and
NOT returned by `secrets_list`, but they are readable from the process
environment at runtime, so read this before writing code that reads a
variable or before adding one the platform already provides.
Each entry has `name`, `secret` (true when the value is mounted from
Secret Manager), `source` (`sdk_credentials`, `platform`, `database`,
or `shopify_app_config` for `SCOPES`), `source_file` (for
`shopify_app_config`, the configuration file the value is read from:
the root `shopify.app*.toml` whose `client_id` is the environment's
client ID, else `shopify.app.toml`; null for the other sources), and
the two directions a name collision with a declared
variable can resolve in: `overridden`: the app's own variable wins and
the injected one is skipped; `shadows_user_variable`: this one is
injected unconditionally and the app's variable of that name never
reaches the runtime, so setting it has no effect (the `MERIDIAN_*`
identifiers). `override_value` says, for an `overridden` entry,
whether the app's variable holds the same value as the managed one
(`same`, `different`, or `unknown` when the values cannot be
compared), and is null when nothing overrides the entry. Only the
Shopify pair and `NODE_ENV` are compared, reading two secrets at most,
the Shopify pair first. Remove an override with `secrets_unset`.
VALUES ARE NEVER RETURNED, for managed or declared variables alike;
read them in the Meridian dashboard. Only variables whose injection
conditions currently hold are listed, so an environment with no
database reports no `DB_*` entries, and `SCOPES` is listed only when
the configuration file on the default branch declares scopes (a
deploy reads it at the deployed commit).
Takes the `app_id` from `apps_list` and the `environment_id` from
`environments_list`.
The description explains the capability, when to use it, and what to expect.
Inputs93/100
Input documentation gives an agent enough context to populate the arguments.
app_id
The app uuid returned by `apps_list`.
Clear enough to supply this argument.
organization_id
An organisation uuid or slug. When supplied, `app_id` is resolved within that organisation and may be a slug instead of a uuid, mirroring the Meridian web app.
Clear enough to supply this argument.
environment_id
The environment to inspect, from `environments_list`.
Clear enough to supply this argument.
Annotations75/100
Declare idempotentHint based on the tool’s actual behavior.
No output schema is declared. Add one for structured results so clients can interpret returned fields.
Not declared
Original tool metadata
{
"name": "managed_variables_list",
"title": "List Managed Environment Variables",
"description": "Lists the environment variables Meridian itself injects into an\nenvironment's runtime at deploy time: `SHOPIFY_API_KEY`,\n`SHOPIFY_API_SECRET`, `SHOPIFY_APP_URL` (the environment's Meridian\naddress), `SCOPES` (the access scopes of the repository's\n`shopify.app.toml`), the `MERIDIAN_*` platform identifiers, and the\nmanaged database `DB_*` set. These are NOT in the app's repository and\nNOT returned by `secrets_list`, but they are readable from the process\nenvironment at runtime, so read this before writing code that reads a\nvariable or before adding one the platform already provides.\n\nEach entry has `name`, `secret` (true when the value is mounted from\nSecret Manager), `source` (`sdk_credentials`, `platform`, `database`,\nor `shopify_app_config` for `SCOPES`), `source_file` (for\n`shopify_app_config`, the configuration file the value is read from:\nthe root `shopify.app*.toml` whose `client_id` is the environment's\nclient ID, else `shopify.app.toml`; null for the other sources), and\nthe two directions a name collision with a declared\nvariable can resolve in: `overridden`: the app's own variable wins and\nthe injected one is skipped; `shadows_user_variable`: this one is\ninjected unconditionally and the app's variable of that name never\nreaches the runtime, so setting it has no effect (the `MERIDIAN_*`\nidentifiers). `override_value` says, for an `overridden` entry,\nwhether the app's variable holds the same value as the managed one\n(`same`, `different`, or `unknown` when the values cannot be\ncompared), and is null when nothing overrides the entry. Only the\nShopify pair and `NODE_ENV` are compared, reading two secrets at most,\nthe Shopify pair first. Remove an override with `secrets_unset`.\n\nVALUES ARE NEVER RETURNED, for managed or declared variables alike;\nread them in the Meridian dashboard. Only variables whose injection\nconditions currently hold are listed, so an environment with no\ndatabase reports no `DB_*` entries, and `SCOPES` is listed only when\nthe configuration file on the default branch declares scopes (a\ndeploy reads it at the deployed commit).\n\nTakes the `app_id` from `apps_list` and the `environment_id` from\n`environments_list`.",
"inputSchema": {
"type": "object",
"required": [
"app_id",
"environment_id"
],
"properties": {
"app_id": {
"type": "string",
"description": "The app uuid returned by `apps_list`."
},
"environment_id": {
"type": "string",
"description": "The environment to inspect, from `environments_list`."
},
"organization_id": {
"type": "string",
"description": "An organisation uuid or slug. When supplied, `app_id` is resolved within that organisation and may be a slug instead of a uuid, mirroring the Meridian web app."
}
}
},
"annotations": {
"readOnlyHint": true,
"openWorldHint": false,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description98/100
Lists the branches and recent commits of the GitHub repository
connected to an app, as Meridian sees them. Use this to get a real
`git_sha` for `deployment_create` instead of guessing one: a sha that
has not been pushed to the connected repository will fail during the
build rather than at the tool call.
Returns `repository` (`owner/name` plus `connected`), `branches` (each
with `name`, `commit_sha`, `protected`) and `commits` (each with `sha`,
`message`, `author`, `date`).
Pass `branch` to list commits from a specific branch; the repository's
default branch is used otherwise. An app with no connected repository
reports `connected: false` with empty lists rather than an error, as do
an empty repository and an unknown branch.
Takes the `app_id` from `apps_list`. Requires the `hosting.view`
permission on the app, like `environments_list`.
The description explains the capability, when to use it, and what to expect.
Inputs94/100
Input documentation gives an agent enough context to populate the arguments.
app_id
The app uuid returned by `apps_list`.
Clear enough to supply this argument.
organization_id
An organisation uuid or slug. When supplied, `app_id` is resolved within that organisation and may be a slug instead of a uuid, mirroring the Meridian web app.
Clear enough to supply this argument.
branch
List commits from this branch. Defaults to the repository default branch.
Clear enough to supply this argument.
Annotations75/100
Declare idempotentHint based on the tool’s actual behavior.
No output schema is declared. Add one for structured results so clients can interpret returned fields.
Not declared
Original tool metadata
{
"name": "github_refs_list",
"title": "List Repository Branches and Commits",
"description": "Lists the branches and recent commits of the GitHub repository\nconnected to an app, as Meridian sees them. Use this to get a real\n`git_sha` for `deployment_create` instead of guessing one: a sha that\nhas not been pushed to the connected repository will fail during the\nbuild rather than at the tool call.\n\nReturns `repository` (`owner/name` plus `connected`), `branches` (each\nwith `name`, `commit_sha`, `protected`) and `commits` (each with `sha`,\n`message`, `author`, `date`).\n\nPass `branch` to list commits from a specific branch; the repository's\ndefault branch is used otherwise. An app with no connected repository\nreports `connected: false` with empty lists rather than an error, as do\nan empty repository and an unknown branch.\n\nTakes the `app_id` from `apps_list`. Requires the `hosting.view`\npermission on the app, like `environments_list`.",
"inputSchema": {
"type": "object",
"required": [
"app_id"
],
"properties": {
"app_id": {
"type": "string",
"description": "The app uuid returned by `apps_list`."
},
"branch": {
"type": "string",
"description": "List commits from this branch. Defaults to the repository default branch."
},
"organization_id": {
"type": "string",
"description": "An organisation uuid or slug. When supplied, `app_id` is resolved within that organisation and may be a slug instead of a uuid, mirroring the Meridian web app."
}
}
},
"annotations": {
"readOnlyHint": true,
"openWorldHint": true,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description97/100
Lists an app's recent deployments with status and timing:
`deployment_id`, `environment_id`, `trigger`, `git_sha`, `git_ref`,
`pr_number`, `status`, `current_step`, `build_step` (`built`,
`reused` when an existing image was deployed: a redeploy of an
already-built commit or a promote, `none` for a rollback, null until a
build starts), `error_code` and
`error_message` (only present for a failed deployment),
`started_at`/`finished_at`, and the
`deployer` who triggered it (`user_id`/`name`/`email`; null for
GitHub-push deploys). Takes the `app_id` returned by `apps_list`.
Optionally scope to one `environment_id` (from `environments_list`),
filter by `status`, and cap the result with `limit` (default 20,
maximum 100). Use `deployment_get` for a single deployment's full
detail, events, and log URLs.
The description explains the capability, when to use it, and what to expect.
Inputs89/100
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
app_id
The app uuid returned by `apps_list`.
Clear enough to supply this argument.
organization_id
An organisation uuid or slug. When supplied, `app_id` is resolved within that organisation and may be a slug instead of a uuid, mirroring the Meridian web app.
Clear enough to supply this argument.
environment_id
Scope to a single environment uuid returned by `environments_list`. Omitted: deployments across every environment for the app.
Clear enough to supply this argument.
status
Filter to a single status: queued, building, deploying, verifying, succeeded, failed, cancelled.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
limit
Maximum number of deployments to return. Default 20, maximum 100.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
Annotations75/100
Declare idempotentHint based on the tool’s actual behavior.
No output schema is declared. Add one for structured results so clients can interpret returned fields.
Not declared
Original tool metadata
{
"name": "deployments_list",
"title": "List Deployments",
"description": "Lists an app's recent deployments with status and timing:\n`deployment_id`, `environment_id`, `trigger`, `git_sha`, `git_ref`,\n`pr_number`, `status`, `current_step`, `build_step` (`built`,\n`reused` when an existing image was deployed: a redeploy of an\nalready-built commit or a promote, `none` for a rollback, null until a\nbuild starts), `error_code` and\n`error_message` (only present for a failed deployment),\n`started_at`/`finished_at`, and the\n`deployer` who triggered it (`user_id`/`name`/`email`; null for\nGitHub-push deploys). Takes the `app_id` returned by `apps_list`.\nOptionally scope to one `environment_id` (from `environments_list`),\nfilter by `status`, and cap the result with `limit` (default 20,\nmaximum 100). Use `deployment_get` for a single deployment's full\ndetail, events, and log URLs.",
"inputSchema": {
"type": "object",
"required": [
"app_id"
],
"properties": {
"limit": {
"type": "integer",
"description": "Maximum number of deployments to return. Default 20, maximum 100."
},
"app_id": {
"type": "string",
"description": "The app uuid returned by `apps_list`."
},
"status": {
"type": "string",
"description": "Filter to a single status: queued, building, deploying, verifying, succeeded, failed, cancelled."
},
"environment_id": {
"type": "string",
"description": "Scope to a single environment uuid returned by `environments_list`. Omitted: deployments across every environment for the app."
},
"organization_id": {
"type": "string",
"description": "An organisation uuid or slug. When supplied, `app_id` is resolved within that organisation and may be a slug instead of a uuid, mirroring the Meridian web app."
}
}
},
"annotations": {
"readOnlyHint": true,
"openWorldHint": false,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description99/100
Returns a single deployment's detail: the same fields as
`deployments_list`, plus `finished`, `steps`, recent `events` and the
`build_logs_url`/`runtime_logs_url` GCP Console deep links. Takes the
`app_id` returned by `apps_list` and the `deployment_id` returned by
`deployments_list`/`deployment_create`/`deployment_rollback`.
To follow a deploy to its end, pass `wait_until: "finished"`: the call
waits up to 50 seconds for the deployment to finish, then returns its
current state. `finished` is true once the status is terminal
(`succeeded`, `failed`, `cancelled`) and a failure's `error_message`
is final; while it is false, call again with `wait_until: "finished"`.
Do not sleep between calls. `waited_seconds` says how long this call
waited. `error_message_pending` is true while a failed deployment's
reason is still waiting for the container's own output.
`steps` lists the phases `queued`, `build`, `deploy`, `verify`, each
with `status` (`pending`, `running`, `succeeded`, `failed`,
`skipped`, `cancelled`), `started_at`, `finished_at`,
`duration_seconds` and `detail` (the Dockerfile instruction the build
ran last, or the phase's latest event).
`events` are orchestration steps and build/release/container log
lines, each with `type`, `level`, `message`, `created_at`. They come
newest first by default (`order: "desc"`) and `limit` keeps the latest
ones (default 100, maximum 1000); `order: "asc"` returns the oldest
first. Build boilerplate (git checkout advice, Docker credential
warnings, BuildKit's builder dump and layer progress, npm update
notices) is left out and counted in `boilerplate_filtered`; pass
`include_noise: true` to get every line.
The description explains the capability, when to use it, and what to expect.
Inputs89/100
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
app_id
The app uuid returned by `apps_list`.
Clear enough to supply this argument.
organization_id
An organisation uuid or slug. When supplied, `app_id` is resolved within that organisation and may be a slug instead of a uuid, mirroring the Meridian web app.
Clear enough to supply this argument.
deployment_id
The deployment uuid returned by `deployments_list`.
Clear enough to supply this argument.
wait_until
`finished`: wait up to 50 seconds for the deployment to finish before answering. Omitted: answer at once.
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": "deployment_get",
"title": "Get Deployment",
"description": "Returns a single deployment's detail: the same fields as\n`deployments_list`, plus `finished`, `steps`, recent `events` and the\n`build_logs_url`/`runtime_logs_url` GCP Console deep links. Takes the\n`app_id` returned by `apps_list` and the `deployment_id` returned by\n`deployments_list`/`deployment_create`/`deployment_rollback`.\n\nTo follow a deploy to its end, pass `wait_until: \"finished\"`: the call\nwaits up to 50 seconds for the deployment to finish, then returns its\ncurrent state. `finished` is true once the status is terminal\n(`succeeded`, `failed`, `cancelled`) and a failure's `error_message`\nis final; while it is false, call again with `wait_until: \"finished\"`.\nDo not sleep between calls. `waited_seconds` says how long this call\nwaited. `error_message_pending` is true while a failed deployment's\nreason is still waiting for the container's own output.\n\n`steps` lists the phases `queued`, `build`, `deploy`, `verify`, each\nwith `status` (`pending`, `running`, `succeeded`, `failed`,\n`skipped`, `cancelled`), `started_at`, `finished_at`,\n`duration_seconds` and `detail` (the Dockerfile instruction the build\nran last, or the phase's latest event).\n\n`events` are orchestration steps and build/release/container log\nlines, each with `type`, `level`, `message`, `created_at`. They come\nnewest first by default (`order: \"desc\"`) and `limit` keeps the latest\nones (default 100, maximum 1000); `order: \"asc\"` returns the oldest\nfirst. Build boilerplate (git checkout advice, Docker credential\nwarnings, BuildKit's builder dump and layer progress, npm update\nnotices) is left out and counted in `boilerplate_filtered`; pass\n`include_noise: true` to get every line.",
"inputSchema": {
"type": "object",
"required": [
"app_id",
"deployment_id"
],
"properties": {
"limit": {
"type": "integer",
"description": "Maximum number of log events to return. Default 100, maximum 1000."
},
"order": {
"enum": [
"desc",
"asc"
],
"type": "string",
"description": "`desc` (default): newest events first, `limit` keeps the latest. `asc`: oldest first."
},
"app_id": {
"type": "string",
"description": "The app uuid returned by `apps_list`."
},
"wait_until": {
"enum": [
"finished"
],
"type": "string",
"description": "`finished`: wait up to 50 seconds for the deployment to finish before answering. Omitted: answer at once."
},
"deployment_id": {
"type": "string",
"description": "The deployment uuid returned by `deployments_list`."
},
"include_noise": {
"type": "boolean",
"description": "Return build boilerplate lines too. Default false."
},
"organization_id": {
"type": "string",
"description": "An organisation uuid or slug. When supplied, `app_id` is resolved within that organisation and may be a slug instead of a uuid, mirroring the Meridian web app."
}
}
},
"annotations": {
"readOnlyHint": true,
"openWorldHint": false,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description96/100
Returns recent runtime logs (container stdout/stderr and HTTP
request logs) for a single environment's live Cloud Run service.
Takes the `app_id` returned by `apps_list` and the `environment_id`
returned by `environments_list`.
Optional `limit` caps the number of lines returned (default 100,
maximum 500). Optional `since` / `until` (ISO 8601) set the time
window; `since` defaults to the last 10 minutes, and omitting
`until` leaves the upper bound open (no `timestamp<=` clause). A
timestamp without an offset is read as UTC. The response echoes the
resolved `since` / `until` in UTC, with `server_time`, the server's
current time in UTC, so you know the window that was actually
queried. A `since` more than 5 minutes after `server_time` is
refused, because it could only return nothing: check the offset. When
the environment was never deployed (`base_url` null in
`environments_list`), the response carries a `note` saying it has no
runtime, so no logs.
Optional `deployment_id` (from `deployments_list`) scopes the tail
to that deployment's Cloud Run revision. Without it, the tail is
service-wide and can include output from a previously live revision
on the same service. The response echoes `deployment_id` when the
result was revision-scoped.
Optional `min_severity` (`DEBUG`/`INFO`/`NOTICE`/`WARNING`/`ERROR`/
`CRITICAL`/`ALERT`/`EMERGENCY`, case-insensitive) is a floor, not
an exact match. HTTP request logs are mostly `INFO`, so a floor of
`WARNING` or above effectively narrows the result to container
output plus failed requests.
Optional `contains` (max 200 characters) is a server-side substring
match against log message text and request URLs, filtered in Cloud
Logging before `limit` truncation, so a match outside the most
recent N lines is not silently lost. Log content is whatever the
app itself writes to stdout/stderr.
Optional `source` picks what is tailed: `web` (the default, the
environment's web server), `worker` (the Worker add-on's background
process), or `all` (both, merged by timestamp). With `all` each line
carries its own `source`. An environment without the Worker add-on
has no worker output. With `deployment_id`, `worker` and `all` read
that deployment's worker version, and a deployment that never
deployed a worker returns no worker lines.
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.
app_id
The app uuid returned by `apps_list`.
Clear enough to supply this argument.
organization_id
An organisation uuid or slug. When supplied, `app_id` is resolved within that organisation and may be a slug instead of a uuid, mirroring the Meridian web app.
Clear enough to supply this argument.
environment_id
The environment uuid returned by `environments_list`.
Clear enough to supply this argument.
limit
Maximum number of log lines to return. Default 100, maximum 500.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
since
ISO 8601 timestamp, read as UTC without an offset. Only return lines at or after this time. Defaults to the last 10 minutes. Refused when more than 5 minutes after the server time.
Clear enough to supply this argument.
until
ISO 8601 timestamp, read as UTC without an offset. Only return lines at or before this time. Omitted: no upper bound.
Clear enough to supply this argument.
deployment_id
Scope to one deployment's Cloud Run revision (uuid from `deployments_list`). Omitted: service-wide, which can include a previously live revision.
No output schema is declared. Add one for structured results so clients can interpret returned fields.
Not declared
Original tool metadata
{
"name": "logs_tail",
"title": "Tail Logs",
"description": "Returns recent runtime logs (container stdout/stderr and HTTP\nrequest logs) for a single environment's live Cloud Run service.\nTakes the `app_id` returned by `apps_list` and the `environment_id`\nreturned by `environments_list`.\n\nOptional `limit` caps the number of lines returned (default 100,\nmaximum 500). Optional `since` / `until` (ISO 8601) set the time\nwindow; `since` defaults to the last 10 minutes, and omitting\n`until` leaves the upper bound open (no `timestamp<=` clause). A\ntimestamp without an offset is read as UTC. The response echoes the\nresolved `since` / `until` in UTC, with `server_time`, the server's\ncurrent time in UTC, so you know the window that was actually\nqueried. A `since` more than 5 minutes after `server_time` is\nrefused, because it could only return nothing: check the offset. When\nthe environment was never deployed (`base_url` null in\n`environments_list`), the response carries a `note` saying it has no\nruntime, so no logs.\n\nOptional `deployment_id` (from `deployments_list`) scopes the tail\nto that deployment's Cloud Run revision. Without it, the tail is\nservice-wide and can include output from a previously live revision\non the same service. The response echoes `deployment_id` when the\nresult was revision-scoped.\n\nOptional `min_severity` (`DEBUG`/`INFO`/`NOTICE`/`WARNING`/`ERROR`/\n`CRITICAL`/`ALERT`/`EMERGENCY`, case-insensitive) is a floor, not\nan exact match. HTTP request logs are mostly `INFO`, so a floor of\n`WARNING` or above effectively narrows the result to container\noutput plus failed requests.\n\nOptional `contains` (max 200 characters) is a server-side substring\nmatch against log message text and request URLs, filtered in Cloud\nLogging before `limit` truncation, so a match outside the most\nrecent N lines is not silently lost. Log content is whatever the\napp itself writes to stdout/stderr.\n\nOptional `source` picks what is tailed: `web` (the default, the\nenvironment's web server), `worker` (the Worker add-on's background\nprocess), or `all` (both, merged by timestamp). With `all` each line\ncarries its own `source`. An environment without the Worker add-on\nhas no worker output. With `deployment_id`, `worker` and `all` read\nthat deployment's worker version, and a deployment that never\ndeployed a worker returns no worker lines.",
"inputSchema": {
"type": "object",
"required": [
"app_id",
"environment_id"
],
"properties": {
"limit": {
"type": "integer",
"description": "Maximum number of log lines to return. Default 100, maximum 500."
},
"since": {
"type": "string",
"description": "ISO 8601 timestamp, read as UTC without an offset. Only return lines at or after this time. Defaults to the last 10 minutes. Refused when more than 5 minutes after the server time."
},
"until": {
"type": "string",
"description": "ISO 8601 timestamp, read as UTC without an offset. Only return lines at or before this time. Omitted: no upper bound."
},
"app_id": {
"type": "string",
"description": "The app uuid returned by `apps_list`."
},
"source": {
"enum": [
"web",
"worker",
"all"
],
"type": "string",
"description": "What to tail: web (default, the web server), worker (the Worker add-on), or all (both, merged by timestamp)."
},
"contains": {
"type": "string",
"description": "Substring to match in log message text or request URL (max 200 characters). Matched server-side before limit truncation."
},
"min_severity": {
"type": "string",
"description": "Severity floor: DEBUG, INFO, NOTICE, WARNING, ERROR, CRITICAL, ALERT, or EMERGENCY (case-insensitive)."
},
"deployment_id": {
"type": "string",
"description": "Scope to one deployment's Cloud Run revision (uuid from `deployments_list`). Omitted: service-wide, which can include a previously live revision."
},
"environment_id": {
"type": "string",
"description": "The environment uuid returned by `environments_list`."
},
"organization_id": {
"type": "string",
"description": "An organisation uuid or slug. When supplied, `app_id` is resolved within that organisation and may be a slug instead of a uuid, mirroring the Meridian web app."
}
}
},
"annotations": {
"readOnlyHint": true,
"openWorldHint": false,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description99/100
Lists the metadata for an app's secrets and plain environment
variables: `secret_id`, `scope` (`app`/`env`), `key`, `is_secret`,
`inherited`, `overridden_by_environment`, `created_by`,
`created_at`, `updated_at`. NEVER includes a value. This is a
metadata-only listing, identical in spirit to what the `secrets`
dashboard table shows before you reveal one. Takes the `app_id`
returned by `apps_list`.
Without `environment_id`, it lists the app-level entries, which
every environment inherits (`inherited: false`,
`overridden_by_environment: null`). Pass `environment_id` (from
`environments_list`) for what that environment really gets: its own
entries plus every app-level entry, marked `inherited: true`. An
app-level entry whose key the environment sets too stays listed,
with `overridden_by_environment: true`: the environment's entry wins
at deploy. Those entries are sorted by key, so an override sits next
to what it replaces, and `count` counts every entry.
The variables Meridian itself injects at deploy are not here: call
`managed_variables_list` for that other half.
The description explains the capability, when to use it, and what to expect.
Inputs95/100
Input documentation gives an agent enough context to populate the arguments.
app_id
The app uuid returned by `apps_list`.
Clear enough to supply this argument.
organization_id
An organisation uuid or slug. When supplied, `app_id` is resolved within that organisation and may be a slug instead of a uuid, mirroring the Meridian web app.
Clear enough to supply this argument.
environment_id
List what this environment gets: its own entries plus the app-level ones it inherits. Uuid returned by `environments_list`.
Clear enough to supply this argument.
Annotations75/100
Declare idempotentHint based on the tool’s actual behavior.
No output schema is declared. Add one for structured results so clients can interpret returned fields.
Not declared
Original tool metadata
{
"name": "secrets_list",
"title": "List Secrets",
"description": "Lists the metadata for an app's secrets and plain environment\nvariables: `secret_id`, `scope` (`app`/`env`), `key`, `is_secret`,\n`inherited`, `overridden_by_environment`, `created_by`,\n`created_at`, `updated_at`. NEVER includes a value. This is a\nmetadata-only listing, identical in spirit to what the `secrets`\ndashboard table shows before you reveal one. Takes the `app_id`\nreturned by `apps_list`.\n\nWithout `environment_id`, it lists the app-level entries, which\nevery environment inherits (`inherited: false`,\n`overridden_by_environment: null`). Pass `environment_id` (from\n`environments_list`) for what that environment really gets: its own\nentries plus every app-level entry, marked `inherited: true`. An\napp-level entry whose key the environment sets too stays listed,\nwith `overridden_by_environment: true`: the environment's entry wins\nat deploy. Those entries are sorted by key, so an override sits next\nto what it replaces, and `count` counts every entry.\n\nThe variables Meridian itself injects at deploy are not here: call\n`managed_variables_list` for that other half.",
"inputSchema": {
"type": "object",
"required": [
"app_id"
],
"properties": {
"app_id": {
"type": "string",
"description": "The app uuid returned by `apps_list`."
},
"environment_id": {
"type": "string",
"description": "List what this environment gets: its own entries plus the app-level ones it inherits. Uuid returned by `environments_list`."
},
"organization_id": {
"type": "string",
"description": "An organisation uuid or slug. When supplied, `app_id` is resolved within that organisation and may be a slug instead of a uuid, mirroring the Meridian web app."
}
}
},
"annotations": {
"readOnlyHint": true,
"openWorldHint": false,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description97/100
Sets one environment variable or secret on an app, like adding or
editing it on the dashboard's Environment page. Creates the key, or
replaces its value when it already exists in that scope (`action`:
`created` or `updated`). Takes the `app_id` from `apps_list`.
`scope` is required: `app` sets the key for every environment
(development, staging and production), and `environment` sets it for
the one `environment_id` (from `environments_list`) only, where it
wins over an `app` entry of the same key.
`is_secret` defaults to true: the value goes to Secret Manager and can
never be read back. Pass `is_secret: false` for a plain variable,
which the dashboard shows. An existing key keeps its kind: changing
`is_secret` is refused, so call `secrets_unset`, then `secrets_set`.
Keys are uppercase (`^[A-Z][A-Z0-9_]*$`, up to 128 characters) and
normalized for you. The value is trimmed, non-empty, at most 8192
characters. Refused names: the `HOSTING_` prefix, and
`MERIDIAN_APP_ID`, `MERIDIAN_API_URL`, `MERIDIAN_OAUTH_CLIENT_ID`,
`MERIDIAN_OAUTH_CLIENT_SECRET`, which Meridian always sets itself.
A key that overrides a variable Meridian manages (the Shopify pair,
`NODE_ENV`, `MERIDIAN_API_KEY`, `DB_*`, the `REDIS_*` set of a ready
Redis add-on, ...) is accepted and listed in `overrides_managed`, one
entry per environment it overrides.
THE VALUE IS NEVER RETURNED. The change reaches the app at its next
deploy: `environments_list` reports `config_pending_deploy`.
The description explains the capability, when to use it, and what to expect.
Inputs89/100
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
app_id
The app uuid returned by `apps_list`.
Clear enough to supply this argument.
organization_id
An organisation uuid or slug. When supplied, `app_id` is resolved within that organisation and may be a slug instead of a uuid, mirroring the Meridian web app.
Clear enough to supply this argument.
key
The variable name, for example `SHOPIFY_APP_URL`. Uppercased and normalized.
Clear enough to supply this argument.
value
The value to set. Trimmed, never returned.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
is_secret
True (the default) for a secret kept in Secret Manager, false for a plain variable the dashboard shows.
Clear enough to supply this argument.
scope
`app` for every environment of the app, `environment` for `environment_id` only.
Clear enough to supply this argument.
environment_id
Required when `scope` is `environment`: the environment uuid from `environments_list`.
No output schema is declared. Add one for structured results so clients can interpret returned fields.
Not declared
Original tool metadata
{
"name": "secrets_set",
"title": "Set Environment Variable or Secret",
"description": "Sets one environment variable or secret on an app, like adding or\nediting it on the dashboard's Environment page. Creates the key, or\nreplaces its value when it already exists in that scope (`action`:\n`created` or `updated`). Takes the `app_id` from `apps_list`.\n\n`scope` is required: `app` sets the key for every environment\n(development, staging and production), and `environment` sets it for\nthe one `environment_id` (from `environments_list`) only, where it\nwins over an `app` entry of the same key.\n\n`is_secret` defaults to true: the value goes to Secret Manager and can\nnever be read back. Pass `is_secret: false` for a plain variable,\nwhich the dashboard shows. An existing key keeps its kind: changing\n`is_secret` is refused, so call `secrets_unset`, then `secrets_set`.\n\nKeys are uppercase (`^[A-Z][A-Z0-9_]*$`, up to 128 characters) and\nnormalized for you. The value is trimmed, non-empty, at most 8192\ncharacters. Refused names: the `HOSTING_` prefix, and\n`MERIDIAN_APP_ID`, `MERIDIAN_API_URL`, `MERIDIAN_OAUTH_CLIENT_ID`,\n`MERIDIAN_OAUTH_CLIENT_SECRET`, which Meridian always sets itself.\nA key that overrides a variable Meridian manages (the Shopify pair,\n`NODE_ENV`, `MERIDIAN_API_KEY`, `DB_*`, the `REDIS_*` set of a ready\nRedis add-on, ...) is accepted and listed in `overrides_managed`, one\nentry per environment it overrides.\n\nTHE VALUE IS NEVER RETURNED. The change reaches the app at its next\ndeploy: `environments_list` reports `config_pending_deploy`.",
"inputSchema": {
"type": "object",
"required": [
"app_id",
"key",
"value",
"scope"
],
"properties": {
"key": {
"type": "string",
"description": "The variable name, for example `SHOPIFY_APP_URL`. Uppercased and normalized."
},
"scope": {
"enum": [
"app",
"environment"
],
"type": "string",
"description": "`app` for every environment of the app, `environment` for `environment_id` only."
},
"value": {
"type": "string",
"description": "The value to set. Trimmed, never returned."
},
"app_id": {
"type": "string",
"description": "The app uuid returned by `apps_list`."
},
"is_secret": {
"type": "boolean",
"description": "True (the default) for a secret kept in Secret Manager, false for a plain variable the dashboard shows."
},
"environment_id": {
"type": "string",
"description": "Required when `scope` is `environment`: the environment uuid from `environments_list`."
},
"organization_id": {
"type": "string",
"description": "An organisation uuid or slug. When supplied, `app_id` is resolved within that organisation and may be a slug instead of a uuid, mirroring the Meridian web app."
}
}
},
"annotations": {
"readOnlyHint": false,
"openWorldHint": false,
"idempotentHint": true,
"destructiveHint": true
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description98/100
Deletes one environment variable or secret from an app, like deleting
it on the dashboard's Environment page. Takes the `app_id` from
`apps_list`, the `key`, and the `scope` it was set in: `app` for an
entry shared by every environment, `environment` with
`environment_id` for an entry of that environment only. Call
`secrets_list` (with `environment_id`) to see which scope a key
lives in.
A key that is not set in that scope answers `deleted: false` and
changes nothing. A key set for every environment cannot be deleted
through `scope: environment`: the call is refused and says so, and
nothing is deleted.
Removing an override: when the key overrides a variable Meridian
manages (`managed_variables_list` reports it `overridden`; the
variables of a ready add-on, such as `REDIS_HOST`, and the `DB_HOST`,
`DB_PORT` and `DB_SSL_CA` of a database reached over TCP count too),
deleting it gives that variable back to Meridian, and
`restores_managed` lists the environments where it happens. When
`override_value` is `same`, the app keeps the same value and the call
goes through. When it is `different` or `unknown` (always `unknown`
for an add-on or database transport variable), the app would run with
another value, so the call is refused until you pass `confirm: true`.
This holds when a key set for every environment takes over from the
deleted one too: `restores_managed` is then empty.
The change reaches the app at its next deploy: `environments_list`
reports `config_pending_deploy`.
The description explains the capability, when to use it, and what to expect.
Inputs94/100
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
app_id
The app uuid returned by `apps_list`.
Clear enough to supply this argument.
organization_id
An organisation uuid or slug. When supplied, `app_id` is resolved within that organisation and may be a slug instead of a uuid, mirroring the Meridian web app.
Clear enough to supply this argument.
key
The variable name to delete. Uppercased and normalized.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
scope
Where the key is set: `app` for every environment, `environment` for `environment_id` only.
Clear enough to supply this argument.
environment_id
Required when `scope` is `environment`: the environment uuid from `environments_list`.
Clear enough to supply this argument.
confirm
Pass `true` to delete a key that overrides a variable Meridian manages with a different (or uncomparable) value: the app then runs with another value from its next deploy.
No output schema is declared. Add one for structured results so clients can interpret returned fields.
Not declared
Original tool metadata
{
"name": "secrets_unset",
"title": "Unset Environment Variable or Secret",
"description": "Deletes one environment variable or secret from an app, like deleting\nit on the dashboard's Environment page. Takes the `app_id` from\n`apps_list`, the `key`, and the `scope` it was set in: `app` for an\nentry shared by every environment, `environment` with\n`environment_id` for an entry of that environment only. Call\n`secrets_list` (with `environment_id`) to see which scope a key\nlives in.\n\nA key that is not set in that scope answers `deleted: false` and\nchanges nothing. A key set for every environment cannot be deleted\nthrough `scope: environment`: the call is refused and says so, and\nnothing is deleted.\n\nRemoving an override: when the key overrides a variable Meridian\nmanages (`managed_variables_list` reports it `overridden`; the\nvariables of a ready add-on, such as `REDIS_HOST`, and the `DB_HOST`,\n`DB_PORT` and `DB_SSL_CA` of a database reached over TCP count too),\ndeleting it gives that variable back to Meridian, and\n`restores_managed` lists the environments where it happens. When\n`override_value` is `same`, the app keeps the same value and the call\ngoes through. When it is `different` or `unknown` (always `unknown`\nfor an add-on or database transport variable), the app would run with\nanother value, so the call is refused until you pass `confirm: true`.\nThis holds when a key set for every environment takes over from the\ndeleted one too: `restores_managed` is then empty.\n\nThe change reaches the app at its next deploy: `environments_list`\nreports `config_pending_deploy`.",
"inputSchema": {
"type": "object",
"required": [
"app_id",
"key",
"scope"
],
"properties": {
"key": {
"type": "string",
"description": "The variable name to delete. Uppercased and normalized."
},
"scope": {
"enum": [
"app",
"environment"
],
"type": "string",
"description": "Where the key is set: `app` for every environment, `environment` for `environment_id` only."
},
"app_id": {
"type": "string",
"description": "The app uuid returned by `apps_list`."
},
"confirm": {
"type": "boolean",
"description": "Pass `true` to delete a key that overrides a variable Meridian manages with a different (or uncomparable) value: the app then runs with another value from its next deploy."
},
"environment_id": {
"type": "string",
"description": "Required when `scope` is `environment`: the environment uuid from `environments_list`."
},
"organization_id": {
"type": "string",
"description": "An organisation uuid or slug. When supplied, `app_id` is resolved within that organisation and may be a slug instead of a uuid, mirroring the Meridian web app."
}
}
},
"annotations": {
"readOnlyHint": false,
"openWorldHint": false,
"idempotentHint": true,
"destructiveHint": true
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description98/100
Lists the pull-request preview deployments for an app, newest first:
each one's `pr_number`, `head_sha`, `base_url`, `status`,
sanitised `error_message` and `expires_at`.
Use it after pushing a branch or opening a pull request to find the
preview URL for that PR, and to check whether its build succeeded. A
preview with a failed status and an `error_message` is the fastest
signal that a change broke the build.
Optionally filter by `pr_number`. `limit` defaults to 20 and caps at
100. Previews expire, so an old PR may have no live preview.
Takes the `app_id` from `apps_list`.
The description explains the capability, when to use it, and what to expect.
Inputs93/100
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
app_id
The app uuid returned by `apps_list`.
Clear enough to supply this argument.
organization_id
An organisation uuid or slug. When supplied, `app_id` is resolved within that organisation and may be a slug instead of a uuid, mirroring the Meridian web app.
Clear enough to supply this argument.
pr_number
Only previews for this pull request number.
Clear enough to supply this argument.
limit
Maximum previews to return. Default 20, maximum 100.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
Annotations75/100
Declare idempotentHint based on the tool’s actual behavior.
No output schema is declared. Add one for structured results so clients can interpret returned fields.
Not declared
Original tool metadata
{
"name": "previews_list",
"title": "List PR Previews",
"description": "Lists the pull-request preview deployments for an app, newest first:\neach one's `pr_number`, `head_sha`, `base_url`, `status`,\nsanitised `error_message` and `expires_at`.\n\nUse it after pushing a branch or opening a pull request to find the\npreview URL for that PR, and to check whether its build succeeded. A\npreview with a failed status and an `error_message` is the fastest\nsignal that a change broke the build.\n\nOptionally filter by `pr_number`. `limit` defaults to 20 and caps at\n100. Previews expire, so an old PR may have no live preview.\n\nTakes the `app_id` from `apps_list`.",
"inputSchema": {
"type": "object",
"required": [
"app_id"
],
"properties": {
"limit": {
"type": "integer",
"description": "Maximum previews to return. Default 20, maximum 100."
},
"app_id": {
"type": "string",
"description": "The app uuid returned by `apps_list`."
},
"pr_number": {
"type": "integer",
"description": "Only previews for this pull request number."
},
"organization_id": {
"type": "string",
"description": "An organisation uuid or slug. When supplied, `app_id` is resolved within that organisation and may be a slug instead of a uuid, mirroring the Meridian web app."
}
}
},
"annotations": {
"readOnlyHint": true,
"openWorldHint": false,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description99/100
Current resource usage for an app's environment(s): CPU and memory
usage against configured limits, network bytes, and (for each
environment's database add-on) connection count, storage, average
query time, and backup size. Also returns `meters`: the app's
hosting/infrastructure metered usage for the CURRENT BILLING PERIOD
(bandwidth GB, autoscaling uptime hours, database storage MB) against
its plan limit.
UNITS: read these before interpreting a number: `cpu.utilization`
is a FRACTION 0 to 1 of `cpu.configured` (the configured vCPU count,
a free-form string like "1" or "2"), NOT a percentage and NOT an
absolute vCPU figure; multiply by 100 yourself for a percent, or
combine with `cpu.configured` if you need "42% of 2 vCPU" phrasing.
`memory` is the opposite: `used_mb`/`configured_mb` are both already
ABSOLUTE megabytes. `network.egress_bytes`/`ingress_bytes` are
bytes, but NOT a cumulative total and NOT necessarily fresh: the
collector sums these counters over a trailing ~30-minute WINDOW and
rewrites the row every ~2 minutes, so consecutive reads overlap
heavily (do not sum them to get a total), and when a window's true
sum is zero, the row keeps its PREVIOUS byte count while still
stamping a current `sampled_at`, so a quiet environment can look
like a fresh nonzero reading.
These are PERIODIC SAMPLES, not live reads. Meridian's collector
samples every ~2 minutes over a rolling ~30-minute window, so a
number can be up to a few minutes stale. `meters`, in contrast,
refresh on their OWN, SLOWER cadence: HOURLY, via the
`usage:sync-meters` schedule, so a meter value can lag the
environment snapshot by up to an hour; check each meter's own
`as_of` rather than assuming it is as fresh as the rest of the
payload. For trends over time (a chart, an alert on a rate of
change), use `resource_usage_history` instead.
Each `meters` entry: `limit: null` means UNLIMITED, `limit: 0` means
NO ALLOWANCE was granted at all (both distinct from a positive cap).
`unlimited` makes the null case explicit. `used: null` means the
meter has never been measured for this app (distinct from `0`,
measured-and-idle); `as_of` is the measurement timestamp, null
exactly when `used` is null. `remaining` is null when `unlimited` or
when `used` is null; otherwise `max(0, limit - used)`. `over_limit`
is always false when `unlimited` or unmeasured.
Takes the `app_id` returned by `apps_list`. Optionally scope to one
`environment_id` (from `environments_list`); omitted returns every
environment. An environment that has never deployed, or that the
collector has not sampled yet, is still returned, with
`sampled_at: null` and every usage field null, never dropped or
errored. `disk` usage is deliberately absent: Cloud Run has no
persistent disk, so the platform never has a number to report there.
The description explains the capability, when to use it, and what to expect.
Inputs92/100
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
app_id
The app uuid returned by `apps_list`.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
organization_id
An organisation uuid or slug. When supplied, `app_id` is resolved within that organisation and may be a slug instead of a uuid, mirroring the Meridian web app.
Clear enough to supply this argument.
environment_id
Scope to a single environment uuid returned by `environments_list`. Omitted: every environment of the app.
Clear enough to supply this argument.
Annotations75/100
Declare idempotentHint based on the tool’s actual behavior.
No output schema is declared. Add one for structured results so clients can interpret returned fields.
Not declared
Original tool metadata
{
"name": "resource_usage_get",
"title": "Get Resource Usage",
"description": "Current resource usage for an app's environment(s): CPU and memory\nusage against configured limits, network bytes, and (for each\nenvironment's database add-on) connection count, storage, average\nquery time, and backup size. Also returns `meters`: the app's\nhosting/infrastructure metered usage for the CURRENT BILLING PERIOD\n(bandwidth GB, autoscaling uptime hours, database storage MB) against\nits plan limit.\n\nUNITS: read these before interpreting a number: `cpu.utilization`\nis a FRACTION 0 to 1 of `cpu.configured` (the configured vCPU count,\na free-form string like \"1\" or \"2\"), NOT a percentage and NOT an\nabsolute vCPU figure; multiply by 100 yourself for a percent, or\ncombine with `cpu.configured` if you need \"42% of 2 vCPU\" phrasing.\n`memory` is the opposite: `used_mb`/`configured_mb` are both already\nABSOLUTE megabytes. `network.egress_bytes`/`ingress_bytes` are\nbytes, but NOT a cumulative total and NOT necessarily fresh: the\ncollector sums these counters over a trailing ~30-minute WINDOW and\nrewrites the row every ~2 minutes, so consecutive reads overlap\nheavily (do not sum them to get a total), and when a window's true\nsum is zero, the row keeps its PREVIOUS byte count while still\nstamping a current `sampled_at`, so a quiet environment can look\nlike a fresh nonzero reading.\n\nThese are PERIODIC SAMPLES, not live reads. Meridian's collector\nsamples every ~2 minutes over a rolling ~30-minute window, so a\nnumber can be up to a few minutes stale. `meters`, in contrast,\nrefresh on their OWN, SLOWER cadence: HOURLY, via the\n`usage:sync-meters` schedule, so a meter value can lag the\nenvironment snapshot by up to an hour; check each meter's own\n`as_of` rather than assuming it is as fresh as the rest of the\npayload. For trends over time (a chart, an alert on a rate of\nchange), use `resource_usage_history` instead.\n\nEach `meters` entry: `limit: null` means UNLIMITED, `limit: 0` means\nNO ALLOWANCE was granted at all (both distinct from a positive cap).\n`unlimited` makes the null case explicit. `used: null` means the\nmeter has never been measured for this app (distinct from `0`,\nmeasured-and-idle); `as_of` is the measurement timestamp, null\nexactly when `used` is null. `remaining` is null when `unlimited` or\nwhen `used` is null; otherwise `max(0, limit - used)`. `over_limit`\nis always false when `unlimited` or unmeasured.\n\nTakes the `app_id` returned by `apps_list`. Optionally scope to one\n`environment_id` (from `environments_list`); omitted returns every\nenvironment. An environment that has never deployed, or that the\ncollector has not sampled yet, is still returned, with\n`sampled_at: null` and every usage field null, never dropped or\nerrored. `disk` usage is deliberately absent: Cloud Run has no\npersistent disk, so the platform never has a number to report there.",
"inputSchema": {
"type": "object",
"required": [
"app_id"
],
"properties": {
"app_id": {
"type": "string",
"description": "The app uuid returned by `apps_list`."
},
"environment_id": {
"type": "string",
"description": "Scope to a single environment uuid returned by `environments_list`. Omitted: every environment of the app."
},
"organization_id": {
"type": "string",
"description": "An organisation uuid or slug. When supplied, `app_id` is resolved within that organisation and may be a slug instead of a uuid, mirroring the Meridian web app."
}
}
},
"annotations": {
"readOnlyHint": true,
"openWorldHint": false,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description99/100
Time-range resource-usage history for ONE environment (CPU, memory,
network/bandwidth, request throughput, latency percentiles, error
rate, and instance count), read live from Cloud Monitoring.
UNITS: read these before interpreting a number: `cpu` and `memory`
are FRACTIONS from 0 to 1 of the environment's configured limit (see
`limits`), NOT percentages and NOT absolute values. Multiply by
`limits.cpu`/`limits.memory_mb` to get an absolute vCPU/MB figure.
`network` values are BYTES per `step_seconds`-second bucket (not a
rate: divide by `step_seconds` for bytes/sec), and each bucket is
an independent Cloud Monitoring aggregation (not an overlapping
rolling window), so summing consecutive buckets is safe. `throughput`
is requests per second. `latency` percentiles (`p50`/`p95`/`p99`) are
in milliseconds. `errors.value` is 5xx requests per second and
`errors.rate` is a percentage of total throughput. `instances` is a
raw count. A null value in any series is a missing sample, not zero.
`summary` (min/avg/max/latest per metric, per percentile for latency,
per direction for network) is ALWAYS returned for every metric the
service came back with, regardless of `metrics` below, and is ALWAYS
computed from the FULL, un-downsampled series. Nulls are skipped
when computing it, and `max_points` below never affects it, so a
spike or a dip cannot be averaged away from `summary` even when
`series` is downsampled.
`series` (the raw time-stamped points) is returned ONLY for the
metrics named in `metrics`, which is OPTIONAL and defaults to EMPTY.
Omitting it (or passing `[]`) returns `summary` only. `summary`
already tells you whether a metric is worth asking for in `series`;
requesting raw points for one or more named metrics is always a
second, explicit call. Before downsampling, a raw series has roughly
60 points at `range=1h`, 288 at `24h`, and 168 at `7d`. Request
`metrics` sparingly at wider ranges.
`max_points` (default 60, minimum 10, maximum 500) bounds how many
points EACH requested series in `series` can return: a series longer
than `max_points` is downsampled into at most `max_points`
equal-width buckets, each bucket's fields AVERAGED across its points
(nulls skipped; a bucket that is all-null for a field stays null),
with each bucket's `t` taken from its first point. The response's
`downsampled` is true when this happened to any requested series,
and `effective_step_seconds` is then `step_seconds` multiplied by
the bucket width in raw points (null when nothing was downsampled).
Use it to label a chart's x-axis correctly.
Takes the `app_id` returned by `apps_list` and the REQUIRED
`environment_id` returned by `environments_list` (this data is
per Cloud Run service, so there is no "every environment" answer).
Optional `range`: `1h`, `24h` (default), or `7d`. For a
live-right-now snapshot instead of history, use `resource_usage_get`.
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.
app_id
The app uuid returned by `apps_list`.
Clear enough to supply this argument.
organization_id
An organisation uuid or slug. When supplied, `app_id` is resolved within that organisation and may be a slug instead of a uuid, mirroring the Meridian web app.
Clear enough to supply this argument.
environment_id
The environment uuid returned by `environments_list`. Required. This data is per Cloud Run service.
Clear enough to supply this argument.
range
Time window: `1h`, `24h`, or `7d`. Default `24h`.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
metrics
Which metrics to return raw `series` points for, subset of `cpu`, `memory`, `network`, `throughput`, `latency`, `errors`, `instances`. Default EMPTY: `summary` only. `summary` always covers every metric regardless of this filter.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
max_points
Maximum points per requested series in `series`; a longer series is downsampled (averaged into equal-width buckets). Default 60, minimum 10, maximum 500. Never affects `summary`, which always reflects the full series.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
Annotations75/100
Declare idempotentHint based on the tool’s actual behavior.
No output schema is declared. Add one for structured results so clients can interpret returned fields.
Not declared
Original tool metadata
{
"name": "resource_usage_history",
"title": "Get Resource Usage History",
"description": "Time-range resource-usage history for ONE environment (CPU, memory,\nnetwork/bandwidth, request throughput, latency percentiles, error\nrate, and instance count), read live from Cloud Monitoring.\n\nUNITS: read these before interpreting a number: `cpu` and `memory`\nare FRACTIONS from 0 to 1 of the environment's configured limit (see\n`limits`), NOT percentages and NOT absolute values. Multiply by\n`limits.cpu`/`limits.memory_mb` to get an absolute vCPU/MB figure.\n`network` values are BYTES per `step_seconds`-second bucket (not a\nrate: divide by `step_seconds` for bytes/sec), and each bucket is\nan independent Cloud Monitoring aggregation (not an overlapping\nrolling window), so summing consecutive buckets is safe. `throughput`\nis requests per second. `latency` percentiles (`p50`/`p95`/`p99`) are\nin milliseconds. `errors.value` is 5xx requests per second and\n`errors.rate` is a percentage of total throughput. `instances` is a\nraw count. A null value in any series is a missing sample, not zero.\n\n`summary` (min/avg/max/latest per metric, per percentile for latency,\nper direction for network) is ALWAYS returned for every metric the\nservice came back with, regardless of `metrics` below, and is ALWAYS\ncomputed from the FULL, un-downsampled series. Nulls are skipped\nwhen computing it, and `max_points` below never affects it, so a\nspike or a dip cannot be averaged away from `summary` even when\n`series` is downsampled.\n\n`series` (the raw time-stamped points) is returned ONLY for the\nmetrics named in `metrics`, which is OPTIONAL and defaults to EMPTY.\nOmitting it (or passing `[]`) returns `summary` only. `summary`\nalready tells you whether a metric is worth asking for in `series`;\nrequesting raw points for one or more named metrics is always a\nsecond, explicit call. Before downsampling, a raw series has roughly\n60 points at `range=1h`, 288 at `24h`, and 168 at `7d`. Request\n`metrics` sparingly at wider ranges.\n\n`max_points` (default 60, minimum 10, maximum 500) bounds how many\npoints EACH requested series in `series` can return: a series longer\nthan `max_points` is downsampled into at most `max_points`\nequal-width buckets, each bucket's fields AVERAGED across its points\n(nulls skipped; a bucket that is all-null for a field stays null),\nwith each bucket's `t` taken from its first point. The response's\n`downsampled` is true when this happened to any requested series,\nand `effective_step_seconds` is then `step_seconds` multiplied by\nthe bucket width in raw points (null when nothing was downsampled).\nUse it to label a chart's x-axis correctly.\n\nTakes the `app_id` returned by `apps_list` and the REQUIRED\n`environment_id` returned by `environments_list` (this data is\nper Cloud Run service, so there is no \"every environment\" answer).\nOptional `range`: `1h`, `24h` (default), or `7d`. For a\nlive-right-now snapshot instead of history, use `resource_usage_get`.",
"inputSchema": {
"type": "object",
"required": [
"app_id",
"environment_id"
],
"properties": {
"range": {
"enum": [
"1h",
"24h",
"7d"
],
"type": "string",
"description": "Time window: `1h`, `24h`, or `7d`. Default `24h`."
},
"app_id": {
"type": "string",
"description": "The app uuid returned by `apps_list`."
},
"metrics": {
"type": "array",
"items": {
"enum": [
"cpu",
"memory",
"network",
"throughput",
"latency",
"errors",
"instances"
],
"type": "string"
},
"description": "Which metrics to return raw `series` points for, subset of `cpu`, `memory`, `network`, `throughput`, `latency`, `errors`, `instances`. Default EMPTY: `summary` only. `summary` always covers every metric regardless of this filter."
},
"max_points": {
"type": "integer",
"maximum": 500,
"minimum": 10,
"description": "Maximum points per requested series in `series`; a longer series is downsampled (averaged into equal-width buckets). Default 60, minimum 10, maximum 500. Never affects `summary`, which always reflects the full series."
},
"environment_id": {
"type": "string",
"description": "The environment uuid returned by `environments_list`. Required. This data is per Cloud Run service."
},
"organization_id": {
"type": "string",
"description": "An organisation uuid or slug. When supplied, `app_id` is resolved within that organisation and may be a slug instead of a uuid, mirroring the Meridian web app."
}
}
},
"annotations": {
"readOnlyHint": true,
"openWorldHint": false,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description97/100
Triggers a manual deployment of `git_sha` to one of an app's
environments, exactly like the Deploy button in the Meridian web app.
Takes the `app_id` returned by `apps_list`, the `environment_id`
returned by `environments_list` (production, or a development or
staging environment when the app has one), and the `git_sha` to
deploy (optional `git_ref` for display only).
IDEMPOTENT: calling this again with the same `environment_id` and
`git_sha` while that exact deployment is still in flight
(queued/building/deploying/verifying) returns the SAME deployment
(`created: false`) instead of creating a duplicate. Calling it with a
DIFFERENT `git_sha` while a deployment is active for that environment
is refused. Meridian allows only one active deployment per
environment. Use `deployment_get` to poll the resulting
`deployment_id` for status, and `deployments_list`/`logs_tail` for
history and live logs.
The description explains the capability, when to use it, and what to expect.
Inputs94/100
Input documentation gives an agent enough context to populate the arguments.
app_id
The app uuid returned by `apps_list`.
Clear enough to supply this argument.
organization_id
An organisation uuid or slug. When supplied, `app_id` is resolved within that organisation and may be a slug instead of a uuid, mirroring the Meridian web app.
Clear enough to supply this argument.
environment_id
The uuid of the environment to deploy to, from `environments_list`.
Clear enough to supply this argument.
git_sha
The exact commit SHA to build and deploy.
Clear enough to supply this argument.
git_ref
Optional git ref (branch or tag) recorded alongside git_sha, for display only.
No output schema is declared. Add one for structured results so clients can interpret returned fields.
Not declared
Original tool metadata
{
"name": "deployment_create",
"title": "Create Deployment",
"description": "Triggers a manual deployment of `git_sha` to one of an app's\nenvironments, exactly like the Deploy button in the Meridian web app.\nTakes the `app_id` returned by `apps_list`, the `environment_id`\nreturned by `environments_list` (production, or a development or\nstaging environment when the app has one), and the `git_sha` to\ndeploy (optional `git_ref` for display only).\n\nIDEMPOTENT: calling this again with the same `environment_id` and\n`git_sha` while that exact deployment is still in flight\n(queued/building/deploying/verifying) returns the SAME deployment\n(`created: false`) instead of creating a duplicate. Calling it with a\nDIFFERENT `git_sha` while a deployment is active for that environment\nis refused. Meridian allows only one active deployment per\nenvironment. Use `deployment_get` to poll the resulting\n`deployment_id` for status, and `deployments_list`/`logs_tail` for\nhistory and live logs.",
"inputSchema": {
"type": "object",
"required": [
"app_id",
"environment_id",
"git_sha"
],
"properties": {
"app_id": {
"type": "string",
"description": "The app uuid returned by `apps_list`."
},
"git_ref": {
"type": "string",
"description": "Optional git ref (branch or tag) recorded alongside git_sha, for display only."
},
"git_sha": {
"type": "string",
"description": "The exact commit SHA to build and deploy."
},
"environment_id": {
"type": "string",
"description": "The uuid of the environment to deploy to, from `environments_list`."
},
"organization_id": {
"type": "string",
"description": "An organisation uuid or slug. When supplied, `app_id` is resolved within that organisation and may be a slug instead of a uuid, mirroring the Meridian web app."
}
}
},
"annotations": {
"readOnlyHint": false,
"openWorldHint": true,
"idempotentHint": true,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description98/100
Rolls back to a previously-succeeded deployment by shifting 100% of
live Cloud Run traffic to its existing revision (no rebuild).
`deployment_id` is the PRIOR SUCCEEDED deployment to restore. There
is no separate release identifier. Refused with a clear error if the
target deployment did not succeed, has no runtime revision to
restore, or its environment currently has another deployment in
progress. Returns the newly-created rollback deployment (trigger
`rollback`), which becomes the current live deployment for that
environment.
The description explains the capability, when to use it, and what to expect.
Inputs94/100
Input documentation gives an agent enough context to populate the arguments.
app_id
The app uuid returned by `apps_list`.
Clear enough to supply this argument.
organization_id
An organisation uuid or slug. When supplied, `app_id` is resolved within that organisation and may be a slug instead of a uuid, mirroring the Meridian web app.
Clear enough to supply this argument.
deployment_id
The prior succeeded deployment to roll back to, from `deployments_list`.
Clear enough to supply this argument.
Annotations75/100
Declare idempotentHint based on the tool’s actual behavior.
No output schema is declared. Add one for structured results so clients can interpret returned fields.
Not declared
Original tool metadata
{
"name": "deployment_rollback",
"title": "Rollback Deployment",
"description": "Rolls back to a previously-succeeded deployment by shifting 100% of\nlive Cloud Run traffic to its existing revision (no rebuild).\n`deployment_id` is the PRIOR SUCCEEDED deployment to restore. There\nis no separate release identifier. Refused with a clear error if the\ntarget deployment did not succeed, has no runtime revision to\nrestore, or its environment currently has another deployment in\nprogress. Returns the newly-created rollback deployment (trigger\n`rollback`), which becomes the current live deployment for that\nenvironment.",
"inputSchema": {
"type": "object",
"required": [
"app_id",
"deployment_id"
],
"properties": {
"app_id": {
"type": "string",
"description": "The app uuid returned by `apps_list`."
},
"deployment_id": {
"type": "string",
"description": "The prior succeeded deployment to roll back to, from `deployments_list`."
},
"organization_id": {
"type": "string",
"description": "An organisation uuid or slug. When supplied, `app_id` is resolved within that organisation and may be a slug instead of a uuid, mirroring the Meridian web app."
}
}
},
"annotations": {
"readOnlyHint": false,
"openWorldHint": true,
"destructiveHint": true
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description98/100
Lists the Shopify webhook topics routed to an app and the path each is
forwarded to, plus `forward_host`, the base URL the platform delivers
to. Use this to check that a topic the app expects is actually routed,
and that its `forward_path` matches the route the app's code handles.
Each route reports `topic`, `forward_path` (null means the platform
default path) and a `registration` summary (`registered_shops`,
`failed_shops` and `last_error`) describing whether Shopify accepted
the per-store subscription. A topic with `failed_shops` above zero is
configured but not actually delivering, which is the usual cause of a
handler that never runs. A store Meridian could not reach at all (its
token revoked or not renewable, or Shopify refusing the request) counts
as failed on every topic it has not registered, with a `last_error`
that starts with `Could not reach` and names the store. A store that
uninstalled the app drops out of these counts at the next save of the
topic set.
`reconcile_available` says whether Meridian can reach the stores that
already installed the app, which needs the app deployed on Meridian
with a ready production database. When it is true, a null `registration`
means Meridian has not attempted that topic yet, and `sign_in` is null.
When it is false, Meridian cannot register topics on those stores at
all: the SDK registers the app's topic set on each store when that
store authenticates. Managed topics (`app/uninstalled` and the billing
topics) are in that set from install on, so every installed store has
them and their `sign_in` is null. A developer route reaches a store
only at the store's first sign-in after the route was added, so each
such route carries `sign_in`: `installed_shops` and `awaiting_shops`,
the installed stores that have not signed in since (a sign-in within
five minutes of the route being added still counts as awaiting, since
the SDK caches the topic set that long). With `awaiting_shops` above
zero, say the topic registers on those stores at their next sign-in,
not that it is registered and idle. At zero, every installed store has
signed in since, which is the best evidence available: the SDK does
not report whether Shopify accepted each subscription.
`forward_host` is resolved by the same code as the live router, and is
the exact origin the platform posts to, not a branded alias assumed to
reach it. `forward_host_source` names the rung it came from: `external`
(a verified host declared by an app hosted outside Meridian), then
`environment` (the app's Meridian deployment, so its raw Cloud Run
base URL), then `platform`. Both are null when nothing is routed at
all, which for an app hosted on Meridian means nothing is deployed.
A `platform` source is Meridian's own receiver, the last-resort target
for an app with no runtime of its own: forwarded events stop there and
never reach the app. It routes by app identifier, so `forward_url`
then carries the single URL every forwarded event goes to. A topic
still needs a `forward_path` to be forwarded at all, but that path
plays no part in the destination. Say so plainly rather than composing
`forward_host` + `forward_path` into an endpoint nothing posts to.
`forward_url` is null for every other source.
Takes the `app_id` from `apps_list`. See `webhook_deliveries_list` for
individual delivery attempts.
The description explains the capability, when to use it, and what to expect.
Inputs95/100
Input documentation gives an agent enough context to populate the arguments.
app_id
The app uuid returned by `apps_list`.
Clear enough to supply this argument.
organization_id
An organisation uuid or slug. When supplied, `app_id` is resolved within that organisation and may be a slug instead of a uuid, mirroring the Meridian web app.
Clear enough to supply this argument.
Annotations75/100
Declare idempotentHint based on the tool’s actual behavior.
No output schema is declared. Add one for structured results so clients can interpret returned fields.
Not declared
Original tool metadata
{
"name": "webhook_routes_list",
"title": "List Shopify Webhook Routes",
"description": "Lists the Shopify webhook topics routed to an app and the path each is\nforwarded to, plus `forward_host`, the base URL the platform delivers\nto. Use this to check that a topic the app expects is actually routed,\nand that its `forward_path` matches the route the app's code handles.\n\nEach route reports `topic`, `forward_path` (null means the platform\ndefault path) and a `registration` summary (`registered_shops`,\n`failed_shops` and `last_error`) describing whether Shopify accepted\nthe per-store subscription. A topic with `failed_shops` above zero is\nconfigured but not actually delivering, which is the usual cause of a\nhandler that never runs. A store Meridian could not reach at all (its\ntoken revoked or not renewable, or Shopify refusing the request) counts\nas failed on every topic it has not registered, with a `last_error`\nthat starts with `Could not reach` and names the store. A store that\nuninstalled the app drops out of these counts at the next save of the\ntopic set.\n\n`reconcile_available` says whether Meridian can reach the stores that\nalready installed the app, which needs the app deployed on Meridian\nwith a ready production database. When it is true, a null `registration`\nmeans Meridian has not attempted that topic yet, and `sign_in` is null.\n\nWhen it is false, Meridian cannot register topics on those stores at\nall: the SDK registers the app's topic set on each store when that\nstore authenticates. Managed topics (`app/uninstalled` and the billing\ntopics) are in that set from install on, so every installed store has\nthem and their `sign_in` is null. A developer route reaches a store\nonly at the store's first sign-in after the route was added, so each\nsuch route carries `sign_in`: `installed_shops` and `awaiting_shops`,\nthe installed stores that have not signed in since (a sign-in within\nfive minutes of the route being added still counts as awaiting, since\nthe SDK caches the topic set that long). With `awaiting_shops` above\nzero, say the topic registers on those stores at their next sign-in,\nnot that it is registered and idle. At zero, every installed store has\nsigned in since, which is the best evidence available: the SDK does\nnot report whether Shopify accepted each subscription.\n\n`forward_host` is resolved by the same code as the live router, and is\nthe exact origin the platform posts to, not a branded alias assumed to\nreach it. `forward_host_source` names the rung it came from: `external`\n(a verified host declared by an app hosted outside Meridian), then\n`environment` (the app's Meridian deployment, so its raw Cloud Run\nbase URL), then `platform`. Both are null when nothing is routed at\nall, which for an app hosted on Meridian means nothing is deployed.\n\nA `platform` source is Meridian's own receiver, the last-resort target\nfor an app with no runtime of its own: forwarded events stop there and\nnever reach the app. It routes by app identifier, so `forward_url`\nthen carries the single URL every forwarded event goes to. A topic\nstill needs a `forward_path` to be forwarded at all, but that path\nplays no part in the destination. Say so plainly rather than composing\n`forward_host` + `forward_path` into an endpoint nothing posts to.\n`forward_url` is null for every other source.\n\nTakes the `app_id` from `apps_list`. See `webhook_deliveries_list` for\nindividual delivery attempts.",
"inputSchema": {
"type": "object",
"required": [
"app_id"
],
"properties": {
"app_id": {
"type": "string",
"description": "The app uuid returned by `apps_list`."
},
"organization_id": {
"type": "string",
"description": "An organisation uuid or slug. When supplied, `app_id` is resolved within that organisation and may be a slug instead of a uuid, mirroring the Meridian web app."
}
}
},
"annotations": {
"readOnlyHint": true,
"openWorldHint": false,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description98/100
Lists recent inbound Shopify webhook deliveries for an app, newest
first. Each entry reports `topic`, `shop_domain`, `status`, `attempts`,
`response_code` (what the app's handler answered), `error_message`, and
the `triggered_at` / `forwarded_at` / `handled_at` timestamps.
Use it to tell apart the two failures that look identical from inside
the repo: no delivery row for a topic means Shopify never sent it (check
`webhook_routes_list`. The topic is probably unrouted or failed to
register), while a row with a 4xx/5xx `response_code` means it arrived
and the app's own handler rejected it.
Optionally filter by `topic` (exact Shopify topic, e.g.
`orders/create`) or `status`. `limit` defaults to 20 and caps at 100.
THE WEBHOOK BODY IS NEVER RETURNED. It is merchant commerce data, and
neither are the request headers, which carry the HMAC signature. Read
a payload in the Meridian dashboard when you need one.
Takes the `app_id` from `apps_list`.
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.
app_id
The app uuid returned by `apps_list`.
Clear enough to supply this argument.
organization_id
An organisation uuid or slug. When supplied, `app_id` is resolved within that organisation and may be a slug instead of a uuid, mirroring the Meridian web app.
Clear enough to supply this argument.
topic
Only deliveries for this exact Shopify topic, e.g. `orders/create`.
Clear enough to supply this argument.
status
Only deliveries in this state: `processed`, `failed`, `ignored`, `received`, `blocked` or `dropped`.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
limit
Maximum deliveries to return. Default 20, maximum 100.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
Annotations75/100
Declare idempotentHint based on the tool’s actual behavior.
No output schema is declared. Add one for structured results so clients can interpret returned fields.
Not declared
Original tool metadata
{
"name": "webhook_deliveries_list",
"title": "List Shopify Webhook Deliveries",
"description": "Lists recent inbound Shopify webhook deliveries for an app, newest\nfirst. Each entry reports `topic`, `shop_domain`, `status`, `attempts`,\n`response_code` (what the app's handler answered), `error_message`, and\nthe `triggered_at` / `forwarded_at` / `handled_at` timestamps.\n\nUse it to tell apart the two failures that look identical from inside\nthe repo: no delivery row for a topic means Shopify never sent it (check\n`webhook_routes_list`. The topic is probably unrouted or failed to\nregister), while a row with a 4xx/5xx `response_code` means it arrived\nand the app's own handler rejected it.\n\nOptionally filter by `topic` (exact Shopify topic, e.g.\n`orders/create`) or `status`. `limit` defaults to 20 and caps at 100.\n\nTHE WEBHOOK BODY IS NEVER RETURNED. It is merchant commerce data, and\nneither are the request headers, which carry the HMAC signature. Read\na payload in the Meridian dashboard when you need one.\n\nTakes the `app_id` from `apps_list`.",
"inputSchema": {
"type": "object",
"required": [
"app_id"
],
"properties": {
"limit": {
"type": "integer",
"description": "Maximum deliveries to return. Default 20, maximum 100."
},
"topic": {
"type": "string",
"description": "Only deliveries for this exact Shopify topic, e.g. `orders/create`."
},
"app_id": {
"type": "string",
"description": "The app uuid returned by `apps_list`."
},
"status": {
"type": "string",
"description": "Only deliveries in this state: `processed`, `failed`, `ignored`, `received`, `blocked` or `dropped`."
},
"organization_id": {
"type": "string",
"description": "An organisation uuid or slug. When supplied, `app_id` is resolved within that organisation and may be a slug instead of a uuid, mirroring the Meridian web app."
}
}
},
"annotations": {
"readOnlyHint": true,
"openWorldHint": false,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description99/100
Lists an app's OPEN Shopify API-deprecation alerts: breaking changes
from Shopify's changelog that were matched against this app's
connected repository and still need action (relevant, not ruled out
by verification, and not yet acknowledged). Each alert has an
`alert_id`, the underlying changelog entry's `title`/`summary`/`url`/
`severity`/`action_required`/`migration_deadline`/`affected_apis`/
`recommendation`, the matched `code_references`, and
`has_fix_suggestion` (whether a stored AI fix already exists: fetch
it with `shopify_alert_get`). Takes the `app_id` returned by
`apps_list`. Optional `limit` caps the result (default 20, maximum
100). Requires the `shopify_alerts.view` permission on the app.
Never triggers a new scan or fix generation.
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.
app_id
The app uuid returned by `apps_list`.
Clear enough to supply this argument.
organization_id
An organisation uuid or slug. When supplied, `app_id` is resolved within that organisation and may be a slug instead of a uuid, mirroring the Meridian web app.
Clear enough to supply this argument.
limit
Maximum number of alerts to return. Default 20, maximum 100.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
Annotations75/100
Declare idempotentHint based on the tool’s actual behavior.
No output schema is declared. Add one for structured results so clients can interpret returned fields.
Not declared
Original tool metadata
{
"name": "shopify_alerts_list",
"title": "List Shopify Alerts",
"description": "Lists an app's OPEN Shopify API-deprecation alerts: breaking changes\nfrom Shopify's changelog that were matched against this app's\nconnected repository and still need action (relevant, not ruled out\nby verification, and not yet acknowledged). Each alert has an\n`alert_id`, the underlying changelog entry's `title`/`summary`/`url`/\n`severity`/`action_required`/`migration_deadline`/`affected_apis`/\n`recommendation`, the matched `code_references`, and\n`has_fix_suggestion` (whether a stored AI fix already exists: fetch\nit with `shopify_alert_get`). Takes the `app_id` returned by\n`apps_list`. Optional `limit` caps the result (default 20, maximum\n100). Requires the `shopify_alerts.view` permission on the app.\nNever triggers a new scan or fix generation.",
"inputSchema": {
"type": "object",
"required": [
"app_id"
],
"properties": {
"limit": {
"type": "integer",
"description": "Maximum number of alerts to return. Default 20, maximum 100."
},
"app_id": {
"type": "string",
"description": "The app uuid returned by `apps_list`."
},
"organization_id": {
"type": "string",
"description": "An organisation uuid or slug. When supplied, `app_id` is resolved within that organisation and may be a slug instead of a uuid, mirroring the Meridian web app."
}
}
},
"annotations": {
"readOnlyHint": true,
"openWorldHint": true,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description99/100
Returns a single Shopify API-deprecation alert's detail: the same
fields as `shopify_alerts_list`, plus the existing stored AI fix
suggestion (`fix_suggestion` (`summary`, `steps`, `references`,
`grounded`) or null when none has been generated yet;
`fix_suggested_at`; `fix_error`/`fix_failed_at` when generation
failed). Never generates a new fix suggestion. Takes the `app_id`
returned by `apps_list` and the `alert_id` returned by
`shopify_alerts_list`. Works for acknowledged alerts too, unlike
`shopify_alerts_list`, which only lists open ones. Requires the
`shopify_alerts.view` permission on the app.
The description explains the capability, when to use it, and what to expect.
Inputs93/100
Input documentation gives an agent enough context to populate the arguments.
app_id
The app uuid returned by `apps_list`.
Clear enough to supply this argument.
organization_id
An organisation uuid or slug. When supplied, `app_id` is resolved within that organisation and may be a slug instead of a uuid, mirroring the Meridian web app.
Clear enough to supply this argument.
alert_id
The alert uuid returned by `shopify_alerts_list`.
Clear enough to supply this argument.
Annotations75/100
Declare idempotentHint based on the tool’s actual behavior.
No output schema is declared. Add one for structured results so clients can interpret returned fields.
Not declared
Original tool metadata
{
"name": "shopify_alert_get",
"title": "Get Shopify Alert",
"description": "Returns a single Shopify API-deprecation alert's detail: the same\nfields as `shopify_alerts_list`, plus the existing stored AI fix\nsuggestion (`fix_suggestion` (`summary`, `steps`, `references`,\n`grounded`) or null when none has been generated yet;\n`fix_suggested_at`; `fix_error`/`fix_failed_at` when generation\nfailed). Never generates a new fix suggestion. Takes the `app_id`\nreturned by `apps_list` and the `alert_id` returned by\n`shopify_alerts_list`. Works for acknowledged alerts too, unlike\n`shopify_alerts_list`, which only lists open ones. Requires the\n`shopify_alerts.view` permission on the app.",
"inputSchema": {
"type": "object",
"required": [
"app_id",
"alert_id"
],
"properties": {
"app_id": {
"type": "string",
"description": "The app uuid returned by `apps_list`."
},
"alert_id": {
"type": "string",
"description": "The alert uuid returned by `shopify_alerts_list`."
},
"organization_id": {
"type": "string",
"description": "An organisation uuid or slug. When supplied, `app_id` is resolved within that organisation and may be a slug instead of a uuid, mirroring the Meridian web app."
}
}
},
"annotations": {
"readOnlyHint": true,
"openWorldHint": true,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description98/100
Returns the CALLING user's own developer database for an app:
`status` (`provisioning`/`ready`/`error`), sanitised `error_message`
when status is `error`, storage usage/limit,
lifecycle timestamps, and up to the 20 most recent migration runs
recorded against it (see `dev_database_migrate`). METADATA ONLY:
never returns a database password, Secret Manager resource id, proxy
token, or any other connection credential; use the Meridian CLI
(`meridian dev`) to actually connect. Takes the `app_id` returned by
`apps_list`. If you have not yet provisioned a developer database for this
app, this returns `dev_database: null` with a `hint` (NOT an error)
pointing you at `meridian dev`. Never returns another developer's
developer database, even for an organization admin/owner.
The description explains the capability, when to use it, and what to expect.
Inputs94/100
Input documentation gives an agent enough context to populate the arguments.
app_id
The app uuid returned by `apps_list`.
Clear enough to supply this argument.
organization_id
An organisation uuid or slug. When supplied, `app_id` is resolved within that organisation and may be a slug instead of a uuid, mirroring the Meridian web app.
Clear enough to supply this argument.
Annotations75/100
Declare idempotentHint based on the tool’s actual behavior.
No output schema is declared. Add one for structured results so clients can interpret returned fields.
Not declared
Original tool metadata
{
"name": "dev_database_get",
"title": "Get Developer Database",
"description": "Returns the CALLING user's own developer database for an app:\n`status` (`provisioning`/`ready`/`error`), sanitised `error_message`\nwhen status is `error`, storage usage/limit,\nlifecycle timestamps, and up to the 20 most recent migration runs\nrecorded against it (see `dev_database_migrate`). METADATA ONLY:\nnever returns a database password, Secret Manager resource id, proxy\ntoken, or any other connection credential; use the Meridian CLI\n(`meridian dev`) to actually connect. Takes the `app_id` returned by\n`apps_list`. If you have not yet provisioned a developer database for this\napp, this returns `dev_database: null` with a `hint` (NOT an error)\npointing you at `meridian dev`. Never returns another developer's\ndeveloper database, even for an organization admin/owner.",
"inputSchema": {
"type": "object",
"required": [
"app_id"
],
"properties": {
"app_id": {
"type": "string",
"description": "The app uuid returned by `apps_list`."
},
"organization_id": {
"type": "string",
"description": "An organisation uuid or slug. When supplied, `app_id` is resolved within that organisation and may be a slug instead of a uuid, mirroring the Meridian web app."
}
}
},
"annotations": {
"readOnlyHint": true,
"openWorldHint": false,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description98/100
RECORDS the outcome of a database migration YOU (or your agent)
ALREADY RAN LOCALLY against your own developer database. Meridian does
NOT execute migrations for you. There is no server-side migration
runner, and calling this tool never applies any schema change by
itself. To actually run a migration, use the Meridian CLI's
`meridian migrate` command locally (it runs `npx prisma migrate
dev` against your proxied developer database and calls this same
recording step automatically). Only call this tool yourself if you
ran the migration another way (e.g. Prisma directly) and want the
run to show up in the same history `dev_database_get` and the
dashboard display.
Takes the `app_id` returned by `apps_list`, the exact `command` you
ran, its `status` (`success`, `failed`, or `rolled_back`), and
optional `started_at`/`finished_at` (ISO-8601) and `output_excerpt`
(truncated to 5000 characters). IDEMPOTENT: re-reporting the exact
same `command` + `started_at` for this developer database returns the
SAME recorded run (`created: false`) instead of creating a
duplicate: safe to retry after a dropped response.
The description explains the capability, when to use it, and what to expect.
Inputs90/100
Remove repeated schema validation from descriptions; focus on meaning and usage context.
app_id
The app uuid returned by `apps_list`.
Clear enough to supply this argument.
organization_id
An organisation uuid or slug. When supplied, `app_id` is resolved within that organisation and may be a slug instead of a uuid, mirroring the Meridian web app.
Clear enough to supply this argument.
command
The exact command you ran locally, e.g. `npx prisma migrate dev --name add_orders`.
Clear enough to supply this argument.
status
Outcome of the run: `success`, `failed`, or `rolled_back`.
Clear enough to supply this argument.
started_at
ISO-8601 timestamp the migration run started, if known.
Clear enough to supply this argument.
finished_at
ISO-8601 timestamp the migration run finished, if known.
Clear enough to supply this argument.
output_excerpt
A short excerpt of the command's output, for debugging context. Truncated to 5000 characters.
No output schema is declared. Add one for structured results so clients can interpret returned fields.
Not declared
Original tool metadata
{
"name": "dev_database_migrate",
"title": "Record Developer Database Migration",
"description": "RECORDS the outcome of a database migration YOU (or your agent)\nALREADY RAN LOCALLY against your own developer database. Meridian does\nNOT execute migrations for you. There is no server-side migration\nrunner, and calling this tool never applies any schema change by\nitself. To actually run a migration, use the Meridian CLI's\n`meridian migrate` command locally (it runs `npx prisma migrate\ndev` against your proxied developer database and calls this same\nrecording step automatically). Only call this tool yourself if you\nran the migration another way (e.g. Prisma directly) and want the\nrun to show up in the same history `dev_database_get` and the\ndashboard display.\n\nTakes the `app_id` returned by `apps_list`, the exact `command` you\nran, its `status` (`success`, `failed`, or `rolled_back`), and\noptional `started_at`/`finished_at` (ISO-8601) and `output_excerpt`\n(truncated to 5000 characters). IDEMPOTENT: re-reporting the exact\nsame `command` + `started_at` for this developer database returns the\nSAME recorded run (`created: false`) instead of creating a\nduplicate: safe to retry after a dropped response.",
"inputSchema": {
"type": "object",
"required": [
"app_id",
"command",
"status"
],
"properties": {
"app_id": {
"type": "string",
"description": "The app uuid returned by `apps_list`."
},
"status": {
"type": "string",
"description": "Outcome of the run: `success`, `failed`, or `rolled_back`."
},
"command": {
"type": "string",
"description": "The exact command you ran locally, e.g. `npx prisma migrate dev --name add_orders`."
},
"started_at": {
"type": "string",
"description": "ISO-8601 timestamp the migration run started, if known."
},
"finished_at": {
"type": "string",
"description": "ISO-8601 timestamp the migration run finished, if known."
},
"output_excerpt": {
"type": "string",
"description": "A short excerpt of the command's output, for debugging context. Truncated to 5000 characters."
},
"organization_id": {
"type": "string",
"description": "An organisation uuid or slug. When supplied, `app_id` is resolved within that organisation and may be a slug instead of a uuid, mirroring the Meridian web app."
}
}
},
"annotations": {
"readOnlyHint": false,
"openWorldHint": false,
"idempotentHint": true,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description99/100
IRREVERSIBLY drops and recreates the CALLING user's own developer database
schema for an app: every table and row is destroyed and replaced
with an empty schema. The underlying MySQL user/credentials are
unaffected. Only the data is wiped. Equivalent to `meridian db
reset` in the Meridian CLI.
REQUIRES `confirm: true` in the SAME call. Omitting it, or passing
`false`, refuses with a clear error and makes NO changes. Never
call this tool speculatively or "just in case". Only pass
`confirm: true` when you (or the developer you are acting for) have
explicitly decided to permanently discard this developer database's
current contents.
Also refuses if the developer database is not currently `ready` (e.g.
still provisioning, or already in an error state). Use
`dev_database_get` to check `status` first if unsure. Takes the
`app_id` returned by `apps_list`.
The description explains the capability, when to use it, and what to expect.
Inputs92/100
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
app_id
The app uuid returned by `apps_list`.
Clear enough to supply this argument.
organization_id
An organisation uuid or slug. When supplied, `app_id` is resolved within that organisation and may be a slug instead of a uuid, mirroring the Meridian web app.
Clear enough to supply this argument.
confirm
Must be exactly `true`. Resetting permanently destroys the developer database's current contents; this tool refuses without explicit confirmation.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
Annotations75/100
Declare idempotentHint based on the tool’s actual behavior.
No output schema is declared. Add one for structured results so clients can interpret returned fields.
Not declared
Original tool metadata
{
"name": "dev_database_reset",
"title": "Reset Developer Database",
"description": "IRREVERSIBLY drops and recreates the CALLING user's own developer database\nschema for an app: every table and row is destroyed and replaced\nwith an empty schema. The underlying MySQL user/credentials are\nunaffected. Only the data is wiped. Equivalent to `meridian db\nreset` in the Meridian CLI.\n\nREQUIRES `confirm: true` in the SAME call. Omitting it, or passing\n`false`, refuses with a clear error and makes NO changes. Never\ncall this tool speculatively or \"just in case\". Only pass\n`confirm: true` when you (or the developer you are acting for) have\nexplicitly decided to permanently discard this developer database's\ncurrent contents.\n\nAlso refuses if the developer database is not currently `ready` (e.g.\nstill provisioning, or already in an error state). Use\n`dev_database_get` to check `status` first if unsure. Takes the\n`app_id` returned by `apps_list`.",
"inputSchema": {
"type": "object",
"required": [
"app_id",
"confirm"
],
"properties": {
"app_id": {
"type": "string",
"description": "The app uuid returned by `apps_list`."
},
"confirm": {
"type": "boolean",
"description": "Must be exactly `true`. Resetting permanently destroys the developer database's current contents; this tool refuses without explicit confirmation."
},
"organization_id": {
"type": "string",
"description": "An organisation uuid or slug. When supplied, `app_id` is resolved within that organisation and may be a slug instead of a uuid, mirroring the Meridian web app."
}
}
},
"annotations": {
"readOnlyHint": false,
"openWorldHint": false,
"destructiveHint": true
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description98/100
Returns the structure of the managed database attached to an
environment: every table with its columns (`name`, `type`, `nullable`,
`default`, and key flags) and its indexes (`name`, `columns`,
`unique`). Read this before writing a migration, model or query, since
the live schema is what the last applied migration produced and the
repository may not match it.
STRUCTURE ONLY. This tool never reads table rows. Meridian does have a
SQL console for that, but it is deliberately not exposed here: running
queries would put merchant data into this conversation. Use the
dashboard when you need to read data.
Requires the environment to have a READY database add-on; environments
without one report a clear error. For a developer's own isolated
database, use `dev_database_get` instead.
Takes the `app_id` from `apps_list` and the `environment_id` from
`environments_list`.
The description explains the capability, when to use it, and what to expect.
Inputs95/100
Input documentation gives an agent enough context to populate the arguments.
app_id
The app uuid returned by `apps_list`.
Clear enough to supply this argument.
organization_id
An organisation uuid or slug. When supplied, `app_id` is resolved within that organisation and may be a slug instead of a uuid, mirroring the Meridian web app.
Clear enough to supply this argument.
environment_id
The environment whose database to describe, from `environments_list`.
Clear enough to supply this argument.
Annotations75/100
Declare idempotentHint based on the tool’s actual behavior.
No output schema is declared. Add one for structured results so clients can interpret returned fields.
Not declared
Original tool metadata
{
"name": "database_schema_get",
"title": "Get Database Schema",
"description": "Returns the structure of the managed database attached to an\nenvironment: every table with its columns (`name`, `type`, `nullable`,\n`default`, and key flags) and its indexes (`name`, `columns`,\n`unique`). Read this before writing a migration, model or query, since\nthe live schema is what the last applied migration produced and the\nrepository may not match it.\n\nSTRUCTURE ONLY. This tool never reads table rows. Meridian does have a\nSQL console for that, but it is deliberately not exposed here: running\nqueries would put merchant data into this conversation. Use the\ndashboard when you need to read data.\n\nRequires the environment to have a READY database add-on; environments\nwithout one report a clear error. For a developer's own isolated\ndatabase, use `dev_database_get` instead.\n\nTakes the `app_id` from `apps_list` and the `environment_id` from\n`environments_list`.",
"inputSchema": {
"type": "object",
"required": [
"app_id",
"environment_id"
],
"properties": {
"app_id": {
"type": "string",
"description": "The app uuid returned by `apps_list`."
},
"environment_id": {
"type": "string",
"description": "The environment whose database to describe, from `environments_list`."
},
"organization_id": {
"type": "string",
"description": "An organisation uuid or slug. When supplied, `app_id` is resolved within that organisation and may be a slug instead of a uuid, mirroring the Meridian web app."
}
}
},
"annotations": {
"readOnlyHint": true,
"openWorldHint": false,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description96/100
Lists an app's CRM custom field definitions: `custom_field_id`,
`handle` (the key a value write is addressed to), `name`, `type`
(`text`, `number`, `boolean`, `select`, `date`, or `json`), `options`
(the allowed values of a `select` field), `segment_operators` (the operators
a segment condition on this field may use; empty for `json`, which is
not filterable), `readable_by_app` (whether `GET /public/me` returns
the value to the app, where the merchant's browser can see it; set in
the dashboard, off by default for a new field), and `values_count` (how
many stores currently have a value). Takes the `app_id` returned by
`apps_list`.
Pass `shop_domain` to additionally resolve that store's value for every
definition, returned under `values` as a `handle => value` map. Fields
the store has no value for are omitted from that map. Definitions
require `crm.custom_fields.view`; resolving a store's values also
requires `crm.merchants.view`.
The description explains the capability, when to use it, and what to expect.
Inputs89/100
Input documentation gives an agent enough context to populate the arguments.
app_id
The app uuid returned by `apps_list`.
Clear enough to supply this argument.
organization_id
An organisation uuid or slug. When supplied, `app_id` is resolved within that organisation and may be a slug instead of a uuid, mirroring the Meridian web app.
Clear enough to supply this argument.
shop_domain
Optional myshopify domain (e.g. "acme.myshopify.com"). When supplied, that store's current value for each definition is returned as well.
Clear enough to supply this argument.
Annotations75/100
Declare idempotentHint based on the tool’s actual behavior.
No output schema is declared. Add one for structured results so clients can interpret returned fields.
Not declared
Original tool metadata
{
"name": "custom_fields_list",
"title": "List CRM Custom Fields",
"description": "Lists an app's CRM custom field definitions: `custom_field_id`,\n`handle` (the key a value write is addressed to), `name`, `type`\n(`text`, `number`, `boolean`, `select`, `date`, or `json`), `options`\n(the allowed values of a `select` field), `segment_operators` (the operators\na segment condition on this field may use; empty for `json`, which is\nnot filterable), `readable_by_app` (whether `GET /public/me` returns\nthe value to the app, where the merchant's browser can see it; set in\nthe dashboard, off by default for a new field), and `values_count` (how\nmany stores currently have a value). Takes the `app_id` returned by\n`apps_list`.\n\nPass `shop_domain` to additionally resolve that store's value for every\ndefinition, returned under `values` as a `handle => value` map. Fields\nthe store has no value for are omitted from that map. Definitions\nrequire `crm.custom_fields.view`; resolving a store's values also\nrequires `crm.merchants.view`.",
"inputSchema": {
"type": "object",
"required": [
"app_id"
],
"properties": {
"app_id": {
"type": "string",
"description": "The app uuid returned by `apps_list`."
},
"shop_domain": {
"type": "string",
"description": "Optional myshopify domain (e.g. \"acme.myshopify.com\"). When supplied, that store's current value for each definition is returned as well."
},
"organization_id": {
"type": "string",
"description": "An organisation uuid or slug. When supplied, `app_id` is resolved within that organisation and may be a slug instead of a uuid, mirroring the Meridian web app."
}
}
},
"annotations": {
"readOnlyHint": true,
"openWorldHint": false,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description95/100
Sets a store's CRM custom field values. Takes the `app_id` returned by
`apps_list`, the store's `shop_domain` (e.g. "acme.myshopify.com"), and
`values`: an object keyed by the definition `handle` returned by
`custom_fields_list`.
Each value must fit its field's type: a number for `number`, true/false
for `boolean`, one of the field's `options` for `select`, a
`YYYY-MM-DD` string for `date`, an object or array for `json`. `null`
clears a field, which deletes its stored value.
Only the handles you send are touched; every other field on the store
keeps its value. At most 20 handles per call.
An unknown handle, or a value that does not fit its field, fails the
whole call and writes nothing. Returns the store's full set of values
after the write.
Writes are accepted for a store the CRM has not mirrored from Shopify
Partner events yet. Setting a value fires the `custom_field.changed`
automation trigger, once per field whose stored value actually changed.
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.
app_id
The app uuid returned by `apps_list`.
Clear enough to supply this argument.
organization_id
An organisation uuid or slug. When supplied, `app_id` is resolved within that organisation and may be a slug instead of a uuid, mirroring the Meridian web app.
Clear enough to supply this argument.
shop_domain
The store's myshopify domain, e.g. "acme.myshopify.com".
Clear enough to supply this argument.
values
Values keyed by custom field handle, from `custom_fields_list`. A null value clears the field. At most 20 entries.
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": "custom_field_values_set",
"title": "Set CRM Custom Field Values",
"description": "Sets a store's CRM custom field values. Takes the `app_id` returned by\n`apps_list`, the store's `shop_domain` (e.g. \"acme.myshopify.com\"), and\n`values`: an object keyed by the definition `handle` returned by\n`custom_fields_list`.\n\nEach value must fit its field's type: a number for `number`, true/false\nfor `boolean`, one of the field's `options` for `select`, a\n`YYYY-MM-DD` string for `date`, an object or array for `json`. `null`\nclears a field, which deletes its stored value.\nOnly the handles you send are touched; every other field on the store\nkeeps its value. At most 20 handles per call.\n\nAn unknown handle, or a value that does not fit its field, fails the\nwhole call and writes nothing. Returns the store's full set of values\nafter the write.\n\nWrites are accepted for a store the CRM has not mirrored from Shopify\nPartner events yet. Setting a value fires the `custom_field.changed`\nautomation trigger, once per field whose stored value actually changed.",
"inputSchema": {
"type": "object",
"required": [
"app_id",
"shop_domain",
"values"
],
"properties": {
"app_id": {
"type": "string",
"description": "The app uuid returned by `apps_list`."
},
"values": {
"type": "object",
"description": "Values keyed by custom field handle, from `custom_fields_list`. A null value clears the field. At most 20 entries."
},
"shop_domain": {
"type": "string",
"description": "The store's myshopify domain, e.g. \"acme.myshopify.com\"."
},
"organization_id": {
"type": "string",
"description": "An organisation uuid or slug. When supplied, `app_id` is resolved within that organisation and may be a slug instead of a uuid, mirroring the Meridian web app."
}
}
},
"annotations": {
"readOnlyHint": false,
"openWorldHint": false,
"idempotentHint": true,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description97/100
Lists an app's email templates: `email_id`, `name`, `status`
(`active`/`inactive`), `subject`, `preview_text`, open/click/conversion
rates, and timestamps. Never includes design JSON or rendered HTML.
Edit those in the Meridian dashboard. Takes the `app_id` returned by
`apps_list`. Optional `status`, `search` (name/subject), and `limit`
(default 20, maximum 100). Newest first, one page per call: while
`next_cursor` is not null, call again with it as `cursor` and the
same `status` and `search` to read the next page. A null
`next_cursor` means there are no more emails.
The description explains the capability, when to use it, and what to expect.
Inputs94/100
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
app_id
The app uuid returned by `apps_list`.
Clear enough to supply this argument.
organization_id
An organisation uuid or slug. When supplied, `app_id` is resolved within that organisation and may be a slug instead of a uuid, mirroring the Meridian web app.
Clear enough to supply this argument.
status
Filter by status: `active` or `inactive`.
Clear enough to supply this argument.
search
Case-insensitive substring match on name or subject.
Clear enough to supply this argument.
limit
Maximum number of emails to return. Default 20, maximum 100.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
cursor
The `next_cursor` of the previous call, passed back unchanged with the same filters. Omit it for the first page.
Clear enough to supply this argument.
Annotations75/100
Declare idempotentHint based on the tool’s actual behavior.
No output schema is declared. Add one for structured results so clients can interpret returned fields.
Not declared
Original tool metadata
{
"name": "emails_list",
"title": "List Emails",
"description": "Lists an app's email templates: `email_id`, `name`, `status`\n(`active`/`inactive`), `subject`, `preview_text`, open/click/conversion\nrates, and timestamps. Never includes design JSON or rendered HTML.\nEdit those in the Meridian dashboard. Takes the `app_id` returned by\n`apps_list`. Optional `status`, `search` (name/subject), and `limit`\n(default 20, maximum 100). Newest first, one page per call: while\n`next_cursor` is not null, call again with it as `cursor` and the\nsame `status` and `search` to read the next page. A null\n`next_cursor` means there are no more emails.",
"inputSchema": {
"type": "object",
"required": [
"app_id"
],
"properties": {
"limit": {
"type": "integer",
"description": "Maximum number of emails to return. Default 20, maximum 100."
},
"app_id": {
"type": "string",
"description": "The app uuid returned by `apps_list`."
},
"cursor": {
"type": "string",
"description": "The `next_cursor` of the previous call, passed back unchanged with the same filters. Omit it for the first page."
},
"search": {
"type": "string",
"description": "Case-insensitive substring match on name or subject."
},
"status": {
"type": "string",
"description": "Filter by status: `active` or `inactive`."
},
"organization_id": {
"type": "string",
"description": "An organisation uuid or slug. When supplied, `app_id` is resolved within that organisation and may be a slug instead of a uuid, mirroring the Meridian web app."
}
}
},
"annotations": {
"readOnlyHint": true,
"openWorldHint": false,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description99/100
Returns one email template's metadata and rates: `email_id`, `name`,
`status`, `subject`, `preview_text`, open/click/conversion rates, and
timestamps. Never includes design JSON or rendered HTML. Takes the
`app_id` from `apps_list` and the `email_id` from `emails_list` /
`email_create`. Recomputes rates from local send rows before returning
so missed webhook deliveries do not leave stale numbers.
The description explains the capability, when to use it, and what to expect.
Inputs94/100
Input documentation gives an agent enough context to populate the arguments.
app_id
The app uuid returned by `apps_list`.
Clear enough to supply this argument.
organization_id
An organisation uuid or slug. When supplied, `app_id` is resolved within that organisation and may be a slug instead of a uuid, mirroring the Meridian web app.
Clear enough to supply this argument.
email_id
The email uuid returned by `emails_list` or `email_create`.
Clear enough to supply this argument.
Annotations75/100
Declare idempotentHint based on the tool’s actual behavior.
No output schema is declared. Add one for structured results so clients can interpret returned fields.
Not declared
Original tool metadata
{
"name": "email_get",
"title": "Get Email",
"description": "Returns one email template's metadata and rates: `email_id`, `name`,\n`status`, `subject`, `preview_text`, open/click/conversion rates, and\ntimestamps. Never includes design JSON or rendered HTML. Takes the\n`app_id` from `apps_list` and the `email_id` from `emails_list` /\n`email_create`. Recomputes rates from local send rows before returning\nso missed webhook deliveries do not leave stale numbers.",
"inputSchema": {
"type": "object",
"required": [
"app_id",
"email_id"
],
"properties": {
"app_id": {
"type": "string",
"description": "The app uuid returned by `apps_list`."
},
"email_id": {
"type": "string",
"description": "The email uuid returned by `emails_list` or `email_create`."
},
"organization_id": {
"type": "string",
"description": "An organisation uuid or slug. When supplied, `app_id` is resolved within that organisation and may be a slug instead of a uuid, mirroring the Meridian web app."
}
}
},
"annotations": {
"readOnlyHint": true,
"openWorldHint": false,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description95/100
Returns the merge-tag variable catalog an email send can substitute:
built-in tags plus the app's CRM custom fields. Each entry has `name`,
sample text, and related metadata. Pass optional `shop_domain` to swap
the store variables' generic samples for that store's real values,
empty where the store has none (unknown stores fall back to samples).
Each variable has `sample_source`: `store` when its sample is that
store's own value, `placeholder` for a generic sample (every variable
without `shop_domain`, an unknown store, and the contact, event and
custom field variables). With `shop_domain`, the root also has
`store_found` (false when Meridian does not know the store).
Takes the `app_id` returned by `apps_list`. Requires
`emails.view`; a store's real values also require `crm.merchants.view`.
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.
app_id
The app uuid returned by `apps_list`.
Clear enough to supply this argument.
organization_id
An organisation uuid or slug. When supplied, `app_id` is resolved within that organisation and may be a slug instead of a uuid, mirroring the Meridian web app.
Clear enough to supply this argument.
shop_domain
Optional myshopify domain (e.g. "acme.myshopify.com"). When supplied, the store variables show that store's values instead of samples, empty where the store has none.
Clear enough to supply this argument.
Annotations75/100
Declare idempotentHint based on the tool’s actual behavior.
No output schema is declared. Add one for structured results so clients can interpret returned fields.
Not declared
Original tool metadata
{
"name": "emails_variables_list",
"title": "List Email Merge Variables",
"description": "Returns the merge-tag variable catalog an email send can substitute:\nbuilt-in tags plus the app's CRM custom fields. Each entry has `name`,\nsample text, and related metadata. Pass optional `shop_domain` to swap\nthe store variables' generic samples for that store's real values,\nempty where the store has none (unknown stores fall back to samples).\nEach variable has `sample_source`: `store` when its sample is that\nstore's own value, `placeholder` for a generic sample (every variable\nwithout `shop_domain`, an unknown store, and the contact, event and\ncustom field variables). With `shop_domain`, the root also has\n`store_found` (false when Meridian does not know the store).\nTakes the `app_id` returned by `apps_list`. Requires\n`emails.view`; a store's real values also require `crm.merchants.view`.",
"inputSchema": {
"type": "object",
"required": [
"app_id"
],
"properties": {
"app_id": {
"type": "string",
"description": "The app uuid returned by `apps_list`."
},
"shop_domain": {
"type": "string",
"description": "Optional myshopify domain (e.g. \"acme.myshopify.com\"). When supplied, the store variables show that store's values instead of samples, empty where the store has none."
},
"organization_id": {
"type": "string",
"description": "An organisation uuid or slug. When supplied, `app_id` is resolved within that organisation and may be a slug instead of a uuid, mirroring the Meridian web app."
}
}
},
"annotations": {
"readOnlyHint": true,
"openWorldHint": false,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description99/100
Creates a new email template as an **inactive** draft. Requires `name`;
optional `subject` and `preview_text`. Status is always forced to
`inactive`, and design/HTML cannot be set through MCP. Edit the body
and activate in the Meridian dashboard. Takes the `app_id` returned by
`apps_list`. Returns the same summary shape as `email_get`.
The description explains the capability, when to use it, and what to expect.
Inputs94/100
Input documentation gives an agent enough context to populate the arguments.
app_id
The app uuid returned by `apps_list`.
Clear enough to supply this argument.
organization_id
An organisation uuid or slug. When supplied, `app_id` is resolved within that organisation and may be a slug instead of a uuid, mirroring the Meridian web app.
Clear enough to supply this argument.
name
Display name for the email template.
Clear enough to supply this argument.
subject
Optional email subject line (may include merge tags).
Clear enough to supply this argument.
preview_text
Optional inbox preview text.
Clear enough to supply this argument.
Annotations75/100
Declare idempotentHint based on the tool’s actual behavior.
No output schema is declared. Add one for structured results so clients can interpret returned fields.
Not declared
Original tool metadata
{
"name": "email_create",
"title": "Create Email",
"description": "Creates a new email template as an **inactive** draft. Requires `name`;\noptional `subject` and `preview_text`. Status is always forced to\n`inactive`, and design/HTML cannot be set through MCP. Edit the body\nand activate in the Meridian dashboard. Takes the `app_id` returned by\n`apps_list`. Returns the same summary shape as `email_get`.",
"inputSchema": {
"type": "object",
"required": [
"app_id",
"name"
],
"properties": {
"name": {
"type": "string",
"description": "Display name for the email template."
},
"app_id": {
"type": "string",
"description": "The app uuid returned by `apps_list`."
},
"subject": {
"type": "string",
"description": "Optional email subject line (may include merge tags)."
},
"preview_text": {
"type": "string",
"description": "Optional inbox preview text."
},
"organization_id": {
"type": "string",
"description": "An organisation uuid or slug. When supplied, `app_id` is resolved within that organisation and may be a slug instead of a uuid, mirroring the Meridian web app."
}
}
},
"annotations": {
"readOnlyHint": false,
"openWorldHint": false,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description98/100
Updates an email template's `name`, `subject`, and/or `preview_text`.
At least one of those fields is required. Status and design/HTML cannot
be changed through MCP. Activate and edit the body in the Meridian
dashboard. An active email must keep a subject: clearing it is refused
until the email is deactivated in the dashboard. Like a save in the
dashboard, it also updates every automation that sends this email,
active or not: each Send Email step keeps a copy of the subject,
preview text and HTML, and that copy is what sends, so the change
applies to the next send. Runs already paused on a Wait keep the
version they started with. Takes `app_id` and `email_id` from
`apps_list` / `emails_list`. Returns the same summary shape as
`email_get`.
The description explains the capability, when to use it, and what to expect.
Inputs75/100
Explain the meaning of this value, not just its name.
app_id
The app uuid returned by `apps_list`.
Clear enough to supply this argument.
organization_id
An organisation uuid or slug. When supplied, `app_id` is resolved within that organisation and may be a slug instead of a uuid, mirroring the Meridian web app.
Clear enough to supply this argument.
email_id
The email uuid returned by `emails_list` or `email_create`.
Clear enough to supply this argument.
name
New display name.
Explain the meaning of this value, not just its name.
subject
New subject line (may include merge tags). Pass null to clear it, except on an active email, which must keep a subject.
Resolve the mismatch between this description and its schema constraints.
preview_text
New inbox preview text. Pass null to clear.
Clear enough to supply this argument.
Annotations75/100
Declare idempotentHint based on the tool’s actual behavior.
No output schema is declared. Add one for structured results so clients can interpret returned fields.
Not declared
Original tool metadata
{
"name": "email_update",
"title": "Update Email",
"description": "Updates an email template's `name`, `subject`, and/or `preview_text`.\nAt least one of those fields is required. Status and design/HTML cannot\nbe changed through MCP. Activate and edit the body in the Meridian\ndashboard. An active email must keep a subject: clearing it is refused\nuntil the email is deactivated in the dashboard. Like a save in the\ndashboard, it also updates every automation that sends this email,\nactive or not: each Send Email step keeps a copy of the subject,\npreview text and HTML, and that copy is what sends, so the change\napplies to the next send. Runs already paused on a Wait keep the\nversion they started with. Takes `app_id` and `email_id` from\n`apps_list` / `emails_list`. Returns the same summary shape as\n`email_get`.",
"inputSchema": {
"type": "object",
"required": [
"app_id",
"email_id"
],
"properties": {
"name": {
"type": "string",
"description": "New display name."
},
"app_id": {
"type": "string",
"description": "The app uuid returned by `apps_list`."
},
"subject": {
"type": "string",
"description": "New subject line (may include merge tags). Pass null to clear it, except on an active email, which must keep a subject."
},
"email_id": {
"type": "string",
"description": "The email uuid returned by `emails_list` or `email_create`."
},
"preview_text": {
"type": "string",
"description": "New inbox preview text. Pass null to clear."
},
"organization_id": {
"type": "string",
"description": "An organisation uuid or slug. When supplied, `app_id` is resolved within that organisation and may be a slug instead of a uuid, mirroring the Meridian web app."
}
}
},
"annotations": {
"readOnlyHint": false,
"openWorldHint": false,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description94/100
Lists an app's automations: `automation_id`, `scoped_id`, `name`,
`status`, `nodes` (node count), `description`, and timestamps. Does
**not** include the graph — use `automation_get` for that. Takes the
`app_id` returned by `apps_list`.
The description explains the capability, when to use it, and what to expect.
Inputs94/100
Input documentation gives an agent enough context to populate the arguments.
app_id
The app uuid returned by `apps_list`.
Clear enough to supply this argument.
organization_id
An organisation uuid or slug. When supplied, `app_id` is resolved within that organisation and may be a slug instead of a uuid, mirroring the Meridian web app.
Clear enough to supply this argument.
Annotations75/100
Declare idempotentHint based on the tool’s actual behavior.
No output schema is declared. Add one for structured results so clients can interpret returned fields.
Not declared
Original tool metadata
{
"name": "automations_list",
"title": "List Automations",
"description": "Lists an app's automations: `automation_id`, `scoped_id`, `name`,\n`status`, `nodes` (node count), `description`, and timestamps. Does\n**not** include the graph — use `automation_get` for that. Takes the\n`app_id` returned by `apps_list`.",
"inputSchema": {
"type": "object",
"required": [
"app_id"
],
"properties": {
"app_id": {
"type": "string",
"description": "The app uuid returned by `apps_list`."
},
"organization_id": {
"type": "string",
"description": "An organisation uuid or slug. When supplied, `app_id` is resolved within that organisation and may be a slug instead of a uuid, mirroring the Meridian web app."
}
}
},
"annotations": {
"readOnlyHint": true,
"openWorldHint": false,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description89/100
Returns one automation's summary plus its graph. Send Email node data
keeps `emailUuid` / subject but never includes `emailHtml`. Takes
`app_id` and `automation_id` (app-local `scoped_id` or uuid from
`automations_list`).
The description explains the capability, when to use it, and what to expect.
Inputs93/100
Input documentation gives an agent enough context to populate the arguments.
app_id
The app uuid returned by `apps_list`.
Clear enough to supply this argument.
organization_id
An organisation uuid or slug. When supplied, `app_id` is resolved within that organisation and may be a slug instead of a uuid, mirroring the Meridian web app.
Clear enough to supply this argument.
automation_id
The automation scoped_id or uuid returned by `automations_list`.
Clear enough to supply this argument.
Annotations75/100
Declare idempotentHint based on the tool’s actual behavior.
No output schema is declared. Add one for structured results so clients can interpret returned fields.
Not declared
Original tool metadata
{
"name": "automation_get",
"title": "Get Automation",
"description": "Returns one automation's summary plus its graph. Send Email node data\nkeeps `emailUuid` / subject but never includes `emailHtml`. Takes\n`app_id` and `automation_id` (app-local `scoped_id` or uuid from\n`automations_list`).",
"inputSchema": {
"type": "object",
"required": [
"app_id",
"automation_id"
],
"properties": {
"app_id": {
"type": "string",
"description": "The app uuid returned by `apps_list`."
},
"automation_id": {
"type": "string",
"description": "The automation scoped_id or uuid returned by `automations_list`."
},
"organization_id": {
"type": "string",
"description": "An organisation uuid or slug. When supplied, `app_id` is resolved within that organisation and may be a slug instead of a uuid, mirroring the Meridian web app."
}
}
},
"annotations": {
"readOnlyHint": true,
"openWorldHint": false,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description89/100
Lists recent runs for one automation: `run_id`, `automation_id`,
`started_at`/`ended_at`, `status`, `retries`, `trigger_event`, and
`failure_reason`. Takes `app_id` and `automation_id` (scoped_id or
uuid). Optional `limit` (default 20, maximum 100).
The description explains the capability, when to use it, and what to expect.
Inputs93/100
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
app_id
The app uuid returned by `apps_list`.
Clear enough to supply this argument.
organization_id
An organisation uuid or slug. When supplied, `app_id` is resolved within that organisation and may be a slug instead of a uuid, mirroring the Meridian web app.
Clear enough to supply this argument.
automation_id
The automation scoped_id or uuid returned by `automations_list`.
Clear enough to supply this argument.
limit
Maximum number of runs to return. Default 20, maximum 100.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
Annotations75/100
Declare idempotentHint based on the tool’s actual behavior.
No output schema is declared. Add one for structured results so clients can interpret returned fields.
Not declared
Original tool metadata
{
"name": "automation_runs_list",
"title": "List Automation Runs",
"description": "Lists recent runs for one automation: `run_id`, `automation_id`,\n`started_at`/`ended_at`, `status`, `retries`, `trigger_event`, and\n`failure_reason`. Takes `app_id` and `automation_id` (scoped_id or\nuuid). Optional `limit` (default 20, maximum 100).",
"inputSchema": {
"type": "object",
"required": [
"app_id",
"automation_id"
],
"properties": {
"limit": {
"type": "integer",
"description": "Maximum number of runs to return. Default 20, maximum 100."
},
"app_id": {
"type": "string",
"description": "The app uuid returned by `apps_list`."
},
"automation_id": {
"type": "string",
"description": "The automation scoped_id or uuid returned by `automations_list`."
},
"organization_id": {
"type": "string",
"description": "An organisation uuid or slug. When supplied, `app_id` is resolved within that organisation and may be a slug instead of a uuid, mirroring the Meridian web app."
}
}
},
"annotations": {
"readOnlyHint": true,
"openWorldHint": false,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description97/100
Returns the static automation builder catalogs from Meridian config:
`triggers`, `actions`, `conditions`, `templates`, and
`template_categories`. Takes no arguments (authenticated user only):
the same catalogs every app shares, matching the HTTP automation
catalog endpoints. Catalog entries (templates, categories, triggers,
actions, conditions) are identified by `key`.
Each `templates[].graph` uses the same shape as `automation_get`
(nodes `node_id`, edges `edge_id`) and can be passed as is to
`automation_update`. Template nodes and edges also carry a deprecated
`key` with the same value, to be removed at the next major version. In
a graph, a trigger node's `data.triggerId` is a trigger `key`, a
condition node's `data.conditionId` is a condition `key`, and an action
is recognized by `data.label`, equal to the action's `label`. A
template's Send Email steps have no `emailUuid` in this catalog: to use a
template with its emails, call `automation_create_from_template` with
its `key`, or point each step to an existing email from `emails_list`.
The description explains the capability, when to use it, and what to expect.
Inputs100/100
This tool declares no inputs, so argument descriptions are not needed.
No input fields.
Annotations75/100
Declare idempotentHint based on the tool’s actual behavior.
No output schema is declared. Add one for structured results so clients can interpret returned fields.
Not declared
Original tool metadata
{
"name": "automations_catalog_get",
"title": "Get Automations Catalog",
"description": "Returns the static automation builder catalogs from Meridian config:\n`triggers`, `actions`, `conditions`, `templates`, and\n`template_categories`. Takes no arguments (authenticated user only):\nthe same catalogs every app shares, matching the HTTP automation\ncatalog endpoints. Catalog entries (templates, categories, triggers,\nactions, conditions) are identified by `key`.\nEach `templates[].graph` uses the same shape as `automation_get`\n(nodes `node_id`, edges `edge_id`) and can be passed as is to\n`automation_update`. Template nodes and edges also carry a deprecated\n`key` with the same value, to be removed at the next major version. In\na graph, a trigger node's `data.triggerId` is a trigger `key`, a\ncondition node's `data.conditionId` is a condition `key`, and an action\nis recognized by `data.label`, equal to the action's `label`. A\ntemplate's Send Email steps have no `emailUuid` in this catalog: to use a\ntemplate with its emails, call `automation_create_from_template` with\nits `key`, or point each step to an existing email from `emails_list`.",
"inputSchema": {
"type": "object",
"properties": {}
},
"annotations": {
"readOnlyHint": true,
"openWorldHint": false,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description97/100
Returns aggregate automation run metrics for an app over the last 30 days
(with the prior equal-length window for deltas): `runs`, `runs_previous`,
`success_rate`, `success_rate_previous`, `failures`, `median_run_time_ms`,
and `p95_run_time_ms`. Skipped runs are excluded. Takes the `app_id`
returned by `apps_list`.
The description explains the capability, when to use it, and what to expect.
Inputs96/100
Input documentation gives an agent enough context to populate the arguments.
app_id
The app uuid returned by `apps_list`.
Clear enough to supply this argument.
organization_id
An organisation uuid or slug. When supplied, `app_id` is resolved within that organisation and may be a slug instead of a uuid, mirroring the Meridian web app.
Clear enough to supply this argument.
Annotations75/100
Declare idempotentHint based on the tool’s actual behavior.
No output schema is declared. Add one for structured results so clients can interpret returned fields.
Not declared
Original tool metadata
{
"name": "automations_metrics_get",
"title": "Get Automations Metrics",
"description": "Returns aggregate automation run metrics for an app over the last 30 days\n(with the prior equal-length window for deltas): `runs`, `runs_previous`,\n`success_rate`, `success_rate_previous`, `failures`, `median_run_time_ms`,\nand `p95_run_time_ms`. Skipped runs are excluded. Takes the `app_id`\nreturned by `apps_list`.",
"inputSchema": {
"type": "object",
"required": [
"app_id"
],
"properties": {
"app_id": {
"type": "string",
"description": "The app uuid returned by `apps_list`."
},
"organization_id": {
"type": "string",
"description": "An organisation uuid or slug. When supplied, `app_id` is resolved within that organisation and may be a slug instead of a uuid, mirroring the Meridian web app."
}
}
},
"annotations": {
"readOnlyHint": true,
"openWorldHint": false,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description92/100
Creates a new automation as an **inactive** draft with an empty graph
(`node_count` 0). Requires `name`; optional `description`. Status is
always forced to `inactive`. Configure the graph via
`automation_update` (while inactive) and activate in the Meridian
dashboard. Takes the `app_id` returned by `apps_list`.
The description explains the capability, when to use it, and what to expect.
Inputs92/100
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
app_id
The app uuid returned by `apps_list`.
Clear enough to supply this argument.
organization_id
An organisation uuid or slug. When supplied, `app_id` is resolved within that organisation and may be a slug instead of a uuid, mirroring the Meridian web app.
Clear enough to supply this argument.
name
Display name for the automation.
Clear enough to supply this argument.
description
Optional description, up to 2,000 characters.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
Annotations75/100
Declare idempotentHint based on the tool’s actual behavior.
No output schema is declared. Add one for structured results so clients can interpret returned fields.
Not declared
Original tool metadata
{
"name": "automation_create",
"title": "Create Automation",
"description": "Creates a new automation as an **inactive** draft with an empty graph\n(`node_count` 0). Requires `name`; optional `description`. Status is\nalways forced to `inactive`. Configure the graph via\n`automation_update` (while inactive) and activate in the Meridian\ndashboard. Takes the `app_id` returned by `apps_list`.",
"inputSchema": {
"type": "object",
"required": [
"app_id",
"name"
],
"properties": {
"name": {
"type": "string",
"description": "Display name for the automation."
},
"app_id": {
"type": "string",
"description": "The app uuid returned by `apps_list`."
},
"description": {
"type": "string",
"maxLength": 2000,
"description": "Optional description, up to 2,000 characters."
},
"organization_id": {
"type": "string",
"description": "An organisation uuid or slug. When supplied, `app_id` is resolved within that organisation and may be a slug instead of a uuid, mirroring the Meridian web app."
}
}
},
"annotations": {
"readOnlyHint": false,
"openWorldHint": false,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description97/100
Copies a catalog template into the app, as **Use this template** does in
the dashboard. Requires `template_key`, a template `key` from
`automations_catalog_get`. Creates an **inactive** automation with the
template's graph and, for each Send Email step, a new **inactive** email
with Meridian's starter copy (subject, preview text and body) attached to
that step. The agent supplies no body, and `status`, `graph` and
`design` are refused. Each call makes a new copy: two calls make two
copies. Returns the `automation` (with its graph, without any email body)
and its `emails`, each with the `node_id` of its step.
Activate the emails, then the automation, in the Meridian dashboard.
Left to choose: a segment (`crm_segments_list`, then `automation_update`),
a custom field (`custom_fields_list`), a Slack channel and a usage view
(dashboard). Takes the `app_id` returned by `apps_list`.
The description explains the capability, when to use it, and what to expect.
Inputs92/100
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
app_id
The app uuid returned by `apps_list`.
Clear enough to supply this argument.
organization_id
An organisation uuid or slug. When supplied, `app_id` is resolved within that organisation and may be a slug instead of a uuid, mirroring the Meridian web app.
Clear enough to supply this argument.
template_key
Template `key` from automations_catalog_get.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
Annotations75/100
Declare idempotentHint based on the tool’s actual behavior.
No output schema is declared. Add one for structured results so clients can interpret returned fields.
Not declared
Original tool metadata
{
"name": "automation_create_from_template",
"title": "Create Automation From Template",
"description": "Copies a catalog template into the app, as **Use this template** does in\nthe dashboard. Requires `template_key`, a template `key` from\n`automations_catalog_get`. Creates an **inactive** automation with the\ntemplate's graph and, for each Send Email step, a new **inactive** email\nwith Meridian's starter copy (subject, preview text and body) attached to\nthat step. The agent supplies no body, and `status`, `graph` and\n`design` are refused. Each call makes a new copy: two calls make two\ncopies. Returns the `automation` (with its graph, without any email body)\nand its `emails`, each with the `node_id` of its step.\nActivate the emails, then the automation, in the Meridian dashboard.\nLeft to choose: a segment (`crm_segments_list`, then `automation_update`),\na custom field (`custom_fields_list`), a Slack channel and a usage view\n(dashboard). Takes the `app_id` returned by `apps_list`.",
"inputSchema": {
"type": "object",
"required": [
"app_id",
"template_key"
],
"properties": {
"app_id": {
"type": "string",
"description": "The app uuid returned by `apps_list`."
},
"template_key": {
"enum": [
"welcome-email",
"welcome-sequence",
"uninstall-followup",
"win-back-reinstall",
"store-paused-alert",
"store-reopened-alert",
"access-token-alert",
"first-identify-onboarding",
"first-identify-tagging",
"subscription-activated",
"review-request",
"subscription-segment-onboarding",
"churn-prevention",
"cancellation-scheduled",
"subscription-frozen",
"subscription-unfrozen",
"subscription-upgraded",
"subscription-downgraded",
"subscription-resubscribed",
"subscription-declined",
"subscription-expired",
"trial-expiring",
"trial-expired",
"one-time-charge",
"capped-amount-alert",
"custom-field-segment-alert",
"usage-event-alert",
"usage-threshold-upsell"
],
"type": "string",
"description": "Template `key` from automations_catalog_get."
},
"organization_id": {
"type": "string",
"description": "An organisation uuid or slug. When supplied, `app_id` is resolved within that organisation and may be a slug instead of a uuid, mirroring the Meridian web app."
}
}
},
"annotations": {
"readOnlyHint": false,
"openWorldHint": false,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description88/100
Updates an automation's `name`, `description`, and/or draft `graph`.
Status cannot be set through MCP (activate/deactivate in the dashboard).
Graph updates are only allowed while the automation is **inactive**;
metadata updates are always allowed. Graphs must not include
`emailHtml`. Reference `emailUuid` instead. Takes `app_id` and
`automation_id` (scoped_id or uuid).
The description explains the capability, when to use it, and what to expect.
Inputs92/100
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
app_id
The app uuid returned by `apps_list`.
Clear enough to supply this argument.
organization_id
An organisation uuid or slug. When supplied, `app_id` is resolved within that organisation and may be a slug instead of a uuid, mirroring the Meridian web app.
Clear enough to supply this argument.
automation_id
The automation scoped_id or uuid returned by `automations_list`.
Clear enough to supply this argument.
name
New display name.
Clear enough to supply this argument.
description
New description, up to 2,000 characters. Pass null to clear.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
graph
Draft automation graph: `{nodes: [...], edges: [...]}`. Only accepted when the automation is inactive. Must not include emailHtml. A node has `node_id` (string), `type` (trigger, action or condition), `position` and `data`. An edge has `edge_id`, `source` and `target` (node ids), and `sourceHandle` (yes or no) when it leaves a condition. `id` and `key` are accepted in place of `node_id` / `edge_id` (priority `id`, then `node_id` / `edge_id`, then `key`). An edge with no identifier gets one; a node needs one. `templates[].graph` from `automations_catalog_get` and `graph` from `automation_get` can be passed as is.
Clear enough to supply this argument.
Annotations75/100
Declare idempotentHint based on the tool’s actual behavior.
No output schema is declared. Add one for structured results so clients can interpret returned fields.
Not declared
Original tool metadata
{
"name": "automation_update",
"title": "Update Automation",
"description": "Updates an automation's `name`, `description`, and/or draft `graph`.\nStatus cannot be set through MCP (activate/deactivate in the dashboard).\nGraph updates are only allowed while the automation is **inactive**;\nmetadata updates are always allowed. Graphs must not include\n`emailHtml`. Reference `emailUuid` instead. Takes `app_id` and\n`automation_id` (scoped_id or uuid).",
"inputSchema": {
"type": "object",
"required": [
"app_id",
"automation_id"
],
"properties": {
"name": {
"type": "string",
"description": "New display name."
},
"graph": {
"type": "object",
"description": "Draft automation graph: `{nodes: [...], edges: [...]}`. Only accepted when the automation is inactive. Must not include emailHtml. A node has `node_id` (string), `type` (trigger, action or condition), `position` and `data`. An edge has `edge_id`, `source` and `target` (node ids), and `sourceHandle` (yes or no) when it leaves a condition. `id` and `key` are accepted in place of `node_id` / `edge_id` (priority `id`, then `node_id` / `edge_id`, then `key`). An edge with no identifier gets one; a node needs one. `templates[].graph` from `automations_catalog_get` and `graph` from `automation_get` can be passed as is."
},
"app_id": {
"type": "string",
"description": "The app uuid returned by `apps_list`."
},
"description": {
"type": "string",
"maxLength": 2000,
"description": "New description, up to 2,000 characters. Pass null to clear."
},
"automation_id": {
"type": "string",
"description": "The automation scoped_id or uuid returned by `automations_list`."
},
"organization_id": {
"type": "string",
"description": "An organisation uuid or slug. When supplied, `app_id` is resolved within that organisation and may be a slug instead of a uuid, mirroring the Meridian web app."
}
}
},
"annotations": {
"readOnlyHint": false,
"openWorldHint": false,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description97/100
Dry-runs an automation against one store and returns the execution
trace (visited steps, condition outcomes, taken edges). Nothing is
sent, metered, or persisted. Provide either `shop_domain` (a CRM
store, or a store known only from the install your app reported) or
`custom_store` (synthetic attributes), XOR. Omit both
only when the saved graph never reads store data. Optional
`event_context` stands in for the triggering event's merge-tag values.
Takes `app_id` and `automation_id` (scoped_id or uuid). Requires
the `automations.edit` permission (the `update` ability on the
automation) and a strictly valid saved graph. A real store
(`shop_domain`) also requires `crm.merchants.view`; `custom_store`
and storeless runs do not.
The description explains the capability, when to use it, and what to expect.
Inputs77/100
Clarify units, where to obtain this value, or conventions not already expressed in the schema.
app_id
The app uuid returned by `apps_list`.
Clear enough to supply this argument.
organization_id
An organisation uuid or slug. When supplied, `app_id` is resolved within that organisation and may be a slug instead of a uuid, mirroring the Meridian web app.
Clear enough to supply this argument.
automation_id
The automation scoped_id or uuid returned by `automations_list`.
Clear enough to supply this argument.
shop_domain
Real store myshopify domain to dry-run against. XOR with custom_store.
Clarify units, where to obtain this value, or conventions not already expressed in the schema.
custom_store › subscription_status
Store status: installed (Active), frozen (Frozen), uninstalled (Churned).
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
custom_store › plan_name
Name of the app plan the store is on.
Explain the meaning of this value, not just its name.
custom_store › email
Store contact email. Omit it and Send Email steps trace as blocked: noRecipient. Nothing is sent.
Clear enough to supply this argument.
custom_store › monthly_revenue
Monthly revenue from the store.
Clarify units, where to obtain this value, or conventions not already expressed in the schema.
custom_store › total_revenue
Total revenue from the store.
Clarify units, where to obtain this value, or conventions not already expressed in the schema.
custom_store › total_charges
Number of charges billed to the store.
Clear enough to supply this argument.
custom_store › custom_fields
Custom field values, handle to value (see `custom_fields_list`).
Explain the meaning of this value, not just its name.
event_context
Optional map of trigger merge-tag variable name → string value for the dry-run.
Clear enough to supply this argument.
Annotations75/100
Declare idempotentHint based on the tool’s actual behavior.
No output schema is declared. Add one for structured results so clients can interpret returned fields.
Not declared
Original tool metadata
{
"name": "automation_test_run",
"title": "Test Run Automation",
"description": "Dry-runs an automation against one store and returns the execution\ntrace (visited steps, condition outcomes, taken edges). Nothing is\nsent, metered, or persisted. Provide either `shop_domain` (a CRM\nstore, or a store known only from the install your app reported) or\n`custom_store` (synthetic attributes), XOR. Omit both\nonly when the saved graph never reads store data. Optional\n`event_context` stands in for the triggering event's merge-tag values.\nTakes `app_id` and `automation_id` (scoped_id or uuid). Requires\nthe `automations.edit` permission (the `update` ability on the\nautomation) and a strictly valid saved graph. A real store\n(`shop_domain`) also requires `crm.merchants.view`; `custom_store`\nand storeless runs do not.",
"inputSchema": {
"type": "object",
"required": [
"app_id",
"automation_id"
],
"properties": {
"app_id": {
"type": "string",
"description": "The app uuid returned by `apps_list`."
},
"shop_domain": {
"type": "string",
"description": "Real store myshopify domain to dry-run against. XOR with custom_store."
},
"custom_store": {
"type": "object",
"required": [
"subscription_status",
"plan_name"
],
"properties": {
"email": {
"type": [
"string",
"null"
],
"format": "email",
"description": "Store contact email. Omit it and Send Email steps trace as blocked: noRecipient. Nothing is sent."
},
"plan_name": {
"type": "string",
"description": "Name of the app plan the store is on."
},
"custom_fields": {
"type": "object",
"description": "Custom field values, handle to value (see `custom_fields_list`)."
},
"total_charges": {
"type": "integer",
"minimum": 0,
"description": "Number of charges billed to the store."
},
"total_revenue": {
"type": "number",
"minimum": 0,
"description": "Total revenue from the store."
},
"monthly_revenue": {
"type": "number",
"minimum": 0,
"description": "Monthly revenue from the store."
},
"subscription_status": {
"enum": [
"installed",
"frozen",
"uninstalled"
],
"type": "string",
"description": "Store status: installed (Active), frozen (Frozen), uninstalled (Churned)."
}
},
"description": "Synthetic store attributes when no real store is available. XOR with shop_domain."
},
"automation_id": {
"type": "string",
"description": "The automation scoped_id or uuid returned by `automations_list`."
},
"event_context": {
"type": "object",
"description": "Optional map of trigger merge-tag variable name → string value for the dry-run."
},
"organization_id": {
"type": "string",
"description": "An organisation uuid or slug. When supplied, `app_id` is resolved within that organisation and may be a slug instead of a uuid, mirroring the Meridian web app."
}
}
},
"annotations": {
"readOnlyHint": false,
"openWorldHint": false,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description96/100
Lists an app's CRM segment definitions: `segment_id`, `handle`, `name`,
`description`, `conditions`, `matched_count`, and timestamps. Also
returns `total_stores` for the app's mirrored store universe. Never
dumps matching store membership. Takes the `app_id` returned by
`apps_list`.
The description explains the capability, when to use it, and what to expect.
Inputs96/100
Input documentation gives an agent enough context to populate the arguments.
app_id
The app uuid returned by `apps_list`.
Clear enough to supply this argument.
organization_id
An organisation uuid or slug. When supplied, `app_id` is resolved within that organisation and may be a slug instead of a uuid, mirroring the Meridian web app.
Clear enough to supply this argument.
Annotations75/100
Declare idempotentHint based on the tool’s actual behavior.
No output schema is declared. Add one for structured results so clients can interpret returned fields.
Not declared
Original tool metadata
{
"name": "crm_segments_list",
"title": "List CRM Segments",
"description": "Lists an app's CRM segment definitions: `segment_id`, `handle`, `name`,\n`description`, `conditions`, `matched_count`, and timestamps. Also\nreturns `total_stores` for the app's mirrored store universe. Never\ndumps matching store membership. Takes the `app_id` returned by\n`apps_list`.",
"inputSchema": {
"type": "object",
"required": [
"app_id"
],
"properties": {
"app_id": {
"type": "string",
"description": "The app uuid returned by `apps_list`."
},
"organization_id": {
"type": "string",
"description": "An organisation uuid or slug. When supplied, `app_id` is resolved within that organisation and may be a slug instead of a uuid, mirroring the Meridian web app."
}
}
},
"annotations": {
"readOnlyHint": true,
"openWorldHint": false,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description90/100
Returns one CRM segment definition: `segment_id`, `handle`, `name`,
`description`, `conditions`, `matched_count`, and timestamps. Takes
`app_id` and `segment_id` (uuid or handle from `crm_segments_list`).
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.
app_id
The app uuid returned by `apps_list`.
Clear enough to supply this argument.
organization_id
An organisation uuid or slug. When supplied, `app_id` is resolved within that organisation and may be a slug instead of a uuid, mirroring the Meridian web app.
Clear enough to supply this argument.
segment_id
The segment uuid or handle returned by `crm_segments_list`.
Clear enough to supply this argument.
Annotations75/100
Declare idempotentHint based on the tool’s actual behavior.
No output schema is declared. Add one for structured results so clients can interpret returned fields.
Not declared
Original tool metadata
{
"name": "crm_segment_get",
"title": "Get CRM Segment",
"description": "Returns one CRM segment definition: `segment_id`, `handle`, `name`,\n`description`, `conditions`, `matched_count`, and timestamps. Takes\n`app_id` and `segment_id` (uuid or handle from `crm_segments_list`).",
"inputSchema": {
"type": "object",
"required": [
"app_id",
"segment_id"
],
"properties": {
"app_id": {
"type": "string",
"description": "The app uuid returned by `apps_list`."
},
"segment_id": {
"type": "string",
"description": "The segment uuid or handle returned by `crm_segments_list`."
},
"organization_id": {
"type": "string",
"description": "An organisation uuid or slug. When supplied, `app_id` is resolved within that organisation and may be a slug instead of a uuid, mirroring the Meridian web app."
}
}
},
"annotations": {
"readOnlyHint": true,
"openWorldHint": false,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description88/100
Lists an app's Plan Builder discounts: `discount_id`, `handle`, `code`,
`name`, `description`, `status`, `type`, `value`, duration fields,
plan restrictions, availability, redemption limits, and timestamps.
Takes the `app_id` returned by `apps_list`.
The description explains the capability, when to use it, and what to expect.
Inputs95/100
Input documentation gives an agent enough context to populate the arguments.
app_id
The app uuid returned by `apps_list`.
Clear enough to supply this argument.
organization_id
An organisation uuid or slug. When supplied, `app_id` is resolved within that organisation and may be a slug instead of a uuid, mirroring the Meridian web app.
Clear enough to supply this argument.
Annotations75/100
Declare idempotentHint based on the tool’s actual behavior.
No output schema is declared. Add one for structured results so clients can interpret returned fields.
Not declared
Original tool metadata
{
"name": "discounts_list",
"title": "List Discounts",
"description": "Lists an app's Plan Builder discounts: `discount_id`, `handle`, `code`,\n`name`, `description`, `status`, `type`, `value`, duration fields,\nplan restrictions, availability, redemption limits, and timestamps.\nTakes the `app_id` returned by `apps_list`.",
"inputSchema": {
"type": "object",
"required": [
"app_id"
],
"properties": {
"app_id": {
"type": "string",
"description": "The app uuid returned by `apps_list`."
},
"organization_id": {
"type": "string",
"description": "An organisation uuid or slug. When supplied, `app_id` is resolved within that organisation and may be a slug instead of a uuid, mirroring the Meridian web app."
}
}
},
"annotations": {
"readOnlyHint": true,
"openWorldHint": false,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description89/100
Returns one Plan Builder discount. `discount_id` is resolved in order:
uuid, then app-local `handle`, then merchant-entered `code`
(case-insensitive). Takes the `app_id` returned by `apps_list`.
Describe the returned information so the agent knows whether it will answer the request.
Inputs91/100
Input documentation gives an agent enough context to populate the arguments.
app_id
The app uuid returned by `apps_list`.
Clear enough to supply this argument.
organization_id
An organisation uuid or slug. When supplied, `app_id` is resolved within that organisation and may be a slug instead of a uuid, mirroring the Meridian web app.
Clear enough to supply this argument.
discount_id
Discount uuid, handle, or code from `discounts_list`.
Clear enough to supply this argument.
Annotations75/100
Declare idempotentHint based on the tool’s actual behavior.
No output schema is declared. Add one for structured results so clients can interpret returned fields.
Not declared
Original tool metadata
{
"name": "discount_get",
"title": "Get Discount",
"description": "Returns one Plan Builder discount. `discount_id` is resolved in order:\nuuid, then app-local `handle`, then merchant-entered `code`\n(case-insensitive). Takes the `app_id` returned by `apps_list`.",
"inputSchema": {
"type": "object",
"required": [
"app_id",
"discount_id"
],
"properties": {
"app_id": {
"type": "string",
"description": "The app uuid returned by `apps_list`."
},
"discount_id": {
"type": "string",
"description": "Discount uuid, handle, or code from `discounts_list`."
},
"organization_id": {
"type": "string",
"description": "An organisation uuid or slug. When supplied, `app_id` is resolved within that organisation and may be a slug instead of a uuid, mirroring the Meridian web app."
}
}
},
"annotations": {
"readOnlyHint": true,
"openWorldHint": false,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description95/100
Creates a Plan Builder discount. Requires `name`, `status`, `type`
(`percentage` or `fixed_amount`), `value`, `duration` (`forever` or
`limited` with `duration_interval_count` billing cycles) and
`availability` (`all` stores or `specific` ones in
`specific_shop_domains`). A code discount needs `code` (unique per
app, stored uppercase): it applies when a merchant types it at
subscribe. With `auto_apply: true` it has no code and applies by
itself to every matching new subscription, so creating it active
REQUIRES `confirm: true`. Optional `plan_ids` restricts it to plans
(empty: every plan), `max_redemptions` caps its uses, `description`.
Subscriptions keep a discount they got after it is deactivated. Takes
the `app_id` returned by `apps_list`. Returns the same shape as
`discount_get`.
The description explains the capability, when to use it, and what to expect.
Inputs91/100
Explain the meaning of this value, not just its name.
app_id
The app uuid returned by `apps_list`.
Clear enough to supply this argument.
organization_id
An organisation uuid or slug. When supplied, `app_id` is resolved within that organisation and may be a slug instead of a uuid, mirroring the Meridian web app.
Clear enough to supply this argument.
name
Internal name of the discount.
Explain the meaning of this value, not just its name.
code
The code merchants type, stored uppercase and unique per app. Required unless `auto_apply` is true; an automatic discount has no code.
Clear enough to supply this argument.
description
Optional description.
Explain the meaning of this value, not just its name.
status
`active` applies it from now on; `inactive` keeps it off. Deactivate a discount with `inactive`.
Clear enough to supply this argument.
type
`percentage` off the plan price, or a `fixed_amount` in USD.
Clear enough to supply this argument.
value
The percentage (0.01 to 100) or the USD amount (min 0.01).
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
duration
`forever`, or `limited` to a number of billing cycles.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
duration_interval_count
Billing cycles the discount lasts. Required when `duration` is `limited`.
Clear enough to supply this argument.
plan_ids
Plan uuids (`plan_id` from `plans_list`) the discount is restricted to. Empty or omitted: every plan.
Clear enough to supply this argument.
availability
`all` stores, or `specific` stores listed in `specific_shop_domains`.
Clear enough to supply this argument.
specific_shop_domains
The *.myshopify.com domains allowed when `availability` is `specific`.
Clear enough to supply this argument.
max_redemptions
How many subscriptions may use it in total (min 1). Null: no limit.
Clear enough to supply this argument.
auto_apply
True for an automatic discount: applied to every matching new subscription without a code. Writing an active automatic discount requires `confirm: true`.
Clear enough to supply this argument.
confirm
Must be `true` when the write leaves an automatic discount active (anything beyond its name or description). Ignored otherwise.
Clear enough to supply this argument.
Annotations75/100
Declare idempotentHint based on the tool’s actual behavior.
No output schema is declared. Add one for structured results so clients can interpret returned fields.
Not declared
Original tool metadata
{
"name": "discount_create",
"title": "Create Discount",
"description": "Creates a Plan Builder discount. Requires `name`, `status`, `type`\n(`percentage` or `fixed_amount`), `value`, `duration` (`forever` or\n`limited` with `duration_interval_count` billing cycles) and\n`availability` (`all` stores or `specific` ones in\n`specific_shop_domains`). A code discount needs `code` (unique per\napp, stored uppercase): it applies when a merchant types it at\nsubscribe. With `auto_apply: true` it has no code and applies by\nitself to every matching new subscription, so creating it active\nREQUIRES `confirm: true`. Optional `plan_ids` restricts it to plans\n(empty: every plan), `max_redemptions` caps its uses, `description`.\nSubscriptions keep a discount they got after it is deactivated. Takes\nthe `app_id` returned by `apps_list`. Returns the same shape as\n`discount_get`.",
"inputSchema": {
"type": "object",
"required": [
"app_id",
"name",
"status",
"type",
"value",
"duration",
"availability"
],
"properties": {
"code": {
"type": [
"string",
"null"
],
"description": "The code merchants type, stored uppercase and unique per app. Required unless `auto_apply` is true; an automatic discount has no code."
},
"name": {
"type": "string",
"description": "Internal name of the discount."
},
"type": {
"enum": [
"percentage",
"fixed_amount"
],
"type": "string",
"description": "`percentage` off the plan price, or a `fixed_amount` in USD."
},
"value": {
"type": "number",
"description": "The percentage (0.01 to 100) or the USD amount (min 0.01)."
},
"app_id": {
"type": "string",
"description": "The app uuid returned by `apps_list`."
},
"status": {
"enum": [
"active",
"inactive"
],
"type": "string",
"description": "`active` applies it from now on; `inactive` keeps it off. Deactivate a discount with `inactive`."
},
"confirm": {
"type": "boolean",
"description": "Must be `true` when the write leaves an automatic discount active (anything beyond its name or description). Ignored otherwise."
},
"duration": {
"enum": [
"forever",
"limited"
],
"type": "string",
"description": "`forever`, or `limited` to a number of billing cycles."
},
"plan_ids": {
"type": "array",
"items": {
"type": "string"
},
"description": "Plan uuids (`plan_id` from `plans_list`) the discount is restricted to. Empty or omitted: every plan."
},
"auto_apply": {
"type": "boolean",
"description": "True for an automatic discount: applied to every matching new subscription without a code. Writing an active automatic discount requires `confirm: true`."
},
"description": {
"type": [
"string",
"null"
],
"description": "Optional description."
},
"availability": {
"enum": [
"all",
"specific"
],
"type": "string",
"description": "`all` stores, or `specific` stores listed in `specific_shop_domains`."
},
"max_redemptions": {
"type": [
"integer",
"null"
],
"description": "How many subscriptions may use it in total (min 1). Null: no limit."
},
"organization_id": {
"type": "string",
"description": "An organisation uuid or slug. When supplied, `app_id` is resolved within that organisation and may be a slug instead of a uuid, mirroring the Meridian web app."
},
"specific_shop_domains": {
"type": "array",
"items": {
"type": "string"
},
"description": "The *.myshopify.com domains allowed when `availability` is `specific`."
},
"duration_interval_count": {
"type": [
"integer",
"null"
],
"description": "Billing cycles the discount lasts. Required when `duration` is `limited`."
}
}
},
"annotations": {
"readOnlyHint": false,
"openWorldHint": false,
"destructiveHint": false
}
}
The title clearly communicates the tool’s action and subject. Keep it concise.
Description93/100
Edits a Plan Builder discount; only the fields sent change.
`discount_id` is its uuid, handle or code, as for `discount_get`.
Deactivate it with `status: inactive`: it stops applying to new
subscriptions, and the ones that already got it keep it. A write that
leaves an AUTOMATIC discount active REQUIRES `confirm: true`, unless it
only changes `name` or `description`. Takes the `app_id` returned by
`apps_list`. Returns the same shape as `discount_get`.
The description explains the capability, when to use it, and what to expect.
Inputs90/100
Explain the meaning of this value, not just its name.
app_id
The app uuid returned by `apps_list`.
Clear enough to supply this argument.
organization_id
An organisation uuid or slug. When supplied, `app_id` is resolved within that organisation and may be a slug instead of a uuid, mirroring the Meridian web app.
Clear enough to supply this argument.
discount_id
Discount uuid, handle or code from `discounts_list`.
Clear enough to supply this argument.
name
Internal name of the discount.
Explain the meaning of this value, not just its name.
code
The code merchants type, stored uppercase and unique per app. Required unless `auto_apply` is true; an automatic discount has no code.
Clear enough to supply this argument.
description
Optional description.
Explain the meaning of this value, not just its name.
status
`active` applies it from now on; `inactive` keeps it off. Deactivate a discount with `inactive`.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
type
`percentage` off the plan price, or a `fixed_amount` in USD.
Clear enough to supply this argument.
value
The percentage (0.01 to 100) or the USD amount (min 0.01).
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
duration
`forever`, or `limited` to a number of billing cycles.
Remove validation rules already expressed in this field’s schema; describe its meaning and usage instead.
duration_interval_count
Billing cycles the discount lasts. Required when `duration` is `limited`.
Clear enough to supply this argument.
plan_ids
Plan uuids (`plan_id` from `plans_list`) the discount is restricted to. Empty or omitted: every plan.
Clear enough to supply this argument.
availability
`all` stores, or `specific` stores listed in `specific_shop_domains`.
Clear enough to supply this argument.
specific_shop_domains
The *.myshopify.com domains allowed when `availability` is `specific`.
Clear enough to supply this argument.
max_redemptions
How many subscriptions may use it in total (min 1). Null: no limit.
Clear enough to supply this argument.
auto_apply
True for an automatic discount: applied to every matching new subscription without a code. Writing an active automatic discount requires `confirm: true`.
Clear enough to supply this argument.
confirm
Must be `true` when the write leaves an automatic discount active (anything beyond its name or description). Ignored otherwise.
Clear enough to supply this argument.
Annotations75/100
Declare idempotentHint based on the tool’s actual behavior.
No output schema is declared. Add one for structured results so clients can interpret returned fields.
Not declared
Original tool metadata
{
"name": "discount_update",
"title": "Update Discount",
"description": "Edits a Plan Builder discount; only the fields sent change.\n`discount_id` is its uuid, handle or code, as for `discount_get`.\nDeactivate it with `status: inactive`: it stops applying to new\nsubscriptions, and the ones that already got it keep it. A write that\nleaves an AUTOMATIC discount active REQUIRES `confirm: true`, unless it\nonly changes `name` or `description`. Takes the `app_id` returned by\n`apps_list`. Returns the same shape as `discount_get`.",
"inputSchema": {
"type": "object",
"required": [
"app_id",
"discount_id"
],
"properties": {
"code": {
"type": [
"string",
"null"
],
"description": "The code merchants type, stored uppercase and unique per app. Required unless `auto_apply` is true; an automatic discount has no code."
},
"name": {
"type": "string",
"description": "Internal name of the discount."
},
"type": {
"enum": [
"percentage",
"fixed_amount"
],
"type": "string",
"description": "`percentage` off the plan price, or a `fixed_amount` in USD."
},
"value": {
"type": "number",
"description": "The percentage (0.01 to 100) or the USD amount (min 0.01)."
},
"app_id": {
"type": "string",
"description": "The app uuid returned by `apps_list`."
},
"status": {
"enum": [
"active",
"inactive"
],
"type": "string",
"description": "`active` applies it from now on; `inactive` keeps it off. Deactivate a discount with `inactive`."
},
"confirm": {
"type": "boolean",
"description": "Must be `true` when the write leaves an automatic discount active (anything beyond its name or description). Ignored otherwise."
},
"duration": {
"enum": [
"forever",
"limited"
],
"type": "string",
"description": "`forever`, or `limited` to a number of billing cycles."
},
"plan_ids": {
"type": "array",
"items": {
"type": "string"
},
"description": "Plan uuids (`plan_id` from `plans_list`) the discount is restricted to. Empty or omitted: every plan."
},
"auto_apply": {
"type": "boolean",
"description": "True for an automatic discount: applied to every matching new subscription without a code. Writing an active automatic discount requires `confirm: true`."
},
"description": {
"type": [
"string",
"null"
],
"description": "Optional description."
},
"discount_id": {
"type": "string",
"description": "Discount uuid, handle or code from `discounts_list`."
},
"availability": {
"enum": [
"all",
"specific"
],
"type": "string",
"description": "`all` stores, or `specific` stores listed in `specific_shop_domains`."
},
"max_redemptions": {
"type": [
"integer",
"null"
],
"description": "How many subscriptions may use it in total (min 1). Null: no limit."
},
"organization_id": {
"type": "string",
"description": "An organisation uuid or slug. When supplied, `app_id` is resolved within that organisation and may be a slug instead of a uuid, mirroring the Meridian web app."
},
"specific_shop_domains": {
"type": "array",
"items": {
"type": "string"
},
"description": "The *.myshopify.com domains allowed when `availability` is `specific`."
},
"duration_interval_count": {
"type": [
"integer",
"null"
],
"description": "Billing cycles the discount lasts. Required when `duration` is `limited`."
}
}
},
"annotations": {
"readOnlyHint": false,
"openWorldHint": 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.
01Search DocumentationSearches Meridian's public product documentation (the same knowledge
02List AppsLists the Meridian apps visible to the calling user, across all of
03Get Documentation PageFetches one Meridian public product documentation page in full by
04Who Am IReturns the calling Meridian user's identity plus every organisation
05Get Automations CatalogReturns the static automation builder catalogs from Meridian config:
Want to run these tasks against your MCP server with us?
Meridian MCP setup, tools, quality score, publishing readiness, and alternatives.
How do I add Meridian MCP to Claude, ChatGPT, or Cursor?
Add Meridian MCP 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.the-meridian.ai/mcp.
Is Meridian MCP MCP ready for ChatGPT and Claude?
As of November 13, 2026, Meridian MCP scores 96/100 on Manufact's MCP publishing checklist. The scan meets ChatGPT publishing checks and meets Claude publishing checks. Passing these checks does not guarantee marketplace approval.
How clear is Meridian MCP's MCP tool documentation?
As of November 13, 2026, Meridian MCP scores 84/100 in Manufact's review of tool titles, descriptions, input and output schemas, and behavior annotations. The review covers 61 of 61 discovered tools. The quality score measures documentation clarity; runtime behavior and marketplace readiness require separate checks.
What are the best alternatives to Meridian MCP?
As of November 13, 2026, alternatives to Meridian MCP in developer-tools on the Manufact MCP leaderboard include Speko, Manufact, AgentMail, Context, and Speko.
How can Meridian MCP improve its MCP documentation?
docs_search is the lowest-scoring reviewed tool at 79/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.
Not your MCP?
Review any public or OAuth MCP server for protocol compatibility, tool documentation, and ChatGPT and Claude publishing readiness. No account required.