Skip to main content

Hosted MCP Resource Server (OAuth — no API keys)

For a client that supports remote MCP servers with OAuth 2.1 + PKCE (e.g. Claude Code, Claude.ai connectors), connect directly to https://mcp.motorical.com instead of running the local package — no mk_live_/ak_live_/MOTORICAL_JWT to manage. The first tool call triggers a normal OAuth consent screen in the browser.

Connect​

Pick the tab that sounds like you. You need only one. The server address is the same everywhere:

https://mcp.motorical.com/v1/motorical/mcp

For you if: you talk to an assistant in an app or in the browser and you do not use a terminal. Nothing to install.

Claude app or claude.ai (tested):

  1. Open the connectors settings (Settings, then Connectors) and choose Add custom connector.
  2. Name it Motorical, paste the address above, and click Connect.
  3. Your browser opens: sign in, or create your account. Set up two-factor authentication (required, cannot be skipped), then press Allow.
  4. Back in the chat, ask: "Set up Motorical for me and send a test email to myself."

ChatGPT (tested 2026-10-14: sign-in, a real send with the outcome read back, and a second dedicated connector all work; setup from OpenAI's documentation): turn on developer mode (in Settings; the menu names change between releases, and on a work plan an admin may need to allow custom connectors), create a custom connector, paste the address above, and choose OAuth as the sign-in method. Connecting does not by itself make the assistant use the tools: in a chat, name what you want, for example "Use the Motorical connector's motorical_get_onboarding_state tool to show my account state". A vaguer request such as "show my Motorical account" may send the assistant to the website instead. ChatGPT does not ask for extra permissions by itself: for webhooks or Motor Block management, add the dedicated server as a second connector (webhook management also needs a paid plan; without one it answers 403 subscription_required).

Will my agent be able to sign in? Motorical's sign-in uses client ID metadata documents (CIMD) and does not offer dynamic client registration. Claude Code is tested end to end. VS Code (with GitHub Copilot) presents a metadata document and has been accepted since 2026-10-14. ChatGPT (it presents https://chatgpt.com/oauth/codex/client.json) signs in the same way. The Cursor domain is on the trusted list, but we have not confirmed that Cursor uses metadata documents. An agent that can only register itself dynamically cannot sign in to the hosted server yet. If yours cannot, you have two other routes that need no OAuth from your agent: agent-led onboarding over the HTTP API or the local npm server (third tab).

Want an account before you connect? Create it at https://motorical.com/register, then connect; sign-in at the consent step works the same. The npm package @motorical/mcp is the local option from the third tab, and @motorical/cli is retired.

What happens in the browser, for the first two tabs: you create your account or sign in, set up two-factor authentication, and press Allow. Consent then resumes by itself, with no second Authenticate. Your new account starts on the free developer sandbox, so you can send a first email to yourself right away.

The first consent on the main server asks only for what a trial needs: account state, domains, sandbox, recipients and sending. The tool list shows only what your connection may use, so on the first sign-in you will not see webhook or Motor Block tools at all. To use them, connect the dedicated server for that area (Webhooks or Motor Blocks below), whose consent asks only for that permission. Webhook management also needs a paid plan, and the sandbox does not offer it. You can also add it to the connection you already have: in the dashboard, Settings, API, Connected AI Agents, choose Allow next to the permission (or open https://motorical.com/settings/api-access?add=webhooks, or ?add=motor-blocks). The tools appear the next time the agent's tool list is loaded: start a new chat, or refresh the connector in your client. No reconnect is needed. An agent that is already running in the same chat may keep its old list until then.

Scoped servers​

8 scoped servers, each a distinct RFC 8707 audience — a token minted for one is rejected by every other, so connecting a narrow one genuinely reduces what the client can do:

ServerURLTools
Main (everything below)https://mcp.motorical.com/v1/motorical/mcpall of the below
Transactionalhttps://mcp.motorical.com/v1/motorical_transactional/mcpmotorical_get_message, motorical_get_message_events, motorical_get_send_status, motorical_integrate_send, motorical_send_email, motorical_wait_for_outcome
Analyticshttps://mcp.motorical.com/v1/motorical_analytics/mcpmotorical_get_account_rate_limits, motorical_get_anomalies, motorical_get_daily_summary, motorical_get_deliverability, motorical_get_error_codes, motorical_get_logs, motorical_get_message_by_smtp_id, motorical_get_metrics, motorical_get_onboarding_state, motorical_get_overview, motorical_get_providers, motorical_get_rate_limits, motorical_get_reputation, motorical_list_motor_blocks
Domainshttps://mcp.motorical.com/v1/motorical_domains/mcpmotorical_domain_add, motorical_domain_check_dns, motorical_domain_list, motorical_domain_verify, motorical_get_config, motorical_get_domain_health
Sandboxhttps://mcp.motorical.com/v1/motorical_sandbox/mcpmotorical_sandbox_status, motorical_sandbox_provision, motorical_sandbox_convert (allowlisting by 6-digit code remains dashboard-only; recipients confirm by emailed link instead — see Free-account recipients below), motorical_free_recipient_add, motorical_free_recipient_list, motorical_free_recipient_remove
Motor Blockshttps://mcp.motorical.com/v1/motorical_motor_blocks/mcpmotorical_motor_block_list, motorical_motor_block_create, motorical_motor_block_rename, motorical_motor_block_change_type, motorical_motor_block_assign_domain, motorical_motor_block_deactivate, motorical_motor_block_reactivate, motorical_motor_block_delete, motorical_motor_block_delete_status — scope manage:motor-blocks
Webhookshttps://mcp.motorical.com/v1/motorical_webhooks/mcpmotorical_webhook_create, motorical_webhook_delete, motorical_webhook_get_deliveries, motorical_webhook_get_stats, motorical_webhook_list, motorical_webhook_test, motorical_webhook_update
Signuphttps://mcp.motorical.com/v1/signup/mcpmotorical_signup_handoff — the one deliberate exception: unauthenticated, no OAuth grant needed. For apps that implement an OAuth client (hosts, embedded agent apps); it needs that client's OAuth values (client id, registered redirect URI, PKCE challenge, resource). A person in Claude Code, Claude Desktop or another chat client with no account should connect the Main server instead and authenticate: the browser opens the sign-in page, they create the account there, set up MFA (required, cannot be skipped), and press Allow; consent resumes by itself

Account-wide vs. Motor-Block-scoped​

Domain tools, list_motor_blocks, the motorical_free_recipient_* tools, and the Motor Block lifecycle tools motorical_motor_block_list, motorical_motor_block_create and motorical_motor_block_delete_status are account-wide: no Motor Block selection needed, works from a brand-new account before any Motor Block exists (a Motor Block is created from a verified domain, not the reverse). Every other tool is bound to whichever Motor Block(s) the OAuth grant covers; when the grant covers more than one, name the block with motorBlockId.

Tool names above are the exact names a client sees — pass them verbatim. The full catalogue, with each tool's scopes and the API route it wraps, is published as machine-readable JSON at mcp-catalogue.json.

motorical_get_config and motorical_get_domain_health sit on the Domains server rather than Analytics: they read config.read, which only the manage:domains scope grants, and a server requests the union of its tools' scopes — so putting them on Analytics would have made connecting an analytics client ask for domain-write authority.

The domain tools each call the same Public API route documented under AI Agent Quickstart: motorical_domain_list → GET /api/public/v1/domains, motorical_domain_add → POST /api/public/v1/domains, motorical_domain_verify → POST /api/public/v1/domains/{id}/verify, motorical_domain_check_dns → POST /api/public/v1/domains/{id}/check-dns.

The analytics and health tools each wrap one Public API route one-to-one, all under /api/public/v1: motorical_get_overview → GET /motor-blocks/{id}/overview, motorical_get_daily_summary → .../daily-summary, motorical_get_metrics → .../metrics, motorical_get_deliverability → .../deliverability, motorical_get_reputation → .../reputation, motorical_get_anomalies → .../anomalies, motorical_get_providers → .../providers, motorical_get_error_codes → .../error-codes, motorical_get_rate_limits → .../rate-limits, motorical_get_logs → .../logs, and motorical_get_message_by_smtp_id → GET /messages?smtpMessageId=.

The webhook tools likewise wrap one route each, all under /api/public/v1/motor-blocks/{id}/webhooks: motorical_webhook_list → GET on the collection, motorical_webhook_create → POST on the collection, motorical_webhook_update → PUT /{webhookId}, motorical_webhook_delete → DELETE /{webhookId}, motorical_webhook_test → POST /{webhookId}/test, motorical_webhook_get_deliveries → GET /{webhookId}/deliveries, and motorical_webhook_get_stats → GET /{webhookId}/stats. They sit on their own Webhooks server, which requests both read:webhooks and manage:webhooks. The three read-only tools — motorical_webhook_list, motorical_webhook_get_deliveries, motorical_webhook_get_stats — are reachable with either scope; the four write tools — motorical_webhook_create, motorical_webhook_update, motorical_webhook_delete, motorical_webhook_test — still require manage:webhooks specifically (which implies webhooks.read, so a manage-scoped grant can call every webhook tool). motorical_webhook_create returns the endpoint's signing secret exactly once; every later read masks it.

Two of these behave differently from the rest. motorical_get_account_rate_limits → GET /account/rate-limits is account-scoped: it reports the ceiling across every Motor Block and needs no motorBlockId, like the domain tools. And motorical_get_message_by_smtp_id is a lookup, not a listing — it requires an exact SMTP Message-ID and returns at most one message; use motorical_get_message when you hold the internal send UUID instead.

Recipient addresses in log and message results are masked. Unmasking requires the logs.pii scope, which is never granted to an OAuth token — passing includePII: true returns a 403 by design. Use the local server with a dashboard session if you need unmasked data.

Sandbox credentials and auth method visibility​

Sandbox credentials follow the same never-over-the-wire principle as the PII masking above. Over this hosted OAuth connection, motorical_sandbox_provision never returns credentials — the response just confirms that credentials aren't included. Provisioning adds the new Motor Block to your authorization, and the backend checks your current authorization on every call, so the new block is usable immediately by naming it explicitly with motorBlockId — no token refresh or re-authorization is needed. (A call that names no block still uses the one block an older token was minted with.) After converting to a verified production domain with motorical_sandbox_convert, the response points you to a dashboard link instead of printing the credential inline — that's where you view or regenerate it. Conversion is also a one-way production identity transition: you may choose the production name and type (transactional or general_purpose), and the block's SMTP username is replaced with a production-derived one. The block keeps its id, password, API keys and auth method — only the username changes, so every SMTP client must switch to the new username (the response reports previousSmtpUsername, smtpUsername, credentialChanges and an integrationActionRequired note). The local MCP server, by contrast, runs as your own process under a dashboard session and does return credentials directly when you provision; because that's your own infrastructure, keeping that value secure from there on is on you.

Separately, a Motor Block's current authentication method — Password, API Key, OAuth 2.0, or mTLS — is visible read-only through motorical_get_config on the Domains server. Changing it is still a dashboard-only action; no MCP tool can flip it.

Two ways to start​

An account with no plan and no domain starts one of two ways: with the person's own domain (on a Free account, when automatic provisioning is enabled and the domain is fully verified, a sandbox Motor Block is created on it automatically once DKIM and SPF pass; otherwise call motorical_sandbox_provision), or on a Motorical-owned .sandbox domain (instant, no DNS) from motorical_sandbox_provision. Use your own domain when the person has one whose DNS they control and want to keep; use the sandbox domain when they are only trying things, have no domain yet, or no human is at the keyboard. motorical_get_onboarding_state returns both options and this rule. The decision, both journeys and how each path is limited are in Two ways to start and the Agent Hub; this page covers only what the hosted connection adds: the manage:recipients scope, the three recipient tools below, and the re-consent note (an authorization granted before that scope existed must be re-approved to include it).

Free-account recipients​

Free accounts can send test email only to their own address and to people who have allowed it. The Sandbox and Main servers carry tools for that, under the separate scope manage:recipients (an existing manage:sandbox authorization does not include it and must be re-approved to include manage:recipients). How these tools fit the two starting paths, and the limits that apply, are in Two ways to start:

ToolWhat it does
motorical_free_recipient_addEmails a person a confirmation link. They must open it and click the button themselves; this tool never confirms for them. The answer is the same whether or not the email was sent, so it cannot reveal who has stopped.
motorical_free_recipient_listLists the addresses you have asked, with status, the recipient limit and usage.
motorical_free_recipient_removeRemoves an address by its id from the list. Asks for confirmation.

They wrap the account-scoped /api/public/v1/account/free-recipients routes.

Production Motor Block lifecycle​

The Motor Blocks server (https://mcp.motorical.com/v1/motorical_motor_blocks/mcp, scope manage:motor-blocks) lets a subscribed account manage its ordinary production Motor Blocks without opening the dashboard. Only transactional and general_purpose blocks are managed; sandbox, marketing and portal blocks are refused. It wraps the account-scoped /api/public/v1/account/motor-blocks* routes.

ToolWhat it does
motorical_motor_block_listLists production blocks covered by your current grant, including inactive ones. Shows each block's domain, activeAuthMethod (read-only) and credentialsAvailable: false.
motorical_motor_block_createCreates a block on a verified, non-sandbox domain you own. Requires a UUID v4 idempotencyKey; reuse it unchanged when retrying so you get the same block, never a duplicate. Subject to your plan's Motor Block limit.
motorical_motor_block_renameChanges the display name only. Rename never changes the SMTP username or any credential.
motorical_motor_block_change_typeSwitches between transactional and general_purpose. Asks for confirmation.
motorical_motor_block_assign_domainMoves a block onto another verified, non-sandbox domain. Asks for confirmation.
motorical_motor_block_deactivatePauses a block — sends are refused until it is reactivated. Reversible; nothing is deleted. Asks for confirmation.
motorical_motor_block_reactivateResumes a paused block. Refused if it has no verified domain or deletion is already queued.
motorical_motor_block_deletePermanently deletes a block. Asynchronous and irrecoverable. The block must be deactivated first, and you must state deleteHistory explicitly (true also deletes its message logs and events). Asks for confirmation and returns a jobId.
motorical_motor_block_delete_statusPolls a deletion by jobId; still works after the block is gone.

Things an agent should know up front:

  • A newly created block is usable immediately. Creation adds the block to your current authorization in the same step, so motorical_send_email with that motorBlockId (start with dryRun: true) works on the same connection — no token refresh.
  • Credentials are never returned here. Responses carry credentialsAvailable: false and a dashboard link; the password, API-key secrets and certificates are only ever shown in the dashboard. The auth method is readable but can only be changed in the dashboard.
  • Deactivate and delete are different things. Deactivate is a reversible pause; delete is permanent. Deleting one block never affects other blocks that share its domain.
  • Confirmations are bound to the request. Consequential operations (type change, domain assignment, deactivate, delete) ask for confirmation, and the confirmation only applies to the exact arguments that were shown. If your client cannot answer a confirmation prompt, the reply also carries a plain confirmation_required message: ask the person to confirm the exact action, then call the tool again with confirm: true, which the server honors.
  • Errors are machine-readable. They carry a stable machine-readable code (for example motor_block_limit_reached, domain_not_verified, motor_block_name_conflict, motor_block_must_be_inactive, motor_block_history_present, motor_block_not_authorized) and, where useful, a nextAction. A request that names two different Motor Blocks is refused with motor_block_id_conflict.
  • Communications (marketing) blocks are not part of this server.

What's not here yet​

Not available over OAuth today: allowlisting by 6-digit code (to confirm a recipient over OAuth, use motorical_free_recipient_add with scope manage:recipients instead). motorical_sandbox_allowlist_request, motorical_sandbox_allowlist_confirm and motorical_web_handoff are dashboard-session-only (MOTORICAL_JWT) — no Public API route backs them. Calling them through an OAuth-connected client fails closed with an explicit error rather than a confusing 401. Use the local server for these. motorical_sandbox_status, motorical_sandbox_provision, and motorical_sandbox_convert call the account-scoped /api/public/v1/account/sandbox* routes and work over OAuth like any other account-scoped tool.

Public API surface with no MCP tool yet: exports is reachable via the Public Analytics API but has no MCP tool. Growing — this list shrinks as tools are added, check back or see openapi.json for the full route inventory.