# How to Build Your Own App on the ZoomInfo MCP

> Build a custom agent or integration on ZoomInfo's hosted MCP server: register an app for credentials, authenticate, connect a client, and call the tools. Covers app creation in the Developer Portal or the ZoomInfo app's API/MCP tab.

**Date:** 2026-06-11  
**Source:** https://gtm.ai/guides/how-to-build-a-custom-mcp-app

---

ZoomInfo's hosted MCP server lives at `https://mcp.zoominfo.com/mcp`. Off-the-shelf clients like Claude and ChatGPT connect to it in a few clicks. When you build your own agent or integration, you connect to the same server, but first you register an application to get the credentials your code authenticates with. This guide takes you from registering that app through calling your first tool.

> **Not building your own app?**
>
> If you just want to use ZoomInfo inside another app, you don't need a custom app. Claude, ChatGPT, Claude Code, and Codex connect through a [listing or plugin](/docs/mcp/clients), and any other MCP-capable app connects by [adding the server as a custom connector](/docs/mcp/clients/custom). This guide is for building your own.

## Before You Start

You need a ZoomInfo account with API access. Where you register your app depends on your package. Existing ZoomInfo customers use the Developer Portal, which a ZoomInfo admin enables by assigning the DevPortal subscription (Admin Portal → User Management → Users). If you signed up through gtm.ai, you use the API/MCP tab in the ZoomInfo app instead. Both produce the same thing: an app with a client ID, a client secret, and a set of scopes.

## Server Details

| Property | Value |
|---|---|
| **MCP Server URL** | `https://mcp.zoominfo.com/mcp` |
| **Protocol** | Model Context Protocol (MCP) |
| **Architecture** | Stateless |
| **Auth** | OAuth 2.0: user sign-in (Authorization Code with PKCE) or service account (Client Credentials) |
| **Rate limit** | 25 requests per second |

## Create Your App

Register an app in whichever place your account exposes: the Developer Portal for existing ZoomInfo customers, or the API/MCP tab in the ZoomInfo app. The steps are the same.

  **Open the app area**

In the Developer Portal, go to [developer.zoominfo.com](https://developer.zoominfo.com) and sign in. In the ZoomInfo app, open the API/MCP tab in the left navigation.

  **Create the app**

Click **Create App** and give it a descriptive name. Users see this name on the consent screen when they sign in. In the Developer Portal, select **MCP App** rather than API App; MCP Apps come pre-configured for the Authorization Code flow that MCP clients use.

  **Set redirect URIs**

Add the sign-in redirect URIs your client uses to receive the authorization code. For local development this is typically `http://localhost:8080/callback`. Register your production callback URL too. You can add several to one app.

  **Select scopes**

Choose the data scopes your tool needs, and only those. There is no dedicated MCP scope; pick the datasets your tools read from, for example `api:data:company`, `api:data:contact`, and `api:data:intent`. Fewer scopes means narrower tool availability at runtime. Full list: [OAuth 2.0 Scopes](https://docs.zoominfo.com/docs/zoominfo-oauth-20-scopes).

  **Create and copy credentials**

Click **Create**. Internal-use apps are approved immediately. Open the app and copy your **Client ID** and **Client Secret**. Treat the secret like a password: store it in a secrets manager or the OS keychain, and never commit it to source control.

Building for users outside your own organization is a Partner app. It uses the user sign-in flow and goes through a ZoomInfo review before it can ship. See the [Partner App process](https://docs.zoominfo.com/docs/app-creation-developer-portal-guide#submitting-a-partner-app) for details.

## Authentication

Pick your flow first. ZoomInfo offers user sign-in, where each person logs in with their own account, and a service account, where the app authenticates once for everyone. For almost any agent, use user sign-in. It adds answers tailored to the signed-in user (their meetings, renewals, and accounts) on top of ZoomInfo's company-level intelligence. See [User Sign-In vs Service Account](/guides/oauth-vs-client-credentials-zoominfo-mcp) for the full comparison and when each fits.

User sign-in uses the Authorization Code flow with PKCE. The flow your client implements:

1. Generate a PKCE code verifier and challenge.
2. Open the ZoomInfo authorization URL in the user's browser, passing your `client_id`, redirect URI, requested scopes, and the PKCE challenge.
3. The user signs in and approves the requested scopes.
4. ZoomInfo redirects to your callback URL with an authorization code.
5. Your client exchanges the code (plus the PKCE verifier and `client_secret`) at the token endpoint for an access token and refresh token.
6. Use the access token in the `Authorization: Bearer <token>` header on requests to `https://mcp.zoominfo.com/mcp`.
7. When the access token expires, use the refresh token to get a new one without prompting the user again.

Detailed endpoint references and example requests live in the API auth docs: [Authorization Code Flow with PKCE](https://docs.zoominfo.com/docs/authorization-code-flow-with-pkce) and [Refresh Token Flow](https://docs.zoominfo.com/docs/refresh-token-flow).

> **Quick testing without building the flow**
>
> Skip the OAuth handshake while you're prototyping. The DevPortal can mint a short-lived bearer token directly from the app detail page (look for **Generate Bearer Token**). It expires fast. Tokens minted this way consume real credits and count against rate limits.

## Connect Your Client

Most MCP clients accept a server URL plus an OAuth configuration. The exact shape varies by client; the example below is the minimum config form, and your client library wraps the OAuth handshake described above.

```json
{
  "mcpServers": {
    "zoominfo": {
      "url": "https://mcp.zoominfo.com/mcp",
      "auth": {
        "type": "oauth2",
        "clientId": "<your-client-id>",
        "clientSecret": "<your-client-secret>",
        "redirectUri": "http://localhost:8080/callback"
      }
    }
  }
}
```

On first connection, the client calls `tools/list` to fetch the active set of tools and their schemas. This happens at the start of every session, so your client always sees the latest definitions without versioning overhead.

## Tool Discovery

`tools/list` returns every tool the authenticated user has access to. Each definition includes:

- **Name:** the identifier passed to `tools/call`.
- **Description:** written for LLM routing. It states when to use the tool and what inputs it expects.
- **Input schema:** JSON Schema describing required and optional parameters.

```json
// Example: tools/list response (abbreviated)
{
  "tools": [
    {
      "name": "lookup",
      "description": "Reference data for valid search filter values...",
      "inputSchema": {
        "type": "object",
        "properties": {
          "fieldName": {
            "type": "string",
            "description": "Field to lookup (e.g., management-levels, industries)"
          }
        },
        "required": ["fieldName"]
      }
    }
  ]
}
```

## Calling a Tool

Use `tools/call` with the tool name and arguments:

```json
{
  "method": "tools/call",
  "params": {
    "name": "search_companies",
    "arguments": {
      "industryId": "6374",
      "employeeCount": { "min": 100, "max": 1000 },
      "location": "United States"
    }
  }
}
```

## Error Handling

ZoomInfo returns standard HTTP status codes. Common ones:

| Code | Cause | Resolution |
|---|---|---|
| `401` | Invalid or expired access token | Refresh the token, or restart the OAuth flow if the refresh token is also expired |
| `403` | Insufficient entitlements or missing scope | Check the user's package, bulk credit availability, and that the app was granted the right scopes at creation |
| `429` | Rate limit exceeded | Back off and retry |

Full error reference: [ZoomInfo API documentation](https://docs.zoominfo.com/reference/overview).

## Context Management

Direct tools (Search, Enrich, Lookup) return data straight into the calling LLM's context window. Cap batch sizes to fit your model's window.

Research tools (Account Research, Contact Research) run a sub-agent layer that synthesizes large payloads before returning a focused summary. This keeps the calling context manageable even for deep account work.

## What's Next

For the full ZoomInfo API and data schema reference, see [docs.zoominfo.com/docs](https://docs.zoominfo.com/docs). For the list of tools your app can call, see the [MCP Tools documentation](/docs/mcp/tools). To work with ZoomInfo over the REST API instead of MCP, see [Building Audiences with the GTM Studio API](/guides/gtm-studio-audiences-api).