Skip to main content
Glama

Google Ads MCP Server

by martechery
README.md25.7 kB
# MCP Server for Google Ads [![npm version](https://img.shields.io/npm/v/mcp-google-ads-ts.svg)](https://www.npmjs.com/package/mcp-google-ads-ts) [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) [![Node.js CI](https://img.shields.io/badge/Node.js-18+-green.svg)](https://nodejs.org/) TypeScript implementation of an MCP server for Google Ads API with GCloud/ADC authentication. Provides tools for campaign management, performance reporting, and account operations with Multi-Customer Center (MCC) support. ## Table of Contents - [Prerequisites](#prerequisites) - [Quick Start](#quick-start) - [Authentication](#authentication) - [Environment Variables](#environment-variables) - [Multi-Tenant Mode](#multi-tenant-mode) - [Client-Specific Instructions](#client-specific-instructions) - [Claude Desktop](#claude-desktop) - [Claude Code](#claude-code) - [Cursor](#cursor) - [VS Code](#vs-code) - [Local Installation](#local-installation) - [Available Tools](#available-tools) - [1. manage_auth](#1-manage_auth---authentication-management) - [2. list_resources](#2-list_resources---list-google-ads-resources) - [3. execute_gaql_query](#3-execute_gaql_query---execute-google-ads-query-language-queries) - [4. get_performance](#4-get_performance---get-performance-metrics) - [5. gaql_help](#5-gaql_help---google-ads-query-language-reference) - [Development](#development) - [License](#license) ## Prerequisites - Node.js 18+ and npm - A GCP project with the Google Ads API enabled - Ensure the credentials you use (user/ADC) have the Service Usage Consumer role on that project (grants `serviceusage.services.use`) - A Google Ads Developer Token is required: - [Documentation](https://developers.google.com/google-ads/api/docs/get-started/dev-token) - [Application form](https://support.google.com/adspolicy/contact/new_token_application) ## Quick Start ### Using npx (Recommended) ```json { "mcpServers": { "google-ads": { "command": "npx", "args": ["mcp-google-ads-ts"], "env": { "GOOGLE_ADS_DEVELOPER_TOKEN": "YOUR_DEV_TOKEN", // Required: Your Google Ads Developer Token "GOOGLE_ADS_ACCOUNT_ID": "1234567890", // Optional: Default customer ID (10 digits, no dashes) "GOOGLE_ADS_MANAGER_ACCOUNT_ID": "9876543210" // Optional: MCC account ID for login customer } } } } ``` ## Authentication The server uses Google Application Default Credentials (ADC) for secure authentication. This is the recommended approach as it provides automatic token refresh and secure credential management. ### How Authentication Works 1. **Application Default Credentials (ADC)**: The server first attempts to use ADC, which automatically finds credentials in this order: - Environment variable `GOOGLE_APPLICATION_CREDENTIALS` pointing to a credential file - User credentials from `gcloud auth application-default login` - Service account attached to the compute resource (GCE, Cloud Functions, etc.) 2. **CLI Token Fallback**: If enabled with `GOOGLE_ADS_GCLOUD_USE_CLI=true`, the server can fall back to using `gcloud auth print-access-token` for authentication 3. **Automatic Token Refresh**: Both methods handle token refresh automatically ### Setting Up Authentication #### Method 1: ADC via gcloud (Recommended) ```bash gcloud auth application-default login --scopes=https://www.googleapis.com/auth/cloud-platform,https://www.googleapis.com/auth/adwords ``` #### Method 2: Existing ADC File Place your ADC file at `.auth/adc.json` in the project directory, or set `GOOGLE_APPLICATION_CREDENTIALS` to point to your authorized_user JSON file. #### Method 3: OAuth Device Flow Use `manage_auth { "action": "oauth_login" }` with `GOOGLE_OAUTH_CLIENT_ID` and `GOOGLE_OAUTH_CLIENT_SECRET` environment variables to create an ADC file interactively. ## Environment Variables ### Required - **`GOOGLE_ADS_DEVELOPER_TOKEN`**: Your Google Ads API developer token (required for all API calls) ### Optional - **`GOOGLE_ADS_ACCOUNT_ID`** (optional): Default Google Ads account ID (10-digit customer ID without dashes). Used as the default customer for all operations when not specified explicitly. - **`GOOGLE_ADS_MANAGER_ACCOUNT_ID`** (optional): For Multi-Customer Center (MCC) accounts - the manager account ID that acts as the login customer. Required when accessing accounts under an MCC. This is typically your MCC account ID (10-digit numeric ID, no dashes). Note: you can override this per call using the `login_customer_id` (aka MCC/manager account id) parameter in tools like `execute_gaql_query` and `get_performance`. - **`GOOGLE_APPLICATION_CREDENTIALS`** (optional): Path to an ADC credentials file (authorized_user JSON). Takes precedence over default ADC locations. - **`GOOGLE_ADS_QUOTA_PROJECT_ID`** (optional): GCP project ID used for quota/billing. Helps avoid 403 errors due to missing quota. Typically your active gcloud project ID. - **`GOOGLE_ADS_API_VERSION`** (optional): API version string (e.g., v20, v21, v22). Defaults to v21 if unset. Supports format normalization ("21" → "v21"). - **`GOOGLE_OAUTH_CLIENT_ID`** and **`GOOGLE_OAUTH_CLIENT_SECRET`** (optional): Desktop OAuth client credentials used by `manage_auth` with `action: "oauth_login"` to create local ADC. Only needed if you cannot use gcloud. - **`GOOGLE_ADS_ACCESS_TOKEN`** (optional): Used by unit tests; for mocked tests this can be any non-empty string. When set, bypasses ADC. For real API calls prefer ADC; if used, this must be a real OAuth 2.0 access token with the Google Ads scope and will not auto-refresh. ### Example Configuration ```env # Required GOOGLE_ADS_DEVELOPER_TOKEN=your-developer-token-here # Optional - Default account GOOGLE_ADS_ACCOUNT_ID=1234567890 # Optional - For MCC accounts GOOGLE_ADS_MANAGER_ACCOUNT_ID=9876543210 # Optional - Authentication GOOGLE_ADS_GCLOUD_USE_CLI=true GOOGLE_APPLICATION_CREDENTIALS=/path/to/credentials.json ``` ## Client-Specific Instructions ### Claude Desktop Add to `~/Library/Application Support/Claude/claude_desktop_config.json` (macOS) or `%APPDATA%\\Claude\\claude_desktop_config.json` (Windows): ```json { "mcpServers": { "google-ads": { "command": "npx", "args": ["mcp-google-ads-ts"], "env": { "GOOGLE_ADS_DEVELOPER_TOKEN": "YOUR_DEV_TOKEN", // Required: Your Google Ads Developer Token "GOOGLE_ADS_ACCOUNT_ID": "1234567890", // Optional: Default customer ID (10 digits, no dashes) "GOOGLE_ADS_MANAGER_ACCOUNT_ID": "9876543210", // Optional: MCC account ID for login customer "GOOGLE_ADS_QUOTA_PROJECT_ID": "my-gcp-project" // Optional: GCP project for quota/billing } } } } ``` ### Claude Code Install and configure with a single command: ```bash # Required claude mcp add google-ads \\ -e GOOGLE_ADS_DEVELOPER_TOKEN=your-token \\ -- npx mcp-google-ads-ts # With optional parameters claude mcp add google-ads \\ -e GOOGLE_ADS_DEVELOPER_TOKEN=your-token \\ -e GOOGLE_ADS_ACCOUNT_ID=1234567890 \\ -e GOOGLE_ADS_MANAGER_ACCOUNT_ID=9876543210 \\ -e GOOGLE_ADS_QUOTA_PROJECT_ID=my-gcp-project \\ -- npx mcp-google-ads-ts ``` For more details, see the [Claude Code MCP documentation](https://docs.anthropic.com/en/docs/claude-code/mcp#installing-mcp-servers). ### Cursor Add to your MCP settings in Cursor. Go to Cursor Settings > Features > Model Context Protocol: ```json { "mcpServers": { "google-ads": { "command": "npx", "args": ["mcp-google-ads-ts"], "env": { "GOOGLE_ADS_DEVELOPER_TOKEN": "YOUR_DEV_TOKEN", // Required: Your Google Ads Developer Token "GOOGLE_ADS_ACCOUNT_ID": "1234567890", // Optional: Default customer ID (10 digits, no dashes) "GOOGLE_ADS_MANAGER_ACCOUNT_ID": "9876543210", // Optional: MCC account ID for login customer "GOOGLE_ADS_API_VERSION": "v21" // Optional: API version (defaults to v21) } } } } ``` For detailed setup instructions, see the [Cursor MCP documentation](https://docs.cursor.com/en/context/mcp). ### VS Code Install the MCP extension and add the server configuration: 1. Install the "MCP Manager" extension from the marketplace 2. Open Command Palette (`Ctrl+Shift+P` / `Cmd+Shift+P`) 3. Run "MCP: Add Server" 4. Configure the server: ```json { "name": "google-ads", "command": "npx", "args": ["mcp-google-ads-ts"], "env": { "GOOGLE_ADS_DEVELOPER_TOKEN": "YOUR_DEV_TOKEN", // Required: Your Google Ads Developer Token "GOOGLE_ADS_ACCOUNT_ID": "1234567890", // Optional: Default customer ID (10 digits, no dashes) "GOOGLE_ADS_MANAGER_ACCOUNT_ID": "9876543210", // Optional: MCC account ID for login customer "GOOGLE_ADS_API_VERSION": "v21" // Optional: API version (defaults to v21) } } ``` For more information, see the [VS Code MCP documentation](https://code.visualstudio.com/docs/copilot/customization/mcp-servers). ### Local Installation For local development or when you want to run from source: #### 1. Clone and Build ```bash # Clone the repository git clone https://github.com/your-username/mcp-google-ads-ts.git cd mcp-google-ads-ts # Install dependencies npm install # Build the project npm run build ``` #### 2. Configure Your MCP Client ```json { "mcpServers": { "google-ads": { "command": "node", "args": ["/absolute/path/to/mcp-google-ads-ts/dist/cli.js"], "env": { "GOOGLE_ADS_DEVELOPER_TOKEN": "YOUR_DEV_TOKEN", // Required: Your Google Ads Developer Token "GOOGLE_ADS_ACCOUNT_ID": "1234567890", // Optional: Default customer ID (10 digits, no dashes) "GOOGLE_ADS_MANAGER_ACCOUNT_ID": "9876543210", // Optional: MCC account ID for login customer "GOOGLE_APPLICATION_CREDENTIALS": "/path/to/adc.json" // Optional: Path to ADC credentials file } } } } ``` #### 3. Development Mode For development with auto-reload: ```bash npm run dev ``` ## Multi-Tenant Mode Multi-tenant mode allows hosted deployments to accept Google Ads credentials at connection time (no filesystem storage) and keep them immutable for the session lifecycle. Enable via environment: - `ENABLE_RUNTIME_CREDENTIALS=true` (default: false) - `RUNTIME_CREDENTIAL_TTL` Session TTL in seconds (default: 3600) - `MAX_CONNECTIONS` Maximum in-memory sessions (default: 1000) - `CONNECTION_SWEEP_INTERVAL` Cleanup interval in seconds (default: 300) - `VERIFY_TOKEN_SCOPE` Optional. When `true`, validates Ads scope at session establishment - `ALLOWED_CUSTOMER_IDS` Optional allowlist of customer IDs (comma-separated) - `GOOGLE_OAUTH_CLIENT_ID` / `GOOGLE_OAUTH_CLIENT_SECRET` Optional, for refresh flows - `HTTPS_PROXY` Optional proxy for outbound requests - `NODE_TLS_REJECT_UNAUTHORIZED` For proxy/cert handling when required - `STRICT_IMMUTABLE_AUTH` Optional. When `true`, blocks re-setting credentials for an existing session (default allows overwrite with a warning) - `OBSERVABILITY_ENABLED` Optional. Set to `false` to disable structured JSON logs (default enabled). Alternatively set `OBSERVABILITY=off`. Behavioral differences when enabled: - Credentials must be provided via `set_session_credentials` - No fallback to ADC/env credentials - `manage_auth` is disabled - Each tool call must include `session_key` - Developer token is required in provided credentials - Sticky sessions required for multi-process deployments Session tools: 1) `set_session_credentials` - Request: ```json { "session_key": "f47ac10b-58cc-4372-a567-0e02b2c3d479", "google_credentials": { "access_token": "ya29...", "refresh_token": "1//...", "developer_token": "DEV_TOKEN_REQUIRED", "login_customer_id": "1234567890", "quota_project_id": "my-project" } } ``` - Response: `{ "status": "success", "session_key": "...", "expires_in": 3600 }` 2) `get_credential_status` - Request: `{ "session_key": "f47ac10b-58cc-4372-a567-0e02b2c3d479" }` - Response: `{ "has_credentials": true, "expires_in": 3542, "has_refresh_token": true, "masked_token": "ya29****abcd" }` 3) `end_session` - Request: `{ "session_key": "f47ac10b-58cc-4372-a567-0e02b2c3d479" }` - Response: `{ "status": "session_ended" }` Using standard tools in multi-tenant mode: include `session_key` in inputs. Example: ```json { "session_key": "f47ac10b-58cc-4372-a567-0e02b2c3d479", "customer_id": "1234567890", "query": "SELECT campaign.id, campaign.name FROM campaign LIMIT 5", "output_format": "table" } ``` Client usage examples - Establish session, then execute a GAQL query and get performance with `session_key`: ```json { "tool": "set_session_credentials", "input": { "session_key": "f47ac10b-58cc-4372-a567-0e02b2c3d479", "google_credentials": { "access_token": "ya29...", "refresh_token": "1//...", "developer_token": "DEV_TOKEN", "login_customer_id": "1234567890", "quota_project_id": "my-project" } }} { "tool": "execute_gaql_query", "input": { "session_key": "f47ac10b-58cc-4372-a567-0e02b2c3d479", "request_id": "req-abc-123", "customer_id": "1234567890", "query": "SELECT campaign.id, campaign.name FROM campaign LIMIT 5" }} { "tool": "get_performance", "input": { "session_key": "f47ac10b-58cc-4372-a567-0e02b2c3d479", "request_id": "req-abc-456", "customer_id": "1234567890", "level": "campaign", "days": 7, "limit": 10 }} ``` 4) `refresh_access_token` When a `refresh_token` is provided and OAuth client env is set, this tool refreshes the access token for the session. Request ```json { "session_key": "f47ac10b-58cc-4372-a567-0e02b2c3d479" } ``` Response (success) ```json { "status": "refreshed", "expires_in": 3600, "masked_token": "ya29****abcd" } ``` Response (invalid grant) ```json { "error": { "code": "ERR_INVALID_GRANT", "message": "Refresh token invalid or revoked. Re-authentication required." } } ``` ### Observability The server emits structured JSON events to stderr (12-factor style) for application-side collection. Each event includes: ```json { "timestamp": "2025-01-01T00:00:00.000Z", "tool": "execute_gaql_query", "session_key": "...", // when available "customer_id": "1234567890", // when available "request_id": "abc-123", // pass-through from input when provided "response_time_ms": 12, "api_version": "v21", "error": { "code": "HTTP_403", "message": "..." } // only on errors } ``` Control via env: - `OBSERVABILITY_ENABLED=false` (disable) - `OBSERVABILITY=off` (disable) ### Error Payloads All tools return structured error payloads when failures occur: ```json { "error": { "code": "ERR_NO_SESSION_KEY", "message": "session_key parameter required in multi-tenant mode" } } ``` Common codes include: `ERR_INPUT`, `ERR_NOT_ENABLED`, `ERR_IMMUTABLE_AUTH`, `ERR_INVALID_GRANT`, `ERR_INSUFFICIENT_SCOPE`, and `HTTP_<status>` for API responses. ### Live Multi-Tenant Integration Test (optional) You can run a live multi-tenant test flow using environment-provided credentials. Recommended gating: - Set `VITEST_REAL=1` and `ENABLE_RUNTIME_CREDENTIALS=true` - Provide runtime test credentials via env (examples): - `TEST_ACCESS_TOKEN`, `TEST_REFRESH_TOKEN`, `TEST_DEVELOPER_TOKEN` - `TEST_LOGIN_CUSTOMER_ID`, `TEST_QUOTA_PROJECT_ID` - Steps: 1) Call `set_session_credentials` with test env values 2) Run `execute_gaql_query` and `get_performance` with `session_key` 3) Optionally call `refresh_access_token` to validate token refresh 4) Optionally set `VERIFY_TOKEN_SCOPE=true` to validate scope against live API 5) Optionally pass `ALLOWED_CUSTOMER_IDS` to validate allowlist enforcement Keep the existing single-tenant live tests as primary validation; multi-tenant live tests are optional and depend on environment-provided credentials. ### Per-Session Rate Limiting (Optional) Token-bucket rate limiting protects quotas on a per-session basis when multi-tenant mode is enabled. - Env (defaults in parentheses): - `ENABLE_RATE_LIMITING` (true) - `REQUESTS_PER_SECOND` (10) - `RATE_LIMIT_BURST` (20) - Error payload on limit: ```json { "error": { "code": "ERR_RATE_LIMITED", "message": "Rate limit exceeded. Retry after 1 seconds", "retry_after": 1 } } ``` Rate limiting is enforced only in multi-tenant mode and only for session-bound tools. ## Available Tools ### 1. `manage_auth` - Authentication management Note: When `ENABLE_RUNTIME_CREDENTIALS=true` (multi-tenant mode), this tool is disabled and returns an error. Use the session tools instead. ```typescript { action?: 'status' | 'switch' | 'refresh' | 'oauth_login' | 'set_project' | 'set_quota_project', // Action to perform (default: 'status') config_name?: string, // For 'switch' action: gcloud configuration name project_id?: string, // For 'set_project' and 'set_quota_project' actions project?: string, // Alias for project_id allow_subprocess?: boolean // Allow gcloud command execution (default: true) } ``` **Comprehensive authentication management tool** with multiple actions: #### `action: 'status'` (default) - **Environment inspection**: Shows all Google Ads environment variables - **ADC file discovery**: Locates and validates Application Default Credentials files - **Token validation**: Checks access token presence and scopes via Google OAuth2 API - **Scope verification**: Tests Google Ads API access by calling `listAccessibleCustomers` - **Account enumeration**: Counts accessible customer accounts under current credentials - **Troubleshooting hints**: Provides guidance when authentication issues are detected #### `action: 'oauth_login'` - **Device OAuth flow**: Interactive browser-based authentication using OAuth client credentials - **Requires env vars**: `GOOGLE_OAUTH_CLIENT_ID` and `GOOGLE_OAUTH_CLIENT_SECRET` - **Saves ADC file**: Creates `authorized_user` JSON at `.auth/adc.json` - **Scope validation**: Automatically verifies Google Ads API access after completion - **Sets credentials**: Updates `GOOGLE_APPLICATION_CREDENTIALS` for immediate use #### `action: 'switch'` - **Configuration switching**: Changes active gcloud configuration - **Requires**: `config_name` parameter - **Auto-execution**: Runs `gcloud config configurations activate <name>` when `allow_subprocess=true` - **Guidance**: Provides next steps for refreshing ADC credentials with correct scopes #### `action: 'refresh'` - **Credential refresh**: Re-authenticates ADC with required Google Ads scopes - **Auto-execution**: Runs `gcloud auth application-default login` with proper scopes - **Token verification**: Prints access token to verify successful authentication - **Scope testing**: Validates Google Ads API access after refresh #### `action: 'set_project'` - **Project configuration**: Sets default GCP project for gcloud - **Requires**: `project_id` parameter - **Command**: `gcloud config set project <project_id>` #### `action: 'set_quota_project'` - **Quota project setup**: Sets ADC quota project for billing attribution - **Requires**: `project_id` parameter - **Command**: `gcloud auth application-default set-quota-project <project_id>` #### Safety Features - **Dry-run mode**: Set `allow_subprocess: false` to see planned commands without execution - **gcloud detection**: Automatically checks for gcloud CLI availability before execution - **Error handling**: Provides clear error messages and installation links when gcloud is missing - **Timeout protection**: Commands have built-in timeouts to prevent hanging **Example user prompts:** ``` // Check authentication status "Check my Google Ads authentication status" // Refresh credentials with Google Ads scopes "Refresh my Google Ads authentication credentials" // Switch gcloud configuration "Switch to my-project gcloud configuration" // Set up OAuth authentication "Help me set up OAuth authentication for Google Ads" // Show what commands would run without executing "Show me what commands would run to refresh my auth (dry-run mode)" ``` ### 2. `list_resources` - List Google Ads resources ```typescript { kind: string, // Required: Resource type (accounts, campaigns, ad_groups, ads, etc.) customer_id?: string, // Customer ID (uses default if not specified) parent_id?: string, // Parent resource ID for hierarchical resources output_format?: string // Output format (table, json, csv) } ``` Lists various Google Ads resources with support for hierarchical relationships and multiple output formats. **Supported resource types:** - `accounts` - List accessible customer accounts - `campaigns` - List campaigns - `ad_groups` - List ad groups - `ads` - List ads - `keywords` - List keywords - `extensions` - List ad extensions **Example user prompts:** ``` "List all my Google Ads accounts" "Show me campaigns for customer ID 1234567890" "Get all ad groups in JSON format" "List keywords for the Search campaign" ``` ### 3. `execute_gaql_query` - Execute Google Ads Query Language queries ```typescript { query: string, // Required: GAQL query customer_id?: string, // Customer ID (uses default if not specified) login_customer_id?: string, // Optional: MCC/manager account ID for this call (overrides env) output_format?: string, // Output format (table, json, csv) page_size?: number, // Results per page (default: 1000) page_token?: string, // Pagination token auto_paginate?: boolean, // Auto-paginate through all results max_pages?: number // Maximum pages to fetch } ``` Executes custom GAQL queries for advanced data retrieval and analysis with automatic pagination support. **Example user prompts:** ``` "Run this GAQL query: SELECT campaign.name, metrics.clicks FROM campaign WHERE segments.date DURING LAST_7_DAYS" "Execute a query to get impressions and CTR for all active campaigns" "Query ad performance data for the past 30 days in CSV format" "Show me all campaigns with their budgets and status" ``` ### 4. `get_performance` - Get performance metrics ```typescript { level: string, // Required: Reporting level (account, campaign, ad_group, ad, keyword) customer_id?: string, // Customer ID (uses default if not specified) login_customer_id?: string, // Optional: MCC/manager account ID for this call (overrides env) date_range?: string, // Date range (LAST_7_DAYS, LAST_30_DAYS, etc.) days?: number, // Custom days back from today metrics?: string[], // Specific metrics to retrieve segments?: string[], // Segmentation dimensions filters?: object, // Query filters output_format?: string, // Output format (table, json, csv) page_size?: number, // Results per page auto_paginate?: boolean // Auto-paginate through all results } ``` Retrieves performance metrics and reports for campaigns, ad groups, ads, and keywords with flexible filtering and segmentation. **Example user prompts:** ``` "Get campaign performance for the last 7 days" "Show me ad group metrics with cost and conversions for last month" "Get keyword performance data segmented by device" "Analyze ad performance with CTR and quality score metrics" ``` ### 5. `gaql_help` - Google Ads Query Language reference ```typescript { topic?: string, // Specific help topic search?: string // Search term for help content } ``` Provides interactive help and documentation for Google Ads Query Language (GAQL), including available resources, fields, functions, and operators. **Example user prompts:** ``` "Help me with GAQL syntax" "What fields are available for the campaign resource?" "Show me examples of GAQL queries for performance data" "How do I filter by date ranges in GAQL?" ``` ## Development ### Setup ```bash # 1. Clone and install git clone https://github.com/your-username/mcp-google-ads-ts.git cd mcp-google-ads-ts npm install # 2. Set up environment cp .env.example .env # Edit .env with your credentials # 3. Development commands npm run dev # Development mode with auto-reload npm test # Run all tests npm run build # Production build npm run lint # Check code quality ``` ### Running Tests ```bash # Unit tests only npm run test:unit # Integration tests (requires real Google Ads API access) VITEST_REAL=1 npm run test:integration # All tests npm test ``` ### Project Structure ``` src/ ├── cli.ts # CLI entry point ├── server.ts # MCP server implementation ├── server-tools.ts # Tool implementations ├── auth.ts # Authentication handling ├── schemas.ts # Zod schemas for validation ├── headers.ts # API request headers ├── tools/ # Individual tool implementations │ ├── accounts.ts # Account listing │ ├── fields.ts # Google Ads field metadata │ ├── gaql.ts # GAQL query execution │ ├── performance.ts # Performance reporting │ └── oauth.ts # Authentication management └── utils/ # Utility functions ├── currency.ts # Currency formatting ├── errorMapping.ts # API error handling ├── exec.ts # Command execution ├── formatCsv.ts # CSV formatting ├── formatTable.ts # Table formatting └── formatCustomerId.ts # Customer ID formatting ``` ## License MIT

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/martechery/mcp-google-ads-ts'

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