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

# Connect an AI assistant (MCP)

> Connect Claude, ChatGPT, Cursor, VS Code or any other MCP client to your Alforse company, either by authorizing in the browser or with an API key.

Alforse runs a Model Context Protocol (MCP) server, so an AI assistant can look up and work with your ERP data: items, sales, purchasing, production, inventory, quality, accounting and more. Anyone in your company can connect their own assistant, and developers can connect coding clients and scripts. The assistant can only do what the person or key it connects as is allowed to do.

## What you need

| | Value |
| - | - |
| Server URL | `https://app.alforse.com/api/mcp` |
| Transport | Streamable HTTP (`POST` only) |
| Plan | **Business**. On other plans the server refuses every call (see [Limits](#limits)). |
| Server manifest | `https://app.alforse.com/.well-known/mcp.json` (public, no company data) |

There are two ways to sign the assistant in. Pick the one your client supports.

| Client | How it connects |
| - | - |
| Claude.ai, Claude Desktop, ChatGPT | **Browser authorization (OAuth).** No key to create or paste. |
| Claude Code | Either. Leave out the key and it starts the browser authorization on first use, or pass an API key. |
| Cursor, VS Code, Codex, scripts and CI | **API key** in the `Authorization` header |
| Clients that only run local (stdio) servers | API key, through `mcp-remote` |

## Connect with browser authorization

Nothing has to be set up in Alforse first. You add the server URL in the assistant, and Alforse asks you to approve the connection.

**Add the server in your assistant.**

* **Claude Desktop / Claude.ai:** **Settings → Connectors → Add custom connector**, then paste `https://app.alforse.com/api/mcp`.
* **ChatGPT:** **Settings → Connectors → Add**, then paste the same URL. ChatGPT offers custom connectors only on some of its plans.
* **Claude Code:** `claude mcp add --transport http alforse https://app.alforse.com/api/mcp` (no `--header`).

**Sign in to Alforse.** Your assistant opens an Alforse page in the browser. Sign in if you are asked to.

**Review the request.** The **Authorize Application** page shows the assistant's name and the website it will return to, followed by "is requesting access to your Alforse account." Below it you see the requested **Scope** (`mcp:tools`).

**Choose the company.** Under **Company**, pick the company the assistant should work in. If you belong to only one company it is shown without a choice. One connection works in exactly one company; to work in another, connect again and pick that one.

**Select Authorize.** The browser returns to your assistant, which is now connected. Ask it something simple, such as "list my five most recent sales orders", to check.

NOTE

**Who can authorize**

The **Authorize Application** page needs the **Update** permission on **Settings** in your current company. Without it you are sent back to the app with "Access Denied". Ask an administrator for the permission, or use an [API key](https://docs.alforse.com/docs/building/api-keys.md) that an administrator creates for you.

### What the connection can do

* It acts **as you, in the company you chose**, with exactly your current [permissions](https://docs.alforse.com/docs/reference/permissions.md). If your permissions change, the assistant's change with them.
* It stops working once you are no longer an active member of that company.
* The company and user always come from the connection itself. The assistant cannot switch company or act as someone else by passing different arguments.

### How the sign-in works behind the scenes

Clients handle this automatically; the details are here for developers building their own client.

| Step | Endpoint |
| - | - |
| A call without a token is answered with `401` and `WWW-Authenticate: Bearer resource_metadata="https://app.alforse.com/.well-known/oauth-protected-resource"` | `/api/mcp` |
| Protected-resource metadata | `https://app.alforse.com/.well-known/oauth-protected-resource` |
| Authorization-server metadata | `https://app.alforse.com/.well-known/oauth-authorization-server` |
| Client registration (open dynamic registration, JSON body with `client_name` and `redirect_uris`) | `https://app.alforse.com/register` |
| Approval page | `https://app.alforse.com/authorize` |
| Token exchange and refresh | `https://app.alforse.com/token` |

* Grant types: `authorization_code` and `refresh_token`. Response type: `code`.
* PKCE with `S256`. A public client (token endpoint auth method `none`) must send a code challenge.
* Client authentication at the token endpoint: `client_secret_post` or `none`.
* Scope: `mcp:tools`.
* An authorization code is valid for 10 minutes and can be used once. An access token is valid for one hour (`expires_in: 3600`); the client renews it with its refresh token.

## Connect with an API key

Use a key for clients that cannot open a browser sign-in, and for scripts. An administrator creates it under **Settings → API Keys**; the key holds its own permission scopes and belongs to one company. See [API keys](https://docs.alforse.com/docs/building/api-keys.md) for creating and scoping keys.

Send the key in the `Authorization` header:

```http theme={null}
Authorization: Bearer alf_your_key_here
```

The `alforse-key: alf_your_key_here` header is accepted as well.

TIP

**The command is ready for you**

When a key is created, its dialog shows an **MCP Command** next to the key. Copy it to add the server to Claude Code in one step.

### Client configuration

**Claude Code**

```bash theme={null}
claude mcp add --transport http alforse \
  https://app.alforse.com/api/mcp \
  --header "Authorization: Bearer alf_your_key_here"
```

**Cursor** (`.cursor/mcp.json` in the project, or merged into your existing `mcpServers`)

```json theme={null}
{
  "mcpServers": {
    "alforse": {
      "url": "https://app.alforse.com/api/mcp",
      "headers": { "Authorization": "Bearer alf_your_key_here" }
    }
  }
}
```

**VS Code** (`.vscode/mcp.json`; VS Code asks for the key so it is not saved in the file)

```json theme={null}
{
  "inputs": [
    { "id": "alforse-key", "type": "promptString", "description": "Alforse API key", "password": true }
  ],
  "servers": {
    "alforse": {
      "type": "http",
      "url": "https://app.alforse.com/api/mcp",
      "headers": { "Authorization": "Bearer ${input:alforse-key}" }
    }
  }
}
```

**Any other client:** give it the URL `https://app.alforse.com/api/mcp` and the `Authorization: Bearer …` header. The name of the URL field differs between clients (for example `url` or `serverUrl`); check your client's documentation.

HEADS UP

**One key per client**

Use a separate key for each assistant or script, with only the scopes it needs (View scopes only, for a read-only assistant). You can then revoke or narrow one without touching the others.

## Tools the assistant sees

Instead of one tool per operation, the server offers three tools that reach all of them:

| Tool | What it does |
| - | - |
| `search_tools` | Searches the available Alforse operations by keyword, module or risk class (`READ`, `WRITE`, `DESTRUCTIVE`). Returns 20 results by default, up to 100. |
| `describe_tool` | Returns the full contract of one or more operations: description, required permission, input and response schema. |
| `call_tool` | Runs an operation with a JSON object of arguments. |

The operations come from these areas: account, accounting, documents, inventory, invoicing, items, people, production, purchasing, quality, resources, sales, settings, shared and users. Only operations Alforse has explicitly published are available; some are deliberately kept off the server.

* Every call goes through the same permission checks as the app, and writes are validated by the same service layer.
* Each operation carries a risk class, so your assistant can ask you before running a `WRITE` or `DESTRUCTIVE` one.
* List reads return **25 rows** by default. The assistant pages with `limit` (1–100) and `offset`.
* The assistant is told today's date in your company's time zone, so relative dates such as "last week" are resolved correctly.

## Limits

| Limit | Value |
| - | - |
| Plan | Business. Otherwise every call returns `402`. |
| Browser-authorized connections | **60 requests per minute per user**, shared by all your connections |
| API keys | The key's own limit, 60 requests per minute by default ([details](https://docs.alforse.com/docs/building/api-keys.md#rate-limit)) |
| Access token lifetime | 1 hour, renewed automatically with the refresh token |
| Rows per list read | 25 by default, at most 100 per page |

When a limit is reached the server answers `429` with `Retry-After` and `X-RateLimit-Limit`, `X-RateLimit-Remaining` and `X-RateLimit-Reset` headers. Wait for the `Retry-After` seconds, then retry.

## Troubleshooting

| Symptom | Cause | Fix |
| - | - | - |
| `402` with "The MCP server is available on the Business plan. Upgrade to connect an agent to Alforse." | The company is not on the Business plan. | Upgrade the plan (see [Billing and subscription](https://docs.alforse.com/docs/reference/billing.md)). The connection itself needs no change. |
| "Access Denied" right after the assistant opens Alforse | You lack the **Update** permission on **Settings**, which the approval page requires. | Ask an administrator for that permission, or connect with an API key. |
| "Invalid company" (`403`) when selecting **Authorize** | You are not a member of the selected company. | Pick a company you belong to. |
| "Invalid redirect URI" or "Invalid client" | The client sent a return address it did not register, or its registration is unknown. | Remove the server from the assistant and add it again so it registers afresh. |
| "PKCE required for public clients" | A client without a secret did not send a code challenge. | Use a client that supports PKCE (`S256`). |
| `401` on every call after it worked before | The access token expired and could not be renewed, you are no longer an active member of the company, or the API key expired or was deleted. | Reconnect (authorize again) or use a valid key. |
| `429` "Rate limit exceeded" | More than the allowed requests per minute. | Wait for `Retry-After`; ask the assistant to fetch fewer, larger pages. |
| `405` "Method not allowed. Use POST." | The URL was opened in a browser or called with `GET`. | Normal: MCP clients use `POST`. Add the URL in your assistant instead. |
| A tool call fails with a permission error | The connected user, or the key's scopes, do not allow that operation. | Grant the permission or scope in Alforse; it applies from the next call. |
| The assistant cannot find an operation | It is not published on the MCP server, or the search words do not match. | Ask the assistant to search by module (for example "sales") or by a field name. |

## Related

**API keys**

Create and scope keys for coding clients, scripts and CI.

[Open](https://docs.alforse.com/docs/building/api-keys.md)

**Permissions**

What a connected assistant is allowed to read and change.

[Open](https://docs.alforse.com/docs/reference/permissions.md)

**Assistant in Slack**

Use Alforse from Slack.

[Open](https://docs.alforse.com/docs/integrations/assistant.md)

**Billing and subscription**

Your plan and how to upgrade it.

[Open](https://docs.alforse.com/docs/reference/billing.md)


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.