4.0 KiB
MCP Runbook
Scope
This runbook covers the MCP adapter exposed by app.mcp_main.
Endpoint
- Streamable HTTP endpoint:
POST /mcp(mounted underapp.mcp_main)
When using Docker Compose:
- Base URL:
http://127.0.0.1:8001/mcp
Runtime modes
Local:
uv run uvicorn app.mcp_main:app --host 0.0.0.0 --port 8001
Docker Compose service:
personal-agent-mcp
Tool surface
Always enabled:
check_availabilityavailable_meeting_intervals
Optional mutation tools (disabled by default):
scan_mailboxlist_unsubscribe_candidatesexecute_unsubscribe
Enable optional tools with:
MCP_ENABLE_MUTATION_TOOLS=true
Authorization and scope gates
MCP tools call the shared auth backend and read auth headers from request context.
MCP auth mode resolution:
MCP_AUTH_MODE=inherit(default): useAUTH_MODEMCP_AUTH_MODE=api_key|jwt|hybrid|oauth: override only for MCP
Supported auth headers:
X-API-KeyAuthorization: Bearer ...
For MCP_AUTH_MODE=oauth, bearer tokens are validated via OAuth token introspection:
MCP_RESOURCE_SERVER_URL(required canonical MCP URL, for RFC 9728 metadata/challenges)MCP_OAUTH_INTROSPECTION_URL(required)MCP_OAUTH_CLIENT_ID/MCP_OAUTH_CLIENT_SECRET(optional; use for introspection endpoint auth)MCP_OAUTH_ISSUER(optional strictissmatch)MCP_OAUTH_AUDIENCE(optional required audience value)MCP_OAUTH_TIMEOUT_SECONDS(default8)
When OAuth mode is enabled, FastMCP exposes protected resource metadata at:
/.well-known/oauth-protected-resource/mcp
and returns OAuth-compliant WWW-Authenticate: Bearer ... challenges for unauthenticated requests.
Scope authorization is enforced at tool level (per required scope above).
Required scopes:
check_availability:availability:readavailable_meeting_intervals:available_meeting_intervals:readscan_mailbox:mail:scanlist_unsubscribe_candidates:unsubscribe:readexecute_unsubscribe:unsubscribe:execute
Tool verification
Verify tool list from Python:
uv run python - <<'PY'
import asyncio
from app.mcp.server import mcp
async def main():
tools = await mcp.list_tools()
print([t.name for t in tools])
asyncio.run(main())
PY
Expected output by mode:
- default:
['check_availability', 'available_meeting_intervals'] - with
MCP_ENABLE_MUTATION_TOOLS=true: all five tools
Protocol notes
- The server uses FastMCP Streamable HTTP.
- Basic GET to
/mcpis not a health endpoint; MCP expects protocol-compliant requests. - In local development, FastMCP may enforce host/origin checks. If you see
421 Misdirected Request, verify host/port and reverse-proxy headers.
Troubleshooting
If tools fail with auth errors:
- Check
AUTH_MODEand credentials - Check
MCP_AUTH_MODEoverride and relatedMCP_OAUTH_*variables - Verify
MCP_RESOURCE_SERVER_URLmatches the public MCP endpoint (for examplehttps://mcp.example.com/mcp) - Confirm JWT contains required scopes
- For API key mode, verify
AGENT_API_KEY
If tool calls fail with Google errors:
- Verify OAuth file mounts in Docker:
GOOGLE_CLIENT_SECRETS_FILEGOOGLE_TOKEN_FILE
In ChatGPT when adding a client application use the following parameters
- Nom = chatgpt-personal-agent
- Description = Check my availability
- Url de serveur MCP = https://mcp.simple-agent.cio-strategies.com/mcp
- Authentication = OAuth
- Paramètres avancés
- Méthode d'enregistrement = Client OAuth défini par l'utilisateur
- URL de rappel --> à reporter dans Casdoor
- ID Client OAuth = chatgpt-personal-agent (idem Casdoor)
- Secret client OAuth = secret OAuth venant de Casdoor
- Méthode d'authentification = client_secret_post
- Périmètres par défaut = openid + offline_access + available_meeting_intervals:read + availability:read
- URL d'autorisation = https://id.simple-agent.cio-strategies.com/login/oauth/authorize
- URL jeton = https://id.simple-agent.cio-strategies.com/api/login/oauth/access_token
- Décocher "OIDC activé" et mettre à blanc tous les autres champs