# GrowthKit Revenue Intelligence (remote · mcp.growthkit.tools)

Sales intelligence for B2B SMEs — lead scoring, ICP fit, CRM enrichment & writeback.

- Trust score: 80/100 (high trust)
- Change this week: +7
- Registry status: active
- Liveness: live
- Owner verified: no
- Last scored: 2026-08-03

## Components

- remote · `mcp.growthkit.tools`: 80/100 (this document), [markdown](https://verifymcp.io/servers/tools-growthkit-revenue-intelligence/mcp.md), [page](https://verifymcp.io/servers/tools-growthkit-revenue-intelligence/mcp)

## Channel facts

- Endpoint: `https://mcp.growthkit.tools`
- Transports: `streamable-http`
- Auth: `none`
- Version: `1.12.2`

## Trust breakdown

How this component scores in each security and reliability category. Every signal is checked automatically against the live server, 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-08-03.

- **Endpoint Security**: 91/100
  - The endpoint's TLS certificate is valid, in date, and uses a strong key.
  - Authorisation is enforced on tool calls, advertised via RFC 9728 protected-resource metadata. Discovery is public, which costs nothing: no tool can be invoked without a token.
  - HTTPS is enforced; there's no plaintext access path.
  - HSTS check failed: the Strict-Transport-Security header is absent.
  - DNSSEC is configured correctly; the domain's records validate against the full chain to the root.
  - The authorisation server offers only Dynamic Client Registration (RFC 7591), which MCP 2026-07-28 deprecated in favour of Client ID Metadata Documents.
- **Transport & Reachability**: 100/100
  - Verified streamable-http transport via a live MCP handshake.
- **Schema Quality & AI Usability**: 75/100
  - 100% of prompts and resources have a non-trivial description (not blank, and not just the item's name).
  - AI-judged instruction clarity (good).
  - Context-footprint check failed: tool/resource definitions use about 8054 tokens (~111/item across 72 items; 66 tools + 6 resources), over budget; trim descriptions and params.
  - Usage-examples check failed: none of the tools include examples.
- **Stability & Change Management**: 27/100
  - Stability observed for 8 of 30 days with no destabilising changes; credit accrues until the full window elapses.
- **Tool Coverage**: 100/100
  - 100% of tools have a non-trivial description (not blank, and not just the tool's name).
  - 100% of tool parameters carry a description.
  - Structured output schemas are declared (9% of tools); any adoption earns full credit.
- **Capabilities**: 100/100
  - Implements a supported MCP spec version (2025-11-25); the latest is 2026-07-28.
  - Supports UI / widget rendering.

## Install

### Claude

```bash
claude mcp add --transport http tools-growthkit-revenue-intelligence https://mcp.growthkit.tools/
```

### Codex

```toml
[mcp_servers.tools-growthkit-revenue-intelligence]
url = "https://mcp.growthkit.tools/"
```

### opencode

```json
{
  "$schema": "https://opencode.ai/config.json",
  "mcp": {
    "tools-growthkit-revenue-intelligence": {
      "type": "remote",
      "url": "https://mcp.growthkit.tools/",
      "enabled": true
    }
  }
}
```

### OpenClaw

```bash
openclaw mcp add tools-growthkit-revenue-intelligence --url https://mcp.growthkit.tools/ --transport streamable-http
```

### Hermes

```yaml
mcp_servers:
  tools-growthkit-revenue-intelligence:
    url: "https://mcp.growthkit.tools/"
```

### Other

```json
{
  "mcpServers": {
    "tools-growthkit-revenue-intelligence": {
      "type": "http",
      "url": "https://mcp.growthkit.tools/"
    }
  }
}
```

The mcpServers block is a cross-client convention. Remote transports vary, so check your client's docs.

## 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-08-02 (score 80, +1)

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

### 2026-07-31 (score 79, +5)

- [functional] We updated how we score, so this day's move reflects our rubric, not a change to the server

### 2026-07-30 (score 74, 0)

- [functional] We updated how we score, so this day's move reflects our rubric, not a change to the server

### 2026-07-28 (score 74, +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-07-27 (score 73, +1)

- [functional] We updated how we score, so this day's move reflects our rubric, not a change to the server

### 2026-07-26 (score 72)

First indexed and scored.

## MCP tools (66)

### `embedMemory` (~335 tokens)

Save Memory

Store knowledge into long-term memory. Supports single items and batch embedding (max 50). IMPORTANT — Chapter System: Every memory MUST be classified into exactly one chapter via metadata.chapter. Available chapters: icp, strategy, campaigns, analytics, brand, competitors, learnings, general, pipeline, signals, playbook. Always analyze the content and pick the most specific chapter. Use general only as a last resort. BEFORE STORING: Search target chapter first to check for duplicates. QUALITY: 50-300 words, specific and factual, one concept per memory. AUTO-TAGGING: Before saving ANY memory, search the playbook chapter for 'tag-taxonomy' to load the current tag taxonomy. Then add 3-7 relevant tags as a comma-separated string in metadata.tags (e.g. metadata: { chapter: 'campaigns', tags: 'saas,series-a,dach,linkedin,demand-gen' }). Pick the most specific tags from the taxonomy. You may add 1-2 free-form tags if needed. For batch embeds, tag each item individually. PLAYBOOK SYSTEM: Available playbooks: icp-workshop, onboarding, campaign-brief, weekly-review, competitor-analysis, content-brief. When the user asks to do any of these tasks, use prompts/get to load the full playbook and follow its steps.

Input parameters:

- `content` (string): Text content to store (for single embed).
- `items` (array): Batch embed: array of {content, metadata}. Max 50. Each MUST include metadata.chapter.
- `metadata` (object): REQUIRED: Must include chapter key.

### `searchMemory` (~169 tokens)

Search Memory

Search long-term memory using semantic similarity. ALWAYS SEARCH BEFORE ANSWERING marketing/strategy questions. Use short, specific keywords as queries. Available chapters: icp, strategy, campaigns, analytics, brand, competitors, learnings, general, pipeline, signals, playbook. TAG FILTERING: Memories are auto-tagged. Use metadata_filter with tags key to filter (e.g. metadata_filter: { chapter: 'campaigns', tags: 'linkedin' }).

Input parameters:

- `limit` (integer): Max results. Default: 10.
- `match_threshold` (number): Min similarity (0-1). Default: 0.5.
- `metadata_filter` (object): Filter by metadata. Use chapter to search within a specific chapter.
- `query` (string, required): Search keywords — short and specific.

### `listMemories` (~105 tokens)

List Memories

List stored memories in stored order with pagination. Unlike searchMemory (semantic relevance ranking), use this to browse, enumerate, or audit a chapter — not to find the most relevant memory for a question. Filter by chapter via metadata_filter.chapter.

Input parameters:

- `limit` (integer): Max results. Default: 50.
- `metadata_filter` (object): Optional metadata filters. Use chapter to list within a specific chapter.
- `offset` (integer): Pagination offset. Default: 0.

### `updateMemory` (~135 tokens)

Update Memory

Update content or metadata of a stored memory. Use to enrich, fix, or reclassify. You MUST provide a change_reason explaining WHAT changed and WHY. The reason is stored in the version history audit log.

Input parameters:

- `change_reason` (string, required): REQUIRED: Why this memory is being updated, e.g. 'Added Q2 metrics', 'Fixed company name', 'User requested update'. Stored in audit log.
- `embedding_id` (string, required): ID of the memory to update.
- `new_content` (string): Updated text content.
- `new_metadata` (object): Optional metadata to replace, e.g. chapter or tags.

### `deleteMemories` (~102 tokens)

Delete Memories

Delete memories by IDs. Always confirm with user first. You MUST provide a change_reason explaining WHY these memories should be deleted. The reason is stored in the version history audit log.

Input parameters:

- `change_reason` (string, required): REQUIRED: Why these memories are being deleted, e.g. 'Outdated', 'Duplicate', 'User requested cleanup'. Stored in audit log.
- `embedding_ids` (array, required): IDs of the memories to delete (from searchMemory/listMemories).

### `clearMemories` (~51 tokens)

Clear All Memories

Delete ALL memories. Irreversible. Always ask for explicit confirmation. You MUST provide a change_reason.

Input parameters:

- `change_reason` (string, required): REQUIRED: Why all memories should be cleared. Stored in audit log.

### `countMemories` (~86 tokens)

Count Memories

Return only counts, not content — use for overview/sizing (e.g. 'how many competitor memories exist?') before deciding whether to list or search. Optionally filter by chapter via metadata_filter.chapter. For a per-chapter breakdown in one call, prefer getChapterOverview.

Input parameters:

- `metadata_filter` (object): Optional metadata filters. Use chapter to count within a specific chapter.

Output parameters:

- `chapter` (string): Chapter the count was filtered to, if any.
- `count` (integer): Number of matching memories.

### `getChapterOverview` (~25 tokens)

Chapter Overview

Get memory count per chapter. Use as FIRST STEP in new conversations or reviews.

Output parameters:

- `chapters` (array): Per-chapter memory counts (readable chapters only).
- `total` (integer): Total memory count across readable chapters.

### `uploadDocument` (~136 tokens)

Upload Document

Upload a file to GrowthKit document storage. Optionally extracts text and embeds insights.

Input parameters:

- `category` (string): Optional storage category.
- `chapter` (string): Optional memory chapter to associate extracted insights with.
- `description` (string): Optional short description of the document.
- `extract_insights` (boolean): If true, extract text and embed insights into memory. Default: false.
- `file_base64` (string, required): Base64-encoded file content.
- `filename` (string, required): Filename with extension.
- `mime_type` (string, required): MIME type.
- `title` (string): Optional document title. Defaults to the filename.

### `listDocuments` (~74 tokens)

List Documents

List stored documents with optional filtering by category or chapter.

Input parameters:

- `category` (string): Optional: filter by storage category.
- `chapter` (string): Optional: filter by associated memory chapter.
- `limit` (integer): Max results. Default: 50.
- `offset` (integer): Pagination offset. Default: 0.

### `getDocument` (~36 tokens)

Get Document

Get a specific document with fresh download URL and linked insights.

Input parameters:

- `document_id` (string, required): ID of the document (from listDocuments).

### `deleteDocument` (~45 tokens)

Delete Document

Delete a document and its associated insights. Irreversible — always confirm with the user first.

Input parameters:

- `document_id` (string, required): ID of the document to delete (from listDocuments).

### `createReminder` (~153 tokens)

Create Reminder

Schedule a reminder. Convert relative times to ISO 8601.

Input parameters:

- `channel` (string): Delivery channel: email | slack | webhook.
- `channel_target` (string): Optional channel target, e.g. email address or webhook URL.
- `description` (string): Optional reminder details.
- `remind_at` (string, required): When to remind, ISO 8601 (convert relative times first).
- `repeat` (string): Repeat interval: none | daily | weekly | monthly. Default: none.
- `task_id` (string): Optional: link this reminder to a task (task UUID). Linked reminders are auto-cancelled when the task is marked done/dropped.
- `title` (string, required): Short reminder title.

### `listReminders` (~113 tokens)

List Reminders

List reminders, ordered by remind_at ascending. By default returns only pending reminders; pass status=sent|cancelled|all to widen. Optionally scope to one task via task_id. Returns each reminder's id, title, remind_at, and status.

Input parameters:

- `limit` (integer): Max results. Default: 50.
- `status` (string): Filter by status: pending | sent | cancelled | all. Default: pending.
- `task_id` (string): Optional: only reminders linked to this task.

Output parameters:

- `reminders` (array): Matching reminders, ordered by remind_at ascending.

### `cancelReminder` (~35 tokens)

Cancel Reminder

Cancel a pending reminder by ID.

Input parameters:

- `reminder_id` (string, required): ID of the pending reminder to cancel (from listReminders).

### `getHistory` (~44 tokens)

Memory Version History

Get the version history of a specific memory. Shows all previous versions with timestamps and who made changes.

Input parameters:

- `embedding_id` (string, required): ID of the memory to get history for.

### `restoreVersion` (~62 tokens)

Restore Memory Version

Restore a memory to a previous version. Works for both existing and deleted memories. Use version_id from getHistory or listDeleted results.

Input parameters:

- `version_id` (string, required): The version ID (restore_id) to restore to. Get this from getHistory or listDeleted.

### `listDeleted` (~38 tokens)

List Deleted Memories

List recently deleted memories that can be restored. Shows content preview and deletion info.

Input parameters:

- `limit` (integer): Max results. Default: 20.

### `listTeam` (~33 tokens)

List Team Members

List all team members (token holders) for your account. Shows display names, roles, and identifies which token is yours.

### `sendNotification` (~107 tokens)

Send Notification

Send a notification to a team member. First use listTeam to find the recipient. For 2-person teams, the recipient is auto-resolved.

Input parameters:

- `broadcast` (boolean): If true, sends to ALL team members. Default: false.
- `context` (object): Optional context, e.g. {chapter: 'icp'}.
- `message` (string, required): The notification message to send.
- `to_prefix` (string): Recipient's token_prefix or display_name from listTeam.

### `checkNotifications` (~18 tokens)

Check Notifications

Check for unread notifications (direct messages and broadcasts).

### `crmSearchCompany` (~53 tokens)

CRM: Search Company

Search CRM for a company by name. ALWAYS search before creating to avoid duplicates.

Input parameters:

- `limit` (integer): Max results. Default: 10.
- `term` (string, required): Company name or keyword to search for.

### `crmGetCompany` (~41 tokens)

CRM: Get Company

Get full company details by ID. Returns name, domain, industry, employees, address, CRM link.

Input parameters:

- `id` (string, required): Company ID from CRM.

### `crmCreateCompany` (~39 tokens)

CRM: Create Company

Create a new company. ALWAYS search first to avoid duplicates.

Input parameters:

- `address` (string): Company address.
- `name` (string, required): Company name.

### `crmGetCompanyDeals` (~46 tokens)

CRM: Get Company Deals

Get all deals linked to a company, by company ID. Use after crmSearchCompany or crmGetCompany to review that company's pipeline.

Input parameters:

- `id` (string, required): Company ID.

### `crmGetCompanyContacts` (~42 tokens)

CRM: Get Company Contacts

Get all contacts linked to a company, by company ID. Use to find who to reach at a known company.

Input parameters:

- `id` (string, required): Company ID.

### `crmSearchContact` (~86 tokens)

CRM: Search Contact

Search CRM for a contact by name or keyword (fuzzy match); returns the top matches. Use to look up one known person. For structured segment queries across the contact base (e.g. 'all CEOs in pipeline companies'), use crmListPeople instead.

Input parameters:

- `limit` (integer): Max results. Default: 10.
- `term` (string, required): Contact name or keyword.

### `crmListCompanies` (~88 tokens)

CRM: List Companies

List companies from CRM with structured filters. Use for segment queries like 'all pharma companies with 50-200 employees in DACH'. All filter fields optional. Returns companies with id, name, industry, employees, country, and pagination info. Unlike crmSearchCompany (which does fuzzy name search), this does precise structured filtering.

Input parameters:

- `filter` (object): Filter object. All fields optional.

### `crmListPeople` (~88 tokens)

CRM: List People

List people/contacts from CRM with structured filters. Use for segment queries like 'all CEOs in pipeline companies'. All filter fields optional. Unlike crmSearchContact (fuzzy lookup of one person by name), this does precise structured filtering across the contact base. Returns contacts with id, name, title, company, and pagination info.

Input parameters:

- `filter` (object): Filter object. All fields optional.

### `crmGetContact` (~25 tokens)

CRM: Get Contact

Get full contact details by ID.

Input parameters:

- `id` (string, required): Contact ID.

### `crmCreateContact` (~65 tokens)

CRM: Create Contact

Create a new contact. ALWAYS pass company_id when the company exists.

Input parameters:

- `company_id` (string): Company ID. REQUIRED when company exists.
- `email` (string): Email address.
- `name` (string, required): Full name.
- `phone` (string): Phone number.

### `crmGetPipelines` (~27 tokens)

CRM: Get Pipelines

Get all pipelines with stages. ALWAYS call before creating deals to get valid stage_id.

### `crmCreateDeal` (~94 tokens)

CRM: Create Deal

Create a new deal. Requires title + stage_id. MUST call crmGetPipelines first.

Input parameters:

- `company_id` (string): Company ID.
- `contact_id` (string): Contact ID.
- `currency` (string): Currency code. Default: EUR.
- `stage_id` (string, required): Stage ID from crmGetPipelines.
- `title` (string, required): Deal title.
- `value` (number): Deal value.

### `crmUpdateDeal` (~89 tokens)

CRM: Update Deal

Update a deal. Use generic names: company_id, contact_id, expected_close.

Input parameters:

- `expected_close` (string): Expected close date YYYY-MM-DD.
- `id` (string, required): Deal ID.
- `stage_id` (string): Optional new stage ID (from crmGetPipelines).
- `title` (string): Optional new deal title.
- `value` (number): Optional new deal value.

### `crmGetDeal` (~45 tokens)

CRM: Get Deal

Get the full record for one deal by ID. Use after a search or list returns a deal id when you need its complete details.

Input parameters:

- `id` (string, required): Deal ID.

### `crmAddNote` (~122 tokens)

CRM: Add Note

Add a note to a CRM record — a deal, company, or contact. Provide content (HTML supported) and at least one target id (deal_id, company_id, or contact_id). Use to log call summaries, context, or decisions against the record.

Input parameters:

- `company_id` (string): Optional company ID to attach the note to.
- `contact_id` (string): Optional contact ID to attach the note to.
- `content` (string, required): Note text — supports HTML.
- `deal_id` (string): Optional deal ID to attach the note to.

### `crmCreateActivity` (~166 tokens)

CRM: Create Activity

Create a follow-up activity on a CRM record. Provide a subject and set type (call | meeting | task | email | deadline; default task). Optionally link it to a deal, company, or contact and set a due_date (YYYY-MM-DD). Use to schedule next steps after an interaction.

Input parameters:

- `company_id` (string): Optional company ID to link the activity to.
- `contact_id` (string): Optional contact ID to link the activity to.
- `deal_id` (string): Optional deal ID to link the activity to.
- `due_date` (string): Due date YYYY-MM-DD.
- `note` (string): Optional note/body for the activity.
- `subject` (string, required): Activity subject.
- `type` (string): Activity type. Default: task.

### `crmCheckConnection` (~20 tokens)

CRM: Check Connection

Check if CRM is connected and which provider is active.

Output parameters:

- `connected` (boolean): Whether a CRM provider is connected.
- `provider` (string|null): Active CRM provider, if connected.

### `enrichCompany` (~57 tokens)

Enrich Company

Get company info by domain or name. Returns industry, employees, revenue, location, technologies.

Input parameters:

- `company_name` (string): Company name (if domain unknown).
- `domain` (string): Company domain e.g. seeburger.de

### `enrichPerson` (~60 tokens)

Enrich Person

Get person profile from email or LinkedIn URL.

Input parameters:

- `email` (string): Person's email address.
- `linkedin_handle` (string): LinkedIn handle/slug (without the full URL).
- `linkedin_url` (string): Full LinkedIn profile URL.

### `findContacts` (~89 tokens)

Find Contacts

Find contacts at a company. Filter by seniority or department.

Input parameters:

- `company` (string): Company name (if domain unknown).
- `department` (string): sales, marketing, it, etc.
- `domain` (string): Company domain to find contacts at.
- `limit` (integer): Max results. Default: 10.
- `seniority` (string): junior, senior, or executive.

### `findEmail` (~86 tokens)

Find Email

Find one person's email by name + domain.

Input parameters:

- `company` (string): Company name (if domain unknown).
- `domain` (string): Company domain to search the email at.
- `first_name` (string): Person's first name.
- `full_name` (string): Full name (alternative to first_name + last_name).
- `last_name` (string): Person's last name.

### `verifyEmail` (~34 tokens)

Verify Email

Check if an email is deliverable. Use before outreach.

Input parameters:

- `email` (string, required): Email address to verify for deliverability.

### `discoverSimilar` (~613 tokens)

Discover Similar Companies

Find lookalike companies for a seed and re-rank them by fit. mode='account' (seed={domain}) finds companies similar to that domain via Hunter similar_to; mode='icp' (no seed) discovers companies matching your saved ICP; mode='won_deals' is not yet implemented. Each candidate comes back with similarity_to_seed (0–100 firmographic closeness to the seed), canonical_icp_score (0–100 vs your global ICP; null if not on the Pro plan), divergence + divergence_flag (≥25 = seed diverges from ICP — a product signal), classification, and already_in_crm. Read-only — it never writes and never reveals emails/phones (do that per-lead separately). To control cost, only the top `shortlist_size` pre-ranked candidates are fully enriched + scored; the rest come back with enriched:false and null scores (candidates with enriched:false were NOT evaluated — null is 'not scored', not a low score). NOTE: mode='account' uses Hunter `similar_to`, which requires a Hunter Premium/Data-Platform key; without it, discovery automatically falls back to query/industry filters and says so in `warnings`.

Input parameters:

- `filters` (object): Optional Hunter Discover filter overrides, passed straight through. Use Hunter's exact sub-shapes — a wrong shape is silently dropped (or 400s). headquarters_location: { include:[{ country:'DE' }], e…
- `limit` (integer): Max candidates to return (hard-capped at 25). Default 25.
- `mode` (string): account = similar to a seed domain (default); icp = match your saved ICP; won_deals = not yet implemented (returns not_implemented).
- `score` (boolean): Re-rank with canonical ICP scoring (calculate-alignment). Default true. similarity_to_seed is always returned regardless of this flag.
- `seed` (object): Seed for mode='account', e.g. { domain: 'intertours.de' }. Leave empty for icp/won_deals.
- `shortlist_size` (integer): How many top pre-ranked candidates get fully enriched + scored (default 10). Pre-ranking uses the free discover fields (geo, size, emails_count). Lower = cheaper (fewer enrichment credits); the rest…

### `scoreLeads` (~213 tokens)

Lead Scoring: Run

Trigger lead scoring against ICP for this user's CRM companies. Scores each (company, contact) pair on 4 dimensions (industry 35%, employees 25%, geo 20%, seniority 20%) with missing-data renormalization. Use mode='full' for all companies, 'delta' for new/changed since last run, 'company_ids' for specific IDs. Persists to lead_scores table; read results via getTopLeads. Returns counts and per-user summary. Requires Pro plan (active or trialing). Write-operation — scores are persisted to lead_scores table.

Input parameters:

- `company_ids` (array): CRM company IDs to score. Required and only used when mode='company_ids'. Max 100 recommended per call.
- `mode` (string, required): Scoring scope. 'full' scores all companies (slow for >1k). 'delta' scores only companies updated since last run or not yet scored (recommended for routine updates). 'company_ids' scores a specific li…

### `getTopLeads` (~218 tokens)

Lead Scoring: Top Leads

Retrieve the highest-scoring leads from the CRM, ranked by ICP fit. Returns company details, contact (if any), 4-dimension score breakdown, and qualitative reasons like 'Industry X — strong match to ICP'. By default filters out leads with <50% data completeness to avoid false-positives from data-sparse ICP matches (e.g. leads where only the contact's seniority matched but industry/employees/country are unknown). Override via filters.min_completeness if you want incomplete leads too. Requires scoreLeads to have been run at least once. Requires Pro plan. Read-only — does not trigger new scoring. Call scoreLeads first if your CRM has new companies or ICP has changed (check icp_version_hash in the response to detect staleness).

Input parameters:

- `filters` (object): Optional result filters.
- `limit` (integer): Number of leads to return. Default 10, max 100.
- `min_score` (integer): Minimum score 0-100 to include. Default 60.

### `email_compose` (~400 tokens)

Compose or Draft an Email

Compose an email via the user's connected email provider (currently Gmail; Microsoft 365 coming in Phase B). DEFAULT mode is 'draft' — creates a real draft in Gmail that the user can review before sending. Only use mode='send' when the user explicitly confirms sending with keywords like 'sende', 'schick raus', 'verschicken', 'send it', 'raus damit'. On 'draft' success, response includes draft_url the user can click to open the draft in Gmail. On 'send' success, response includes a tracking_id (1×1 pixel auto-injected for open-tracking). The From address is resolved server-side (5-level precedence: explicit from > user-token integration > user-token default > account default > account email) — do NOT fabricate a From address. Optional crm_deal_id links the message to a deal for future activity writeback. Requires active email provider OAuth connection.

Input parameters:

- `body_html` (string): HTML email body with <p>, <br>, <strong>, <a href> tags as needed. For send mode, an open-tracking pixel is auto-injected.
- `body_text` (string): Optional plain-text fallback. If only one of body_html/body_text is provided, the other is auto-generated.
- `crm_deal_id` (string): Optional CRM deal UUID if this email relates to a specific deal.
- `from` (string): Optional From address override. Must be an address the user has authorized.
- `in_reply_to` (string): Optional Message-ID of the message being replied to.
- `mode` (string, required): Default: 'draft'. Use 'send' only on explicit user confirmation.
- `provider` (string): Default: 'auto'. Backend resolves from user's active integration.
- `subject` (string, required): Email subject line.
- `thread_id` (string): Optional Gmail thread ID for replies in-thread.
- `to` (string, required): Recipient email address.

### `createCampaign` (~416 tokens)

Campaign: Create Briefing

Create a new campaign briefing. Use after collecting the 7 required fields via the campaign-briefing-playbook (search 'campaign-briefing-playbook' in playbook chapter to load the methodology). Sets status='draft'. Returns the created campaign id. NEVER call this without first running the playbook conversation — every campaign needs a complete briefing.

Input parameters:

- `briefing_source` (string): Default 'wizard'.
- `channels` (array, required): Outreach channels for this campaign: email | linkedin | event | paid | cold_call | referral | webinar.
- `description` (string): Optional free-text summary of the campaign.
- `end_date` (string): Optional ISO date YYYY-MM-DD. Null = open-ended.
- `icp_snapshot` (object, required): Frozen ICP at creation time. May be a NARROWED variant of the user's global ICP.
- `messaging_angle` (string, required): The hook in the first email/message. The news/trend/insight that earns the read.
- `name` (string, required): Short campaign label, 3-200 chars. Include strategic axis (e.g. 'Q2-DACH-Maschinenbau-EU-AI-Act').
- `notes` (string): Optional internal notes about the campaign.
- `offer` (string, required): The concrete CTA, NOT the product name. E.g. 'Free 30-day pilot', not 'Buy GrowthKit'.
- `pain_hypothesis` (string, required): ONE sentence stating the specific pain this campaign assumes the persona has.
- `persona_snapshot` (object, required): Frozen target persona for this campaign.
- `product_snapshot` (object): Frozen product info at creation time. Schema: { name, description, value_props[], differentiators[], pricing_hint }.
- `source_document_id` (string): Optional documents.id if briefing was parsed from upload.
- `start_date` (string, required): ISO date YYYY-MM-DD.
- `success_metric` (object, required): { type: 'replies'|'demos'|'sqls'|'pipeline_eur', target: number }

### `listCampaigns` (~66 tokens)

Campaign: List

List campaigns for the current user, optionally filtered by status. Returns campaign metadata plus per-stage lead counts.

Input parameters:

- `limit` (integer): Default 25, max 100.
- `status` (string): Optional: filter by status: draft | active | paused | completed | archived.

### `getCampaign` (~38 tokens)

Campaign: Get

Get a single campaign with full briefing details and lead-stage counts.

Input parameters:

- `campaign_id` (string, required): ID of the campaign (from listCampaigns).

### `updateCampaign` (~304 tokens)

Campaign: Update

Update fields on an existing campaign. Pass only the fields to change.

Input parameters:

- `campaign_id` (string, required): ID of the campaign to update (from listCampaigns).
- `channels` (array): Outreach channels for this campaign.
- `end_date` (string): Optional ISO date YYYY-MM-DD. Null = open-ended.
- `icp_snapshot` (object): Frozen ICP for this campaign. May be a narrowed variant of the global ICP.
- `messaging_angle` (string): The hook in the first email/message — the news/trend/insight that earns the read.
- `name` (string): Short campaign label, 3-200 chars.
- `notes` (string): Optional internal notes about the campaign.
- `offer` (string): The concrete CTA, NOT the product name. E.g. 'Free 30-day pilot'.
- `pain_hypothesis` (string): ONE sentence stating the specific pain this campaign assumes the persona has.
- `persona_snapshot` (object): Frozen target persona for this campaign.
- `product_snapshot` (object): Frozen product info. Schema: { name, description, value_props[], differentiators[], pricing_hint }.
- `start_date` (string): ISO date YYYY-MM-DD.
- `status` (string): Campaign status: draft | active | paused | completed | archived.
- `success_metric` (object): { type: 'replies'|'demos'|'sqls'|'pipeline_eur', target: number }

### `addCampaignLeads` (~157 tokens)

Campaign: Add Leads

Add one or more leads to a campaign. Standard fields (company_name, contact_email, etc.) go to typed columns. ANY OTHER FIELD you pass automatically gets stored in the metadata jsonb column — no schema migration needed for new fields. Examples of custom fields: booth_number, source_event, scanned_at, follow_up_priority, notes_from_call. Call getCampaignLeadFields first to discover what custom fields are already used in this campaign.

Input parameters:

- `campaign_id` (string, required): ID of the campaign (from listCampaigns).
- `leads` (array, required): Array of lead objects. Standard fields go to columns; unknown keys go to metadata jsonb. Max 100 per call.
- `source` (string): Default 'mcp'.

### `getCampaignLeadFields` (~87 tokens)

Campaign: Discover Lead Fields

Discover which fields are actually used in a campaign's leads. Returns standard columns with non-null values PLUS all metadata (custom) keys with usage counts and sample values. ALWAYS call this BEFORE asking the user about lead structure or before adding new custom fields — it tells you what's already established for this list.

Input parameters:

- `campaign_id` (string, required): ID of the campaign (from listCampaigns).

### `updateCampaignLead` (~172 tokens)

Campaign: Update Lead

Update fields on an existing campaign lead. Pass lead_id (UUID from listCampaignLeads) and an updates object with only the fields to change. Use this to mark leads as rejected, manually correct enrichment data, or attach custom metadata. Setting lifecycle_stage='rejected' REQUIRES rejected_reason in the same call. The metadata field is shallow-merged into existing metadata jsonb — existing keys are preserved unless overwritten by the same key. Score/dim_*/icp_version_hash are NOT writable here (those come from scoreLeads). crm_external_id/crm_synced_at are NOT writable either (CRM-Sync owns those).

Input parameters:

- `lead_id` (string, required): UUID of the campaign_lead to update
- `updates` (object, required): Object with fields to change. metadata is shallow-merged.

### `listCampaignLeads` (~92 tokens)

Campaign: List Leads

List leads in a campaign, optionally filtered by lifecycle_stage or enrichment_status. Returns up to 100 per call.

Input parameters:

- `campaign_id` (string, required): ID of the campaign (from listCampaigns).
- `enrichment_status` (string): Optional: filter by enrichment status.
- `lifecycle_stage` (string): Optional: filter by lifecycle stage.
- `limit` (integer): Default 50, max 100.

### `show_callable_leads` (~186 tokens)

☎ Show Callable Leads

Render an interactive call card of leads that have a phone number, each with a ☎ Anrufen button. The HUMAN user clicks a button to place a click-to-call from their own verified caller ID. This tool ONLY displays the card — it never places a call itself, and there is no model-callable call tool (UWG § 7: calls are human-initiated only). Optionally scope to one campaign_id; omit it to aggregate all callable leads across the user's campaigns. Use when the user asks to see or call leads (e.g. "zeig mir anrufbare Leads", "welche Leads kann ich anrufen").

Input parameters:

- `campaign_id` (string): Optional campaign UUID (from listCampaigns). Omit to aggregate callable leads across all campaigns.
- `limit` (integer): Max leads to render. Default 50, max 100.

### `place_call` (~111 tokens)

Place Call (app-private)

APP-PRIVATE: initiates a click-to-call to one lead from the user's own verified caller ID. Not model-callable (hidden via _meta.ui.visibility:["app"]). Invoked only by the lead-call-card iframe when the human clicks ☎ Anrufen. The gk_ session token is taken server-side; the app passes campaign_lead_id only.

Input parameters:

- `campaign_lead_id` (string, required): ID of the campaign lead to call (campaign_lead_id from show_callable_leads' structuredContent).

### `save_call_outcome` (~148 tokens)

Save Call Outcome (app-private)

APP-PRIVATE: saves the post-call disposition / note / next action for one call. Not model-callable (hidden via _meta.ui.visibility:["app"]). Invoked only by the lead-call-card iframe after a call. The gk_ session token is taken server-side; the app passes call_log_id (from place_call) plus optional disposition / notes / next_action.

Input parameters:

- `call_log_id` (string, required): call_log_id returned by place_call in its structuredContent.
- `disposition` (string): Optional call disposition.
- `next_action` (object): Optional follow-up reminder (typically for a callback disposition).
- `notes` (string): Optional free-text note about the call.

### `setWorkingMemory` (~330 tokens)

Working Memory: Set

Store structured state for the current chat session. Use this to persist data that must survive history compression — wizard fields, suggestion lists, active entities. Three kinds: 'wizard' (multi-turn field collection), 'working_set' (ephemeral suggestion lists with TTL), 'pinned_entity' (durable context). Call this AFTER the user confirms a value, BEFORE moving to the next step. The state object replaces (not merges) — fetch first if you need to merge.

Input parameters:

- `key` (string, required): Logical identifier within a kind. Examples: 'campaign_briefing', 'lead_candidates', 'active_campaign'. Use snake_case.
- `kind` (string, required): wizard = multi-turn field collection. working_set = ephemeral suggestion lists with TTL. pinned_entity = durable context across turns.
- `session_id` (string, required): The current chat session_id. REQUIRED. Comes from the conversation context.
- `state` (object, required): The full state object to store. Replaces any previous state for this (kind, key). Schema is free-form but conventions: wizard = { fields, required, collected, current_step }; working_set = { items, c…
- `status` (string): Default 'active'. Set to 'completed' when a wizard finishes successfully (triggers completed_at timestamp).
- `ttl_turns` (integer): Optional TTL in user-turns. After this many turns, the record auto-expires. NULL/omit = permanent (typical for wizard and pinned_entity). Use 5 for working_set / suggestion lists.

### `getWorkingMemory` (~143 tokens)

Working Memory: Get

Retrieve the current state for a (kind, key) in the current session. Returns null if not set. Use this when you need to merge into existing state or verify what's stored. NOTE: Active working memory entries are ALSO automatically injected into the system prompt by Build Messages — you usually don't need to call this manually. Only call when you need a specific record's full state on-demand.

Input parameters:

- `key` (string, required): Logical identifier within the kind (same key used in setWorkingMemory).
- `kind` (string, required): Which kind of state to retrieve: wizard | working_set | pinned_entity.
- `session_id` (string, required): The current chat session_id. REQUIRED.

### `createTask` (~208 tokens)

Create Task

Create a prioritized task. Provide the four ICE inputs (impact, confidence, effort_constraint, effort_nonconstraint); the DB computes ice_score. Show the inputs to the user for confirmation before calling.

Input parameters:

- `bucket` (string): Time horizon: now | next | later | follow-up.
- `confidence` (number): ICE confidence, 0-1 (probability the impact materializes).
- `detail` (string): Optional longer description of the task.
- `effort_constraint` (integer): Effort on the bottleneck lane (see workspace label_constraint)
- `effort_nonconstraint` (integer): Effort on the non-bottleneck lane
- `impact` (integer): ICE impact, 1-10 (higher = more impact).
- `owner` (string): Assignee (free text)
- `related_memory_id` (string): Optional ID of a related memory to link.
- `steps` (array): Optional checklist of sub-steps.
- `title` (string, required): Short task title.

### `listTasks` (~93 tokens)

List Tasks

List tasks in the workspace, ranked by ICE (highest first). Optional filters.

Input parameters:

- `bucket` (string): Optional: filter by bucket: now | next | later | follow-up.
- `limit` (integer): Max results. Default: 50.
- `owner` (string): Optional: filter by assignee.
- `status` (string): Optional: filter by status: open | in_progress | done | dropped.

Output parameters:

- `tasks` (array): Tasks ranked by ICE (highest first).

### `getOpenTasks` (~80 tokens)

Get Open Tasks

Return the workspace's open/in-progress tasks ranked by ICE (highest priority first) plus the total open count. Call this at the START of any planning, prioritization, or 'what should I work on next' discussion to ground the conversation in current open tasks before advising.

Input parameters:

- `limit` (integer): Max tasks to return. Default: 20.

Output parameters:

- `tasks` (array): Tasks ranked by ICE (highest first).

### `updateTask` (~225 tokens)

Update Task

Update fields of a task. Partial update; status='done' sets done_at automatically. ice_score recomputes when impact/confidence/effort change.

Input parameters:

- `bucket` (string): Time horizon: now | next | later | follow-up.
- `confidence` (number): ICE confidence, 0-1 (probability the impact materializes).
- `detail` (string): Optional longer description of the task.
- `effort_constraint` (integer): Effort on the bottleneck lane (see workspace label_constraint).
- `effort_nonconstraint` (integer): Effort on the non-bottleneck lane.
- `id` (string, required): ID of the task to update (from listTasks).
- `impact` (integer): ICE impact, 1-10 (higher = more impact).
- `owner` (string): Assignee (free text).
- `status` (string): New status: open | in_progress | done | dropped.
- `steps` (array): Replace the task's checklist. Omit to leave unchanged.
- `title` (string): Optional new task title.

### `setTaskWeights` (~128 tokens)

Set Task Weights

Set the workspace effort weights (constraint vs non-constraint lane) and optional display labels. Re-stamps open tasks so their ICE re-ranks.

Input parameters:

- `label_constraint` (string): Optional display label for the constraint lane (e.g. 'Engineering').
- `label_nonconstraint` (string): Optional display label for the non-constraint lane (e.g. 'Design').
- `w_constraint` (number, required): Weight for the constraint (bottleneck) effort lane in the ICE score.
- `w_nonconstraint` (number, required): Weight for the non-constraint effort lane in the ICE score.

### `toggleStep` (~129 tokens)

Toggle Step

Check off or re-open a single step in a task's checklist. Provide the task `id` and the `step_id` of the step to toggle. Omit `done` to flip the step's current state; set done=true/false to force a specific state (idempotent). Use when the user completes or reopens a checklist item on a task that has steps.

Input parameters:

- `done` (boolean): Omit to flip the current state.
- `id` (string, required): Task UUID.
- `step_id` (string, required): ID of the step to toggle (from the task's steps).

## Diagnostics

Captured diagnostic sections: TLS, DNSSEC, Authorisation, Transports. The full working is on the page: https://verifymcp.io/servers/tools-growthkit-revenue-intelligence/mcp#diagnostics

## Score history

- 2026-08-03: 80
- 2026-08-02: 80
- 2026-08-01: 79
- 2026-07-31: 79
- 2026-07-30: 74
- 2026-07-29: 74
- 2026-07-28: 74
- 2026-07-27: 73
- 2026-07-26: 72

## Links

- Remote endpoint: https://mcp.growthkit.tools/
- Repository: https://github.com/growthkit-tools/mcp
- Website: https://growthkit.tools/en/mcp
- Changelog RSS feed: https://verifymcp.io/servers/tools-growthkit-revenue-intelligence/mcp/changelog.xml
- Changelog JSON feed: https://verifymcp.io/servers/tools-growthkit-revenue-intelligence/mcp/changelog.json
- HTML version of this page: https://verifymcp.io/servers/tools-growthkit-revenue-intelligence/mcp
