# Publish your API as an MCP server

At the end of this tutorial, Claude creates a contact in Nimbus CRM through a gateway of yours. Before the contact is created, Claude shows a confirmation card and waits for you to approve it.

Nimbus CRM is the example app of these docs: a CRM with contacts, companies and deals, and a REST API under `/api`. The code is at [github.com/faustine-ai/example-nimbus-crm](https://github.com/faustine-ai/example-nimbus-crm).

In this tutorial, you:

- [Create the API and run the analysis](#create-the-api-and-run-the-analysis)
- [Require confirmation to create a contact](#require-confirmation-to-create-a-contact)
- [Create the gateway and a gateway user](#create-the-gateway-and-a-gateway-user)
- [Choose the operations](#choose-the-operations)
- [Connect Claude](#connect-claude)
- [Create a contact and approve it](#create-a-contact-and-approve-it)
- [Find the request in Logs](#find-the-request-in-logs)

## Before you begin

- A Faustine workspace with a model provider connected. See [Connect your model provider](https://docs.faustine.ai/get-started/connect-your-ai-provider/).
- Nimbus CRM running at a URL that Faustine can reach over the internet. A server on `localhost` is not reachable.
- An account on claude.ai that can add custom connectors.

## Create the API and run the analysis

A gateway serves APIs that Faustine has analyzed. [Analyze your first API](https://docs.faustine.ai/apis/analyze-your-first-api/) covers this part step by step on Nimbus CRM. Follow it to the end, then come back. In short:

1. In the portal, go to [**APIs**](https://auth.faustine.ai/go?to=%2Fintegrations%2Fapis) and select **New API**.
2. Name the API `Nimbus CRM` and connect your fork of the repository. The wizard sets the namespace to `nimbuscrm`.
3. Start the analysis and wait for it to finish.
4. In the API's **Connections** tab, add a connection with the base URL of your Nimbus CRM server and the seeded account from its README. See [Add a connection](https://docs.faustine.ai/apis/add-a-connection/).

The API's **Operations** tab lists the operations the analysis found, among them one that creates a contact with `POST /api/contacts`.

## Require confirmation to create a contact

The analysis marks destructive writes, such as deletes, as requiring confirmation. Creating a contact is not one of them, so you mark it yourself.

1. In the API's **Operations** tab, find the operation that creates a contact.
2. In the **Requires confirmation** column, turn the switch on.
3. Select **Save changes**.
4. Select **Publish** in the API's header.

The flag belongs to the API. Every gateway that serves this version applies it. See [Mark an operation as requiring confirmation](https://docs.faustine.ai/apis/require-confirmation/).

## Create the gateway and a gateway user

1. Go to [**Agent Gateway**](https://auth.faustine.ai/go?to=%2Fintegrations%2Fagent-gateway) and select **New Gateway**.
2. Under **Who is this gateway for?**, select **People using chat and coding agents**.
3. Under **APIs**, select **Nimbus CRM**, then **Continue**.
4. Under **Name & URL**, enter `Nimbus CRM` in **Name**. The **Slug** becomes `nimbus-crm`. Copy the address in **MCP URL**, then select **Continue**.

   ```text
   https://gateway.faustine.ai/<workspace>/nimbus-crm/mcp
   ```

5. Under **First credential**, select **A user**. Enter your name in **Display name**. The **Username** is filled in from it. Keep the generated password.
6. Select **Continue**. The review shows the gateway's name, its URL, the API and the user.
7. Select **Create gateway**.
8. Copy the username and the password from the dialog. The password is shown once.

The gateway opens on its **Overview** tab. The setup path there shows **Add an API**, **Choose the operations** and **Create a key or a user** as done, and **Connect a client** as the next step.

The user you created is set to **Ask the person**: when a client calls an operation that requires confirmation, the call waits for the person. You can see it in **Access** > **Users**, on the user's page, under **Confirmation**.

## Choose the operations

The operations of the API start exposed, except recipes. For this tutorial, hide the deletes so that Claude cannot call them.

1. Select the **Operations** tab.
2. In **Search operations…**, enter `delete`.
3. Select **Hide matching**.
4. Select **Save changes**.

The counter above the table shows how many operations are exposed. The operation that creates a contact is still among them.

## Connect Claude

1. In claude.ai, go to **Settings** > **Connectors** and select **Add custom connector**.
2. Enter `Nimbus CRM` as the name and paste the MCP URL.
3. Leave the OAuth client ID and client secret fields empty.
4. Connect. A browser window opens on the gateway's sign-in page.
5. Enter the username and the password of the gateway user.

Claude lists four tools for the connector: `search_operations`, `get_operation` and `run_code`, plus `review_pending`, which shows the confirmation card. The gateway serves in Code mode, where Claude looks up the operations it needs and writes a short script that calls them. See [Connect Claude Desktop and claude.ai](https://docs.faustine.ai/technologies/claude-desktop/) for more on this client.

## Create a contact and approve it

1. Start a conversation in claude.ai with the connector turned on.
2. Send this message:

   ```text
   Add Ada Lovelace (ada@example.com) as a contact in Nimbus CRM.
   ```

3. Allow Claude to use the connector's tools when it asks.

Claude searches the operations, reads the schema of the one that creates a contact, and runs a script that calls it. The gateway does not run the call. It pauses the script, and Claude shows the Faustine confirmation card in the conversation.

The card is titled **Approve this operation?**. It names the operation and shows the arguments Claude sent. Nothing has run at this point.

4. Select **Approve**.

> **Checkpoint:** The card changes to **Done** and Claude reports that the contact was created. In Nimbus CRM, Ada Lovelace is in the contacts list. If you select **Reject all** instead, nothing runs and no contact is created.

## Find the request in Logs

1. In the portal, open the gateway's **Logs** tab. The list shows the requests of the conversation, newest first. The **Actor** is your gateway user.
2. Select the `run_code` request. Its page shows the script Claude wrote.
3. Go back and select the `decide_pending` request, which is your approval. Its page shows the call to the operation that creates a contact and, under it, the exchange with your server: `POST /api/contacts` with the status Nimbus CRM answered.

Every request has an ID that starts with `req_`. Your server received the same ID in the `x-request-id` header.

Requests for `search_operations` and `get_operation` are discovery calls. To see them, turn on **Show discovery calls** under **More**.

## What you built

Your workspace has a gateway named Nimbus CRM that serves the Nimbus CRM API over MCP and REST, with one gateway user. It is listed under [**Agent Gateway**](https://auth.faustine.ai/go?to=%2Fintegrations%2Fagent-gateway), and every call made through it is in its **Logs** tab.

## Next steps

- [Confirmation](https://docs.faustine.ai/agent-gateway/confirmation/): what each choice does and which clients can ask.
- [Create an API key](https://docs.faustine.ai/agent-gateway/api-keys/): call the same gateway from an automation.
- [Scope a key or user](https://docs.faustine.ai/agent-gateway/scope-a-credential/): give each person only the operations they need.
- [Environments](https://docs.faustine.ai/agent-gateway/environments/): add Staging and try changes there first.
- [Connect clients](https://docs.faustine.ai/agent-gateway/connect-clients/): connect ChatGPT, Claude Code, Cursor and others.
