> ## Documentation Index
> Fetch the complete documentation index at: https://docs.gc.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Client credentials (M2M)

> Connect a backend service or agent platform to the GC AI MCP server with the OAuth 2.0 client-credentials grant.

The GC AI MCP server supports two ways for a client to authenticate:

* **User access.** A person logs in and consents, using the OAuth 2.0 authorization-code grant. This is how hosts like ChatGPT and Claude connect. Each request acts as that user.
* **Machine access (M2M).** A service authenticates with a client ID and secret, using the OAuth 2.0 client-credentials grant. No human is in the loop. Each request acts for the organization.

This guide covers machine access: minting an org-scoped credential and connecting any OAuth 2.0 client that speaks the client-credentials grant. The steps are client-agnostic; [Salesforce](#example-salesforce) is included as one worked example at the end.

<Note>
  Machine credentials are **org-scoped**. A token issued this way acts for your whole organization, with no user identity attached. Tools that require a user (creating projects, skills, or playbooks, and uploading files) are not available over a machine credential. See [Tools available to a machine token](#tools-available-to-a-machine-token).
</Note>

## When to use machine access

* A backend service or agent platform connects to MCP with no human in the loop.
* The client only supports the client-credentials grant. Salesforce AgentForce, for example, does not yet support the authorization-code grant for external MCP servers.
* You want a stable, org-scoped connection that does not depend on any single user's session.

## Before you start

You need:

* A way to mint the credential: either **org admin** access in GC AI (to use the settings screen) or an **org-scoped** GC AI API key (`gcai_...`) to call the REST endpoint. User-scoped keys receive `403`. See [API keys](/api-reference/concepts/api-keys).
* MCP access enabled for your organization. If it is not, you can still mint a credential, but any token it issues is rejected when you call the MCP server. An org admin can turn it on under **Settings → API**.

## How machine access works

The flow has three parts:

1. **Mint a credential** in GC AI (**Settings → API → MCP credentials**), or with `POST /v1/mcp/credentials`. GC AI provisions a single machine application for your organization on the first call and reuses it thereafter, so the `client_id` is stable.
2. **Exchange the credential** at GC AI's token endpoint (`grant_type=client_credentials`) for a short-lived access token.
3. **Call the MCP server** with that token. GC AI verifies it, binds it back to your organization, and runs each tool in your organization's context.

## Step 1: Mint a credential

Most people generate the credential from the GC AI app. If you are automating setup, the REST endpoint returns the same values.

<Tabs>
  <Tab title="In the app (org admins)">
    Go to **Settings → API**, find the **MCP credentials** section, and choose **Set up MCP credentials**. In the dialog, choose **Generate credentials**. GC AI reveals the `client_secret` alongside the `client_id`; the `token_endpoint` and `resource` are under **Connection details**. Copy the **client secret** before closing the dialog: it is shown only once.

    <Frame>
      <img src="https://mintcdn.com/gcai/pNfsdD6wfIy-BrMu/images/mcp-credentials-generated.png?fit=max&auto=format&n=pNfsdD6wfIy-BrMu&q=85&s=344740120ced0204c8e5a31a1e21f30e" alt="The MCP credentials dialog after generating, showing the client ID, the one-time client secret, and the token endpoint and resource under Connection details" width="971" height="1175" data-path="images/mcp-credentials-generated.png" />
    </Frame>

    On return visits, choose **Manage credentials**. The dialog shows the stable `client_id`, with `token_endpoint` and `resource` under **Connection details**; use **Generate new secret** to rotate.
  </Tab>

  <Tab title="Over the API">
    Call the provisioning endpoint with your org-scoped key:

    ```bash theme={null}
    curl -X POST https://app.gc.ai/api/external/v1/mcp/credentials \
      -H "Authorization: gcai_your_org_scoped_key_here"
    ```
  </Tab>
</Tabs>

Either way you get everything the client needs:

```json theme={null}
{
  "client_id": "client_01HXWKHA5SX0JZYAD037JBE3PT",
  "client_secret": "<shown once>",
  "token_endpoint": "https://auth.gc.ai/oauth2/token",
  "resource": "https://app.gc.ai/api/mcp",
  "grant_type": "client_credentials"
}
```

| Field            | Use it for                                                                          |
| ---------------- | ----------------------------------------------------------------------------------- |
| `client_id`      | The OAuth client ID. Stable across rotations.                                       |
| `client_secret`  | The OAuth client secret. Shown once, when generated.                                |
| `token_endpoint` | The token endpoint URL the client exchanges the credential at.                      |
| `resource`       | The `resource` request parameter, and the MCP server URL the token is used against. |
| `grant_type`     | Always `client_credentials`.                                                        |

<Warning>
  The `client_secret` is shown only once, when generated, and cannot be retrieved again. Store it securely before you leave the screen or response. See [Rotating credentials](#rotating-credentials) if you lose it.
</Warning>

## Step 2: Configure your OAuth client

The client is whatever connects to MCP: Salesforce AgentForce, a backend service, or your own script. Give it these values and it fetches a short-lived access token and calls the MCP server for you. You do not perform the token exchange by hand.

* **Grant type:** `client_credentials`
* **Token endpoint:** the `token_endpoint` from step 1 (`https://auth.gc.ai/oauth2/token`)
* **Client ID and secret:** the `client_id` and `client_secret` from step 1
* **`resource` parameter:** the `resource` from step 1 (`https://app.gc.ai/api/mcp`)
* **MCP server URL:** `https://app.gc.ai/api/mcp`, over **Streamable HTTP** transport

For Salesforce, the [example below](#example-salesforce) maps each of these to its field in Setup.

<Note>
  The `resource` parameter is part of OAuth 2.1, and some clients (including Salesforce) require it on the token request. Send it exactly as returned. GC AI binds the issued token to your organization using the credential's client ID, so the token is org-scoped whether or not `resource` is present. Sending it satisfies clients that require it without changing how the token is scoped.
</Note>

<Accordion title="Fetch a token manually (for testing)">
  To verify a credential outside your client, exchange it directly:

  ```bash theme={null}
  curl -X POST https://auth.gc.ai/oauth2/token \
    -H "Content-Type: application/x-www-form-urlencoded" \
    -d "grant_type=client_credentials" \
    -d "client_id=client_01HXWKHA5SX0JZYAD037JBE3PT" \
    -d "client_secret=your_client_secret_here" \
    -d "resource=https://app.gc.ai/api/mcp"
  ```

  The response contains an `access_token`. Send it as `Authorization: Bearer <access_token>` on requests to the MCP server.
</Accordion>

## Tools available to a machine token

Over a client-credentials (organization) token, the MCP server exposes these tools:

| Tool                  | What it does                                                    |
| --------------------- | --------------------------------------------------------------- |
| `ask_gcai`            | Ask a legal question grounded in your organization's files.     |
| `ask_gcai_status`     | Fetch the result of an `ask_gcai` job by its ID.                |
| `get_files`           | Look up files in your organization by ID, or list recent files. |
| `get_playbooks`       | List playbooks and their checks.                                |
| `get_projects`        | List projects and their attached files.                         |
| `run_playbook`        | Run a playbook against one or more files.                       |
| `run_playbook_status` | Fetch the result of a `run_playbook` job by its ID.             |

Tools that create or modify resources (projects, skills, playbooks, and file uploads) require a user identity and are not available over a machine credential.

<Tip>
  `ask_gcai` and `run_playbook` are asynchronous: they return a job ID, and the client polls `ask_gcai_status` or `run_playbook_status` for the result. Allow the matching status tool alongside each one. See [Asynchronous Requests](/api-reference/concepts/async-jobs).
</Tip>

## Example: Salesforce

Salesforce (including AgentForce) connects to an external MCP server using the client-credentials grant, so the steps above apply directly. It is one concrete example; any client that speaks the grant follows the same shape. In Salesforce Setup, create the external identity provider it authenticates with, using the values from [step 1](#step-1-mint-a-credential):

<Steps>
  <Step title="Set the authentication flow">
    Choose **Client Credentials** as the authentication (grant) flow.
  </Step>

  <Step title="Set the token endpoint">
    Enter the `token_endpoint` from step 1 as the token endpoint URL.
  </Step>

  <Step title="Enter the client ID and secret">
    Use the `client_id` and `client_secret` from step 1.
  </Step>

  <Step title="Add the resource parameter">
    Add a custom token request parameter named `resource`, set to the `resource` value from step 1 (`https://app.gc.ai/api/mcp`).
  </Step>

  <Step title="Register the MCP server">
    Add the GC AI MCP server (`https://app.gc.ai/api/mcp`) over Streamable HTTP transport, pointed at the identity provider you just configured.
  </Step>

  <Step title="Allow the tools you need">
    Allowlist the [tools available to a machine token](#tools-available-to-a-machine-token) that the agent should call.
  </Step>
</Steps>

## Rotating credentials

Generating again (via **Generate new secret** in the app, or another `POST /v1/mcp/credentials`) mints a **new** secret and reuses the same application, so the `client_id` does not change. Update the secret in your client and the connection keeps working. A single application allows up to 5 live secrets at a time; once that limit is reached, generating another secret fails. Individual secrets cannot be retired on their own: use **Revoke access** to delete the application and all its secrets, then generate again. Revoking issues a new `client_id`, so update both the `client_id` and the secret in your client.

## Troubleshooting

**Minting a credential:**

| Status | Cause                                                                                                                                                                                                             |
| ------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `403`  | The API key is not org-scoped, or the key is invalid. Use an `gcai_...` org key.                                                                                                                                  |
| `404`  | MCP is not configured for this deployment.                                                                                                                                                                        |
| `502`  | The identity provider failed to mint the credential, for example when the 5-secret limit is reached. Also returned if your organization is not yet linked to the identity provider; contact support in that case. |

**Calling the MCP server:**

| Status | Cause                                                                                                                                         |
| ------ | --------------------------------------------------------------------------------------------------------------------------------------------- |
| `401`  | The access token is missing, invalid, or expired. Fetch a new token.                                                                          |
| `403`  | The organization is not provisioned for MCP, or MCP is turned off for the organization. An org admin can turn it on under Settings, API.      |
| `404`  | MCP is not configured for this deployment, or your organization is not provisioned for MCP. An org admin cannot change this. Contact support. |

## Related

* [Provision MCP Client-credentials](/api-reference/provision-mcp-credentials): the endpoint reference for `POST /v1/mcp/credentials`.
* [API keys](/api-reference/concepts/api-keys): user-scoped vs. org-scoped keys.
* [Asynchronous Requests](/api-reference/concepts/async-jobs): how `ask_gcai` and `run_playbook` return results.
* [API Introduction](/api-reference/introduction): base URL, authentication, and a first request.
