Mcp auth fastmcp scalekit
35 skills that teach AI coding agents to integrate Scalekit auth — agent auth, full-stack login, MCP OAuth 2.1, enterprise SSO, and SCIM. Works with Claude Code, Cursor, Windsurf, and 35+ other agents.
npx -y skills add scalekit-inc/skills --skill mcp-auth-fastmcp-scalekitAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
2 things to look at
- no licenseNo license file was found in the repository. Code published without one is not open source by default, so using it at work is a question for whoever answers licensing questions where you are.
- 2 stars2 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
What its author says it does
Copied from the file, not written here
Add Scalekit OAuth authentication to a FastMCP server (Python). Use when you need to protect FastMCP tools with OAuth 2.1 Bearer tokens and enforce per-tool scope checks (e.g. todo:read, todo:write). Authentication is added in 5 lines via ScalekitProvider; scope checks use get_access_token() inside each tool.
SKILL.md
5.2 KB, as published. Nobody here has run it
Add OAuth auth to a FastMCP server (Scalekit)
What this skill builds
- A FastMCP server with
stateless_http=Truethat boots an HTTP transport on a configured port. - OAuth protection via
ScalekitProvider— handles token validation, .well-known discovery, and WWW-Authenticate on 401 automatically. - Per-tool scope enforcement using
get_access_token()fromfastmcp.server.dependencies. - Scopes are pre-configured in the Scalekit dashboard; tools check them at runtime.
Key difference from Express skill
- No manual middleware, no manual .well-known route.
- Auth is injected at the
FastMCP(auth=...)constructor. ScalekitProviderusesresource_id(starts withres_) andmcp_url(base URL + trailing slash).- FastMCP appends
/mcpto the base URL automatically — always register the BASE URL with trailing slash in Scalekit, not the /mcp path.
Inputs to collect (ask if missing)
- SCALEKIT_ENVIRONMENT_URL (your Scalekit env URL, e.g. https://your-env.scalekit.com)
- SCALEKIT_CLIENT_ID
- SCALEKIT_RESOURCE_ID (starts with res_, from Dashboard > MCP Servers)
- MCP_URL: base URL with trailing slash (e.g. http://localhost:3002/)
- PORT (default 3002)
- Scopes to configure (e.g. todo:read, todo:write); these must also be created in the Scalekit dashboard
Mode detection
Ask: "Are we scaffolding a new FastMCP server, or adding auth to an existing FastMCP server?"
- Mode A: New server → use assets/server.py or assets/server-minimal.py as the base
- Mode B: Existing server → apply the patch plan below
Mode A — New server scaffold
Steps
-
Create a directory and virtual environment:
mkdir -p <project-name> cd <project-name> python3 -m venv venv source venv/bin/activate -
Install dependencies using assets/requirements.txt:
pip install -r requirements.txt -
Create .env using assets/env.example (fill real values from Scalekit dashboard).
-
Copy assets/server-minimal.py to server.py and add your tools.
-
Run:
python server.py -
Test with MCP Inspector (point to http://localhost:3002/mcp — note: /mcp, not /):
npx @modelcontextprotocol/inspector@latestLeave Authentication fields empty; DCR handles client registration automatically.
Mode B — Retrofit an existing FastMCP server
Identify insertion points
Ask for the existing server file. Look for:
- How
FastMCP(...)is instantiated - Whether
mcp.run(...)is already present
Patch plan (minimal diffs)
1. Add env vars
Add to .env:
SCALEKIT_ENVIRONMENT_URL=...
SCALEKIT_CLIENT_ID=...
SCALEKIT_RESOURCE_ID=...
MCP_URL=http://localhost:3002/
PORT=3002
2. Add imports
from fastmcp.server.auth.providers.scalekit import ScalekitProvider
from fastmcp.server.dependencies import AccessToken, get_access_token
3. Patch FastMCP constructor
Before (typical):
mcp = FastMCP("My Server")
After:
mcp = FastMCP(
"My Server",
stateless_http=True,
auth=ScalekitProvider(
environment_url=os.getenv("SCALEKIT_ENVIRONMENT_URL"),
client_id=os.getenv("SCALEKIT_CLIENT_ID"),
resource_id=os.getenv("SCALEKIT_RESOURCE_ID"),
mcp_url=os.getenv("MCP_URL"),
),
)
4. Add scope helper
Add once near the top of the file:
def _require_scope(scope: str):
token: AccessToken = get_access_token()
if scope not in token.scopes:
return f"Insufficient permissions: `{scope}` scope required."
return None
5. Add scope checks to each tool
At the top of each @mcp.tool function body, add:
error = _require_scope("your:scope")
if error:
return {"error": error}
See assets/tool-template.py for the full pattern.
6. Patch run call
if __name__ == "__main__":
mcp.run(transport="http", port=int(os.getenv("PORT", "3002")))
Scope design guide
- Register scopes in Scalekit dashboard BEFORE running the server.
- Group by read vs write per resource: e.g. todo:read, todo:write.
- Tools that only read → require read scope.
- Tools that mutate (create/update/delete) → require write scope.
- A token with no matching scope will get {"error": "Insufficient permissions: <scope> required."}.
Verification checklist
- Server boots and logs HTTP transport on http://localhost:PORT/
- MCP Inspector connects to http://localhost:PORT/mcp
- Tool with correct scope → success
- Tool with wrong scope → {"error": "Insufficient permissions..."}
- No token → 401 + WWW-Authenticate (handled by ScalekitProvider automatically)
See references/TROUBLESHOOTING.md for common issues.