Integrations & Machine Auth
Overview
SpeedPy supports two machine-authentication methods for integrations:
- OAuth2 (primary) — for MCP servers, ChatGPT/GPT Actions, automation platforms (n8n, Make.com), and CLIs
- Personal Access Tokens (PATs) — for scripts, CI/CD pipelines, and local development tools
Which auth method to use
| Use case | Auth method | Notes |
|---|---|---|
| Remote MCP server (Claude, Cursor) | OAuth2 Device Code | MCP spec mandates OAuth 2.1 for remote servers |
| ChatGPT / GPT Actions | OAuth2 Authorization Code + PKCE | Per-user access with consent screen |
| First-party CLI | OAuth2 Device Code or PAT | Device flow preferred; PAT for quick scripting |
| CI/CD pipelines | PAT | Non-interactive, short-lived scoped tokens |
| Shell scripts / cron jobs | PAT | Static bearer token via environment variable |
| n8n / Make.com / Zapier | OAuth2 Authorization Code + PKCE | These platforms support OAuth natively |
| Local/stdio MCP server | PAT via env var | Configured out-of-band in MCP client config |
| Server-to-server | PAT | Client Credentials grant can be added later |
Connecting an MCP server
MCP (Model Context Protocol) servers let AI assistants like Claude and Cursor interact with your API. The MCP spec requires OAuth 2.1 for remote servers.
Step 1: Register the application
python manage.py create_oauth2_app "My MCP Server"
This creates a public OAuth2 application with the Device Code grant type and prints the client_id.
Step 2: Configure the MCP server
Point your MCP server at your SpeedPy instance with the client_id from step 1. See examples/mcp_server/speedpy_mcp.py for a ready-to-use implementation.
Step 3: Authorize
When a user first connects through the MCP client:
- The client calls
POST /o/device-authorization/with theclient_idand requested scopes - The user receives a
user_codeand opens/o/device/in their browser - The user enters the code and approves access
- The client polls
POST /o/token/until authorization completes
Using Personal Access Tokens
PATs are ideal for scripts and CI/CD where no browser is available.
Create a token
- Navigate to
/accounts/tokens/ - Name the token and select scopes (e.g.,
read:profile,read:teams) - Optionally set an expiry date
- Copy the token — it is shown only once
Use the token
curl -H "Authorization: Bearer spd_abc123..." https://your-app.com/api/v1/me/
Tokens use the spd_ prefix. Only a SHA-256 hash is stored — the raw token cannot be recovered.
ChatGPT / GPT Actions
To connect your SpeedPy API as a GPT Action:
- Register an OAuth2 application in Django admin with grant type Authorization Code
- Set the redirect URI to OpenAI's callback URL
- In the GPT builder, configure OAuth with:
- Authorization URL:
https://your-app.com/o/authorize/ - Token URL:
https://your-app.com/o/token/ - Client ID / Secret: from the registered application
- Scopes: e.g.,
read:profile read:teams
- Authorization URL:
n8n / Make.com / Zapier
These automation platforms support OAuth2 natively:
- Register an OAuth2 application in Django admin with grant type Authorization Code and PKCE enabled
- Set the redirect URI to the platform's OAuth callback URL
- Configure the platform's OAuth2 credentials with your authorization and token URLs
For n8n specifically, you can also use the "Header Auth" credential type with a PAT as a fallback.
Dynamic Client Registration (RFC 7591)
The MCP spec recommends Dynamic Client Registration so MCP clients can self-register without manual admin setup. SpeedPy provides an optional registration endpoint.
Endpoint
POST /o/register/ (unauthenticated when DCR is enabled)
Request
{
"client_name": "My MCP Client",
"grant_types": ["urn:ietf:params:oauth:grant-type:device_code"],
"scope": "read:profile read:teams",
"token_endpoint_auth_method": "none"
}
Response (201 Created)
{
"client_id": "abc123...",
"client_name": "My MCP Client",
"grant_types": ["urn:ietf:params:oauth:grant-type:device_code"],
"scope": "read:profile read:teams",
"token_endpoint_auth_method": "none",
"client_id_issued_at": 1750000000
}
For confidential clients (Authorization Code grant), the response also includes a client_secret.
Configuration
# project/settings.py
DCR_ENABLED = env.bool("DCR_ENABLED", default=DEBUG)
- Development: enabled by default — MCP clients can self-register
- Production: disabled by default — register apps via Django admin or
create_oauth2_appcommand
When DCR is enabled, any client can register an OAuth2 application. In production, either disable DCR or add authentication requirements (e.g., an initial access token).
Available scopes
| Scope | Description |
|---|---|
read:profile | Read the authenticated user's profile |
write:profile | Update the authenticated user's profile |
read:teams | Read teams and members |
write:teams | Create invitations and manage teams |
read:products | Read products (demo) |
admin | Administrative access (reserved) |
Add custom scopes for your business resources by updating OAUTH2_PROVIDER["SCOPES"] in project/settings.py.
Starter examples
SpeedPy includes ready-to-use client examples in the examples/ directory:
| Example | Description |
|---|---|
examples/cli/speedpy_cli.py | CLI with PAT and device-flow auth |
examples/mcp_server/speedpy_mcp.py | MCP server exposing API tools for AI assistants |
examples/README.md | Setup guide and extension instructions |