Skip to main content
Glama
README.md
# Vruum MCP (`@vruum/mcp`)

[![npm](https://img.shields.io/npm/v/@vruum/mcp)](https://www.npmjs.com/package/@vruum/mcp)
[![license](https://img.shields.io/badge/license-MIT-blue)](LICENSE)
[![registry](https://img.shields.io/badge/MCP%20registry-ai.vruum%2Fmcp-6E56CF)](https://registry.modelcontextprotocol.io)

Official MCP access to [**Vruum**](https://vruum.ai), the AI revenue platform. Give your agent the whole revenue motion — research prospects, build pipeline, run email and LinkedIn outreach, triage replies, manage deals through close, and read Stripe-backed revenue truth — through **35 compound tools** rather than a sprawl of endpoints. Outreach runs inside **objectives**: a goal, the people it targets, and the policy for reaching them.

This package is a **stdio bridge**: it serves the tool surface locally (no credentials needed to introspect) and proxies execution to `https://api.vruum.ai/mcp` under your token. Every call is authorized server-side — the bridge grants no authority your Vruum account doesn't already have.

> [!TIP]
> **Using a client that supports remote MCP? Connect directly instead.**
> Claude Code, Claude Desktop, Cursor, Codex and friends should point straight at `https://api.vruum.ai/mcp` (OAuth 2.1). Fewer moving parts and no token in an env var. This bridge exists for **stdio-only clients** and for **credential-free tool introspection**. See [vruum.ai/docs/mcp](https://vruum.ai/docs/mcp).

## Quickstart

You need Node 20+ and a Vruum account. Create a personal access token in the web app under **Settings → API tokens** (`vk_live_…`).

<details open>
<summary><b>Claude Desktop / Claude Code</b> — <code>claude_desktop_config.json</code> or <code>.mcp.json</code></summary>

```json
{
  "mcpServers": {
    "vruum": {
      "command": "npx",
      "args": ["-y", "@vruum/mcp"],
      "env": { "VRUUM_MCP_TOKEN": "vk_live_…" }
    }
  }
}
```
</details>

<details>
<summary><b>Cursor</b> — <code>~/.cursor/mcp.json</code></summary>

```json
{
  "mcpServers": {
    "vruum": {
      "command": "npx",
      "args": ["-y", "@vruum/mcp"],
      "env": { "VRUUM_MCP_TOKEN": "vk_live_…" }
    }
  }
}
```
</details>

<details>
<summary><b>Codex CLI</b> — <code>~/.codex/config.toml</code></summary>

```toml
[mcp_servers.vruum]
command = "npx"
args = ["-y", "@vruum/mcp"]
env = { VRUUM_MCP_TOKEN = "vk_live_…" }
```
</details>

<details>
<summary><b>Already use the Vruum CLI?</b> — no token needed here</summary>

```sh
npx @vruum/cli login --token vk_live_…
```

The CLI needs Node 22+. Credentials land in `~/.vruum/credentials` and the bridge picks them up automatically — omit the `env` block entirely.
</details>

Verify it works without configuring anything:

```sh
npx -y @modelcontextprotocol/inspector --cli npx -y @vruum/mcp --method tools/list
```

## What you can ask for

Once connected, these are ordinary requests to your agent:

| You say | What happens |
| --- | --- |
| *"What should I work on today?"* | `get_daily_briefing` — pending approvals, new replies, stalled deals, warm paths, one recommended next action |
| *"Review my outreach drafts"* | `get_outreach_review` → you approve, edit, or reject each one |
| *"Research Acme Corp and tell me if they fit"* | `research` — website, funding, careers signals, ICP match with reasoning |
| *"Find a warm intro to this person"* | `find_warm_path` — separates verified paths from unverified connector candidates |
| *"Which objectives are actually working?"* | `get_objective_outcomes` — contacted, replied, and meetings booked, compared across objectives |
| *"What's at risk in my pipeline?"* | `inspect_pipeline` — the 5 most at-risk deals, risk-first |
| *"Draft a LinkedIn post about X"* | `manage_content` — your agent writes it, you approve, Vruum schedules and publishes |

Your harness authors outreach copy, replies, LinkedIn posts, and comments through
their review surfaces. It can also chat with Vruum through `manage_assistant`
(`start_conversation`, `append_message`): the same chat as the app's floating
panel, which reads your records and applies reversible record changes with Undo.
The chat does not draft or send messages.

## Tool surface

35 compound tools. Read operations inspect saved data; write operations mutate it.
Some writes buy provider work or produce external effects. Each tool describes
its own authorization and retry contract.

| Area | Tools |
| --- | --- |
| **Daily operating** | `get_daily_briefing` · `get_next_actions` · `inspect_pipeline` |
| **Search & research** | `search` · `fetch` · `research` · `research_lookup` · `import_prospects` · `find_warm_path` |
| **People** | `get_person_360` · `manage_person` |
| **Relationship identity** | `get_network_identity_review` · `manage_network_identity_resolution` |
| **Objectives & outreach** | `inspect_objective` · `get_outreach_review` · `manage_messages` · `manage_outreach` · `manage_relationship_action` |
| **Engagement & content** | `get_engagement_review` · `manage_engagements` · `get_content_review` · `manage_content` |
| **Performance** | `get_objective_outcomes` · `get_performance_metrics` |
| **Deals** | `get_deal_360` · `manage_deal` |
| **Revenue** | `get_revenue` · `manage_revenue` |
| **Accounts & knowledge** | `manage_account` · `manage_kb` |
| **Imports & assistant** | `manage_history_import` · `manage_assistant` |
| **Workspaces, config & skills** | `get_operator_companies` · `manage_settings` · `skill` |

`manage_outreach` also creates, configures, launches, and pauses objectives; `inspect_objective` reads an objective's setup, audience, forecast, and sourcing plan. No tool mixes reads with writes: `research_lookup` holds the external lookups (work email, LinkedIn profile, company website, careers page, LinkedIn people search), which can spend provider credits or LinkedIn budget. `get_operator_companies` lists the workspaces your login can act in; it is not limited to Vruum staff.

Full schemas, descriptions and MCP safety annotations live in [`tools.json`](tools.json) — generated from the live server definition, never hand-edited.

The current package also carries the retained-email decision instructions in
`manage_messages`. A saved email uses its displayed Action version, proposal
revision, and fingerprint. Approval is not a delivery receipt; changed content
requires new work.

Chat with Vruum through `manage_assistant`. `start_conversation` takes
`payload={request_id, message, context?}` and waits up to 50 seconds for the
answer; `append_message` takes `id=<chat UUID>` and the same payload. The result
names the chat, the turn's state, the question, the answer, `changes` (each
record change the chat applied, with its Undo state) and `cards`. A turn still
running after 50 seconds returns `running`; read the chat later with
`inspect_assistant action=read id=<chat UUID>`. Actions Undo cannot reverse,
and actions that reach a customer or spend, come back as a card with the exact
call, and the turn returns `awaiting_approval`. `manage_assistant
action=decide_card id=<item UUID> payload={decision: approved|declined}` decides
one, only with the user's own answer: approved runs that exact call once under
your credentials, declined never runs it; it waits up to 50 seconds for the
turn. `manage_assistant action=undo id=<item UUID>` runs a change's exact
inverse and is refused when the record was edited since; `action=rate
id=<message UUID>` rates an answer. Keep the same `request_id` on a
retry after an uncertain response: the server runs each request once.

## Configuration

| Env var | Meaning | Default |
| --- | --- | --- |
| `VRUUM_MCP_TOKEN` | Vruum personal access token | falls back to `VRUUM_TOKEN`, then `~/.vruum/credentials` |
| `VRUUM_MCP_URL` | Hosted MCP endpoint | `https://api.vruum.ai/mcp` |
| `VRUUM_MCP_TIMEOUT_MS` | Per-call timeout — research and imports run long | `300000` |
| `VRUUM_CONFIG_DIR` | Credentials directory | `~/.vruum` |

## How it works

```
your agent  ──stdio/JSON-RPC──▶  @vruum/mcp
                                     │
                    tools/list ──────┤  served locally from tools.json
                                     │  (no network, no credentials)
                                     │
                    tools/call ──────┴──HTTPS+Bearer──▶  api.vruum.ai/mcp
                                                          (authorized server-side)
```

Listings are a **static snapshot** bundled at release. That's what makes credential-free introspection possible, and it means a newly added tool won't *appear* until the next release — calls still execute correctly, since they proxy through. In the monorepo, a snapshot test fails any change that lets `tools.json` drift from the server definition, so a release never ships a stale listing.

## Safety and credentials

- **Server-side authorization.** The bridge adds no permissions. Your token is exactly your Vruum account, and role/tenant checks happen on the server.
- **No automatic retries.** A failed `tools/call` is never replayed. Many of these tools send outreach or spend money, and an ambiguous failure may mean the server already executed — a silent retry could double-send. The connection is discarded, the error says so, and your agent decides whether re-running is safe.
- **Your token never leaves your machine** except as a `Bearer` header to `api.vruum.ai`.

> [!WARNING]
> **The bridge picks up ambient credentials.** With no `VRUUM_MCP_TOKEN` set it falls back to `~/.vruum/credentials`. If you are logged in with the Vruum CLI, then running this server — via the MCP Inspector, a client, or a script — executes **against your real account and real data**. Write tools will really write.
>
> To poke at it with no credentials, pass an explicit env that reaches the process:
>
> ```sh
> env -i PATH="$PATH" HOME=/tmp/empty node dist/index.js
> ```
>
> Note that MCP clients following the SDK default only forward an allowlist (`HOME`, `PATH`, `SHELL`, `TERM`, `USER`, `LOGNAME`) to spawned servers — so setting `VRUUM_CONFIG_DIR` in your shell may be **stripped before it reaches the bridge**, while `HOME` survives and the credentials file is found anyway. Set credentials in the client's own `env` block instead.

## Development

This repo is a **build artifact of the Vruum monorepo**, resynced automatically on release. `tools.json` is generated from the server definition, and a snapshot test in the monorepo fails when the two differ. Between releases, the hosted server can be ahead of this snapshot.

```
src/index.ts   the bridge — token resolution, static listings, proxied calls
tools.json     generated tool surface (do not edit by hand)
test/          black-box tests: spawn the built binary, speak raw JSON-RPC
```

```sh
npm install
npm test        # builds, then runs the black-box suite
npm run typecheck
```

Tests drive the built binary over stdin/stdout and assert **at the wire level** rather than through an SDK client — an SDK-mediated test hides protocol mistakes, since it will happily hand back a result object whether the server returned `result` or `error`. They cover the initialize handshake, credential-free listing, protocol-vs-execution error semantics, cursor rejection, capability declaration, and stdout hygiene.

**Issues and PRs are welcome here.** Maintainers apply accepted changes upstream in the monorepo and they flow back on the next sync — so a merged fix here may appear as part of a sync commit rather than your original one. Changes to `tools.json` must come from the generator, not by hand.

## Links

[Vruum](https://vruum.ai) · [MCP docs](https://vruum.ai/docs/mcp) · [Getting started](https://vruum.ai/docs/getting-started) · [CLI reference](https://vruum.ai/docs/cli-reference)

Registry entry `ai.vruum/mcp` · Claude & Codex plugin [`vruum-gtm/skills`](https://github.com/vruum-gtm/skills)

## License

[MIT](LICENSE)

TDQS

A3.9/5.0

Scored across 29 tools

Disambiguation3/5

The manage_* writers are mostly cleanly separated by entity (person, deal, campaign, message, engagement, content), and the review tools for outreach vs engagement are clearly differentiated. However, there is meaningful overlap among read surfaces: search, fetch, and the many get_* tools all provide entity reads, and get_daily_briefing vs get_next_actions both return prioritized next steps. The long descriptions help, but an agent picking among 29 tools could still land on the wrong read tool.

Naming Consistency4/5

The dominant convention is clear and consistent: get_* for reads and manage_* for domain writers (manage_deal, manage_messages, manage_content, manage_campaign). Exceptions like search, fetch, research, skill, import_prospects, inspect_pipeline, and find_warm_path break the strict pattern, but they are readable and purposeful rather than chaotic.

Tool Count3/5

29 tools is heavy and above the typical comfort zone, but the server covers an unusually broad all-in-one sales platform: pipeline, outreach, engagement, content, ads, revenue, research, relationships, settings, and knowledge. Each tool is a consolidated action facade for one domain, so the count is defensible; still, merging overlapping read surfaces would tighten the set.

Completeness4/5

The surface is unusually complete: major entities have read paths, write paths, triage/review, enrichment, and lifecycle actions. Minor gaps exist, such as tasks being surfaced in get_daily_briefing but lacking a dedicated task management writer, and some cross-tool choreography between research, import_prospects, and manage_person requires care. Core workflows have no obvious dead ends.

Maintenance

ActivityActive
ResponsivenessNo issues