Eve

GTM Tools' Eve integration

Getting started

Eve is Vercel’s agent framework: you write an agent/ directory of instructions, typed tools, and skills, and Eve compiles it into a deployable agent with durable workflows and channels for Slack, Discord, Teams, WhatsApp, web, and plain APIs. By adding GTM Tools to Eve, your agent gains the go-to-market data surface: buying-signal detection on any domain, LinkedIn company and people lookup, SMTP-verified email finding, and Reddit reads and writes.

There are two ways to integrate GTM Tools with Eve: installing the official gtm-tools skill, or adding an MCP connection.

The easiest way to add GTM capabilities to Eve is by installing the official GTM Tools skill from skills.sh. This skill is maintained by the GTM Tools team and provides the full go-to-market toolset.

Installation

Install the skill into your Eve project:

$npx skills add arnaudjnn/gtm-skills --skill gtm-tools --agent eve --yes

That writes agent/skills/gtm-tools/, which is where Eve scans for skills. Use --subagent <name> to install into a subagent instead, since skills are scoped to the agent that declares them.

Configuration

The skill calls the API with a bearer token, so set your key in the environment Eve runs with. For local development that is .env.local:

$GTM_TOOLS_API_KEY=sk_your_api_key

Add the same variable to your Vercel project environment for deploys, then vercel env pull to sync it locally. Get a key with get_api_key or gtm-tools admin login. See Getting Your API Key.

Features

The official skill includes:

  • Buying signals: hiring, Trustpilot sentiment, follower spikes, and tech-stack detection on any domain
  • LinkedIn lookup: company and profile resolution from a domain or a name, employee search with boolean title filters
  • LinkedIn writes: DMs and connection requests from your own logged-in account
  • Reddit: thread and subreddit reads, comments, posts, votes, and DMs through Reddit Chat
  • Email: SMTP-verified professional email finding, with a reason on every unconfirmed lookup
  • Billing: balance, top-ups, and auto-reload, so the agent can manage its own wallet
  • Cost discipline: the full 63-tool catalog with token costs, the metering rules, and the error contract

Verify installation

Eve advertises each skill’s description and loads the body only when a turn calls for it, through a framework-owned load_skill tool. Start the agent and ask for something the skill covers:

$npx eve dev

Then send what is my GTM Tools token balance?. The agent should load the skill and answer. get_token_balance costs 0 tokens, so the check is free.

Option 2: MCP Connection

For typed tool schemas instead of shell calls, add an MCP connection. Eve then exposes our tools through connection_search, and its own tool filters and approval gates apply to them.

Add the connection

Connections are one file each under agent/connections/. The filename becomes the connection name, and its tools surface as <connection>__<tool>:

agent/connections/gtm.ts
1import { defineMcpClientConnection } from "eve/connections";
2
3export default defineMcpClientConnection({
4 url: "https://api.gtm-tools.sh/mcp",
5 description:
6 "GTM data: buying signals on a domain, LinkedIn company and people lookup, " +
7 "SMTP-verified professional emails, and Reddit threads. Use when the task " +
8 "involves prospecting, enriching a contact, or checking whether a company " +
9 "is worth reaching out to.",
10 auth: {
11 getToken: async () => ({ token: process.env.GTM_TOOLS_API_KEY! }),
12 },
13});

Eve sends the returned token as Authorization: Bearer <token>, which is what our endpoint expects. Write the description for the model: it is the main signal connection_search uses when deciding which connection to query.

Configure the connection

We expose 63 tools, so allowlist the ones this agent should discover with exactly one of tools.allow or tools.block:

agent/connections/gtm.ts
1export default defineMcpClientConnection({
2 url: "https://api.gtm-tools.sh/mcp",
3 description: "GTM data: buying signals, LinkedIn lookup, verified emails.",
4 auth: { getToken: async () => ({ token: process.env.GTM_TOOLS_API_KEY! }) },
5 tools: {
6 allow: [
7 "detect_signal",
8 "get_linkedin_company_url",
9 "list_linkedin_company_employees",
10 "get_email",
11 "get_token_balance",
12 ],
13 },
14});

Five of our tools act as your own account, so gate them rather than allowing them silently. A blanket always() would prompt on every harmless lookup, so pass a policy that gates only the sends:

agent/connections/gtm.ts
1const SENDS = [
2 "send_linkedin_message",
3 "send_linkedin_invitation",
4 "create_reddit_comment",
5 "create_reddit_post",
6 "send_reddit_message",
7];
8
9export default defineMcpClientConnection({
10 url: "https://api.gtm-tools.sh/mcp",
11 description: "GTM data and outreach: signals, LinkedIn, Reddit, verified emails.",
12 auth: { getToken: async () => ({ token: process.env.GTM_TOOLS_API_KEY! }) },
13 approval: ({ toolName }) =>
14 SENDS.some((name) => toolName.endsWith(name)) ? "user-approval" : "not-applicable",
15});

Return "user-approval" to pause for a person and "not-applicable" to run without a prompt. A policy can also decide on its own with "approved" or "denied", and once(), always(), and never() from eve/tools/approval cover the blanket cases. Match on endsWith, since the policy sees the namespaced tool name.

Verify the connection

Run the agent locally and ask for something only the connection can answer:

$npx eve dev

what is my GTM Tools token balance? is the cheapest check: get_token_balance costs 0 tokens, so a successful answer proves auth and transport in one call.

Example use cases

Once GTM Tools is integrated with Eve, you can ask your agent to:

  • “Which of these domains are hiring SDRs right now?”
  • “Find the Head of CX at gymshark.com and verify their email”
  • “Draft a LinkedIn DM to that person referencing the signal that fired”
  • “Check r/sales for threads about our category this week”
  • “How many tokens are left on the workspace?”