# MCP access, permissions & audit

> Who can connect an AI client to a Convia workspace, how tokens and OAuth sign-in work, what each request is checked against, and how to audit activity.

> For the complete documentation index, see [llms.txt](https://docs.conviapro.com/llms.txt).

Convia Pro checks every MCP request against the workspace, the person behind the credential, their role and the workspace's plan, before any tool runs. This page is for workspace owners deciding who may connect an AI client, and for developers building a client that must handle tokens, OAuth and errors correctly.

## Who can connect

MCP Connections is limited to the people who manage a workspace.

| Role | Can create tokens | Can connect a client | Can see and revoke tokens and Activity |
|---|---|---|---|
| **Owner** | Yes | Yes | Yes |
| **Manager** | Yes | Yes | Yes |
| **Contributor** | No | No | No |
| **Viewer** | No | No | No |

The role is checked on every request, not only when a token is created. If an Owner or Manager is changed to Contributor or Viewer, their tokens and connectors stop working on the next request. Roles are described in [Workspaces & teams](https://docs.conviapro.com/docs/workspaces-and-teams.md).

A token always acts as the person who created it. Owners and Managers can see every token in the workspace and revoke any of them, but they can only create tokens for themselves.

## Plan entitlement

The workspace's plan must include MCP Connections. Without it, **MCP Connections** does not appear under **Integrations** (under **Workspace** in the launcher), and every request from an existing token or connector is refused with `feature_disabled`. The plan is checked on every request, so if a plan change removes MCP Connections, all of the workspace's connections stop at once.

Six tools need a second capability on the plan, checked each time they are called:

| Tools | Also requires |
|---|---|
| `get_post_analytics`, `get_web_analytics`, `get_search_queries` | Advanced Analytics |
| `create_campaign_from_plan`, `get_campaign_plan`, `update_campaign_plan` | Magic Campaign |

Without it, the connection still works and those tools return a `feature_disabled` tool error. See [Plans & billing](https://docs.conviapro.com/docs/plans-and-billing.md).

## Workspace scoping

An MCP connection reaches exactly one workspace: the one whose ID ends the MCP URL.

- **A token** belongs to one workspace. Used against another workspace's URL, it is refused with `workspace_mismatch`.
- **An OAuth sign-in** acts as you, and each request is limited to the workspace in its URL. You need a separate connector for each workspace.
- **Every tool** reads and writes only that workspace. An id from another workspace gets the same answer as an id that does not exist, so a client cannot even confirm that it exists.

## What each request is checked against

The Convia MCP server runs these checks in order on every request. The first that fails ends the request, and no tool runs.

1. The URL carries a valid workspace ID.
2. The credential is valid. A token must exist, not be revoked or expired, and belong to this workspace. An OAuth access token must be valid and issued to Convia's MCP client.
3. The person behind it is still a member of the workspace.
4. They are still an **Owner** or **Manager**.
5. The workspace's plan includes MCP Connections.

Because these run every time, removing a member, changing a role, revoking a token or changing plan takes effect on the very next request.

## Token lifecycle

Workspace tokens are for clients that send a fixed header, such as Claude Code. Create and revoke them in **Integrations → MCP Connections**; the steps are in [Connect an AI assistant (MCP)](https://docs.conviapro.com/docs/mcp-quickstart.md).

| Stage | What happens |
|---|---|
| Format | `mcp_live_` followed by 64 hexadecimal characters |
| Creation | Shown once, in the **Your MCP token** dialog. The dialog cannot be closed until you tick **I have saved this token in a safe place** |
| Storage | Convia keeps only a SHA-256 hash of the token, so it cannot show it again or recover it. The list shows the first 12 characters to help you tell tokens apart |
| Expiry | **Never**, **30 days** or **90 days**, chosen at creation. An expired token is refused with `token_expired` and marked **Expired** |
| Last used | Updated as the token is used, at most about once a minute |
| Revocation | **Revoke** on the token's row. Immediate and permanent. The token is kept, marked **Revoked**, so its past activity stays attributed |
| Number of tokens | A workspace can have several tokens. Give each client its own, so you can revoke one without breaking the others |

Treat a token like a password. Anyone holding it can act in the workspace as you, with your role, until it is revoked or expires.

## Removing a member

Removing a person from the workspace stops every token and connector they use, on the next request (`not_a_member`). Their tokens are not revoked automatically, though: they stay in the **Tokens** list.

> [!IMPORTANT]
> If a removed or demoted person is later given back an Owner or Manager role, any of their tokens that were never revoked work again. Revoke a departing member's tokens as well as removing them.

## OAuth for client developers

claude.ai connectors sign in with OAuth instead of a token. A client developer needs the following.

1. **Discovery.** A request with no credential gets HTTP `401` with a challenge pointing at the protected resource metadata:

    ```text
    WWW-Authenticate: Bearer realm="mcp", resource_metadata="<your MCP URL>/.well-known/oauth-protected-resource"
    ```

    A request with a credential that is not accepted gets the same header with `error="invalid_token"` added. The header is exposed to browser clients through CORS.

2. **Protected resource metadata.** `GET <your MCP URL>/.well-known/oauth-protected-resource` is public and returns:

    ```json
    {
      "resource": "<your MCP URL>",
      "authorization_servers": ["<authorization server issuer>"],
      "bearer_methods_supported": ["header"],
      "scopes_supported": ["openid", "email", "profile", "offline_access"],
      "resource_documentation": "<link to the MCP Connections page>"
    }
    ```

    `resource` is exactly the MCP URL the person pasted. Fetch the authorization server's own metadata from the issuer in `authorization_servers` using standard OAuth discovery.

3. **Client registration.** Dynamic client registration is not available. Use Convia's OAuth Client ID, shown in **Integrations → MCP Connections → How to connect a client**. It is a public client: use PKCE and no client secret.

4. **Consent.** The person signs in to Convia and sees **Connect** followed by the name of Convia's registered OAuth app, explaining that it can use Convia as them to read and create content. They choose **Approve** or **Deny**.

5. **Scopes.** Only the standard scopes above exist; there are no custom scopes. Request `offline_access` to receive a refresh token.

6. **Calls.** Send the access token as `Authorization: Bearer <access token>` on every request.

Convia refuses an ordinary Convia sign-in session token sent as a bearer (`oauth_token_required`), and a token issued to any client other than Convia's MCP client (`client_not_allowed`). A `403` never carries a challenge: the credential was fine but the person is not allowed, so signing in again will not help.

## Connection errors

These happen before any tool runs and are returned as HTTP errors with a JSON body such as `{"error":"token_revoked"}`. Tool-level errors are listed in the [MCP tool reference](https://docs.conviapro.com/docs/mcp-tools.md).

| HTTP status | Error | Meaning and fix |
|---|---|---|
| 400 | `invalid_workspace_id` | The URL does not end in a valid workspace ID. Copy the Server URL again |
| 400 | `unsupported_protocol_version` | The `MCP-Protocol-Version` header is not one Convia supports. The response lists the supported versions |
| 401 | `missing_bearer` | No `Authorization: Bearer` header |
| 401 | `invalid_token` | The token or access token is not recognized |
| 401 | `token_revoked` | The token was revoked. Create a new one |
| 401 | `token_expired` | The token passed its expiry date. Create a new one |
| 401 | `workspace_mismatch` | The token belongs to a different workspace than the URL |
| 401 | `oauth_token_required` | The bearer is a normal sign-in session, not an OAuth access token |
| 401 | `client_not_allowed` | The access token was issued to a different OAuth client |
| 403 | `not_a_member` | The person is no longer a member of the workspace |
| 403 | `insufficient_role` | The person is not an Owner or Manager |
| 403 | `feature_disabled` | The workspace's plan does not include MCP Connections |
| 405 | `method_not_allowed` | Only `POST` is accepted, apart from the metadata document |
| 429 | `rate_limited` | More than 60 requests in a minute from one credential. Wait for `Retry-After` (60 seconds) |

The rate limit is a best-effort safeguard against floods, applied per credential, or per IP address when no credential is sent.

## The Activity log

Every tool call made through MCP is recorded, and Owners and Managers can review it.

1. Open **Integrations → MCP Connections**.
2. Click the **Activity** tab.

Each row shows **When**, **Token** (the token's name), **Tool**, **Result** (**Success**, or the error code) and **Latency**. Rows are newest first, 50 to a page.

| Recorded | Not recorded |
|---|---|
| Every `tools/call`, successful or failed | Requests refused before a tool runs: credential, membership, role or plan failures, rate limits and malformed requests |
| A short summary of the arguments (counts, lengths, flags), never post content | `initialize`, `ping` and `tools/list` |
| The first 200 characters of the reason given to `unschedule_posts`, `archive_posts` and `delete_posts` | |

The argument summary and the reason are stored with each entry but are not shown on the **Activity** tab. Calls through an OAuth connector are not tied to a token, so the **Token** column shows **(deleted token)** for them. The log is append-only: nobody in the workspace can edit or delete entries.

## What MCP never does

Whatever the credential, the Convia MCP server cannot:

- Publish a post, schedule one to go out, approve one, or send one to the approval queue. New posts are always written as drafts. Editing a post a person already scheduled leaves it scheduled, even when the edit changes its date. See [Approval & review](https://docs.conviapro.com/docs/approval-and-review.md).
- Edit, archive or delete a published or approved post.
- Change the live default AI prompt template or a per-platform social prompt.
- Set TikTok privacy or branded-content options, or YouTube's Made for Kids, privacy status or publish time.
- Upload new media.
- Reach any workspace other than the one in its URL.

Using MCP spends no [AI credits](https://docs.conviapro.com/docs/ai-credits.md): your assistant writes the copy on your own subscription with that assistant.

## Related

- [Connect an AI assistant (MCP)](https://docs.conviapro.com/docs/mcp-quickstart.md): create a token or a connector step by step.
- [MCP tool reference](https://docs.conviapro.com/docs/mcp-tools.md): tool-level errors, limits and side effects.
- [Workspaces & teams](https://docs.conviapro.com/docs/workspaces-and-teams.md): roles and how to change them.
- [Plans & billing](https://docs.conviapro.com/docs/plans-and-billing.md): which plans include MCP Connections and Advanced Analytics.

---

Source: https://docs.conviapro.com/docs/mcp-security · Section: AI agents & MCP · Last updated: 2026-10-03
