EchoRelay
by echorelay.dev · remote · no sign-in to list tools · v0.13.0 · published by dev.echorelay
A managed runtime for custom API integrations. Manage lines, endpoints, keys, logs and DLQ via MCP.
80 tools: 30 can delete or cancel things, 3 do something that can't be undone, 17 change things and 30 only read.
Scanned Oct 21, 2026
- Deletes or cancels30Claude Code: deny: see these tools
- Can't be undone3Claude Code: ask: see these tools
- Changes things17Claude Code: ask: see these tools
- Only reads30Claude Code: allow: see these tools
27 checks matched something in the tool definitions. No finding is not a safety guarantee. How the checks work.
claude mcp add --transport http management https://mcp.echorelay.dev --header 'Authorization: <your-authorization>'Findings
Matches of fixed checks, with the text they matched.
- Warndry_run_endpoint
The server marks "dry_run_endpoint" read-only (readOnlyHint: true), and its own name, description or input give the class "write".
What this check looks forMatched text
annotations: {"readOnlyHint":true,"destructiveHint":false}; The name "dry_run_endpoint" says "run": a word for a change.
- Infocreate_endpoint
The input schema at properties.endpoint.properties.senderSignature.description mentions "credential".
What this check looks forMatched text
inputSchema.properties.endpoint.properties.senderSignature.description: "...needs your API key. `credentialId` is a credential of type signingSecret (create_credentia..."
- Infocreate_endpoint
The input schema at properties.endpoint.properties.senderSignature.properties.credentialId.description mentions "credential".
What this check looks forMatched text
inputSchema.properties.endpoint.properties.senderSignature.properties.credentialId.description: "UUID of the signingSecret credential holding the sender's secret."
- Infocreate_endpoint
The input schema at properties.endpoint.properties.targets.items.properties.auth.properties.clientAuth.description mentions "credentials".
What this check looks forMatched text
inputSchema.properties.endpoint.properties.targets.items.properties.auth.properties.clientAuth.description: "...oauthClientCredentials only. How client credentials are sent to the token URL: basic (Autho..."
- Infocreate_endpoint
The input schema at properties.endpoint.properties.targets.items.properties.credentialVaultEntryId.description mentions "credential".
What this check looks forMatched text
inputSchema.properties.endpoint.properties.targets.items.properties.credentialVaultEntryId.description: "References a saved credential (see list_credentials/create_credential..."
- Infoupdate_endpoint
The input schema at properties.patch.properties.senderSignature.description mentions "credential".
What this check looks forMatched text
inputSchema.properties.patch.properties.senderSignature.description: "...needs your API key. `credentialId` is a credential of type signingSecret (create_credentia..."
Show 21 more findingsShow fewer
- Infoupdate_endpoint
The input schema at properties.patch.properties.senderSignature.properties.credentialId.description mentions "credential".
What this check looks forMatched text
inputSchema.properties.patch.properties.senderSignature.properties.credentialId.description: "UUID of the signingSecret credential holding the sender's secret."
- Infoupdate_endpoint
The input schema at properties.patch.properties.targets.items.properties.auth.properties.clientAuth.description mentions "credentials".
What this check looks forMatched text
inputSchema.properties.patch.properties.targets.items.properties.auth.properties.clientAuth.description: "...oauthClientCredentials only. How client credentials are sent to the token URL: basic (Autho..."
- Infoupdate_endpoint
The input schema at properties.patch.properties.targets.items.properties.credentialVaultEntryId.description mentions "credential".
What this check looks forMatched text
inputSchema.properties.patch.properties.targets.items.properties.credentialVaultEntryId.description: "References a saved credential (see list_credentials/create_credential..."
- Infodry_run_endpoint
The input schema at properties.endpoint.properties.senderSignature.description mentions "credential".
What this check looks forMatched text
inputSchema.properties.endpoint.properties.senderSignature.description: "...needs your API key. `credentialId` is a credential of type signingSecret (create_credentia..."
- Infodry_run_endpoint
The input schema at properties.endpoint.properties.senderSignature.properties.credentialId.description mentions "credential".
What this check looks forMatched text
inputSchema.properties.endpoint.properties.senderSignature.properties.credentialId.description: "UUID of the signingSecret credential holding the sender's secret."
- Infodry_run_endpoint
The input schema at properties.endpoint.properties.targets.items.properties.auth.properties.clientAuth.description mentions "credentials".
What this check looks forMatched text
inputSchema.properties.endpoint.properties.targets.items.properties.auth.properties.clientAuth.description: "...oauthClientCredentials only. How client credentials are sent to the token URL: basic (Autho..."
- Infodry_run_endpoint
The input schema at properties.endpoint.properties.targets.items.properties.credentialVaultEntryId.description mentions "credential".
What this check looks forMatched text
inputSchema.properties.endpoint.properties.targets.items.properties.credentialVaultEntryId.description: "References a saved credential (see list_credentials/create_credential..."
- Infolist_credentials
The annotations title mentions "credentials".
What this check looks forMatched text
annotations.title: "List credentials"
- Infolist_credentials
The description mentions "credentials".
What this check looks forMatched text
description: "List the project's saved credentials — reusable target-auth secrets that can..."
The annotations title mentions "credential".
What this check looks forMatched text
annotations.title: "Create credential"
The description mentions "credential".
What this check looks forMatched text
description: "Save a new reusable credential, sealed with the project's encryption k..."
The input schema at properties.destinationHost.description mentions "credential".
What this check looks forMatched text
inputSchema.properties.destinationHost.description: "The only host this credential may be sent to, e.g. "api.stripe.com",..."
The input schema at properties.auth.description mentions "credential".
What this check looks forMatched text
inputSchema.properties.auth.description: "The credential's auth shape."
The input schema at properties.auth.properties.clientAuth.description mentions "credentials".
What this check looks forMatched text
inputSchema.properties.auth.properties.clientAuth.description: "...nly. "basic" (default) sends the client credentials in an Authorization header, "post" in t..."
The annotations title mentions "credential".
What this check looks forMatched text
annotations.title: "Update credential"
The description mentions "credential".
What this check looks forMatched text
description: "Rename a credential and/or rotate its secret, publishing th..."
The input schema at properties.credentialId.description mentions "credential".
What this check looks forMatched text
inputSchema.properties.credentialId.description: "UUID of the credential (from list_credentials)."
The input schema at properties.destinationHost.description mentions "credential".
What this check looks forMatched text
inputSchema.properties.destinationHost.description: "Permanent — may only restate the credential's current host (omit it, or send back w..."
The annotations title mentions "credential".
What this check looks forMatched text
annotations.title: "Delete credential"
The description mentions "credential".
What this check looks forMatched text
description: "Delete a saved credential. Blocked (not a permission or not-found..."
The input schema at properties.credentialId.description mentions "credential".
What this check looks forMatched text
inputSchema.properties.credentialId.description: "UUID of the credential to delete."
Tools
Open a tool for its reasons and full description. Descriptions are the publisher's own words, shown as they are.
80 tools
Deletes or cancels 30Claude Code: deny
archive_projectArchive a project you own.No findings
Why it is in this group
- The name "archive_project" says "archive": a word for removing or ending something.
- The server marks it destructive (destructiveHint: true).
Description, as the server wrote it Archive a project you own. Reversible: the project + slug persist and credits are kept, but the data plane drops the tenant (callers get 404). Idempotent. Fails with an error if the project has archive protection enabled. That is a support-only unlock, not something this call can override. Requires an ACCOUNT-scoped management token and the `config` scope.
Annotations the server declares
- title: Archive project
- readOnlyHint: false
- destructiveHint: true
cancel_line_publishCancel one line schedule before its two-minute lock.No findings
Why it is in this group
- The name "cancel_line_publish" says "cancel": a word for removing or ending something.
- The server marks it destructive (destructiveHint: true).
Description, as the server wrote it Cancel one line schedule before its two-minute lock.
Annotations the server declares
- title: Cancel line publish
- readOnlyHint: false
- destructiveHint: true
cancel_subscriptionSchedule the project owner's subscription for cancellation at the end of the current billing period.No findings
Why it is in this group
- The name "cancel_subscription" says "cancel": a word for removing or ending something.
- The server marks it destructive (destructiveHint: true).
Description, as the server wrote it Schedule the project owner's subscription for cancellation at the end of the current billing period. Returns `{kind: 'scheduled', newPlan: 'free', effectiveAt}`. Add-ons keep renewing while the plan is active; after it ends they stop renewing and each already-paid add-on cycle stays active until its own end date (use unsubscribe_addon to stop one sooner). Owner-only; requires a token minted with the billing scope.
Annotations the server declares
- title: Cancel subscription
- readOnlyHint: false
- destructiveHint: true
change_planSwitch the project owner between Pro and Scale, or cancel the subscription (effectively dropping to Free at period end).No findings
Why it is in this group
- Nothing in its name or description says what it does, so it is counted as a write.
- The server marks it destructive (destructiveHint: true).
Description, as the server wrote it Switch the project owner between Pro and Scale, or cancel the subscription (effectively dropping to Free at period end). Returns `{kind, newPlan, effectiveAt, applied}` — `applied=true` means Paddle was charged immediately, otherwise the change is queued for the current period end. Use preview_plan_change first to see the dollar impact. Owner-only; requires a token minted with the billing scope.
Annotations the server declares
- title: Change plan
- readOnlyHint: false
- destructiveHint: true
deactivate_lineTake a line off the data plane immediately (callers get 404) without deleting it — endpoints/targets/config are preserved and it can be reactivated later.No findings
Why it is in this group
- Nothing in its name or description says what it does, so it is counted as a write.
- The server marks it destructive (destructiveHint: true).
Description, as the server wrote it Take a line off the data plane immediately (callers get 404) without deleting it — endpoints/targets/config are preserved and it can be reactivated later. A deliberate action; live traffic is never auto-disabled. Requires edit access.
Annotations the server declares
- title: Deactivate line
- readOnlyHint: false
- destructiveHint: true
delete_credentialDelete a saved credential.3 findings
Why it is in this group
- The name "delete_credential" says "delete": a word for removing or ending something.
- The server marks it destructive (destructiveHint: true).
Findings
- Info
The annotations title mentions "credential".
What this check looks forMatched text
annotations.title: "Delete credential"
- Info
The description mentions "credential".
What this check looks forMatched text
description: "Delete a saved credential. Blocked (not a permission or not-found..."
- Info
The input schema at properties.credentialId.description mentions "credential".
What this check looks forMatched text
inputSchema.properties.credentialId.description: "UUID of the credential to delete."
Description, as the server wrote it Delete a saved credential. Blocked (not a permission or not-found error — a validation error) while any target still references it; repoint or remove those targets first.
Annotations the server declares
- title: Delete credential
- readOnlyHint: false
- destructiveHint: true
delete_endpointDelete an endpoint and its targets, immediately or by staging the removal in the line's draft with commitMode "draft" and draftRevision (returns `{draft}` instead of deleting right…No findings
Why it is in this group
- The name "delete_endpoint" says "delete": a word for removing or ending something.
- The server marks it destructive (destructiveHint: true).
Description, as the server wrote it Delete an endpoint and its targets, immediately or by staging the removal in the line's draft with commitMode "draft" and draftRevision (returns `{draft}` instead of deleting right away). An immediate delete publishes a new revision without the endpoint and returns `{deleted: true, endpointId}`, but the line's prior revision still has it, so list_config_revisions can find that revision and rollback_config can republish over the deletion. Errors when `lineKey`/`endpointId` is missing, the line or endpoint doesn't exist, the draft revision is stale, removing the endpoint would leave an active line with no endpoints, or the publish is refused (a rejected target mapping or an outbound-allowlist violation is a validation error; a publish the platform could not verify is retryable). Requires edit access.
Annotations the server declares
- title: Delete endpoint
- readOnlyHint: false
- destructiveHint: true
delete_lineDelete a line and every endpoint under it, immediately or by staging the removal in the line's draft with commitMode "draft" and draftRevision (returns `{draft}`, discardable via d…No findings
Why it is in this group
- The name "delete_line" says "delete": a word for removing or ending something.
- The server marks it destructive (destructiveHint: true).
Description, as the server wrote it Delete a line and every endpoint under it, immediately or by staging the removal in the line's draft with commitMode "draft" and draftRevision (returns `{draft}`, discardable via discard_line_draft, instead of deleting right away). An immediate delete removes the line's own revision history along with it, so list_config_revisions has nothing left to list and rollback_config cannot bring the line back. Errors when `lineKey` is missing, doesn't match a line in the project, or the draft revision is stale. Requires edit access.
Annotations the server declares
- title: Delete line
- readOnlyHint: false
- destructiveHint: true
discard_dlq_entryPermanently delete a DLQ entry without retrying it: the delivery is never re-sent and the entry cannot be restored.No findings
Why it is in this group
- The description's first verb is "delete": a word for removing or ending something.
- The description says "Permanently delete".
- The server marks it destructive (destructiveHint: true).
Description, as the server wrote it Permanently delete a DLQ entry without retrying it: the delivery is never re-sent and the entry cannot be restored. Use retry_dlq_entry instead when the delivery should still reach its target. The inbound request stays answerable through get_request for the project's requestLogRetentionDays window. Errors if the entry is already gone (retried, discarded, purged or evicted). Requires edit access.
Annotations the server declares
- title: Discard DLQ entry
- readOnlyHint: false
- destructiveHint: true
discard_draft_endpointDiscard one endpoint change from a line draft.No findings
Why it is in this group
- Nothing in its name or description says what it does, so it is counted as a write.
- The server marks it destructive (destructiveHint: true).
Description, as the server wrote it Discard one endpoint change from a line draft.
Annotations the server declares
- title: Discard draft endpoint
- readOnlyHint: false
- destructiveHint: true
discard_line_draftDiscard every unpublished change and schedule for one line.No findings
Why it is in this group
- Nothing in its name or description says what it does, so it is counted as a write.
- The server marks it destructive (destructiveHint: true).
Description, as the server wrote it Discard every unpublished change and schedule for one line.
Annotations the server declares
- title: Discard line draft
- readOnlyHint: false
- destructiveHint: true
downgrade_addonSchedule a tier downgrade for a non-stackable add-on (RPM tier).No findings
Why it is in this group
- The description's first verb is "schedule": a word for a change.
- The server marks it destructive (destructiveHint: true).
Description, as the server wrote it Schedule a tier downgrade for a non-stackable add-on (RPM tier). The current tier stays active until `nextRenewalAt`; at that point the lower tier is charged and activated. No mid-cycle charge. Use list_addons to find available keys. Returns {addonKey, targetAddonKey, project, effectiveAt}. Owner-only; requires a token minted with the billing scope.
Annotations the server declares
- title: Schedule add-on downgrade
- readOnlyHint: false
- destructiveHint: true
publish_line_draftPublish one line draft now and clear only its schedule.No findings
Why it is in this group
- The name "publish_line_draft" says "publish": a word for a change that another call does not undo.
- The server marks it destructive (destructiveHint: true).
Description, as the server wrote it Publish one line draft now and clear only its schedule.
Annotations the server declares
- title: Publish line draft
- readOnlyHint: false
- destructiveHint: true
remove_memberRemove a member (accepted or pending) from this project by memberId or email, matching the first record found; returns `{message, email}`.No findings
Why it is in this group
- The name "remove_member" says "remove": a word for removing or ending something.
- The server marks it destructive (destructiveHint: true).
Description, as the server wrote it Remove a member (accepted or pending) from this project by memberId or email, matching the first record found; returns `{message, email}`. This deletes the membership record outright with no undo, so getting the person back onto the project takes a fresh invite_member call, not a restore. Errors when neither `memberId` nor `email` is given, no member matches, the caller isn't the project owner, or the token lacks the config scope. Owner only.
Annotations the server declares
- title: Remove member
- readOnlyHint: false
- destructiveHint: true
rename_projectRename a project you own (the display name only: the slug, which identifies the project in URLs and API paths, never changes).No findings
Why it is in this group
- The name "rename_project" says "rename": a word for a change.
- The server marks it destructive (destructiveHint: true).
Description, as the server wrote it Rename a project you own (the display name only: the slug, which identifies the project in URLs and API paths, never changes). Requires an ACCOUNT-scoped management token and the `config` scope. 404-equivalent error when you do not own the slug.
Annotations the server declares
- title: Rename project
- readOnlyHint: false
- destructiveHint: true
revoke_api_keyRevoke a key immediately: it stops authenticating as soon as the change reaches the relay, with no overlap window, so callers still using it start failing.No findings
Why it is in this group
- The name "revoke_api_key" says "revoke": a word for removing or ending something.
- The server marks it destructive (destructiveHint: true).
Description, as the server wrote it Revoke a key immediately: it stops authenticating as soon as the change reaches the relay, with no overlap window, so callers still using it start failing. To replace a key without downtime, use rotate_api_key instead; if the key already has a successor, fetch it with reveal_rotation_successor, because rotate_api_key refuses a key that has one. Revoking a successor leaves its predecessor unable to rotate again. Owner anywhere, editor on own keys.
Annotations the server declares
- title: Revoke API key
- readOnlyHint: false
- destructiveHint: true
revoke_project_tokenRevoke a PROJECT-scoped management token on a project you own, any holder's, not just your own (the account-owner kill switch for a leaked or retired integration's management token…No findings
Why it is in this group
- The name "revoke_project_token" says "revoke": a word for removing or ending something.
- The server marks it destructive (destructiveHint: true).
Description, as the server wrote it Revoke a PROJECT-scoped management token on a project you own, any holder's, not just your own (the account-owner kill switch for a leaked or retired integration's management token). Soft-revoke: the row stays for traceability and the management token is rejected immediately. Idempotent. Requires an ACCOUNT-scoped management token and the `config` scope.
Annotations the server declares
- title: Revoke project management token
- readOnlyHint: false
- destructiveHint: true
rollback_configPreview or apply publishing a retained line revision over what is currently published, clearing any pending schedule.No findings
Why it is in this group
- The description's first verb is "preview": a word for reading.
- The server marks it destructive (destructiveHint: true).
Description, as the server wrote it Preview or apply publishing a retained line revision over what is currently published, clearing any pending schedule. Without confirmRevision this only returns the diff (the redacted change-gate preview, same shape as config_diff) between what is currently published and the target revision — it changes nothing. To apply, call again with confirmRevision set to the diff's currentRevision; if a publish landed since the preview, confirmRevision is now stale and the call is refused with error "rollback_confirmation_conflict" instead of silently overwriting the newer publish — read the fresh diff and confirm again. Applying also requires confirmUnsigned, the preview's unsignedFingerprint, so a signing secret expiring between the preview and the confirm cannot roll a target back unsigned without you having seen it named.
Annotations the server declares
- title: Roll back config
- readOnlyHint: false
- destructiveHint: true
rotate_api_keyMint a linked successor for an existing key.No findings
Why it is in this group
- Nothing in its name or description says what it does, so it is counted as a write.
- The server marks it destructive (destructiveHint: true).
Description, as the server wrote it Mint a linked successor for an existing key. Returns the successor plaintext exactly once — store it now. The predecessor stays valid through its overlap window so callers can swap without downtime. Owner anywhere, editor on own keys.
Annotations the server declares
- title: Rotate API key
- readOnlyHint: false
- destructiveHint: true
schedule_line_publishSchedule one non-empty line draft.No findings
Why it is in this group
- The name "schedule_line_publish" says "schedule": a word for a change.
- The server marks it destructive (destructiveHint: true).
Description, as the server wrote it Schedule one non-empty line draft. Active subscribers required.
Annotations the server declares
- title: Schedule line publish
- readOnlyHint: false
- destructiveHint: true
set_burst_opt_inEnable or disable the auto-decaying burst window for live traffic and publish the change immediately.No findings
Why it is in this group
- The name "set_burst_opt_in" says "set": a word for a change.
- The server marks it destructive (destructiveHint: true).
Description, as the server wrote it Enable or disable the auto-decaying burst window for live traffic and publish the change immediately. When enabled, brief spikes a little above your steady RPM cap are absorbed at the normal credit rate (no surcharge, no burst SKU) instead of being rejected. Sustained overage decays back to your steady cap; headroom returns once traffic cools below the cap or you add RPM. Burst usage is tracked so you can see when to upgrade. Default is off (steady cap is a hard 429). Requires edit access.
Annotations the server declares
- title: Set burst opt-in
- readOnlyHint: false
- destructiveHint: true
set_key_policyOwner-only.No findings
Why it is in this group
- The name "set_key_policy" says "set": a word for a change.
- The server marks it destructive (destructiveHint: true).
Description, as the server wrote it Owner-only. Edit the project's key policy. Only fields present in the patch are touched. Editors calling this get an error — use get_key_policy to read.
Annotations the server declares
- title: Set key policy
- readOnlyHint: false
- destructiveHint: true
set_member_roleChange a member's role between editor, viewer, and billing.No findings
Why it is in this group
- The name "set_member_role" says "set": a word for a change.
- The server marks it destructive (destructiveHint: true).
Description, as the server wrote it Change a member's role between editor, viewer, and billing. Identify the member by their member ID or email (from list_members); the project owner's own role cannot be changed. Returns the updated member record. Owner only.
Annotations the server declares
- title: Set member role
- readOnlyHint: false
- destructiveHint: true
set_outbound_allowlistNarrow the project's outbound host allowlist — the hosts a target may point at.No findings
Why it is in this group
- The name "set_outbound_allowlist" says "set": a word for a change.
- The server marks it destructive (destructiveHint: true).
Description, as the server wrote it Narrow the project's outbound host allowlist — the hosts a target may point at. The current list is on get_project as `outboundHostAllowlist` (empty means any public host). This tool may only narrow it: `patterns` must be a strict subset of, or equal to, the current list, compared as exact strings — submitting a wildcard that would cover an existing exact host, or clearing to empty, is refused as a widen. Widening the list is web-only, in the panel. Refused when the project already has a target (inactive lines included) outside the submitted list. Requires edit access.
Annotations the server declares
- title: Narrow outbound host allowlist
- readOnlyHint: false
- destructiveHint: true
set_overage_billingTurn the project owner's overage billing on or off, for the whole account.No findings
Why it is in this group
- The name "set_overage_billing" says "set": a word for a change.
- The server marks it destructive (destructiveHint: true).
Description, as the server wrote it Turn the project owner's overage billing on or off, for the whole account. Returns `{overageBilling}`, the setting get_billing reads back. Owner-only; requires a token minted with the billing scope.
Annotations the server declares
- title: Set overage billing
- readOnlyHint: false
- destructiveHint: true
set_rpm_ceilingSet or clear a self-set ceiling on this project's own effective live-traffic RPM (Traffic shaping) — for when your origin can't take the throughput your plan grants.No findings
Why it is in this group
- The name "set_rpm_ceiling" says "set": a word for a change.
- The server marks it destructive (destructiveHint: true).
Description, as the server wrote it Set or clear a self-set ceiling on this project's own effective live-traffic RPM (Traffic shaping) — for when your origin can't take the throughput your plan grants. Never plan-gated: the ceiling can only LOWER your effective RPM below your plan/add-on rate, never raise it, and never touches billing. Steady traffic is capped at the ceiling; if Burst Protect is on, its headroom is measured above the ceiling, not above the plan rate. The current value is on get_project as `rpmCeiling` (null = no ceiling). Requires edit access.
Annotations the server declares
- title: Set RPM ceiling
- readOnlyHint: false
- destructiveHint: true
unsubscribe_addonCancel an active add-on subscription.No findings
Why it is in this group
- The name "unsubscribe_addon" says "unsubscribe": a word for a change.
- The description's first verb is "cancel": a word for removing or ending something.
- The server marks it destructive (destructiveHint: true).
Description, as the server wrote it Cancel an active add-on subscription. Stops future charges; the current cycle stays active until expiry. RPM upgrades are cancelled for THIS project. Returns `{addonKey, project, cancelledAt}`. Owner-only; requires a token minted with the billing scope.
Annotations the server declares
- title: Unsubscribe add-on
- readOnlyHint: false
- destructiveHint: true
update_credentialRename a credential and/or rotate its secret, publishing the change immediately so every target that uses this credential picks it up right away.4 findings
Why it is in this group
- The name "update_credential" says "update": a word for a change.
- The server marks it destructive (destructiveHint: true).
Findings
- Info
The annotations title mentions "credential".
What this check looks forMatched text
annotations.title: "Update credential"
- Info
The description mentions "credential".
What this check looks forMatched text
description: "Rename a credential and/or rotate its secret, publishing th..."
- Info
The input schema at properties.credentialId.description mentions "credential".
What this check looks forMatched text
inputSchema.properties.credentialId.description: "UUID of the credential (from list_credentials)."
- Info
The input schema at properties.destinationHost.description mentions "credential".
What this check looks forMatched text
inputSchema.properties.destinationHost.description: "Permanent — may only restate the credential's current host (omit it, or send back w..."
Description, as the server wrote it Rename a credential and/or rotate its secret, publishing the change immediately so every target that uses this credential picks it up right away. Omit a secret field (or the whole `auth` object) to keep the existing value — the vault can never show a secret back to confirm it, so leaving it out means "unchanged," not "cleared." The destination host cannot be changed here: create a new credential for a new destination.
Annotations the server declares
- title: Update credential
- readOnlyHint: false
- destructiveHint: true
update_endpointUpdate an endpoint immediately or by staging the change in its line draft with commitMode "draft" and draftRevision; the patch is merged field-by-field onto the endpoint's current …4 findings
Why it is in this group
- The name "update_endpoint" says "update": a word for a change.
- The server marks it destructive (destructiveHint: true).
Findings
- Info
The input schema at properties.patch.properties.senderSignature.description mentions "credential".
What this check looks forMatched text
inputSchema.properties.patch.properties.senderSignature.description: "...needs your API key. `credentialId` is a credential of type signingSecret (create_credentia..."
- Info
The input schema at properties.patch.properties.senderSignature.properties.credentialId.description mentions "credential".
What this check looks forMatched text
inputSchema.properties.patch.properties.senderSignature.properties.credentialId.description: "UUID of the signingSecret credential holding the sender's secret."
- Info
The input schema at properties.patch.properties.targets.items.properties.auth.properties.clientAuth.description mentions "credentials".
What this check looks forMatched text
inputSchema.properties.patch.properties.targets.items.properties.auth.properties.clientAuth.description: "...oauthClientCredentials only. How client credentials are sent to the token URL: basic (Autho..."
- Info
The input schema at properties.patch.properties.targets.items.properties.credentialVaultEntryId.description mentions "credential".
What this check looks forMatched text
inputSchema.properties.patch.properties.targets.items.properties.credentialVaultEntryId.description: "References a saved credential (see list_credentials/create_credential..."
Description, as the server wrote it Update an endpoint immediately or by staging the change in its line draft with commitMode "draft" and draftRevision; the patch is merged field-by-field onto the endpoint's current values, so omitted keys keep their values. Targets are matched by the `id` get_endpoint returned; without one, by the same `name` and `targetUrl` (when only one stored target has that pair); without either, a patch to the target in the same position matches it, as long as the list keeps its length, the patch doesn't change both its `name` and `targetUrl`, and a changed `targetUrl` stays on the same host. A matched target keeps its stored secrets (auth and signingSecret) when they are omitted or redacted; an unmatched target is new, must carry its secrets, and a redacted `***` on it is rejected. An immediate update treats a target that exists only in the line draft as unmatched. Draft mode returns `{draft}`; an immediate update returns `{endpoint, scheduledAt}` with the endpoint's full updated document. Errors on a missing `lineKey`/`endpointId`, an unknown line or endpoint, a patch that fails validation (including a rejected target mapping or an outbound-allowlist violation), or a stale draftRevision. Requires edit access.
Annotations the server declares
- title: Update endpoint
- readOnlyHint: false
- destructiveHint: true
Can't be undone 3Claude Code: ask
invite_memberInvite a person by email to collaborate on this project.No findings
Why it is in this group
- The name "invite_member" says "invite": a word for sending, and what is sent cannot be taken back.
Description, as the server wrote it Invite a person by email to collaborate on this project. Returns the new invitation record; the invitee receives an email with an accept link. Enforces the seat cap for the plan tier. Owner only.
Annotations the server declares
- title: Invite member
- readOnlyHint: false
- destructiveHint: false
resend_inviteRe-send the invitation email for a still-pending invite, by member ID or email (from list_members).No findings
Why it is in this group
- The name "resend_invite" says "resend": a word for sending, and what is sent cannot be taken back.
Description, as the server wrote it Re-send the invitation email for a still-pending invite, by member ID or email (from list_members). The original accept link is reused. Already-accepted members are rejected. Owner only.
Annotations the server declares
- title: Resend invite
- readOnlyHint: false
- destructiveHint: false
start_topupBegin a credit-pack top-up for the project owner.No findings
Why it is in this group
- The name "start_topup" says "start": a word for a change.
- The name "start_topup" also says "topup": a word that usually means money moves, which cannot be taken back.
Description, as the server wrote it Begin a credit-pack top-up for the project owner. Pass the pack`s `eurCents` (from list_credit_packs). Returns `{checkoutUrl, credits, eurCents, directCharge}` or `{transactionId, credits, eurCents, directCharge:true}` on subsequent MCP purchases. Owner-only; requires a token minted with the billing scope.
Annotations the server declares
- title: Start credit top-up
- readOnlyHint: false
- destructiveHint: false
Changes things 17Claude Code: ask
activate_lineActivate and immediately publish an inactive line so it serves traffic again.No findings
Why it is in this group
- Nothing in its name or description says what it does, so it is counted as a write.
Description, as the server wrote it Activate and immediately publish an inactive line so it serves traffic again. Blocked at the active-line cap — deactivate another line first. Requires edit access.
Annotations the server declares
- title: Activate line
- readOnlyHint: false
- destructiveHint: false
create_api_keyMint an inbound relay (data-plane) API key for callers to send traffic to this project.No findings
Why it is in this group
- The name "create_api_key" says "create": a word for a change.
Description, as the server wrote it Mint an inbound relay (data-plane) API key for callers to send traffic to this project. Its `er_live_` or `er_test_` secret authenticates relay requests; it cannot call management MCP or REST. Returns the plaintext exactly once — store it now, it cannot be retrieved later. Editor + owner; subject to the project key policy (see get_key_policy).
Annotations the server declares
- title: Create API key
- readOnlyHint: false
- destructiveHint: false
create_credentialSave a new reusable credential, sealed with the project's encryption key at write time.5 findings
Why it is in this group
- The name "create_credential" says "create": a word for a change.
Findings
- Info
The annotations title mentions "credential".
What this check looks forMatched text
annotations.title: "Create credential"
- Info
The description mentions "credential".
What this check looks forMatched text
description: "Save a new reusable credential, sealed with the project's encryption k..."
- Info
The input schema at properties.destinationHost.description mentions "credential".
What this check looks forMatched text
inputSchema.properties.destinationHost.description: "The only host this credential may be sent to, e.g. "api.stripe.com",..."
- Info
The input schema at properties.auth.description mentions "credential".
What this check looks forMatched text
inputSchema.properties.auth.description: "The credential's auth shape."
- Info
The input schema at properties.auth.properties.clientAuth.description mentions "credentials".
What this check looks forMatched text
inputSchema.properties.auth.properties.clientAuth.description: "...nly. "basic" (default) sends the client credentials in an Authorization header, "post" in t..."
Description, as the server wrote it Save a new reusable credential, sealed with the project's encryption key at write time. Neither this call nor any later read ever returns the secret back — reference it from a target by id (see create_endpoint/update_endpoint's target.credentialVaultEntryId) instead of copying the secret around. `auth.type` selects which fields apply: bearer→token, basic→username+password, apiKeyHeader→headerName+key, apiKeyQuery→paramName+key, publicPrivateKey→secret+key, oauthClientCredentials→tokenUrl+clientId+clientSecret (+ optional scope, audience, clientAuth "basic"|"post"; the access token is fetched at delivery, and clientSecret is never returned. The client secret is only ever sent to tokenUrl, and the access token only to the bound destinationHost; tokenUrl is permanent like destinationHost — it must pass the project's outbound host allowlist at create, and an update that changes it is refused), signingSecret→secret (the secret a sender such as GitHub or Stripe signs the webhooks it sends you with; attach it to an endpoint as senderSignature.credentialId). `destinationHost` is required and permanent: the credential is only ever sent to that host, over https, and no later call can re-aim it. A signingSecret credential is never sent anywhere, so it takes no destinationHost.
Annotations the server declares
- title: Create credential
- readOnlyHint: false
- destructiveHint: false
create_endpointCreate an endpoint under a line.4 findings
Why it is in this group
- The name "create_endpoint" says "create": a word for a change.
Findings
- Info
The input schema at properties.endpoint.properties.senderSignature.description mentions "credential".
What this check looks forMatched text
inputSchema.properties.endpoint.properties.senderSignature.description: "...needs your API key. `credentialId` is a credential of type signingSecret (create_credentia..."
- Info
The input schema at properties.endpoint.properties.senderSignature.properties.credentialId.description mentions "credential".
What this check looks forMatched text
inputSchema.properties.endpoint.properties.senderSignature.properties.credentialId.description: "UUID of the signingSecret credential holding the sender's secret."
- Info
The input schema at properties.endpoint.properties.targets.items.properties.auth.properties.clientAuth.description mentions "credentials".
What this check looks forMatched text
inputSchema.properties.endpoint.properties.targets.items.properties.auth.properties.clientAuth.description: "...oauthClientCredentials only. How client credentials are sent to the token URL: basic (Autho..."
- Info
The input schema at properties.endpoint.properties.targets.items.properties.credentialVaultEntryId.description mentions "credential".
What this check looks forMatched text
inputSchema.properties.endpoint.properties.targets.items.properties.credentialVaultEntryId.description: "References a saved credential (see list_credentials/create_credential..."
Description, as the server wrote it Create an endpoint under a line. Defaults to immediate publish; draft mode requires draftRevision. scheduledAt stages the line draft then schedules it. Requires edit access.
Annotations the server declares
- title: Create endpoint
- readOnlyHint: false
- destructiveHint: false
create_lineCreate a new versioned line.No findings
Why it is in this group
- The name "create_line" says "create": a word for a change.
Description, as the server wrote it Create a new versioned line. A new line has no endpoints, so creating one publishes nothing and serves no traffic yet — add an endpoint, which publishes the line with it. Draft mode requires draftRevision 0. Requires edit access.
Annotations the server declares
- title: Create line
- readOnlyHint: false
- destructiveHint: false
create_projectCreate a new project on your account so an agent can bootstrap from a fresh account.No findings
Why it is in this group
- The name "create_project" says "create": a word for a change.
Description, as the server wrote it Create a new project on your account so an agent can bootstrap from a fresh account. The slug is derived from the name and validated server-side (format, reserved words, uniqueness). Each plan includes a fixed number of active projects (free tiers one; paid plans more: see list_subscription_plans); at the limit this errors. If an existing project can host this integration, skip create_project and call create_project_token against it instead of adding another. Requires an ACCOUNT-scoped management token and the `config` scope. Returns the created project ({id, slug, name, apiBaseUrl, archived}); call create_project_token next to mint a management token for it.
Annotations the server declares
- title: Create project
- readOnlyHint: false
- destructiveHint: false
create_project_tokenMint a PROJECT-scoped management token (`er_mcp_`) for MCP and REST; it cannot authenticate relay traffic.No findings
Why it is in this group
- The name "create_project_token" says "create": a word for a change.
Description, as the server wrote it Mint a PROJECT-scoped management token (`er_mcp_`) for MCP and REST; it cannot authenticate relay traffic. Use it after create_project to configure a fresh project, or for any project you already own. Attenuated by design: the scopes must be a subset of THIS management token's own grant (`read` is always included), expiry is mandatory (1–90 days, default 30, never "never"), and the minted management token (being project-scoped) can never mint management tokens itself. `spend` is human-granted only: no management token, of any scope, can mint one carrying it. Mint a spend-scoped token from the project's panel instead. Requires an ACCOUNT-scoped management token and the `config` scope. Returns the plaintext exactly once; only its hash is stored.
Annotations the server declares
- title: Create project management token
- readOnlyHint: false
- destructiveHint: false
dry_run_endpointValidate an endpoint document without writing it.5 findings
Why it is in this group
- The name "dry_run_endpoint" says "run": a word for a change.
- The server marks it read-only (readOnlyHint: true), but an annotation never lowers a class.
Findings
- Info
The input schema at properties.endpoint.properties.senderSignature.description mentions "credential".
What this check looks forMatched text
inputSchema.properties.endpoint.properties.senderSignature.description: "...needs your API key. `credentialId` is a credential of type signingSecret (create_credentia..."
- Info
The input schema at properties.endpoint.properties.senderSignature.properties.credentialId.description mentions "credential".
What this check looks forMatched text
inputSchema.properties.endpoint.properties.senderSignature.properties.credentialId.description: "UUID of the signingSecret credential holding the sender's secret."
- Info
The input schema at properties.endpoint.properties.targets.items.properties.auth.properties.clientAuth.description mentions "credentials".
What this check looks forMatched text
inputSchema.properties.endpoint.properties.targets.items.properties.auth.properties.clientAuth.description: "...oauthClientCredentials only. How client credentials are sent to the token URL: basic (Autho..."
- Info
The input schema at properties.endpoint.properties.targets.items.properties.credentialVaultEntryId.description mentions "credential".
What this check looks forMatched text
inputSchema.properties.endpoint.properties.targets.items.properties.credentialVaultEntryId.description: "References a saved credential (see list_credentials/create_credential..."
- Warn
The server marks "dry_run_endpoint" read-only (readOnlyHint: true), and its own name, description or input give the class "write".
What this check looks forMatched text
annotations: {"readOnlyHint":true,"destructiveHint":false}; The name "dry_run_endpoint" says "run": a word for a change.
Description, as the server wrote it Validate an endpoint document without writing it. Returns either {ok: true, resolved: <Framework config slice>} or {ok: false, errors: {...}}. Pass endpointId to dry-run a PATCH against an existing endpoint; omit it to dry-run a create. Supply sample and/or answerSample to also run each target's mapping against a real payload and see what it produces, which field came from which node, and every rule that failed with the value that broke it. No DB write, no queue entry, no billing, and the payload is never sent anywhere.
Annotations the server declares
- title: Dry-run endpoint
- readOnlyHint: true
- destructiveHint: false
duplicate_lineCopy a line and all its endpoints/targets/rules into a new line key — build v2 from v1.No findings
Why it is in this group
- The description's first verb is "copy": a word for a change.
Description, as the server wrote it Copy a line and all its endpoints/targets/rules into a new line key — build v2 from v1. The copy is saved inactive and remains off the data plane; edit it, then activate_line when ready. Requires edit access.
Annotations the server declares
- title: Duplicate line
- readOnlyHint: false
- destructiveHint: false
generate_line_draftGenerate a draft endpoint under a line from a sample inbound request and a description of the target: infers the inbound body schema from the sample, reads the target's method/URL/…No findings
Why it is in this group
- The name "generate_line_draft" says "generate": a word for a change.
Description, as the server wrote it Generate a draft endpoint under a line from a sample inbound request and a description of the target: infers the inbound body schema from the sample, reads the target's method/URL/fields from an OpenAPI document (targetDocument) or a bare sample plus targetUrl, and proposes an outgoingMapping pairing every target field to a same-named inbound field. Nothing is guessed — a target field with no same-named match is reported in the "unmapped" list instead of being mapped, and every field it did map carries "inferred": true in the stored mapping tree. Always writes a draft (never publishes); the draft flows through preview_line_draft, dry_run_endpoint, config_diff and publish_line_draft like any other. Requires edit access.
Annotations the server declares
- title: Generate line draft
- readOnlyHint: false
- destructiveHint: false
protect_projectTurn on archive protection for a project you own: archive_project (on every surface: panel, REST, and this tool) then refuses until it is lifted.No findings
Why it is in this group
- Nothing in its name or description says what it does, so it is counted as a write.
Description, as the server wrote it Turn on archive protection for a project you own: archive_project (on every surface: panel, REST, and this tool) then refuses until it is lifted. Idempotent. Permanent from here: there is no tool or API call to turn it back off; only contacting support can. Requires an ACCOUNT-scoped management token and the `config` scope.
Annotations the server declares
- title: Protect project from archiving
- readOnlyHint: false
- destructiveHint: false
resume_addonResume (un-cancel) a pending-cancel add-on whose paid-through cycle has not yet ended.No findings
Why it is in this group
- Nothing in its name or description says what it does, so it is counted as a write.
Description, as the server wrote it Resume (un-cancel) a pending-cancel add-on whose paid-through cycle has not yet ended. Clears the cancellation so the add-on renews normally at the next cycle boundary. No new charge — the cycle was already paid. Stackable add-ons cannot be resumed; buy a new unit instead. Returns {addonKey, project, nextRenewalAt, resumed}. Owner-only; requires a token minted with the billing scope.
Annotations the server declares
- title: Resume add-on
- readOnlyHint: false
- destructiveHint: false
retry_dlq_entryRe-enqueue a DLQ entry to the main relay stream and delete it from the DLQ.No findings
Why it is in this group
- Nothing in its name or description says what it does, so it is counted as a write.
Description, as the server wrote it Re-enqueue a DLQ entry to the main relay stream and delete it from the DLQ. A replay is billed like any relay — it charges the entry's original credit cost to the project before re-sending; if the balance is too low the entry stays in the DLQ and this returns an insufficient-credits error (top up and retry). Succeeds if the entry exists, errors if it's already gone (retried or discarded). Requires edit access.
Annotations the server declares
- title: Retry DLQ entry
- readOnlyHint: false
- destructiveHint: false
reveal_rotation_successorOne-shot retrieval of the plaintext for a successor minted by the auto-rotation scheduler (not by rotate_api_key — that returns its own plaintext directly).No findings
Why it is in this group
- Nothing in its name or description says what it does, so it is counted as a write.
- The server marks it read-only (readOnlyHint: true), but an annotation never lowers a class.
Description, as the server wrote it One-shot retrieval of the plaintext for a successor minted by the auto-rotation scheduler (not by rotate_api_key — that returns its own plaintext directly). Decrypts the at-rest ciphertext, returns it once, then destroys it; a second call errors. Only available while the predecessor still has an unrevealed successor.
Annotations the server declares
- title: Reveal rotation successor
- readOnlyHint: true
- destructiveHint: false
start_subscriptionBegin a new Pro or Scale subscription for the project owner.No findings
Why it is in this group
- The name "start_subscription" says "start": a word for a change.
Description, as the server wrote it Begin a new Pro or Scale subscription for the project owner. Returns `{checkoutUrl, plan}` — surface the URL to the human for approval. Errors if the owner is already on an active paid plan (use change_plan instead). Owner-only; requires a token minted with the billing scope.
Annotations the server declares
- title: Start subscription
- readOnlyHint: false
- destructiveHint: false
subscribe_addonSubscribe the project owner to a monthly add-on (RPM upgrade, team seat, extended log retention, extra file storage in +5 GB blocks, …).No findings
Why it is in this group
- The name "subscribe_addon" says "subscribe": a word for a change.
Description, as the server wrote it Subscribe the project owner to a monthly add-on (RPM upgrade, team seat, extended log retention, extra file storage in +5 GB blocks, …). Charges the saved payment method immediately, then auto-renews every 30 days until `unsubscribe_addon` — or until the subscription ends, after which the already-paid cycle stays active to its own end date and stops without further charges. Requires an active Pro/Scale subscription and a saved PM. RPM upgrades (rpm_*) are per-project and apply to THIS project automatically. Returns `{addonKey, project, monthlyEurCents, transactionId, chargeStatus, activatedAt, nextRenewalAt}`. `transactionId`: The Paddle transaction id, or null while Paddle has not yet listed the charge. The purchase is recorded either way; do not retry it. `chargeStatus`: `pending` or `completed`. Owner-only; requires a token minted with the billing scope.
Annotations the server declares
- title: Subscribe add-on
- readOnlyHint: false
- destructiveHint: false
unarchive_projectRestore an archived project you own to the data plane.No findings
Why it is in this group
- Nothing in its name or description says what it does, so it is counted as a write.
Description, as the server wrote it Restore an archived project you own to the data plane. Restoring consumes one of your plan's active-project slots, so at the limit this returns an error telling you to archive another project or upgrade. Idempotent for an already-active project. Requires an ACCOUNT-scoped management token and the `config` scope.
Annotations the server declares
- title: Unarchive project
- readOnlyHint: false
- destructiveHint: false
Only reads 30Claude Code: allow
config_diffPreview what Save & Publish (or the pending scheduled publish, if one exists) would change: added/removed/changed lines, and within each changed line the added/removed/changed endp…No findings
Why it is in this group
- The name "config_diff" says "diff": a word for reading.
Description, as the server wrote it Preview what Save & Publish (or the pending scheduled publish, if one exists) would change: added/removed/changed lines, and within each changed line the added/removed/changed endpoints and targets, plus any project-level setting change. Outbound auth secrets are redacted the same as get_config.
Annotations the server declares
- title: Config diff
- readOnlyHint: true
- destructiveHint: false
default_endpoint_templateReturn a canonical minimal-valid endpoint JSON for a fresh line.No findings
Why it is in this group
- The description's first verb is "return": a word for reading.
Description, as the server wrote it Return a canonical minimal-valid endpoint JSON for a fresh line. POST it verbatim to create_endpoint to land an immediately-working endpoint, then customise. It comes back with `mock: true`: it answers callers with its own canned body and never dials the target it carries, so a 200 from it proves the endpoint is reachable and nothing about delivery. Set `mock: false` and give the target a real URL before treating a call as delivered. Read-only.
Annotations the server declares
- title: Default endpoint template
- readOnlyHint: true
- destructiveHint: false
get_billingGet the project's credit balances (paid + testing) and which ledger it settles on.No findings
Why it is in this group
- The name "get_billing" says "get": a word for reading.
Description, as the server wrote it Get the project's credit balances (paid + testing) and which ledger it settles on. `billingModel` is `prepaid` (metered against the credit balance) or `invoiceable` (an Enterprise account, settled on the contract — its credit fields read empty/zero by design, not because it is out of credits). A zero balance is not on its own a reason to stop: live traffic is never refused for an empty balance, and a free-tier project is exempt from live credit billing entirely. Only the testing pool refuses when exhausted (402 `testing_credits_exhausted`). Read this before concluding from any other field that a project cannot send. On a Pro or Scale plan billed for overage, `overage` reports the billing cycle running now: `usedCredits`, `overageCredits` (beyond the allowance and prepaid credits), `amount` so far in minor units of `currency` (null when it cannot be worked out), `windowEndsAt`, `throttled` (true while this cycle's request limit is halved because spend passed five times the plan's credits) and `throttledUntil` (when the halved limit ends, or null); it is absent otherwise. On Pro or Scale, `overageBilling` is the account's own overage setting, changed with set_overage_billing.
Annotations the server declares
- title: Get billing balances
- readOnlyHint: true
- destructiveHint: false
get_configGet the project's published relay configuration — the exact JSON the EchoRelay Framework consumes.No findings
Why it is in this group
- The name "get_config" says "get": a word for reading.
Description, as the server wrote it Get the project's published relay configuration — the exact JSON the EchoRelay Framework consumes. Includes pendingPublish with its frozen, redacted config when one is scheduled.
Annotations the server declares
- title: Get relay config
- readOnlyHint: true
- destructiveHint: false
get_dlq_entryGet DLQ entries by entry id (`{ms}-{seq}`, as returned by list_dlq's `id`) or by `requestId`.No findings
Why it is in this group
- The name "get_dlq_entry" says "get": a word for reading.
Description, as the server wrote it Get DLQ entries by entry id (`{ms}-{seq}`, as returned by list_dlq's `id`) or by `requestId`. `requestId` is the durable handle — stable across a retry, unlike `id`, which changes every time an entry is replayed and later dead-letters again — and returns every fanned-out target's entry for that inbound request (one request can fan out to N targets, and several may dead-letter); `id` returns at most one. Each entry includes configVersion (the published config that authorised the delivery; 0 means unstamped). Errors if nothing matches this project — purged, retried, or discarded entries age out the same as any other.
Annotations the server declares
- title: Get DLQ entry
- readOnlyHint: true
- destructiveHint: false
get_endpointGet one endpoint's full document by `lineKey` and `endpointId`: `id`, `lineKey`, `name`, `url`, `httpMethod`, `strict`, `rateLimit`, `allowedIPs`, `idempotencyEnabled`, `senderSign…No findings
Why it is in this group
- The name "get_endpoint" says "get": a word for reading.
Description, as the server wrote it Get one endpoint's full document by `lineKey` and `endpointId`: `id`, `lineKey`, `name`, `url`, `httpMethod`, `strict`, `rateLimit`, `allowedIPs`, `idempotencyEnabled`, `senderSignature` (`{scheme, credentialId}`, plus `custom` for the custom-hmac scheme, or null: whether the sender's signature is verified, never the secret), `mock`, `mockResponse`, `attributes`, `targets` (auth redacted), and `transformers`. Each target carries its `id`, and its secrets come back redacted: the `targets` array can be edited and sent back in update_endpoint's `patch`, where a target that keeps its `id` keeps its stored secrets unless new ones are given. Errors when either argument is missing or when the line or endpoint doesn't exist in this project.
Annotations the server declares
- title: Get endpoint
- readOnlyHint: true
- destructiveHint: false
get_key_policyReturn the project's key policy: `defaultKeyTtlDays` (what create_api_key uses when `ttlDays` is omitted), plus `maxKeyTtlDays` and `editorsMayCreateNonExpiringKeys`, the limits cr…No findings
Why it is in this group
- The name "get_key_policy" says "get": a word for reading.
Description, as the server wrote it Return the project's key policy: `defaultKeyTtlDays` (what create_api_key uses when `ttlDays` is omitted), plus `maxKeyTtlDays` and `editorsMayCreateNonExpiringKeys`, the limits create_api_key enforces when minting a key. Read-only; use set_key_policy to change these values.
Annotations the server declares
- title: Get key policy
- readOnlyHint: true
- destructiveHint: false
get_line_draftRead one line draft, its optimistic revision, preview, and schedule.No findings
Why it is in this group
- The name "get_line_draft" says "get": a word for reading.
Description, as the server wrote it Read one line draft, its optimistic revision, preview, and schedule.
Annotations the server declares
- title: Get line draft
- readOnlyHint: true
- destructiveHint: false
get_metricsAggregate request metrics for this project over a time window — volume, error rate and p50/p95/p99 latency, bucketed for charting.No findings
Why it is in this group
- The name "get_metrics" says "get": a word for reading.
Description, as the server wrote it Aggregate request metrics for this project over a time window — volume, error rate and p50/p95/p99 latency, bucketed for charting. By default the series cover inbound requests; pass `targetId` to slice over one outbound target's per-attempt rows instead (answers "which target is degraded?"); pass `endpointId` to slice over inbound rows for a single endpoint (answers "is this endpoint receiving traffic / erroring?"). Pass at most one of targetId / endpointId. Free plans see "hour" and "day"; "week" and "month" require an active paid subscription on the project owner and are silently downgraded to "day" otherwise (the response includes `planGated: true` when that happens). Returns `{window, requestedWindow, planGated, scope, targetId?, endpointId?, bucketSeconds, buckets[], volume[], errors[], totalVolume, totalErrors, errorRate}` plus latency series whose keys depend on scope: an inbound read (project-wide, or `endpointId`) carries `relayP50[]/relayP95[]/relayP99[]` for our own time and `targetP50[]/targetP95[]/targetP99[]` for the destination's, never blended; a `targetId` read carries `p50[]/p95[]/p99[]` for that target's attempts — series arrays are dense (one point per bucket, zero-filled when no traffic).
Annotations the server declares
- title: Get metrics
- readOnlyHint: true
- destructiveHint: false
get_projectGet the EchoRelay project this token is scoped to: id, slug, name, caller-facing API base URL, whether the token has edit access, and the request-log hot-tier retention window.No findings
Why it is in this group
- The name "get_project" says "get": a word for reading.
Description, as the server wrote it Get the EchoRelay project this token is scoped to: id, slug, name, caller-facing API base URL, whether the token has edit access, and the request-log hot-tier retention window.
Annotations the server declares
- title: Get project
- readOnlyHint: true
- destructiveHint: false
get_receiptsGet every target this request fanned out to, each with its delivery receipt or the reason it has none.No findings
Why it is in this group
- The name "get_receipts" says "get": a word for reading.
Description, as the server wrote it Get every target this request fanned out to, each with its delivery receipt or the reason it has none. A still-moving delivery (queued/retrying) answers from the live tracking copy, a terminal one (delivered/failed) from durable storage — the response shape is identical either way, so poll this on an interval with the same requestId a 202 response returned and watch `status` move to a terminal value. Each entry has targetId, targetURL, available, and when available: status (queued/retrying/delivered/failed), attempt, enqueuedAt/updatedAt/completedAt (unix ms), terminalError, callbackState (none/pending/delivered/failed — whether the target's completion-callback URL, if any, has been notified). When available is false, `reason` is "sync_or_stream_delivery" (the target answers inside the original HTTP response and is never tracked here — see the response body from that call instead) or "not_found" (no record for this target, e.g. aged past the retention window).
Annotations the server declares
- title: Get delivery receipts
- readOnlyHint: true
- destructiveHint: false
get_requestGet one inbound request envelope + every per-target delivery attempt made on the way out (success / permanent_failure / retry_scheduled / dlq).No findings
Why it is in this group
- The name "get_request" says "get": a word for reading.
Description, as the server wrote it Get one inbound request envelope + every per-target delivery attempt made on the way out (success / permanent_failure / retry_scheduled / dlq). The request and each attempt carry configVersion, the published config that authorised them; 0 means unstamped. Scoped to this project; returns null once the request has aged out of the project's log-retention window (requestLogRetentionDays — see get_project).
Annotations the server declares
- title: Get request
- readOnlyHint: true
- destructiveHint: false
get_subscriptionGet the project owner's current subscription: plan, active flag, period start/end, cancel-at-period-end flag, external Paddle subscription id, and whether a payment method is on fi…No findings
Why it is in this group
- The name "get_subscription" says "get": a word for reading.
Description, as the server wrote it Get the project owner's current subscription: plan, active flag, period start/end, cancel-at-period-end flag, external Paddle subscription id, and whether a payment method is on file at the provider. Owner-only; requires a token minted with the billing scope.
Annotations the server declares
- title: Get subscription
- readOnlyHint: true
- destructiveHint: false
list_active_addonsList the project owner`s currently-active add-ons.No findings
Why it is in this group
- The name "list_active_addons" says "list": a word for reading.
Description, as the server wrote it List the project owner`s currently-active add-ons. Returns `[{addonKey, project, monthlyEurCents, activatedAt, nextRenewalAt, consecutiveFailures}, ...]`. RPM upgrades are per-project; `project` is the slug they apply to (null for account-wide add-ons). Owner-only; requires a token minted with the billing scope.
Annotations the server declares
- title: List active add-ons
- readOnlyHint: true
- destructiveHint: false
list_addonsList the optional add-on subscriptions (RPM upgrades, extra team seats, extended log retention, extra file-delivery storage in +5 GB blocks, …).No findings
Why it is in this group
- The name "list_addons" says "list": a word for reading.
Description, as the server wrote it List the optional add-on subscriptions (RPM upgrades, extra team seats, extended log retention, extra file-delivery storage in +5 GB blocks, …). Each entry is monthly, renews every 30 days until cancelled, and carries `scope` (per_account or per_project). Read-only.
Annotations the server declares
- title: List add-ons
- readOnlyHint: true
- destructiveHint: false
list_api_keysList the project's inbound API keys as metadata only — the secret plaintext is never returned, only `id`, `name`, `mode`, `prefix`, `createdAt`, `createdBy`, `lastUsedAt`, `expires…No findings
Why it is in this group
- The name "list_api_keys" says "list": a word for reading.
Description, as the server wrote it List the project's inbound API keys as metadata only — the secret plaintext is never returned, only `id`, `name`, `mode`, `prefix`, `createdAt`, `createdBy`, `lastUsedAt`, `expiresAt`, `revokedAt`, `successorId`, `predecessorId`, and `successorRevealedAt`. Returns `{keys: []}` with no paging — every key on the project comes back in one call.
Annotations the server declares
- title: List API keys
- readOnlyHint: true
- destructiveHint: false
list_audit_eventsList project audit-log entries, newest first.No findings
Why it is in this group
- The name "list_audit_events" says "list": a word for reading.
Description, as the server wrote it List project audit-log entries, newest first. Captures who changed what — lines, endpoints, targets, API keys. Outbound-target `auth.token` / `auth.password` are redacted in the diff per the same policy used for endpoint reads. Retention is the `auditRetentionDays` advertised on get_project (default 365 days); rows older than that are purged by the cleanup job. Returns `{total, limit, offset, retentionDays, rows[]}` where each row has `id`, `createdAt`, `actor` (email or null), `action`, `entityType`, `entityId`, `entityLabel`, `diff`.
Annotations the server declares
- title: List audit events
- readOnlyHint: true
- destructiveHint: false
list_config_revisionsList every retained revision of one line, newest first, so a target revision can be picked for rollback_config.No findings
Why it is in this group
- The name "list_config_revisions" says "list": a word for reading.
Description, as the server wrote it List every retained revision of one line, newest first, so a target revision can be picked for rollback_config. Returns `{revisions: []}` with no paging; each entry has `revision`, `publishedAt`, `current`, and `active`. Errors when `lineKey` is missing or doesn't match a line in the project.
Annotations the server declares
- title: List config revisions
- readOnlyHint: true
- destructiveHint: false
list_credentialsList the project's saved credentials — reusable target-auth secrets that can be referenced from any number of targets instead of entering auth inline per target.2 findings
Why it is in this group
- The name "list_credentials" says "list": a word for reading.
Findings
- Info
The annotations title mentions "credentials".
What this check looks forMatched text
annotations.title: "List credentials"
- Info
The description mentions "credentials".
What this check looks forMatched text
description: "List the project's saved credentials — reusable target-auth secrets that can..."
Description, as the server wrote it List the project's saved credentials — reusable target-auth secrets that can be referenced from any number of targets instead of entering auth inline per target. `auth` is redacted (secret fields never returned, even encrypted — see create_credential for why).
Annotations the server declares
- title: List credentials
- readOnlyHint: true
- destructiveHint: false
list_credit_packsList the prepaid credit packs available to purchase, returned as a bare array of `{credits, eurCents, usdCents, plnGrosze, welcomeEligible}` objects — not wrapped in an envelope, a…No findings
Why it is in this group
- The name "list_credit_packs" says "list": a word for reading.
Description, as the server wrote it List the prepaid credit packs available to purchase, returned as a bare array of `{credits, eurCents, usdCents, plnGrosze, welcomeEligible}` objects — not wrapped in an envelope, and not paginated (the whole catalog every time). Read-only; identify a pack to start_topup by its `eurCents`.
Annotations the server declares
- title: List credit packs
- readOnlyHint: true
- destructiveHint: false
list_dlqList entries currently in this project's dead-letter queue, newest first.No findings
Why it is in this group
- The name "list_dlq" says "list": a word for reading.
Description, as the server wrote it List entries currently in this project's dead-letter queue, newest first. One inbound request fans out per-target, so a single request may produce several DLQ entries, one per target that didn't accept it (different `targetId`s). Returns `{total, limit, offset, rows[], evictedCount}` where each row has `id` (the dead-letter entry id, `{ms}-{seq}`), `requestId`, `targetId`, `configVersion` (the published config that authorised the delivery; 0 means unstamped), `failureReason`, `failureCode` (stable machine-readable cause; `unclassified` for entries written before codes existed), `failedAttempts`, `failedAt`, `payload` (the JSON of the queued delivery as it was attempted); `evictedCount` is the lifetime count of entries the queue's capacity cap discarded before they could be triaged. DLQ entries — including the original request body and headers — are kept for up to 30 days from the failure time or until cleared, then purged automatically (or discarded early past capacity — see `evictedCount`); they are never written to a database. get_request still answers what happened to a purged/evicted/discarded entry's inbound request for the project's requestLogRetentionDays window, independent of whether the DLQ row itself still exists. `requestId` is the durable handle across a retry: an entry's own `id` changes every time it is replayed and later dead-letters again, so get_dlq_entry accepts a `requestId` lookup as well as `id`.
Annotations the server declares
- title: List DLQ entries
- readOnlyHint: true
- destructiveHint: false
list_endpointsList the endpoints under one line, identified by `lineKey`; returns `{lineKey, endpoints: []}` with no paging.No findings
Why it is in this group
- The name "list_endpoints" says "list": a word for reading.
Description, as the server wrote it List the endpoints under one line, identified by `lineKey`; returns `{lineKey, endpoints: []}` with no paging. Each entry reports `id`, `name`, `path`, `httpMethod`, `strict`, `mock`, and `targetCount` — not the endpoint's full body, which get_endpoint returns. Errors when `lineKey` is missing or doesn't match a line in the project.
Annotations the server declares
- title: List endpoints
- readOnlyHint: true
- destructiveHint: false
list_linesList every line in the project: returns `{lines: []}` in one call, with no paging.No findings
Why it is in this group
- The name "list_lines" says "list": a word for reading.
Description, as the server wrote it List every line in the project: returns `{lines: []}` in one call, with no paging. Each entry reports `lineKey`, `name`, `active`, `docsShared`, `publishedAt`, `endpointCount`, and its draft state (`draftRevision`, `hasDraft`, `scheduledPublish`). A project with no lines yet returns an empty `lines` array rather than an error.
Annotations the server declares
- title: List lines
- readOnlyHint: true
- destructiveHint: false
list_membersList accepted and pending members of this project, plus the owner (role "owner"), each with `id`, `email`, `name`, `role`, and whether the invite has been accepted.No findings
Why it is in this group
- The name "list_members" says "list": a word for reading.
Description, as the server wrote it List accepted and pending members of this project, plus the owner (role "owner"), each with `id`, `email`, `name`, `role`, and whether the invite has been accepted. Returns `{members: [], count, seatCap, seatsUsed}` with no paging — `count` is the roster size, `seatCap`/`seatsUsed` are the plan's seat limit and how many seats are used. Errors when the caller isn't the project owner or the token lacks the config scope. Owner only.
Annotations the server declares
- title: List members
- readOnlyHint: true
- destructiveHint: false
list_project_tokensList the management tokens scoped to a project you own (any holder): id, label, scopes, createdAt, lastUsedAt, expiresAt, revokedAt: never the secret (only its hash is stored).No findings
Why it is in this group
- The name "list_project_tokens" says "list": a word for reading.
Description, as the server wrote it List the management tokens scoped to a project you own (any holder): id, label, scopes, createdAt, lastUsedAt, expiresAt, revokedAt: never the secret (only its hash is stored). Requires an ACCOUNT-scoped management token and the `read` scope.
Annotations the server declares
- title: List project management tokens
- readOnlyHint: true
- destructiveHint: false
list_projectsList the projects on your account (archived included), each with `id`, `slug`, `name`, `apiBaseUrl` and `archived`, plus `accountEmail` — the account this token authenticates as.No findings
Why it is in this group
- The name "list_projects" says "list": a word for reading.
Description, as the server wrote it List the projects on your account (archived included), each with `id`, `slug`, `name`, `apiBaseUrl` and `archived`, plus `accountEmail` — the account this token authenticates as. Requires an ACCOUNT-scoped management token (one minted with no project) and the `read` scope. A PROJECT-scoped management token cannot call this: use it on its own project's tools instead.
Annotations the server declares
- title: List projects
- readOnlyHint: true
- destructiveHint: false
list_requestsList inbound API requests the relay has processed for this project, newest first.No findings
Why it is in this group
- The name "list_requests" says "list": a word for reading.
Description, as the server wrote it List inbound API requests the relay has processed for this project, newest first. Hot-tier window is the project's requestLogRetentionDays (see get_project). Optional filters narrow the result. Returns {total, limit, offset, rows[]} where each row has ts (unix ms), requestId, method, path, status, durationMs, targets, creditsDeducted, authType, errorMessage, bytesSent, configVersion (the published config that authorised the request; 0 means unstamped), and closeReason (for a streaming request: complete / abortedOrError / byteCap / noValue; empty for non-stream requests).
Annotations the server declares
- title: List requests
- readOnlyHint: true
- destructiveHint: false
list_subscription_plansList the available subscription plans (Free, Pro, Scale) with monthly EUR price, credit allowance, per-project RPM cap, and how many active projects the plan includes.No findings
Why it is in this group
- The name "list_subscription_plans" says "list": a word for reading.
Description, as the server wrote it List the available subscription plans (Free, Pro, Scale) with monthly EUR price, credit allowance, per-project RPM cap, and how many active projects the plan includes. Read-only.
Annotations the server declares
- title: List subscription plans
- readOnlyHint: true
- destructiveHint: false
preview_line_draftPreview one line draft without publishing it.No findings
Why it is in this group
- The name "preview_line_draft" says "preview": a word for reading.
Description, as the server wrote it Preview one line draft without publishing it.
Annotations the server declares
- title: Preview line draft
- readOnlyHint: true
- destructiveHint: false
preview_plan_changePreview what would happen if change_plan were called with this plan: the immediate-charge amount (cents), the next-invoice amount, the effective date, and the kind (`applied` for i…No findings
Why it is in this group
- The name "preview_plan_change" says "preview": a word for reading.
Description, as the server wrote it Preview what would happen if change_plan were called with this plan: the immediate-charge amount (cents), the next-invoice amount, the effective date, and the kind (`applied` for in-cycle upgrade, `scheduled` for at-period-end downgrade / cancel). Owner-only; requires a token minted with the billing scope.
Annotations the server declares
- title: Preview plan change
- readOnlyHint: true
- destructiveHint: false
This is not a safety rating, and no finding is not a safety guarantee. The groups and findings come from fixed checks of the tool definitions the server returned on the date shown, not from its code or what it does when called. How the checks work.
Install
Pinned to version 0.13.0. Values in angle brackets are yours to fill in.
claude mcp add --transport http management https://mcp.echorelay.dev --header 'Authorization: <your-authorization>'Run in a terminal.
Claude Code permissions
Allow the reads, ask before a change, deny the deletes. Paste into .claude/settings.json.
{
"permissions": {
"allow": [
"mcp__management__get_project",
"mcp__management__list_lines",
"mcp__management__list_endpoints",
"mcp__management__get_endpoint",
"mcp__management__get_config",
"mcp__management__config_diff",
"mcp__management__list_config_revisions",
"mcp__management__get_line_draft",
"mcp__management__preview_line_draft",
"mcp__management__get_billing",
"mcp__management__default_endpoint_template",
"mcp__management__list_members",
"mcp__management__list_api_keys",
"mcp__management__get_key_policy",
"mcp__management__list_credentials",
"mcp__management__list_requests",
"mcp__management__get_request",
"mcp__management__get_receipts",
"mcp__management__get_metrics",
"mcp__management__list_dlq",
"mcp__management__get_dlq_entry",
"mcp__management__list_subscription_plans",
"mcp__management__list_credit_packs",
"mcp__management__list_addons",
"mcp__management__get_subscription",
"mcp__management__preview_plan_change",
"mcp__management__list_active_addons",
"mcp__management__list_audit_events",
"mcp__management__list_projects",
"mcp__management__list_project_tokens"
],
"ask": [
"mcp__management__create_line",
"mcp__management__activate_line",
"mcp__management__duplicate_line",
"mcp__management__create_endpoint",
"mcp__management__generate_line_draft",
"mcp__management__dry_run_endpoint",
"mcp__management__invite_member",
"mcp__management__resend_invite",
"mcp__management__create_api_key",
"mcp__management__reveal_rotation_successor",
"mcp__management__create_credential",
"mcp__management__retry_dlq_entry",
"mcp__management__start_subscription",
"mcp__management__start_topup",
"mcp__management__subscribe_addon",
"mcp__management__resume_addon",
"mcp__management__create_project",
"mcp__management__protect_project",
"mcp__management__unarchive_project",
"mcp__management__create_project_token"
],
"deny": [
"mcp__management__publish_line_draft",
"mcp__management__discard_line_draft",
"mcp__management__discard_draft_endpoint",
"mcp__management__schedule_line_publish",
"mcp__management__cancel_line_publish",
"mcp__management__rollback_config",
"mcp__management__set_burst_opt_in",
"mcp__management__set_rpm_ceiling",
"mcp__management__set_outbound_allowlist",
"mcp__management__delete_line",
"mcp__management__deactivate_line",
"mcp__management__set_docs_shared",
"mcp__management__update_endpoint",
"mcp__management__delete_endpoint",
"mcp__management__remove_member",
"mcp__management__set_member_role",
"mcp__management__rotate_api_key",
"mcp__management__revoke_api_key",
"mcp__management__set_key_policy",
"mcp__management__update_credential",
"mcp__management__delete_credential",
"mcp__management__discard_dlq_entry",
"mcp__management__change_plan",
"mcp__management__cancel_subscription",
"mcp__management__set_overage_billing",
"mcp__management__unsubscribe_addon",
"mcp__management__downgrade_addon",
"mcp__management__rename_project",
"mcp__management__archive_project",
"mcp__management__revoke_project_token"
]
}
}Tools that only read are allowed, tools that change things ask first, tools that delete or cancel are denied. It assumes the server is installed as management. Review it before you use it.