Skip to content

Commit f2ec971

Browse files
authored
Add example fastmcp mcp (#45)
* adds fastmcp mcp example * fix linting * fix lint * more cleaning up * more clean up * fix lint * address feedback * cleaning up * address feedback * fix lint error * add config.py * more typings and add docstrings * fix space issue * Register scopes automatically for PRM * fail fast when required envs are missing * add comments to .env.example * adds auth0 tenant setup to README * adds some curl commands in testing
1 parent f906607 commit f2ec971

13 files changed

Lines changed: 1911 additions & 1 deletion

File tree

.gitignore

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ dist
1818
docs
1919

2020
#testfile
21-
server.py
2221
setup.py
2322
test.py
2423
test-script.py
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
# Auth0 Configuration
2+
3+
# Auth0 tenant domain (e.g., your-tenant.us.auth0.com)
4+
AUTH0_DOMAIN=your-tenant.auth0.com
5+
6+
# Auth0 API Identifier - must match the audience in your Auth0 API configuration
7+
AUTH0_AUDIENCE=https://api.example.com
8+
9+
# URL where this MCP server is accessible (used for OAuth metadata)
10+
MCP_SERVER_URL=http://localhost:3001
11+
12+
# Port the server will listen on
13+
PORT=3001
14+
15+
# Enable debug mode for detailed logging
16+
DEBUG=false
17+
18+
# CORS origins - comma-separated list of allowed origins (* for all)
19+
CORS_ORIGINS=*
Lines changed: 178 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,178 @@
1+
# Example FastMCP MCP Server with Auth0 Integration
2+
3+
This example demonstrates how to create a FastMCP MCP server that uses Auth0 for authentication using the `auth0-api-python` library.
4+
5+
## Install dependencies
6+
7+
```
8+
poetry install
9+
```
10+
11+
## Auth0 Tenant Setup
12+
13+
### Pre-requisites:
14+
15+
This guide uses [Auth0 CLI](https://auth0.github.io/auth0-cli/) to configure an Auth0 tenant for secure MCP tool access. If you don't have it, you can follow the [Auth0 CLI installation instructions](https://auth0.github.io/auth0-cli/) to set it up. Alternatively, all the following configuration steps can be done through the [Auth0 Management Dashboard](https://manage.auth0.com/).
16+
17+
### Step 1: Authenticate with Auth0 CLI
18+
19+
First, you need to log in to the Auth0 CLI with the correct scopes to manage all the necessary resources.
20+
21+
1. Run the login command: This command will open a browser window for you to authenticate. We are requesting a set of
22+
scopes to configure APIs, roles, and clients.
23+
24+
```
25+
auth0 login --scopes "read:client_grants,create:client_grants,delete:client_grants,read:clients,create:clients,update:clients,read:resource_servers,create:resource_servers,update:resource_servers,read:roles,create:roles,update:roles,update:tenant_settings,read:connections,update:connections"
26+
```
27+
28+
2. Verify your tenant: After logging in, confirm you are operating on the tenant you want to configure.
29+
30+
```
31+
auth0 tenants list
32+
```
33+
34+
### Step 2: Configure Tenant Settings
35+
36+
Next, enable tenant-level flags required for Dynamic Client Registration (DCR) and an improved user consent experience.
37+
38+
- `enable_dynamic_client_registration`: Allows MCP tools to register themselves as applications automatically.
39+
[Learn more](https://auth0.com/docs/get-started/applications/dynamic-client-registration#enable-dynamic-client-registration)
40+
- `use_scope_descriptions_for_consent`: Shows user-friendly descriptions for scopes on the consent screen.
41+
[Learn more](https://auth0.com/docs/customize/login-pages/customize-consent-prompts).
42+
43+
Execute the following command to enable the above mentioned flags through the tenant settings:
44+
45+
```
46+
auth0 tenant-settings update set flags.enable_dynamic_client_registration flags.use_scope_descriptions_for_consent
47+
```
48+
49+
### Step 3: Promote Connections to Domain Level
50+
51+
[Learn more](https://auth0.com/docs/authenticate/identity-providers/promote-connections-to-domain-level) about promoting
52+
connections to domain level.
53+
54+
1. List your connections to get their IDs: `auth0 api get connections`
55+
2. From the list, identify only the connections that should be available to be used with third party applications. For each of those specific connection IDs, run the following command to mark it as a domain-level connection. Replace `YOUR_CONNECTION_ID` with the actual ID (e.g., `con_XXXXXXXXXXXXXXXX`)
56+
57+
```
58+
auth0 api patch connections/YOUR_CONNECTION_ID --data '{"is_domain_connection": true}'
59+
```
60+
61+
### Step 4: Configure the API and Default Audience
62+
63+
This step creates the API (also known as a Resource Server) that represents your protected MCP Server and sets it as the
64+
default for your tenant.
65+
66+
1. Create the API: This command registers the API with Auth0, defines its signing algorithm, enables Role-Based Access
67+
Control (RBAC), and specifies the available scopes. Replace `http://localhost:3001` and `MCP Tools API`
68+
with your desired identifier and name. Add your tool-specific scopes to the scopes array.
69+
70+
Note that `rfc9068_profile_authz` is used instead of `rfc9068_profile` as the token dialect to enable RBAC. [Learn more](https://auth0.com/docs/get-started/apis/enable-role-based-access-control-for-apis#token-dialect-options)
71+
72+
```
73+
auth0 api post resource-servers --data '{
74+
"identifier": "http://localhost:3001",
75+
"name": "MCP Tools API",
76+
"signing_alg": "RS256",
77+
"token_dialect": "rfc9068_profile_authz",
78+
"enforce_policies": true,
79+
"scopes": [
80+
{"value": "tool:whoami", "description": "Access the WhoAmI tool"},
81+
{"value": "tool:greet", "description": "Access the Greeting tool"}
82+
]
83+
}'
84+
85+
```
86+
87+
2. Set the Default Audience: This ensures that users logging in interactively get access tokens that are valid for your
88+
newly created MCP Server. Replace `http://localhost:3001` with the same API identifier you used above.
89+
90+
**Note:** This step is currently required but temporary. Without setting a default audience, the issued access tokens will not be scoped specifically to your MCP resource server. Support for RFC 8707 (Resource Indicators for OAuth 2.0) is coming soon, which will provide proper resource targeting. Once available, these instructions will be updated to explain how to enable support for RFC 8707 instead of the default audience approach.
91+
92+
```
93+
auth0 api patch "tenants/settings" --data '{"default_audience": "http://localhost:3001"}'
94+
```
95+
96+
### Step 5: Configure RBAC Roles and Permissions
97+
98+
Now, set up roles and assign permissions to them. This allows you to control which users can access which tools.
99+
100+
1. Create Roles: For each role you need (e.g., "Tool Administrator", "Tool User"), run the create command.
101+
102+
```
103+
# Example for an admin role
104+
auth0 roles create --name "Tool Administrator" --description "Grants access to all MCP tools"
105+
106+
# Example for a basic user role
107+
auth0 roles create --name "Tool User" --description "Grants access to basic MCP tools"
108+
```
109+
110+
2. Assign Permissions to Roles: After creating roles, note the ID from the output (e.g. `rol_`) and and assign the API
111+
permissions to it. Replace `YOUR_ROLE_ID`, `http://localhost:3001`, and the list of scopes.
112+
113+
```
114+
# Example for admin role (all scopes)
115+
auth0 roles permissions add YOUR_ADMIN_ROLE_ID --api-id "http://localhost:3001" --permissions "tool:whoami,tool:greet"
116+
117+
# Example for user role (one scope)
118+
auth0 roles permissions add YOUR_USER_ROLE_ID --api-id "http://localhost:3001" --permissions "tool:whoami"
119+
```
120+
121+
3. Assign Roles to Users: Find users and assign them to the roles.
122+
123+
```
124+
# Find a user's ID
125+
auth0 users search --query "email:\"example@google.com\""
126+
127+
# Assign the role using the user's ID and the role's ID
128+
auth0 users roles assign "auth0|USER_ID_HERE" --roles "YOUR_ROLE_ID_HERE"
129+
```
130+
131+
**Note:** Further customization not supported out of the box by RBAC can be done via a custom Post-Login action trigger.
132+
133+
## Configuration
134+
135+
Rename `.env.example` to `.env` and configure the domain and audience:
136+
137+
```
138+
# Auth0 tenant domain
139+
AUTH0_DOMAIN=example-tenant.us.auth0.com
140+
141+
# Auth0 API Identifier
142+
AUTH0_AUDIENCE=http://localhost:3001
143+
```
144+
145+
With the configuration in place, the example can be started by running:
146+
147+
```bash
148+
poetry run python -m src.server
149+
```
150+
151+
## Testing
152+
153+
Use an MCP client like [MCP Inspector](https://github.com/modelcontextprotocol/inspector) to test your server interactively:
154+
155+
```bash
156+
npx @modelcontextprotocol/inspector
157+
```
158+
159+
The server will start up and the UI will be accessible at http://localhost:6274.
160+
161+
In the MCP Inspector, select `Streamable HTTP` as the `Transport Type` and enter `http://localhost:3001/mcp` as the URL.
162+
163+
### Using cURL
164+
165+
You can use cURL to verify that the server is running:
166+
167+
```bash
168+
# Test that the server is running and accessible - check OAuth resource metadata
169+
curl -v http://localhost:3001/.well-known/oauth-protected-resource
170+
171+
# Test MCP initialization (requires valid Auth0 access token)
172+
curl -X POST http://localhost:3001/mcp \
173+
-H "Content-Type: application/json" \
174+
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
175+
-d '{"jsonrpc": "2.0", "id": 1, "method": "initialize", "params": {"protocolVersion": "2025-06-18", "capabilities": {}, "clientInfo": {"name": "curl-test", "version": "1.0.0"}}}'
176+
```
177+
178+
**Note:** Use the MCP Inspector or other MCP-compatible clients for comprehensive testing.

0 commit comments

Comments
 (0)