Connect an AI agent with MCP

Point Claude, ChatGPT, Cursor or Gemini at the hosted MCP server so the assistant can read your locations, listings and reviews and act on them with the same tools you would call.

The Listings API ships a hosted Model Context Protocol (MCP) server at https://listingsapi.com/mcp. There is nothing to install or run. An AI assistant that speaks MCP connects to that URL, discovers one tool per REST endpoint plus a few documentation tools, and calls them on your account. This guide walks through connecting each major client, then verifying the link.

1. Know what the agent gets

The server exposes just over sixty tools, about two thirds of them read-only. Names follow the REST resources, so locations_search, listings_premium, reviews_respond and posts_create_social do what the matching endpoints do, with the same parameters and the same response envelope. Three documentation tools, search_docs, get_doc and get_endpoint, let the assistant look up a page or an endpoint contract instead of guessing a payload shape.

Tool familyExamplesNeeds
Locationslocations_all, locations_search, locations_create, locations_updateRead for lookups, Write for create and update
Listingslistings_premium, listings_duplicates, listings_mark_duplicateRead, Write for marking duplicates
Connected accountsconnected_accounts_list, connected_accounts_listings, connected_accounts_connect_listingRead, Write for connect and import
Reviewsreviews_list, reviews_get, reviews_respond, reviews_analyticsRead, Write for responses
Postsposts_social_post_view, posts_create_socialRead, Write for publishing
Analyticsanalytics_google, analytics_facebook, analytics_bingRead
Accountwhoami, get_usage, get_subscription, recent_errorsRead
Docssearch_docs, get_doc, get_endpoint, list_endpointsNone

Destructive operations such as deleting a post or archiving a location are not exposed as tools. Use the REST API or an SDK for those, so an assistant cannot remove data on its own.

2. Pick how the client signs in

Every client authenticates in one of two ways. Both end up as the same API key on the server side, so rate limits and usage reporting are identical.

MethodWhat you pasteBest for
API key headerAuthorization: API <your key> as a static headerCLIs and editors where you control the config file
OAuth 2.0Nothing. The client opens a browser, you sign in and approve read or read writeHosted assistants such as Claude and ChatGPT, or anyone who should not hold a raw key

OAuth uses the authorization code flow with PKCE and dynamic client registration, so a client needs no pre-issued credentials. The metadata lives at https://listingsapi.com/.well-known/oauth-authorization-server. Scopes are read and write; a client that asks for nothing gets read. Each approval mints a dedicated key for that connection, which you can revoke from /dashboard/keys like any other key.

3. Connect Claude

Claude.ai and Claude Desktop. The server is listed in the connector directory, so the fastest path is to open https://claude.ai/directory/listings-api and click Connect. Claude runs the OAuth flow, you approve the scopes, and the tools are available in any chat where you enable the connector with the + button, then Connectors.

If you would rather add it by URL, go to Customize, then Connectors, click + and Add custom connector, paste https://listingsapi.com/mcp and click Add. Leave Advanced settings empty; the server registers Claude as a client automatically. On Team and Enterprise plans an owner adds the connector under Organization settings, then Connectors, and members click Connect on it afterwards. Claude connects from Anthropic's servers, not from your machine, which is why the hosted URL matters.

Claude Code. One command adds the server with your key:

Claude Code
claude mcp add --transport http listingsapi https://listingsapi.com/mcp \--header "Authorization: API $LISTINGSAPI_KEY"

Drop the --header flag and run /mcp inside Claude Code to sign in through the browser instead. Use --scope project to commit the server to a .mcp.json the whole team shares; do not commit a key with it.

4. Connect ChatGPT

ChatGPT connects to remote MCP servers as a custom connector once Developer mode is on. It is available on Plus, Pro, Business, Enterprise and Edu plans, not on the free tier.

  1. Open Settings from your profile menu and turn on Developer mode. Depending on the build it sits under Apps & Connectors or Security and login.
  2. On the connectors page (labelled Plugins in current builds) click + or Create.
  3. Enter a name, paste https://listingsapi.com/mcp as the server URL, and choose OAuth for authentication. Save.
  4. ChatGPT opens the sign-in page. Approve read or read write.
  5. In a new chat, open the tools menu, pick the connector, and confirm it appears with its tools. Write tools stay behind a confirmation prompt.

Codex CLI. OpenAI's terminal agent reads MCP servers from ~/.codex/config.toml. Codex starts OAuth on its own for HTTP servers and honours the advertised scopes, so the header line is optional:

~/.codex/config.toml
[mcp_servers.listingsapi]url = "https://listingsapi.com/mcp"http_headers = { "Authorization" = "API <your key>" }

5. Connect Cursor

The dashboard page at /dashboard/mcp has an Add to Cursor button. It opens a Cursor install link with the server URL and your key already filled in, so one click finishes the setup.

To do it by hand, add the server to ~/.cursor/mcp.json for every project, or to .cursor/mcp.json inside one repository:

~/.cursor/mcp.json
{"mcpServers": {  "listingsapi": {    "url": "https://listingsapi.com/mcp",    "headers": {      "Authorization": "API <your key>"    }  }}}

Remove the headers block to sign in with OAuth instead: Cursor shows a Connect button on the server entry under Settings, then MCP, and opens the browser flow. Never commit a key inside a project-level .cursor/mcp.json; use the global file or OAuth for shared repositories.

6. Connect Gemini

Gemini CLI. Google's terminal agent takes remote servers in ~/.gemini/settings.json (or .gemini/settings.json in a project). Use httpUrl, not url, so it picks the Streamable HTTP transport:

~/.gemini/settings.json
{"mcpServers": {  "listingsapi": {    "httpUrl": "https://listingsapi.com/mcp",    "headers": {      "Authorization": "API <your key>"    },    "timeout": 30000  }}}

For OAuth, replace the headers block with "oauth": { "enabled": true }, start the CLI and run /mcp auth listingsapi. Run /mcp at any time to list the server, its connection state and the tools it discovered.

Gemini app. The consumer Gemini app has no custom connector setting. Custom MCP servers are available to team administrators of Gemini Enterprise Business edition: sign in at business.gemini.google, open Settings & help, then Manage team and Connected apps, and click Add MCP Server. Paste https://listingsapi.com/mcp as the URL. The form asks for OAuth details: the authorization URL is https://listingsapi.com/oauth/authorize, the token URL is https://listingsapi.com/oauth/token, and the scopes are read write. It also asks for a client ID and client secret. This server issues public PKCE clients with no secret, so register one with the redirect URL the form shows and leave the secret blank if the form allows it:

Register an OAuth client
curl -s https://listingsapi.com/oauth/register \-H "Content-Type: application/json" \-d '{  "client_name": "Gemini Business",  "redirect_uris": ["<redirect URL shown in the Gemini form>"],  "grant_types": ["authorization_code", "refresh_token"],  "token_endpoint_auth_method": "none"}'

The response carries client_id. If your Gemini form insists on a secret, use the Gemini CLI path above or build with the Gemini API instead.

Building with the Gemini API. The Gemini API SDK accepts an MCP client session as a tool, so a script can give a Gemini model the same tools:

gemini_agent.py
import asyncio, osfrom google import genaifrom mcp import ClientSessionfrom mcp.client.streamable_http import streamablehttp_client HEADERS = {"Authorization": "API " + os.environ["LISTINGSAPI_KEY"]} async def main():  gemini = genai.Client()  async with streamablehttp_client("https://listingsapi.com/mcp", headers=HEADERS) as (r, w, _):      async with ClientSession(r, w) as session:          await session.initialize()          reply = await gemini.aio.models.generate_content(              model="gemini-2.5-pro",              contents="Which of my locations have a Google listing that is not live yet?",              config=genai.types.GenerateContentConfig(tools=[session]),          )          print(reply.text) asyncio.run(main())

7. Verify the connection

Before you trust the assistant, confirm the server answers you directly. Tool discovery needs no key, so this call succeeds with any client that can reach the URL:

List the tools
curl -s https://listingsapi.com/mcp \-H "Content-Type: application/json" \-H "Accept: application/json, text/event-stream" \-d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}' | head -c 400

Then, inside the assistant, ask for something that has to hit your account:

Use the listingsapi tools to tell me which account I am connected as, how many locations it has, and my API usage this month.

A correct connection answers from whoami, locations_all and get_usage with your real account id and counts. A wrong or expired key surfaces as an Unauthenticated error on the first tool call, not on discovery.

Good first prompts once it works:

  • "List my locations that have listing errors and summarise each error."
  • "Show unanswered reviews from the last 7 days and draft a reply for each. Do not send them yet."
  • "Compare Google profile analytics for location 1800289 across the last two months."
  • "Read the create-location endpoint contract, then add this location: ..."

Troubleshooting

SymptomCauseFix
401 on the first tool callKey mistyped, revoked, or the header is not the literal API word plus a spaceRecreate the key in /dashboard/keys and paste it as API <key>
SY90016 on a writeRead key or read scopeReconnect with a Write key or approve write
429 with Retry-AfterThe agent is calling faster than your plan allowsAsk it to work in smaller batches; see Rate limits
Client says it cannot reach the serverClient only supports stdio or SSEUse a client that supports Streamable HTTP, or the mcp-remote bridge shown on /dashboard/mcp
A tool the docs mention is missingDestructive tools are not exposedUse REST or an SDK for archive and delete

Next steps