Source: https://datafa.st/docs/mcp-oauth
Markdown source: https://datafa.st/docs/mcp-oauth.md
Description: Understand how DataFast authorizes OAuth requests, which tools and data are available, and how to implement an MCP OAuth client.

# OAuth reference

**Setting up a connection?** Start with [Get started](/docs/mcp-introduction). It explains the two connection methods and includes complete setup instructions for both [OAuth](/docs/mcp-introduction#connect-with-oauth) and [API tokens](/docs/mcp-introduction#connect-with-an-api-token).

This reference covers OAuth permissions, shared data, token handling, and client implementation. MCP uses **Streamable HTTP** to carry requests; OAuth controls how a client obtains permission to make them.

## How OAuth requests are authorized

1. **You approve a connection.** Sign in to DataFast and select websites and permissions. DataFast saves that approval against your account and the OAuth client.
2. **The client receives a token.** The token identifies that saved connection. It does not contain your password or give the client your existing API keys.
3. **MCP verifies each request.** DataFast checks the token's expiry, its intended MCP endpoint, whether the connection is still active, the requested permission, and your current membership of the approved websites.
4. **The existing API handler checks access too.** The MCP tool calls the same handler used by the corresponding REST endpoint, with the identity and permissions verified by DataFast. The handler still enforces its authorization, validation, rate limits, and applicable plan restrictions before returning data.

For example, a connection approved to read Website A cannot fetch Website B by changing a website ID, or write to Website A without write permission and a suitable current role. Removing your membership of Website A also removes that connection's access to it.

DataFast does not exchange OAuth tokens for a master API key. The verified identity is passed inside the server for that request. OAuth tokens cannot authenticate directly to the public REST API or sign in to the dashboard.

## Manage a connection

Only selected websites are included. Adding a website to DataFast later does not add it to existing connections. Your active API access, website membership, team role, and each feature's plan restrictions still apply. For example, Starter social mention limits and owner-only Bot traffic controls also apply through OAuth.

If a client asks for more permissions later, review a new consent request. It cannot widen its own connection. To stop access, open [Connected apps](/oauth/connections) from Settings → API / MCP and choose **Revoke access**. Subsequent requests and token refreshes are rejected; a request already running may finish. Revocation does not delete data already received by the other application.

## Permissions and shared data

| Scope | Access |
| --- | --- |
| `websites:read` | List selected websites with their names, domains, and your team role. |
| `analytics:read` | Read traffic, revenue, custom goal parameters, and stored social mentions. Recorded URLs and custom parameters may contain personal data. |
| `visitors:read` | Read visitor journeys with direct identifiers removed. This includes individual activity and purchases. Also requires analytics:read. |
| `notes:read` | Read manual chart notes, including their text and timestamps. |
| `notes:write` | Create, edit, and delete manual chart notes. |
| `goals:read` | Read goals and goal display settings. |
| `goals:write` | Record or delete goal events and change goal display settings. |
| `funnels:read` | Read funnel definitions. |
| `funnels:write` | Create, edit, and delete funnels. |
| `alerts:read` | Read alerts and their delivery history. |
| `alerts:write` | Create, edit, and delete alerts, including notification recipients. |
| `settings:read` | Read website display settings, integration status and bot traffic settings. |
| `settings:write` | Edit website names, domains, timezones, display settings, and bot traffic settings. |
| `team:read` | Read team membership, including member names, emails, and roles. |
| `team:write` | Invite or remove team members. Only website owners can do this. |

Visitor tools require **both** `analytics:read` and `visitors:read`. They return pseudonymous visitor IDs so you can request one visitor's activity, while excluding names, emails, IP addresses, fingerprints, profiles, arbitrary metadata, acquisition parameters, and payment provider identifiers. Query strings and fragments are removed from visitor URLs. Recorded paths and goal names can still contain personal data if your site put it there.

The realtime widget groups visitors by coordinates rounded to 0.1 degrees and country. It excludes visitor IDs, paths, conversion predictions, names, and profiles. Geographic accuracy depends on the location data available to DataFast.

The [ChatGPT app](/docs/chatgpt-app) adds interactive charts to authorized tool results. Its widgets do not receive access tokens, API keys, or integration credentials. Refreshes and drilldowns call MCP again and repeat authorization.

Custom goal parameters, chart notes, recorded paths, and alert recipients can contain information your site or team deliberately recorded. Grant access only to applications you trust to receive it. Team tools include member names, emails and roles, and require the explicit team scope.

OAuth does not expose API-key management, account-token management, Bot traffic credentials, account profiles/settings, account-wide billing usage, or website creation. No OAuth permission is a wildcard. Use the [API-token setup](/docs/mcp-introduction#connect-with-an-api-token) for workflows that need its broader administration tools.

## Writes and retries

Write tools require the appropriate `:write` permission, a role that permits the operation, `confirm: true`, and an `idempotencyKey` of 8–128 characters. The agent should explain the exact target and change and obtain your confirmation first. A confirmation argument does not prove a person clicked a button: use a client you trust to ask before making changes. Enabled alerts can send email notifications. Creating a team invitation stores a pending invitation; it does not send email or immediately add a member.

Reuse the same key and identical arguments to retry a write. Completed results are retained for 24 hours within that specific OAuth connection. Changed arguments are rejected. If an attempt's outcome is unknown, DataFast will not execute it again automatically; inspect the website before deliberately issuing a new operation. Revoked or removed website access is checked before a cached result can be returned.

## OAuth client implementation

| Item | Value |
| --- | --- |
| Issuer | `https://datafa.st` |
| Authorization metadata | `https://datafa.st/.well-known/oauth-authorization-server` |
| Authorization endpoint | `https://datafa.st/oauth/authorize` |
| Token endpoint | `https://datafa.st/oauth/token` |
| Client registration | `https://datafa.st/oauth/register` |
| Revocation endpoint | `https://datafa.st/oauth/revoke` |
| General MCP resource | `https://datafa.st/api/mcp` |
| ChatGPT MCP resource | `https://datafa.st/api/chatgpt/mcp` |
| Grants | Authorization code with PKCE S256; rotating refresh tokens |
| Access token lifetime | 1 hour |
| Refresh token lifetime | Up to 30 days from issuance |
| Connection lifetime | Up to 90 days from consent; reconnect afterward |

Use the **exact MCP URL** as `resource` in authorization, code exchange, and refresh requests. A token for one MCP resource does not work at the other. Token requests use `application/x-www-form-urlencoded`. Send the resulting token only in `Authorization: Bearer …`, never in a URL. OAuth tokens are accepted at MCP endpoints; they are not general REST API credentials.

These are Bearer tokens, so possession of a valid token permits its approved access. Binding a token to a client and resource does not bind it to one device or prove which application is presenting it. Store tokens securely and revoke the connection if a token is exposed.

The authorization response includes `iss=https://datafa.st` and echoes the client's `state`. Redirect URIs must match registration exactly. Public clients use `none` with PKCE; confidential clients use `client_secret_basic` or `client_secret_post` **in addition** to PKCE. Implicit and password grants and plain PKCE are unsupported.

ChatGPT's official client metadata documents are supported, including `https://chatgpt.com/oauth/client.json` and its callback-specific variants. Other clients use dynamic registration with exact HTTPS or loopback redirect URIs. Registration names are developer-supplied and shown as unverified during consent. Registration records expire after one year.

Unauthenticated MCP requests return a `WWW-Authenticate` header pointing to the resource metadata. Tools advertise their exact OAuth scopes. Insufficient-scope tool responses include `mcp/www_authenticate` to let the client start another authorization request.

Access tokens, refresh tokens, authorization codes, and client secrets are stored as hashes. Codes expire after two minutes and are consumed once. Reusing a consumed code or rotated refresh token revokes the connection. Consent requests expire after ten minutes and are bound to the browser and the signed-in account. Consent pages contain no analytics or third-party scripts.

MCP keeps the standard 60-requests-per-minute credential budget, plus the normal backing API limits and an authentication limit per IP. Authorization, registration and token endpoints are also rate limited. A `429` response means to back off and retry; reconnect after invalid or expired authorization.

## OAuth tool reference

New tools are excluded until explicitly assigned a permission. The following tools are available, subject to your consent and current website access.

The ChatGPT app's chart tools — `render_timeseries_chart`, `render_breakdown_chart`, `render_funnel_chart`, and `render_realtime_map` — each require `analytics:read` and an approved website.

| Tool | Required scopes |
| --- | --- |
| `datafast_analytics_overview` | `analytics:read` |
| `datafast_analytics_timeseries` | `analytics:read` |
| `datafast_analytics_realtime` | `analytics:read` |
| `datafast_analytics_metadata` | `analytics:read` |
| `datafast_analytics_pages` | `analytics:read` |
| `datafast_analytics_exit_clicks` | `analytics:read` |
| `datafast_analytics_referrers` | `analytics:read` |
| `datafast_analytics_countries` | `analytics:read` |
| `datafast_analytics_regions` | `analytics:read` |
| `datafast_analytics_cities` | `analytics:read` |
| `datafast_analytics_browsers` | `analytics:read` |
| `datafast_analytics_devices` | `analytics:read` |
| `datafast_analytics_operating_systems` | `analytics:read` |
| `datafast_analytics_campaigns` | `analytics:read` |
| `datafast_analytics_goals_breakdown` | `analytics:read` |
| `datafast_analytics_goal_properties` | `analytics:read` |
| `datafast_analytics_hostnames` | `analytics:read` |
| `datafast_analytics_funnel` | `analytics:read` |
| `datafast_mentions_list` | `analytics:read` |
| `datafast_bot_traffic_summary` | `analytics:read` |
| `datafast_bot_traffic_pages` | `analytics:read` |
| `datafast_websites_list` | `websites:read` |
| `datafast_websites_get` | `settings:read` |
| `datafast_integrations_status` | `settings:read` |
| `datafast_bot_traffic_settings_get` | `settings:read` |
| `datafast_websites_update` | `settings:write` |
| `datafast_bot_traffic_settings_update` | `settings:write` |
| `datafast_notes_list` | `notes:read` |
| `datafast_notes_create` | `notes:write` |
| `datafast_notes_update` | `notes:write` |
| `datafast_notes_delete` | `notes:write` |
| `datafast_goals_list` | `goals:read` |
| `datafast_goals_customizations_list` | `goals:read` |
| `datafast_goals_track` | `goals:write` |
| `datafast_goals_delete_events` | `goals:write` |
| `datafast_goals_customizations_update` | `goals:write` |
| `datafast_goals_customizations_reset` | `goals:write` |
| `datafast_funnels_list` | `funnels:read` |
| `datafast_funnels_create` | `funnels:write` |
| `datafast_funnels_update` | `funnels:write` |
| `datafast_funnels_delete` | `funnels:write` |
| `datafast_alerts_list` | `alerts:read` |
| `datafast_alerts_history` | `alerts:read` |
| `datafast_alerts_create` | `alerts:write` |
| `datafast_alerts_update` | `alerts:write` |
| `datafast_alerts_delete` | `alerts:write` |
| `datafast_team_list` | `team:read` |
| `datafast_team_invite` | `team:write` |
| `datafast_team_remove` | `team:write` |
| `datafast_visitors_search` | `analytics:read` + `visitors:read` |
| `datafast_visitors_get` | `analytics:read` + `visitors:read` |

For each tool's arguments and underlying response contract, see the [MCP tool reference](/docs/mcp-tools), [REST API reference](/docs/api), and [custom goal property endpoint](/docs/api/website/goals/properties).
