# Adwarp (npm · adwarp)

Open-source ad agent for LinkedIn Ads and Google Ads. Drafts campaigns, audiences and reports.

- Trust score: 72/100 (medium)
- Registry status: active
- Liveness: live
- Owner verified: no
- Last scored: 2026-10-25

## Components

- remote · `mcp.adwarp.dev`: 36/100, [markdown](https://verifymcp.io/servers/adwarp-dev-adwarp/api-mcp.md), [page](https://verifymcp.io/servers/adwarp-dev-adwarp/api-mcp)
- npm · `adwarp`: 72/100 (this document), [markdown](https://verifymcp.io/servers/adwarp-dev-adwarp/adwarp.md), [page](https://verifymcp.io/servers/adwarp-dev-adwarp/adwarp)

## Channel facts

- Registry: `npm`
- Package: `adwarp`
- Version: `0.4.0`
- Transport: `stdio`

## Trust breakdown

How this component scores in each security and reliability category. Every signal is checked automatically from public evidence about the published package, including repeated runs of it in an isolated sandbox, and we only credit what we can confirm. Scores are 0–100 per category. Scoring method: https://verifymcp.io/docs/scoring (what has changed: https://verifymcp.io/docs/scoring/changelog)

Scored 2026-10-25.

- **Supply Chain Security**: 81/100
  - No malware found by supply-chain analysis.
  - CVE check failed: a known high-severity CVE affects zod 3.25.76, a direct dependency. A fixed version is available.
  - No install/post-install scripts declared.
  - 32 of 105 dependencies flagged as unhealthy.
- **Provenance & Transparency**: 97/100
  - Source repository is publicly reachable at the declared URL.
  - Cryptographically verified build provenance (signed, bound to adwarp-dev/adwarp).
  - Clear OSI-approved license (MIT).
  - Actively maintained (last published 6 days ago).
  - Disclosure check failed: no security disclosure policy was found in the source repository.
- **Schema Quality & AI Usability**: 60/100
  - AI-judged instruction clarity (good).
  - Context-footprint check failed: tool/resource definitions use about 4568 tokens (~123/item across 37 items; 37 tools + 0 resources), over budget; trim descriptions and params.
  - Usage-examples check failed: none of the tools include examples.
- **Stability & Change Management**: 20/100
  - Stability observed for 6 of 30 days with no destabilising changes; credit accrues until the full window elapses.
- **Tool Coverage**: 82/100
  - 100% of tools have a non-trivial description (not blank, and not just the tool's name).
  - 46% of tool parameters carry a description.
- **Tool Safety**: 75/100
  - No prompt-injection markers were found in the server instructions, tool names or descriptions we captured.
  - 0 of 1 tool(s) whose name or description implies an irreversible operation declare an MCP destructiveHint annotation; "delete_ad" implies "delete" and declares no destructiveHint at all, which the MCP spec reads as destructive by default.
  - An AI judge read all 37 captured unit(s) of tool text and found none that tries to manipulate the model reading it.
- **Capabilities**: 100/100
  - Implements a supported MCP spec version (2025-11-25); the latest is 2026-07-28.

## Install

### How do I install the Adwarp MCP server?

Adwarp runs locally as an npm package, launched with npx -y adwarp. Ready-made configuration for Claude, Cursor, VS Code, Codex and 5 more is on this page, copied from each client's own documentation.

### Claude

```bash
claude mcp add adwarp-dev-adwarp -- npx -y adwarp
```

### Cursor

```json
{
  "mcpServers": {
    "adwarp-dev-adwarp": {
      "command": "npx",
      "args": [
        "-y",
        "adwarp"
      ]
    }
  }
}
```

### VS Code

```json
{
  "servers": {
    "adwarp-dev-adwarp": {
      "command": "npx",
      "args": [
        "-y",
        "adwarp"
      ]
    }
  }
}
```

### Codex

```bash
codex mcp add adwarp-dev-adwarp -- npx -y adwarp
```

### opencode

```json
{
  "$schema": "https://opencode.ai/config.json",
  "mcp": {
    "adwarp-dev-adwarp": {
      "type": "local",
      "command": [
        "npx",
        "-y",
        "adwarp"
      ],
      "enabled": true
    }
  }
}
```

### OpenClaw

```bash
openclaw mcp add adwarp-dev-adwarp --command npx --arg -y --arg adwarp
```

### Hermes

```yaml
mcp_servers:
  adwarp-dev-adwarp:
    command: "npx"
    args: ["-y", "adwarp"]
```

### Netclaw

```json
{
  "McpServers": {
    "adwarp-dev-adwarp": {
      "Transport": "stdio",
      "Command": "npx",
      "Arguments": [
        "-y",
        "adwarp"
      ]
    }
  }
}
```

### Vellum

```bash
assistant mcp add adwarp-dev-adwarp -t stdio -c npx -a -y adwarp
```

### Other

```json
{
  "mcpServers": {
    "adwarp-dev-adwarp": {
      "command": "npx",
      "args": [
        "-y",
        "adwarp"
      ]
    }
  }
}
```

## Changelog

Every change recorded for this component, newest first. Days that predate change tracking, or that we cannot explain, say so: "we were watching and nothing happened" and "we were not watching" are different claims.

### 2026-10-24 (score 72, −1)

- [security regression] CVE-2023-54404 affects this package: high

### 2026-10-21 (score 73, +1)

No change was recorded against any check on this day. Stability & Change Management went from 3 to 7. That category is still filling its 30-day observation window: 1 days of observed history at the previous scan, 2 at this one. The score rises as the window fills, whether or not the server changes.

### 2026-10-20 (score 72, +8)

- [security regression] CVE-2026-85063 affects this package: medium
- [security regression] Known CVEs: unverified → fail
- [functional improvement] Dependency health: unverified → 0.86

### 2026-10-19 (score 64)

First indexed and scored.

## MCP tools (37)

### `gads_list_accounts` (~39 tokens)

List every Google Ads customer this login can reach. Run this first: it proves the OAuth client, developer token, and account access all work.

### `gads_list_client_accounts` (~40 tokens)

List the client accounts under a Google Ads manager (MCC) account.

Input parameters:

- `managerId` (string, required): Manager customer id, digits only

### `gads_keyword_ideas` (~98 tokens)

Keyword research: search volume, competition, and top-of-page bid range for seed terms and/or a landing page. The sizing step before committing budget, equivalent to estimating audience reach on LinkedIn.

Input parameters:

- `customerId` (string)
- `languages` (array)
- `limit` (integer)
- `locations` (array)
- `pageUrl` (string)
- `seeds` (array, required): Seed keywords or phrases

### `gads_list_campaigns` (~43 tokens)

Account structure: campaigns with their ad groups nested. Paused campaigns are included.

Input parameters:

- `customerId` (string)
- `includeRemoved` (boolean)

### `gads_list_ads` (~41 tokens)

Ads in an ad group, with their responsive-search headlines and descriptions.

Input parameters:

- `adGroupId` (string, required)
- `customerId` (string)

### `gads_list_conversion_actions` (~37 tokens)

Conversion actions on the account, so a launch can name one instead of guessing an id.

Input parameters:

- `customerId` (string)

### `gads_launch_search_campaign` (~344 tokens)

Create a PAUSED Search campaign from a brief: budget, campaign, geo/language targeting, ad groups, keywords, and responsive search ads, all in one atomic mutate. Defaults to validateOnly=true, which asks Google to validate the whole batch and persist nothing. Show the returned plan to the user and only re-call with validateOnly=false after they confirm. House rules are applied automatically and cannot be overridden: search network only (display expansion and search partners off), physical-presence-only location targeting, and Manual CPC. Nothing created here can serve. Activation is a human step in the Google Ads UI.

Input parameters:

- `adGroups` (array, required)
- `budgetName` (string): Defaults to the campaign name
- `campaignName` (string, required)
- `conversionActionNames` (array): Conversion actions to set as this campaign's goals; falls back to the config default
- `cpcBid`: Amount in the ad account's currency, e.g. 150 for $150
- `customerId` (string): 10-digit customer id; falls back to config default
- `dailyBudget` (number, required): Amount in the ad account's currency, e.g. 150 for $150
- `endDateTime` (string)
- `finalUrl` (string, required): Landing page for ads that do not override it
- `languages` (array): ISO language codes
- `locations` (array): ISO country codes (US, GB) or raw geoTargetConstant ids
- `negativeKeywordListId` (string)
- `negativeKeywords` (array)
- `startDateTime` (string)
- `validateOnly` (boolean)

### `gads_performance` (~99 tokens)

Performance rows at campaign, ad_group, ad, keyword, or search_term level, with totals and derived KPIs (CTR, CPC, CPM, conversion rate, cost per conversion).

Input parameters:

- `campaignId` (string)
- `customerId` (string)
- `endDate` (string): YYYY-MM-DD
- `level` (string)
- `period` (string)
- `startDate` (string): YYYY-MM-DD

### `gads_search` (~58 tokens)

Run a raw GAQL query against the account. Read-only escape hatch for anything the other tools do not cover.

Input parameters:

- `customerId` (string)
- `query` (string, required): A GAQL query. Read-only: SELECT ... FROM ...

### `list_ad_accounts` (~19 tokens)

List LinkedIn ad accounts this app can access.

### `list_targeting_facets` (~69 tokens)

List LinkedIn targeting facets you can target on. Common short names: locations, profileLocations, seniorities, titles, functions, industries, staffCountRanges, skills, employers, employersPast, audienceMatchingSegments, dynamicSegments, interests, degrees, fieldsOfStudy, schools, groups.

### `search_targeting` (~94 tokens)

Typeahead-search entities within a facet to get their URNs (e.g. facet='titles', query='marketing' -> Marketing Manager urn). Use 'list_facet_entities' for small fixed sets like seniorities. These URNs go into a targeting spec.

Input parameters:

- `facet` (string, required): short facet name, e.g. titles, industries, skills, staffCountRanges, locations
- `query` (string, required)

### `list_facet_entities` (~50 tokens)

List all entities of a small facet (e.g. seniorities, functions, degrees) to pick URNs from.

Input parameters:

- `facet` (string, required): short facet name, e.g. seniorities

### `estimate_audience` (~70 tokens)

Estimate audience size for a structured targeting spec (facet short name -> entity URNs). A campaign needs >=300 members to serve.

Input parameters:

- `exclude` (object): facet short name -> entity URNs to exclude
- `include` (object, required): facet short name -> entity URNs (ANDed across facets)

### `upload_audience_csv` (~127 tokens)

Clean a CSV at csvPath and upload it as a matched-audience DMP segment. Auto-detects contact (email) vs company (account) lists, normalizes column names, drops non-matcher columns, hashes emails, and converts company domains to website URLs. Requires the Audiences product; matching takes up to 48h.

Input parameters:

- `accountId` (string)
- `csvPath` (string, required): Path to the CSV file on the server
- `name` (string, required)
- `type` (string): Force the list type; auto-detected if omitted

### `audience_from_salesforce` (~108 tokens)

Build a matched audience from a Salesforce SOQL query that selects an email column. Closes the loop: flagged accounts/contacts -> DMP segment. Requires the local `sf` CLI to be authenticated.

Input parameters:

- `accountId` (string, required)
- `emailField` (string): Email column name if not 'Email'
- `name` (string, required): Audience/segment name
- `soql` (string, required): SOQL selecting an email column, e.g. SELECT Email FROM Contact WHERE ...

### `audience_from_hubspot` (~265 tokens)

Build a matched audience from HubSpot contacts or companies. Pass exactly 1 source: a HubSpot listId (its members), or filters for a CRM search (all ANDed). Reads every page, cleans the records like a CSV upload, and uploads only SHA256 email hashes for contacts (name and website for companies). Pass dryRun=true first: it returns counts and a masked sample and uploads nothing. Needs a HubSpot private app token on this machine (ADWARP_HUBSPOT_TOKEN or ~/.adwarp/hubspot.json); matching takes up to 48h.

Input parameters:

- `accountId` (string): LinkedIn ad account id; defaults to config defaultAccountId
- `dryRun` (boolean): Return counts and a masked sample without uploading anything
- `filters` (array): CRM search filters, all ANDed (HubSpot allows up to 6 per group). Pass this or listId, not both.
- `listId` (string): HubSpot list id (the ILS list id). Pass this or filters, not both.
- `name` (string, required): Audience/segment name
- `type` (string): contact or company. With listId it defaults to the list's object type; with filters it defaults to contact.

### `list_conversions` (~49 tokens)

List the account's existing conversions (insight tags) so you can select one to track on a campaign. Pass accountId or omit to use the default.

Input parameters:

- `accountId` (string)

### `list_campaigns` (~118 tokens)

List the account structure: campaign groups (campaigns) and/or their campaigns (ad groups), DRAFTS INCLUDED, unlike performance reports, which only show entities with spend. Pass level=groups for campaign groups only, level=campaigns for ad groups (optionally scoped by groupId), or level=both (default) for the full tree.

Input parameters:

- `accountId` (string)
- `groupId` (string): Scope campaigns to one campaign group id
- `includeArchived` (boolean)
- `level` (string)

### `list_ads` (~51 tokens)

List the creatives (ads) in a campaign (ad group), drafts included: id, name, status, and backing post urn.

Input parameters:

- `accountId` (string)
- `campaignId` (string, required)

### `delete_ad` (~91 tokens)

Delete an ad: removes the creative and (best-effort) the Direct Sponsored Content post behind it. Accepts a numeric creative id or a full urn:li:sponsoredCreative URN. Use for cleaning up drafts or replacing an ad whose copy must change (Campaign Manager's editor does not reflect post edits, so recreate instead).

Input parameters:

- `accountId` (string)
- `creativeId` (string, required)

### `update_ad` (~234 tokens)

Change a single ad's (creative's) status in place: PAUSED stops it serving, ACTIVE starts it serving, ARCHIVED retires it. Use PAUSED to stop an ad without touching the rest of its ad group. Accepts a numeric creative id or a full urn:li:sponsoredCreative URN. Setting ACTIVE starts spend, so set it only when the user explicitly asks to turn the ad on, never as a side effect of another request. An ACTIVE ad still only serves while its campaign (ad group) is ACTIVE. LinkedIn refuses to pause an ad that is still in review. Pass dryRun=true to preview the patch without sending it.

Input parameters:

- `accountId` (string): Numeric ad account id; defaults to the configured account
- `creativeId` (string, required): Numeric creative (ad) id or a full urn:li:sponsoredCreative URN
- `dryRun` (boolean): Return the patch without sending it
- `status` (string, required): PAUSED stops the ad serving. ACTIVE starts it serving and spending: set it only when the user explicitly asks. ARCHIVED retires it.

### `get_audience_status` (~30 tokens)

Check a DMP segment's matching status and resolved size.

Input parameters:

- `segmentId` (string, required)

### `create_campaign_group` (~71 tokens)

Create a campaign group (the top-level 'campaign'). Defaults to DRAFT.

Input parameters:

- `accountId` (string, required): Numeric ad account id (no urn prefix)
- `name` (string, required)
- `runSchedule` (object)
- `status` (string)
- `totalBudget` (object)

### `create_campaign` (~348 tokens)

Create a campaign (the 'ad group') with targeting, budget, bid or bidding strategy (optimizationTargetType MAX_CLICK = Maximum Delivery on landing page clicks), schedule, and optional ad rotation (creativeSelection: OPTIMIZED or ROUND_ROBIN = rotate ads evenly). Defaults to DRAFT.

Input parameters:

- `accountId` (string, required)
- `applyDefaultConversion` (boolean)
- `applyDefaultExclusions` (boolean)
- `audienceSegmentUrn` (string): urn:li:adSegment:... to target a matched audience
- `campaignGroupId` (string, required): Numeric campaign group id
- `conversionIds` (array)
- `costType` (string)
- `creativeSelection` (string): Ad rotation: OPTIMIZED (LinkedIn default, favors the predicted winner) or ROUND_ROBIN (rotate ads evenly)
- `dailyBudget` (object)
- `geoUrns` (array): urn:li:geo:... locations to include
- `locale` (object)
- `name` (string, required)
- `objectiveType` (string): Campaign objective. Required to be ENGAGEMENT to sponsor another member's post (thought-leader ads).
- `optimizationTargetType` (string): Bidding strategy. MAX_CLICK = Maximum Delivery optimized for landing page clicks (automated bid, charged CPM, unitCost ignored). Omit or NONE for a manual bid.
- `politicalIntent` (string)
- `runSchedule` (object, required)
- `status` (string)
- `targeting` (object)
- `targetingCriteria` (object)
- `totalBudget`
- `type` (string)
- `unitCost`: Bid amount

### `update_campaign` (~400 tokens)

Update an existing campaign (the 'ad group') in place: change its targeting and/or name, status, budget, bid, bidding strategy (optimizationTargetType, costType), schedule, ad rotation (creativeSelection: OPTIMIZED or ROUND_ROBIN = rotate ads evenly). Only the fields you pass change. Targeting is REPLACED when you pass any targeting form: a structured `targeting` spec, the `audienceSegmentUrn` (+ optional `geoUrns`) shorthand, or a raw `targetingCriteria`, and default exclusions are re-applied unless applyDefaultExclusions=false. Audience Expansion / Audience Network stay off. Pass dryRun=true first to preview the patch before touching a live campaign.

Input parameters:

- `accountId` (string, required)
- `applyDefaultExclusions` (boolean)
- `audienceSegmentUrn` (string): urn:li:adSegment:... (or bare id) matched audience to target, which replaces existing targeting
- `campaignId` (string, required): Numeric campaign (ad group) id to update
- `costType` (string): Change the cost type (CPM for Maximum Delivery)
- `creativeSelection` (string): Ad rotation: OPTIMIZED (favors the predicted winner) or ROUND_ROBIN (rotate ads evenly)
- `dailyBudget` (object)
- `dryRun` (boolean)
- `geoUrns` (array): urn:li:geo:... locations to include alongside the audience
- `name` (string)
- `optimizationTargetType` (string): Bidding strategy. MAX_CLICK = Maximum Delivery optimized for landing page clicks (automated bid, charged CPM, unitCost ignored). Omit or NONE for a manual bid.
- `runSchedule` (object)
- `status` (string)
- `targeting` (object)
- `targetingCriteria` (object)
- `totalBudget`
- `unitCost`: Bid amount

### `create_text_ad` (~65 tokens)

Create a Text Ad creative (DRAFT by default).

Input parameters:

- `accountId` (string, required)
- `campaignId` (string, required)
- `clickUri` (string, required)
- `status` (string)
- `text` (string, required)
- `title` (string, required)

### `create_image_ad` (~141 tokens)

Create a single-image Sponsored Content creative (DRAFT). Omit imagePath to leave the campaign ready for an image later.

Input parameters:

- `accountId` (string, required)
- `callToAction` (string): Call-to-action button label
- `campaignId` (string, required)
- `clickUri` (string, required)
- `commentary` (string, required): The post body / ad intro text
- `headline` (string, required)
- `imagePath` (string)
- `name` (string): Ad name shown in Campaign Manager
- `organizationUrn` (string, required): urn:li:organization:... that owns the post
- `status` (string)

### `performance_summary` (~105 tokens)

Account performance rollup over a period: totals + KPIs, top campaigns by spend/CTR, worst by cost-per-conversion, and flagged campaigns (spend with no conversions, high CPC, low CTR). Start here for 'how are my ads doing'.

Input parameters:

- `accountId` (string)
- `endDate` (string): YYYY-MM-DD
- `period` (string)
- `startDate` (string): YYYY-MM-DD; with endDate, overrides period

### `get_performance` (~150 tokens)

Per-entity performance with derived KPIs (CTR, CPC, CPM, CPL, conversion rate). level: campaign_group (campaign), campaign (ad group), or creative (ad). Pass parentId to scope campaigns to a group or creatives to a campaign.

Input parameters:

- `accountId` (string)
- `endDate` (string): YYYY-MM-DD
- `level` (string): campaign_group=campaign, campaign=ad group, creative=ad
- `parentId` (string): Parent group id (for level=campaign) or campaign id (for level=creative)
- `period` (string)
- `startDate` (string): YYYY-MM-DD; with endDate, overrides period

### `performance_trend` (~113 tokens)

Weekly or monthly trend for one entity, with period-over-period deltas on impressions, clicks, spend, conversions, and CTR. Use to spot momentum or creative fatigue.

Input parameters:

- `bucket` (string)
- `endDate` (string): YYYY-MM-DD
- `entityId` (string, required): Numeric id of the account/group/campaign/creative to trend
- `level` (string)
- `period` (string)
- `startDate` (string): YYYY-MM-DD; with endDate, overrides period

### `launch_from_brief` (~157 tokens)

End-to-end: optional audience upload -> campaign group -> campaign -> draft creatives. Everything DRAFT. Returns Campaign Manager review links.

Input parameters:

- `accountId` (string, required)
- `audience` (object)
- `bid`
- `campaignGroupName` (string, required)
- `campaignName` (string, required)
- `conversionIds` (array)
- `conversionName` (string): e.g. 'Demo Booked - Insight Tag'
- `creativeSelection` (string)
- `creatives` (array)
- `dailyBudget` (object, required)
- `geoUrns` (array): Defaults to United States
- `runSchedule` (object, required)
- `targeting` (object)
- `type` (string)

### `log_ad_change` (~252 tokens)

Record a change to an ad entity in the local change journal, so a later lift report can compare performance before vs. after it. Adwarp logs its own changes automatically. Use this for changes made elsewhere (e.g. in Campaign Manager) or to attach a hypothesis/label. Provide field+after for a field change, or note for a freeform annotation.

Input parameters:

- `after` (string): New value
- `at` (string): ISO 8601 time the change took effect; defaults to now
- `before` (string): Prior value, if known
- `entityId` (string, required): Numeric id of the campaign group / campaign / creative
- `entityType` (string, required): campaignGroup (the 'campaign'), campaign (the 'ad group'), or creative (the 'ad')
- `field` (string): Field that changed, e.g. dailyBudget, headline, status
- `label` (string): Hypothesis/label, e.g. 'outcome-led headline test'
- `name` (string): Human name of the entity (for nicer listings)
- `note` (string): Freeform note (used when there is no specific field)
- `tags` (array)

### `list_ad_changes` (~99 tokens)

List recorded ad changes (newest first) from the local change journal. Filter by entity type/id or tag. Use this to see what's been changed before computing lift.

Input parameters:

- `entityId` (string)
- `entityType` (string): campaignGroup (the 'campaign'), campaign (the 'ad group'), or creative (the 'ad')
- `limit` (integer): Max rows (default 50)
- `tag` (string)

### `compute_lift` (~171 tokens)

For each recorded change to an entity, compare performance in the window before the change against the window after it (default 14 days each side). Returns before/after KPI windows and per-metric relative deltas (CTR, CPC, conversion rate, cost-per-conversion, etc.). This is a directional pre/post comparison, NOT a controlled experiment. It is confounded by seasonality, the LinkedIn learning phase after edits, and concurrent budget changes; present it as a signal and call out partial after-windows on recent changes.

Input parameters:

- `entityId` (string, required)
- `entityType` (string, required): campaignGroup (the 'campaign'), campaign (the 'ad group'), or creative (the 'ad')
- `windowDays` (integer): Days on each side of a change (default 14)

### `inspect_competitor_ads` (~269 tokens)

Discover competitor ads through the official API. auto optionally queues up to 10 creatives on the remote worker; api returns metadata only. Always provide advertiser plus companyId to filter unrelated name matches before collection. No local browser or scraper fallback. Read pending results with get_competitor_creatives. Cached screenshots require worker authentication. Report sample coverage and collection dates; never retry a blocked worker or use another browser/client. Synthesize findings rather than dumping rows.

Input parameters:

- `advertiser` (string): Competitor/advertiser display name (accountOwner)
- `companyId` (string): Numeric LinkedIn company id, more precise than name
- `concurrency` (number): Remote worker concurrency is fixed at one.
- `copyMax` (integer): Creative sample size, capped at 10. Worker budgets cannot be overridden.
- `countries` (array): ISO-3166 country codes to scope, e.g. ['US','GB']
- `deep` (boolean): Enqueue up to 10 verified company ads on the remote worker; reuse cached creatives.
- `engine` (string): auto = official API plus remote creative worker; api = metadata only. Local scraping is disabled.
- `keyword` (string): Free-text keyword search across ad copy
- `max` (integer): Max ads to collect

### `get_competitor_creatives` (~53 tokens)

Read remote creative job status and cached copy by ad IDs. Read-only: does not enqueue work or visit LinkedIn. Screenshots are available through the authenticated worker endpoint.

Input parameters:

- `ids` (array, required)

## Diagnostics

Captured diagnostic sections: Provenance, Vulnerabilities, Dependencies. The full working is on the page: https://verifymcp.io/servers/adwarp-dev-adwarp/adwarp#diagnostics

## Score history

- 2026-10-25: 72
- 2026-10-24: 72
- 2026-10-23: 73
- 2026-10-22: 73
- 2026-10-21: 73
- 2026-10-20: 72
- 2026-10-19: 64

## Common questions

### What is the Adwarp MCP server?

Adwarp is an MCP server listed in the public MCP registry as io.github.adwarp-dev/adwarp. Open-source ad agent for LinkedIn Ads and Google Ads. Drafts campaigns, audiences and reports. This page covers its npm package (adwarp).

### Is the Adwarp MCP server safe to use?

Adwarp scores 72 out of 100 on VerifyMCP. We recorded 2 known advisories against it as of 25 October 2026. It declares no install or post-install scripts. Its build provenance is signed and verified. That is a record of what we were able to check automatically, not an endorsement. The category breakdown on this page shows every signal behind the number, including the ones we could not confirm.

### What tools does the Adwarp MCP server expose?

Adwarp exposes 37 tools: gads_list_accounts, gads_list_client_accounts, gads_keyword_ideas, gads_list_campaigns, gads_list_ads, and 32 more. Their descriptions and schemas cost roughly 4,568 tokens of context every time the server is loaded.

### Is the Adwarp MCP server still maintained?

Adwarp is still listed as active in the MCP registry. We last reached this channel on 25 October 2026. Those dates come from our own scans of the registry and the channel itself, not from anything the publisher announced.

### What licence is the Adwarp MCP server under?

Adwarp declares the MIT licence, which is OSI-approved. That covers the source only, and says nothing about the cost of any service it calls.

## Links

- npm package: https://www.npmjs.com/package/adwarp
- Socket report: https://socket.dev/npm/package/adwarp
- Repository: https://github.com/adwarp-dev/adwarp
- Website: https://adwarp.dev/
- Changelog RSS feed: https://verifymcp.io/servers/adwarp-dev-adwarp/adwarp.xml
- Changelog JSON feed: https://verifymcp.io/servers/adwarp-dev-adwarp/adwarp.json
- HTML version of this page: https://verifymcp.io/servers/adwarp-dev-adwarp/adwarp
