Skip to main content

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 caseAuth methodNotes
Remote MCP server (Claude, Cursor)OAuth2 Device CodeMCP spec mandates OAuth 2.1 for remote servers
ChatGPT / GPT ActionsOAuth2 Authorization Code + PKCEPer-user access with consent screen
First-party CLIOAuth2 Device Code or PATDevice flow preferred; PAT for quick scripting
CI/CD pipelinesPATNon-interactive, short-lived scoped tokens
Shell scripts / cron jobsPATStatic bearer token via environment variable
n8n / Make.com / ZapierOAuth2 Authorization Code + PKCEThese platforms support OAuth natively
Local/stdio MCP serverPAT via env varConfigured out-of-band in MCP client config
Server-to-serverPATClient 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:

  1. The client calls POST /o/device-authorization/ with the client_id and requested scopes
  2. The user receives a user_code and opens /o/device/ in their browser
  3. The user enters the code and approves access
  4. 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

  1. Navigate to /accounts/tokens/
  2. Name the token and select scopes (e.g., read:profile, read:teams)
  3. Optionally set an expiry date
  4. 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:

  1. Register an OAuth2 application in Django admin with grant type Authorization Code
  2. Set the redirect URI to OpenAI's callback URL
  3. 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

n8n / Make.com / Zapier

These automation platforms support OAuth2 natively:

  1. Register an OAuth2 application in Django admin with grant type Authorization Code and PKCE enabled
  2. Set the redirect URI to the platform's OAuth callback URL
  3. 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_app command
warning

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

ScopeDescription
read:profileRead the authenticated user's profile
write:profileUpdate the authenticated user's profile
read:teamsRead teams and members
write:teamsCreate invitations and manage teams
read:productsRead products (demo)
adminAdministrative 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:

ExampleDescription
examples/cli/speedpy_cli.pyCLI with PAT and device-flow auth
examples/mcp_server/speedpy_mcp.pyMCP server exposing API tools for AI assistants
examples/README.mdSetup guide and extension instructions