Skip to main content
Glama
README.md
# Gripp MCP

Model Context Protocol server for the Gripp API 3.0 endpoint at `https://api.gripp.com/public/api3.php`.

The Gripp API is JSON-RPC-like: requests are POSTed as a batch array, and the API token is sent as `Authorization: Bearer <token>`.

## Setup

```bash
npm install
npm run fetch:metadata
npm run build
```

Set your Gripp API token before starting the server:

```bash
export GRIPP_API_TOKEN="your-token"
npm start
```

Optional environment variables:

```bash
GRIPP_API_URL=https://api.gripp.com/public/api3.php
GRIPP_REQUEST_TIMEOUT_MS=30000
```

`GRIPP_API_URL` is intentionally restricted to the `https://api.gripp.com/` host.

## MCP Client Config

Example stdio config:

```json
{
  "mcpServers": {
    "gripp": {
      "command": "node",
      "args": ["/absolute/path/to/MCP Gripp/dist/src/cli.js"],
      "env": {
        "GRIPP_API_TOKEN": "your-token"
      }
    }
  }
}
```

After publishing or linking the package, you can also run the `gripp-mcp` binary.

## Vercel Remote MCP

This repo also exposes a Streamable HTTP MCP endpoint for Vercel through a Next.js route:

```text
https://your-vercel-domain.vercel.app/api/mcp
```

For Claude custom connectors, use the `/api/mcp` URL. The root URL only returns a health response.

Set this environment variable in Vercel before using Gripp tools:

```bash
GRIPP_API_TOKEN=your-token
MCP_ACCESS_KEY=long-random-secret
```

Use the access key in Claude's custom connector URL:

```text
https://your-vercel-domain.vercel.app/api/mcp?access_key=long-random-secret
```

The `/api/mcp` endpoint fails closed in production if `MCP_ACCESS_KEY` is not set. If the URL leaks, rotate `MCP_ACCESS_KEY` in Vercel and redeploy.

The remote endpoint can also read a Gripp token from `Authorization: Bearer <token>` or `x-gripp-api-token`, but Claude's custom connector UI does not currently provide a simple custom-header field. For Claude, the practical setup is to store `GRIPP_API_TOKEN` in the Vercel project environment.

## GoHighLevel Remote MCP

The same Vercel project can also host a GoHighLevel MCP endpoint with OAuth token storage:

```text
https://your-vercel-domain.vercel.app/api/connect/mcp
```

Set these environment variables in Vercel:

```bash
GHL_CLIENT_ID=your-highlevel-client-id
GHL_CLIENT_SECRET=your-highlevel-client-secret
GHL_APP_ID=your-highlevel-app-or-version-id
GHL_INSTALL_URL=your-highlevel-installation-url
GHL_REDIRECT_URI=https://your-vercel-domain.vercel.app/api/connect/callback
GHL_OAUTH_USER_TYPE=Company
GHL_MCP_ACCESS_KEY=long-random-secret
GHL_TOKEN_ENCRYPTION_KEY=$(openssl rand -hex 32)
KV_REST_API_URL=your-upstash-or-vercel-kv-rest-url
KV_REST_API_TOKEN=your-upstash-or-vercel-kv-rest-token
```

`UPSTASH_REDIS_REST_URL` and `UPSTASH_REDIS_REST_TOKEN` also work instead of the `KV_*` names.

In the HighLevel Marketplace app settings, add this redirect URL:

```text
https://your-vercel-domain.vercel.app/api/connect/callback
```

Then open the OAuth start URL in your browser:

```text
https://your-vercel-domain.vercel.app/api/connect/start
```

After HighLevel redirects back, the callback page stores that subaccount installation. Use one shared URL in Claude's custom connector screen:

```text
https://your-vercel-domain.vercel.app/api/connect/mcp?access_key=long-random-secret
```

Install the app once per subaccount by reopening `/api/connect/start` and choosing the next location. The MCP keeps an index of all connected installations. In Claude, call `ghl_list_installations` first, then pass the chosen `installId` to the contact, opportunity, or generic API tools.

If your Marketplace app can only be installed by an agency admin, set `GHL_OAUTH_USER_TYPE=Company`. After installing once at agency level, use `ghl_list_installed_locations` to see where the app is actually installed, then `ghl_connect_location` to create a stored Location installation for the subaccount you want to query. `ghl_list_locations` only lists visible subaccounts and does not prove the app is installed on them.

The GoHighLevel MCP fails closed in production if `GHL_MCP_ACCESS_KEY`, encrypted token storage, or OAuth credentials are missing.

### GoHighLevel Tools

- `ghl_installation_status`: show the OAuth installation metadata without exposing tokens.
- `ghl_list_installations`: list all connected subaccounts/installations.
- `ghl_list_locations`: list/search subaccounts from a connected agency/company install.
- `ghl_list_installed_locations`: list locations where this app is installed/authorized.
- `ghl_connect_location`: create and store a Location token from an agency/company install.
- `ghl_get_contact`: retrieve one contact by contact ID.
- `ghl_search_contacts`: search contacts with `/contacts/search`.
- `ghl_create_contact`: create a contact; requires `confirm: true`.
- `ghl_update_contact`: update a contact; requires `confirm: true`.
- `ghl_search_opportunities`: search opportunities with `/opportunities/search`.
- `ghl_api_call`: call any relative HighLevel API path; non-GET calls require `confirm: true`.

## Shared Google Ads MCP for Claude

For a shared Google Ads MCP that multiple people can use in Claude, run the official `googleads/google-ads-mcp` server as a separate remote service instead of using a local stdio MCP process.

See [docs/google-ads-mcp-claude.md](docs/google-ads-mcp-claude.md) for the Cloud Run deployment and Claude custom connector setup.

## Tools

- `gripp_list_entities`: list available Gripp entities and method names.
- `gripp_describe_entity`: inspect fields, enum values, references, methods, and examples for one entity.
- `gripp_get`: call `<entity>.get` with filters and options.
- `gripp_getone`: call `<entity>.getone` with filters.
- `gripp_create`: call `<entity>.create`; requires `confirm: true`.
- `gripp_update`: call `<entity>.update`; requires `confirm: true`.
- `gripp_delete`: call `<entity>.delete`; requires `confirm: true`.
- `gripp_call`: call any documented Gripp method by full name.
- `gripp_batch`: execute multiple documented Gripp calls in one transaction.

Non-read methods are blocked unless `confirm: true` is provided. This also applies to `gripp_call` and each item in `gripp_batch`.

## Examples

Find companies by name:

```json
{
  "entity": "company",
  "filters": [
    {
      "field": "company.companyname",
      "operator": "like",
      "value": "%Acme%"
    }
  ],
  "options": {
    "paging": {
      "firstresult": 0,
      "maxresults": 10
    },
    "orderings": [
      {
        "field": "company.companyname",
        "direction": "asc"
      }
    ]
  }
}
```

Call a nonstandard read method:

```json
{
  "method": "company.getCompanyByCOC",
  "params": ["12345678"]
}
```

Create a tag:

```json
{
  "entity": "tag",
  "fields": {
    "name": "Imported"
  },
  "confirm": true
}
```

## Metadata

The committed metadata snapshot is generated from the public API docs page:

```bash
npm run fetch:metadata
```

Refresh it when Gripp updates the API docs.

TDQS

A3.7/5.0

Scored across 9 tools

Disambiguation4/5

Most tools have clearly distinct purposes. However, 'gripp_call' is a catch-all that can replicate other tools, and 'gripp_get' vs 'gripp_getone' may cause minor confusion, but descriptions help differentiate.

Naming Consistency4/5

All tools follow a 'gripp_verb' or 'gripp_verb_entity' pattern. Minor deviations: 'describe_entity' and 'list_entities' are slightly more descriptive than imperative, and 'getone' breaks the verb-noun pattern.

Tool Count5/5

With 9 tools, the set covers essential operations (CRUD, batch, metadata) without being overwhelming. The count is well-scoped for a generic API wrapper.

Completeness4/5

The tool surface covers most needed operations: listing, describing, CRUD, batch, and raw calls. Missing advanced search or count, but the general call and batch can fill minor gaps.

Maintenance

ActivityActive
ResponsivenessNo issues