# Connect an AI assistant over MCP

> Connect Claude, ChatGPT, Cursor, VS Code or any other MCP app to one website: the address, how each app adds it, what you grant, and what it can never do.

An AI assistant can work with one of your websites through the Model Context
Protocol (MCP), the open standard Claude, ChatGPT, Cursor, VS Code and other
apps use to reach outside services. You add one address to the app, sign in
here, and choose what it may do. There is nothing to install and no key to
copy.

## The address

```text
https://backendfree.com/mcp
```

Every app connects to this same address. Each connection is held to the one
website you pick when it signs in.

## How it connects

1. You add the address to your app, wherever it adds a remote MCP server.
2. The first time the app uses it, it opens this site in your browser. You
   sign in as you do to the dashboard, then choose the website, live or test
   data, and a level for each part.
3. You approve, the browser goes back to the app, and from then on the app
   works with that website alone, at those levels.

Underneath, this is OAuth 2.1 with PKCE, the way MCP apps sign in. The app
finds where to sign in from the address itself, and either registers itself
here or names itself with a metadata document it publishes, so there is no
client ID or secret to copy. Any app that adds remote MCP servers over HTTP
and signs in with OAuth connects the same way, whoever makes it.

## Adding it to your app

The steps say where to start in each app. Each maker's own guide, linked under
its steps, has what its screens show today.

### Claude

1. In Claude on the web or in the desktop app, open Customize, then Connectors.
2. Choose Add, then Add custom connector. Give it a name and paste the address.
3. Continue, and sign in when Claude asks: it opens this site for you to do it.
4. On a Team or Enterprise plan, an owner adds it first, under Organization settings, then Connectors. Each member then connects it from Customize, then Connectors.

[Claude's own guide](https://support.claude.com/en/articles/11175166-getting-started-with-custom-connectors-using-remote-mcp)

### ChatGPT

1. Open Plugins, select the plus button, then Add custom MCP server.
2. Give it a name and a description, and paste the address under Connection.
3. Choose OAuth for authentication, confirm the warning, and select Create as a plugin.
4. When it connects, ChatGPT opens this site for you to sign in.

[ChatGPT's own guide](https://developers.openai.com/apps-sdk/deploy/connect-chatgpt)

### Cursor

1. Add the entry below to `~/.cursor/mcp.json`, which every project reads, or to `.cursor/mcp.json` in one project.
2. Leave out any `auth` block: Cursor registers itself here.
3. Find it among the MCP servers on Cursor's Customize page, and sign in from there.

```json title=mcp.json
{
  "mcpServers": {
    "backendfree": {
      "url": "https://backendfree.com/mcp"
    }
  }
}
```

[Cursor's own guide](https://cursor.com/docs/context/mcp)

### VS Code

1. Run MCP: Add Server from the Command Palette, choose HTTP, and paste the address.
2. Or add the entry below yourself: MCP: Open User Configuration opens the `mcp.json` every workspace reads.
3. Start the server when VS Code offers to, and sign in in the browser it opens.
4. Its tools are then in Copilot Chat, in agent mode.

```json title=mcp.json
{
  "servers": {
    "backendfree": {
      "type": "http",
      "url": "https://backendfree.com/mcp"
    }
  }
}
```

[VS Code's own guide](https://code.visualstudio.com/docs/copilot/customization/mcp-servers)

### Codex

1. Run the two lines below in a terminal. The first adds the server, the second signs in.
2. The Codex IDE extension and desktop app read the same setting. Either can also add it under MCP servers, with Add server and Streamable HTTP.

```sh
codex mcp add backendfree --url https://backendfree.com/mcp
codex mcp login backendfree
```

[Codex's own guide](https://learn.chatgpt.com/docs/extend/mcp)

### Claude Code

1. Run the line below in a terminal. Add `--scope user` to have it in every project.
2. In Claude Code, run `/mcp`, choose `backendfree`, and sign in.

```sh
claude mcp add --transport http backendfree https://backendfree.com/mcp
```

[Claude Code's own guide](https://code.claude.com/docs/en/mcp)

### Any other app

1. Find where it adds a remote MCP server. It may be called a connector, an integration or a plugin.
2. Paste the address. If it asks for a transport, choose HTTP, which some apps call Streamable HTTP. If it asks how to sign in, choose OAuth.
3. Leave any client ID and secret empty: an app registers itself here, or names itself with a metadata document it publishes.
4. An app that only starts MCP servers as a program on your own computer cannot connect to an address.

## What you choose when it connects

- **One website.** A connection reaches the website you pick and no other, even
  when your account holds more than one.
- **Live or test.** A test connection reads and writes test data only, as a
  test key does, and has no reports, since those are live figures. Pages have
  no test copy, so it writes them as drafts and publishes nothing, though it may
  change the section types, which no published page is reshaped by. Services and
  people it adds are test only, it changes the test copy of the booking rules,
  and it leaves the opening hours and anything customers are offered alone.
- **A level for each part**: off, read, or read and write where the part has
  something to write. Payments starts off, and only the account owner can
  grant it.

You can change the levels, or end a connection, at any time on the website's
AI assistants screen, and the change applies to the assistant's next request.
With two-step sign-in on, connecting asks for an app code unless you signed in
moments before. Every connection made sends a mail to the account.

Whatever a tool answers, customers' names, emails and notes included, goes to
the app you connected, under your own agreement with its maker. If your
customers' details can reach it, your own privacy notice is the place to say so.

## The tools

| Tool | Part | Level | Does |
|---|---|---|---|
| `get_availability` | Bookings | read | When a service can be booked |
| `get_booking_settings` | Bookings | read | The rules a booking has to satisfy |
| `list_closures` | Bookings | read | List dated closures and special hours |
| `set_closure` | Bookings | read and write | Set a dated closure or special hours |
| `remove_closure` | Bookings | read and write | Remove a dated closure |
| `get_opening_hours` | Bookings | read | Fetch the opening hours |
| `set_opening_hours` | Bookings | read and write | Set opening hours |
| `use_business_hours` | Bookings | read and write | Put somebody on the business's hours |
| `get_booking_rules` | Bookings | read | Fetch every booking rule |
| `update_booking_rules` | Bookings | read and write | Change the booking rules |
| `apply_test_rules` | Bookings | read and write | Make the test rules the live rules |
| `discard_test_rules` | Bookings | read and write | Drop the test rules |
| `list_all_services` | Bookings | read | List every service as it is set up |
| `create_service` | Bookings | read and write | Add a service |
| `update_service` | Bookings | read and write | Change a service |
| `delete_service` | Bookings | read and write | Remove a service |
| `make_service_live` | Bookings | read and write | Make a test-only service live |
| `move_service` | Bookings | read and write | Move a service up or down the list |
| `assign_staff` | Bookings | read and write | Set who does a service, and on what terms |
| `unassign_staff` | Bookings | read and write | Take somebody off a service |
| `list_all_staff` | Bookings | read | List everybody as they are set up |
| `create_staff` | Bookings | read and write | Add somebody who takes bookings |
| `update_staff` | Bookings | read and write | Change somebody's details |
| `delete_staff` | Bookings | read and write | Remove somebody |
| `make_staff_live` | Bookings | read and write | Make a test-only person live |
| `move_staff` | Bookings | read and write | Move somebody up or down the list |
| `list_bookings` | Bookings | read | List bookings |
| `create_booking` | Bookings | read and write | Book an appointment |
| `get_booking` | Bookings | read | Fetch one booking |
| `cancel_booking` | Bookings | read and write | Cancel a booking |
| `reschedule_booking` | Bookings | read and write | Move a booking to another time |
| `list_drafts` | Content | read | List every page's draft |
| `create_page` | Content | read and write | Create a page as a draft |
| `get_draft` | Content | read | Fetch one page's draft |
| `update_page` | Content | read and write | Change a page's draft |
| `delete_page` | Content | read and write | Delete a page |
| `publish_page` | Content | read and write | Publish a page |
| `restore_page_version` | Content | read and write | Publish an earlier version again |
| `unpublish_page` | Content | read and write | Take a page off the website |
| `list_page_versions` | Content | read | List a page's published versions |
| `list_pages` | Content | read | List published pages |
| `get_page` | Content | read | Fetch one published page |
| `get_content_schema` | Content | read | Fetch the content schema |
| `create_section_type` | Content | read and write | Add a section type |
| `update_section_type` | Content | read and write | Change a section type |
| `delete_section_type` | Content | read and write | Remove a section type |
| `add_section_field` | Content | read and write | Add a field to a section type |
| `update_section_field` | Content | read and write | Change a field |
| `remove_section_field` | Content | read and write | Remove a field |
| `list_images` | Content | read | List the image library |
| `get_image` | Content | read | Fetch one library image |
| `list_messages` | Inbox | read | List messages |
| `get_message` | Inbox | read | Fetch one message |
| `list_payments` | Payments | read | List payments |
| `get_payment` | Payments | read | Fetch one payment |
| `get_project` | Every website | read | What this key can reach |
| `list_services` | Bookings | read | List bookable services |
| `get_service` | Bookings | read | Fetch one service |
| `list_staff` | Bookings | read | List staff who take bookings |
| `get_staff` | Bookings | read | Fetch one member of staff |
| `bookings_report` | Bookings | read | Bookings report |
| `payments_report` | Payments | read | Payments report |
| `analytics_report` | Analytics | read | Analytics report |
| `webanalytics_report` | Web analytics | read | Web analytics report |

Every tool but the reports makes the same API call a secret key makes, so it
answers what that endpoint answers and is refused the same way. A report reads
the figures the Reports screen draws, over 7, 30, 90 or 365 days.

## What it can never do

- Refund, or move money out in any other way. Payments is read only: an
  assistant lists payments and reads one.
- On live data, send a customer who has to pay for a booking anywhere
  afterwards except this website's own address, or one its live publishable
  keys list.
- Point the link in booking emails, which carries each customer's manage
  token, anywhere but those same addresses, on test data too: applying the
  test rules makes that link the live one.
- See a booking's manage token, which belongs to the customer.
- Delete a page that is on the website. It has to be unpublished first.
- Reach another website, or the other mode's data.

## What it costs

Each tool call is one API request from the account's monthly
250,000, refused the same way once the month is spent (see
[allowances and rate limits](/docs/limits/)). Connecting and listing
the tools cost nothing. One connection may make `600/min` calls.

## How long a connection lasts

An assistant renews its access every 60 minutes by
itself, without asking you. A connection nobody uses for
30 days ends by itself. A website holds at most
10 assistants, and connecting the same app again
replaces its earlier connection.
