Twynity OAuth 2.0 MCP Template
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@Twynity OAuth 2.0 MCP Templateconnect my ClickUp account"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Twynity OAuth 2.0 MCP Template
A production-shaped FastMCP server template for building a Twynity MCP where each user logs in to their own account at an upstream provider via OAuth 2.0 — like ClickUp, Google, Microsoft, GitHub, etc. Tokens are exchanged through the Twynity Interconnector oauth category and stored encrypted in MongoDB, scoped to the exact (user_id, persona_id) pair.
This is the right starting point when your MCP needs the user's own provider credentials (access/refresh tokens) rather than a shared API key or a static configuration.
Features
Twynity Interconnector
oauthcategory:GET /api/v1/auth/{provider}/login?redirect_uri={uri}— mints a single-usestate(TTL-expired Mongooauth_sessionscollection) and returns the provider authorization URLPOST /api/v1/auth/{provider}/token-callback?redirect_uri={uri}&code={code}— looks upstate, exchanges the code for tokens, stores them encrypted inoauth_tokens, deletes the one-shot sessionPOST /api/v1/auth/{provider}/logout— best-effort provider-side revoke + deletes the stored tokens
Encrypted access/refresh token storage in MongoDB (Fernet, scoped to
(user_id, persona_id))public_metadatareturns onlyhas_access_token/has_refresh_token— never the raw tokens (Interconnector §11.3, enforced by a test)GET /api/v1/external-connection/meconnection-status endpointMCP manifest (
/.well-known/mcp.json) declaringexternal_connections.oauthTwynity JWT auth (audience-checked
JWTVerifier) +Persona-IdscopingTools resolve identity from FastMCP's verified access-token context (no re-verify of the stripped
authorizationheader)Docker + Render deployment (Python 3.12 pinned)
OAuth configuration (env vars)
Set these for your upstream provider (see .env.example):
OAUTH_PROVIDER— the{provider}path segment (e.g.clickup)OAUTH_CLIENT_ID/OAUTH_CLIENT_SECRET— your OAuth app credentialsOAUTH_REDIRECT_URI— the redirect URI Twynity provides. It must exactly match what you registered with the OAuth provider, or the flow fails silently. This is not your callback endpoint — Twynity calls yourtoken-callbackroute after the provider bounces here.OAUTH_AUTHORIZE_URL/OAUTH_TOKEN_URL/OAUTH_REVOKE_URL— your provider's endpointsOAUTH_SCOPES— the scopes to requestOAUTH_SESSION_TTL_SECONDS— how long an unexchangedstatestays valid
Related MCP server: Entra ID On-Behalf-Of MCP
Setup
Prerequisites
Python 3.11 or higher
MongoDB instance (for token + session storage)
An OAuth app registered with your upstream provider, configured with the Twynity redirect URI
A Twynity account-service URL + the MCP registered on Twynity (so user JWTs carry your hyphenated service ID in
aud)
Installation
Install the dependencies:
uv sync --lockedCopy
.env.exampleto.envand configure the environment variables:
cp .env.example .envEdit .env with your configuration:
MONGODB_URI- MongoDB connection string for storing encrypted connectionsENCRYPTION_KEY- Fernet encryption key for securing credentials (generate withuv run python -c "from cryptography.fernet import Fernet; print(Fernet.generate_key().decode())")ACCOUNT_SERVICE_URL- Twynity account service URLACCOUNT_SERVICE_JWKS_ENDPOINT- JWKS endpoint for verifying JWTsACCOUNT_SERVICE_JWKS_CACHE_TTL- Cache TTL for JWKSLICENSE_KEY- License key for usage trackingLICENSE_SERVER_BASE_URL- License server base URLLICENSE_SERVER_JWKS_ENDPOINT- JWKS endpoint for license verificationLICENSE_SERVER_ACTIVATION_ENDPOINT- License activation endpointUSAGE_REPORT_ENDPOINT- Usage reporting endpoint
Run the Server
uv run uvicorn app.main:app --host 0.0.0.0 --port 8000Tools
Replace the say_hello example tool with your own. A typical tool reads the user's stored OAuth token:
from fastmcp.tools import ToolResult
from app.tools.connection import get_current_connection
async def my_tool(...) -> ToolResult:
token = await get_current_connection() # {"id", "access_token", "refresh_token"}
# call your upstream API with token["access_token"]
return ToolResult(content=[...], structured_content={...})get_current_connection() returns the decrypted token grant for the verified user/persona, or raises an actionable auth error if the user hasn't completed the OAuth flow yet. Handle expired access tokens by refreshing with refresh_token against your provider's token URL.
Configuration
The server expects a .env file with the following variables:
# MongoDB for secure connection storage
MONGODB_URI=mongodb://localhost:27017
DATABASE_NAME=twynity_mcp
# Encryption key (required)
ENCRYPTION_KEY=your_fernet_encryption_key_here
# Twynity account service details
ACCOUNT_SERVICE_URL=https://accounts.twynity.com
ACCOUNT_SERVICE_JWKS_ENDPOINT=/oauth2/keys
ACCOUNT_SERVICE_JWKS_CACHE_TTL=300
# License service details
LICENSE_KEY=
LICENSE_SERVER_BASE_URL=https://license.twynity.com
LICENSE_SERVER_JWKS_ENDPOINT=/oauth2/keys
LICENSE_SERVER_ACTIVATION_ENDPOINT=/activate
# Usage reporting endpoint
USAGE_REPORT_ENDPOINT=https://usage.twynity.com/api/v1/report
# Public URL for the server
PUBLIC_URL=http://localhost:8000
# Environment (development, staging, production)
ENVIRONMENT=development
# Allowed origins for CORS
ALLOWED_ORIGINS=*Authentication and Security
This server uses Twynity's authentication system which requires:
A valid bearer JWT token
A
Persona-Idheader identifying the user's project/persona context
Credentials are stored securely encrypted in MongoDB, with each connection scoped to a specific user and persona pair.
Development
Running Tests
uv run pytest -qCode Quality
uv run ruff check app testsDeployment
Docker
docker build -t oauth-mcp .
docker run -p 8000:8000 oauth-mcpLicense
MIT License - see LICENSE for details.
This server cannot be deployed
Maintenance
Related MCP Connectors
Prove end users to agents and apps: login-links, OIDC clients, and API keys over remote MCP
Your OpenWork org's skills, plugins, workflows, and connections through one OAuth MCP URL.
Unauthenticated OAuth2 callback collector for Tollbooth MCP services
Managed MCP gateway with OAuth, per-agent permissions, shared accounts and activity logs.
Related MCP Servers
- AlicenseNot gradedqualityCmaintenanceEnables MCP clients to act as an authenticated Overleaf user, letting them access and manipulate projects through Overleaf's web API.1GPL 3.0
- AlicenseNot gradedqualityBmaintenanceEnables MCP clients to exchange an MCP-audience token for a Microsoft Graph token and call Graph as the signed-in user, with tools for identity verification and recent mail access.MIT
- FlicenseNot gradedqualityCmaintenanceEnables a single authenticated MCP endpoint to resolve users to the correct tenant, role, permissions, and tenant-specific backend integration, with support for shared, individual, and hybrid identity modes.-
- AlicenseNot gradedqualityAmaintenanceEnables existing apps to expose their users and data to external AI agents via MCP with OAuth 2.1 authentication and scoped tools.45 npmMIT