Skip to main content
Glama
KuudoAI

Amazon Ads API MCP

by KuudoAI

Server Configuration

Describes the environment variables required to run the server.

NameRequiredDescriptionDefault
AUTH_METHODNoAuthentication method - 'direct' for BYOA or 'openbridge' for partner app
AMAZON_AD_API_PACKAGESNoComma-separated list of tool packages to activate (e.g., 'profiles,amc-workflow')
AMAZON_AD_API_CLIENT_IDNoYour Amazon Ads API client ID (required for BYOA)
OPENBRIDGE_REFRESH_TOKENNoYour Openbridge API token (required when using Openbridge partner app)
AMAZON_AD_API_CLIENT_SECRETNoYour Amazon Ads API client secret (required for BYOA)

Capabilities

Features and capabilities supported by this server

CapabilityDetails
tasks
{
  "list": {},
  "cancel": {},
  "requests": {
    "tools": {
      "call": {}
    },
    "prompts": {
      "get": {}
    },
    "resources": {
      "read": {}
    }
  }
}
tools
{
  "listChanged": true
}
logging
{}
prompts
{
  "listChanged": false
}
resources
{
  "subscribe": false,
  "listChanged": false
}
extensions
{
  "io.modelcontextprotocol/ui": {}
}
experimental
{}

Tools

Functions exposed to the LLM to take actions

NameDescription
tags

List available tool tags.

Use to browse available tools by tag before searching.

search

Search for available tools by query.

Returns matching tools ranked by relevance.

get_schema

Get parameter schemas for specific tools.

Use after searching to get the detail needed to call a tool.

execute

Run async Python in a sandboxed interpreter. The whole script runs as one turn; use return to produce the tool result.

Available in scope:

  • await call_tool(name: str, params: dict) -> Any — calls any backend tool. Failures raise RuntimeError(<envelope_json>) where the message body is the full v1 cross-server error envelope JSON. Inside the sandbox: try: await call_tool(name, params) except RuntimeError as e: env = json.loads(str(e)) # env['error_kind'], env['hints'], env['error_code'], # env['retryable'], env.get('_meta', {}) all available. Non-envelope failures fall back to RuntimeError("<OriginalType>: <message>"). Both forms are catchable with try/except RuntimeError:. The format matches Amazon SP MCP for cross-server symmetry.

Sandbox guardrails (Monty interpreter):

  • No network: urllib, requests, httpx, socket not importable. Use call_tool.

  • No filesystem writes: open() is missing from builtins; os and pathlib import successfully but most side-effecting methods are gated. Tool results larger than ~1 MB may be auto-stashed by the host client.

  • Stdlib (verified against pydantic_monty==0.0.11; allowlist is hardcoded in Monty's compiled extension and not configurable from Python — may differ on other CodeMode hosts running a different pydantic_monty):

    • Available: json, re, math, datetime, sys, typing, asyncio, os, pathlib.

    • Blocked: collections, itertools, functools, statistics, decimal, dataclasses, random, string, time, base64, hashlib, urllib.parse. Use built-ins and comprehensions for aggregation; for hashing/encoding/URL work, request a server-side tool via await call_tool(...).

  • Builtins (verified missing / behavior differences):

    • hasattr(o, k) is unavailable. Use a unique sentinel with getattr: _MISSING = [] (or {}), then getattr(o, k, _MISSING) is not _MISSING. object() is unavailable in this sandbox.

    • callable(x) is unavailable and getattr(x, '__call__', None) is not None is not reliable for built-in instances or functions in this sandbox. Prefer known-callable inputs, or guarded invocation with try: x(...); except TypeError: when safe.

    • No reliable capability-probing on objects. The _MISSING sentinel pattern above works for module attributes (e.g. getattr(math, 'pi', _MISSING)) but not for methods on built-in instances or attributes on user-defined functions. In this sandbox, built-in methods are invokable via d.keys() syntax but are not reachable as attributes via d.keys (which itself raises AttributeError). Same for function attributes — fn.__name__ raises AttributeError. getattr(o, k, default) returns default for these cases not because getattr is misbehaving but because the attribute isn't there. Write code that knows the shape of its inputs rather than probing for capabilities.

    • setattr, dir, vars, globals, locals, open are all absent.

  • Blocked-import error semantics: inside the sandbox, from collections import Counter raises a stock Python ImportError (NOT a RuntimeError-wrapped envelope). Catch with except ImportError: (or except Exception:). The v1 sandbox_runtime / SANDBOX_MODULE_BLOCKED envelope only fires when the import error is uncaught and propagates out of execute — at which point the calling tool layer sees the typed envelope.

  • Unsupported-syntax error semantics: class definitions, match statements, and other parser-not-yet-supported constructs raise a NotImplementedError that DOES surface as a v1 envelope with error_kind=sandbox_runtime / error_code=SANDBOX_RUNTIME_ERROR. Asymmetric with imports — known limitation.

  • print() output may be discarded depending on the client path; return data via the script's final expression instead.

  • asyncio.sleep is unavailable by design in this sandbox path. Don't sleep — chain await call_tool calls (e.g. poll a report-status tool) instead. For long-running reports (typically 1-20 minutes), do NOT rapid-poll inside a single execute block; return after one status check and let the user decide when to re-check.

  • try/except/finally work normally. To probe many candidates in one block, wrap each await call_tool(...) in its own try/except RuntimeError.

  • with works for pure-Python context managers (e.g. decimal.localcontext()). It does NOT work for open(...) because file I/O is blocked.

  • json.dumps(default=...) may trip on Pydantic models; call model_dump() first.

Auth, region, and active profile are managed by the server. Do not pass Amazon-Ads-AccountId, Amazon-Advertising-API-Scope, or bearer tokens in params — set them once via set_active_identity / set_region / set_active_profile and they ride every subsequent call_tool.

Session-scope contract:

  • Call get_session_state first; if state_scope == 'request', re-run set_active_identity / set_region / set_active_profile in each execute block. If state_scope == 'session', set them once via the corresponding tools and they ride subsequent call_tool calls in that session.

  • To detect the transport's scope, call get_session_state at the start of a block. It is a read-only probe with no side effects.

  • Rule: Re-establish context before the next tool call iff state_scope == 'request' or state_reason is not null.

  • Within a block the scope cannot change; one probe per block is sufficient.

  • state_reason enumerates: "no_mcp_session" (request-scoped transport), "token_swapped" (a different bearer/refresh token arrived mid-session and the previous tenant's state was cleared — state_scope stays 'session' but you must re-establish context for the new tenant), and "bridge_unavailable" (reserved; treat as 'request').

Prompts

Interactive templates invoked by user choice

NameDescription
auth_profile_setupComplete authentication and profile setup for Amazon Ads API
export_entity_downloadRequest entity export, poll status, and download when ready
create_campaignCreate a new advertising campaign with proper validation
troubleshoot_api_errorDiagnose and recover from common API errors
generate_async_reportCreate and retrieve an async report with polling
setup_regionConfigure region for API routing

Resources

Contextual data attached and managed by the client

NameDescription

No resources

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/KuudoAI/amazon_ads_mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server