From 83085c3cd3d5f43addf973eb5ca06fec6e24f258 Mon Sep 17 00:00:00 2001 From: Jeremiah Lowin <153965+jlowin@users.noreply.github.com> Date: Mon, 1 Dec 2025 13:39:43 -0500 Subject: [PATCH] Fix version badges for icons and website_url; add Discord example (#2509) * Fix version badges and remove redundant badges from Discord doc * Add Discord OAuth example --- docs/integrations/discord.mdx | 4 --- docs/servers/prompts.mdx | 2 +- docs/servers/resources.mdx | 2 +- docs/servers/server.mdx | 4 +-- docs/servers/tools.mdx | 2 +- examples/auth/discord_oauth/README.md | 33 +++++++++++++++++++++++++ examples/auth/discord_oauth/client.py | 32 ++++++++++++++++++++++++ examples/auth/discord_oauth/server.py | 35 +++++++++++++++++++++++++++ 8 files changed, 105 insertions(+), 9 deletions(-) create mode 100644 examples/auth/discord_oauth/README.md create mode 100644 examples/auth/discord_oauth/client.py create mode 100644 examples/auth/discord_oauth/server.py diff --git a/docs/integrations/discord.mdx b/docs/integrations/discord.mdx index 9e8338c84..4e3670358 100644 --- a/docs/integrations/discord.mdx +++ b/docs/integrations/discord.mdx @@ -149,8 +149,6 @@ auth_provider = DiscordProvider( ## Production Configuration - - For production deployments with persistent token management across server restarts, configure `jwt_signing_key` and `client_storage`: ```python server.py @@ -187,8 +185,6 @@ For complete details on these parameters, see the [OAuth Proxy documentation](/s ## Environment Variables - - For production deployments, use environment variables instead of hardcoding credentials. ### Provider Selection diff --git a/docs/servers/prompts.mdx b/docs/servers/prompts.mdx index c122daa2b..710b35ce3 100644 --- a/docs/servers/prompts.mdx +++ b/docs/servers/prompts.mdx @@ -98,7 +98,7 @@ def data_analysis_prompt( - + Optional list of icon representations for this prompt. See [Icons](/servers/icons) for detailed examples diff --git a/docs/servers/resources.mdx b/docs/servers/resources.mdx index d3c8e3cdd..86c043d35 100644 --- a/docs/servers/resources.mdx +++ b/docs/servers/resources.mdx @@ -107,7 +107,7 @@ def get_application_status() -> dict: - + Optional list of icon representations for this resource or template. See [Icons](/servers/icons) for detailed examples diff --git a/docs/servers/server.mdx b/docs/servers/server.mdx index 8c46654a0..f1f4ed6da 100644 --- a/docs/servers/server.mdx +++ b/docs/servers/server.mdx @@ -45,13 +45,13 @@ The `FastMCP` constructor accepts several arguments: - + URL to a website with more information about your server. Displayed in client applications - + List of icon representations for your server. Icons help users visually identify your server in client applications. See [Icons](/servers/icons) for detailed examples diff --git a/docs/servers/tools.mdx b/docs/servers/tools.mdx index 92812378d..553f257dd 100644 --- a/docs/servers/tools.mdx +++ b/docs/servers/tools.mdx @@ -82,7 +82,7 @@ def search_products_implementation(query: str, category: str | None = None) -> l - + Optional list of icon representations for this tool. See [Icons](/servers/icons) for detailed examples diff --git a/examples/auth/discord_oauth/README.md b/examples/auth/discord_oauth/README.md new file mode 100644 index 000000000..74217f833 --- /dev/null +++ b/examples/auth/discord_oauth/README.md @@ -0,0 +1,33 @@ +# Discord OAuth Example + +Demonstrates FastMCP server protection with Discord OAuth. + +## Setup + +1. Create a Discord OAuth App: + - Go to https://discord.com/developers/applications + - Click "New Application" and give it a name + - Go to OAuth2 in the left sidebar + - Add a Redirect URL: `http://localhost:8000/auth/callback` + - Copy the Client ID and Client Secret + +2. Set environment variables: + + ```bash + export FASTMCP_SERVER_AUTH_DISCORD_CLIENT_ID="your-client-id" + export FASTMCP_SERVER_AUTH_DISCORD_CLIENT_SECRET="your-client-secret" + ``` + +3. Run the server: + + ```bash + python server.py + ``` + +4. In another terminal, run the client: + + ```bash + python client.py + ``` + +The client will open your browser for Discord authentication. diff --git a/examples/auth/discord_oauth/client.py b/examples/auth/discord_oauth/client.py new file mode 100644 index 000000000..880b86f4d --- /dev/null +++ b/examples/auth/discord_oauth/client.py @@ -0,0 +1,32 @@ +"""Discord OAuth client example for connecting to FastMCP servers. + +This example demonstrates how to connect to a Discord OAuth-protected FastMCP server. + +To run: + python client.py +""" + +import asyncio + +from fastmcp.client import Client + +SERVER_URL = "http://127.0.0.1:8000/mcp" + + +async def main(): + try: + async with Client(SERVER_URL, auth="oauth") as client: + assert await client.ping() + print("✅ Successfully authenticated!") + + tools = await client.list_tools() + print(f"🔧 Available tools ({len(tools)}):") + for tool in tools: + print(f" - {tool.name}: {tool.description}") + except Exception as e: + print(f"❌ Authentication failed: {e}") + raise + + +if __name__ == "__main__": + asyncio.run(main()) diff --git a/examples/auth/discord_oauth/server.py b/examples/auth/discord_oauth/server.py new file mode 100644 index 000000000..424c97bdb --- /dev/null +++ b/examples/auth/discord_oauth/server.py @@ -0,0 +1,35 @@ +"""Discord OAuth server example for FastMCP. + +This example demonstrates how to protect a FastMCP server with Discord OAuth. + +Required environment variables: +- FASTMCP_SERVER_AUTH_DISCORD_CLIENT_ID: Your Discord OAuth app client ID +- FASTMCP_SERVER_AUTH_DISCORD_CLIENT_SECRET: Your Discord OAuth app client secret + +To run: + python server.py +""" + +import os + +from fastmcp import FastMCP +from fastmcp.server.auth.providers.discord import DiscordProvider + +auth = DiscordProvider( + client_id=os.getenv("FASTMCP_SERVER_AUTH_DISCORD_CLIENT_ID") or "", + client_secret=os.getenv("FASTMCP_SERVER_AUTH_DISCORD_CLIENT_SECRET") or "", + base_url="http://localhost:8000", + # redirect_path="/auth/callback", # Default path - change if using a different callback URL +) + +mcp = FastMCP("Discord OAuth Example Server", auth=auth) + + +@mcp.tool +def echo(message: str) -> str: + """Echo the provided message.""" + return message + + +if __name__ == "__main__": + mcp.run(transport="http", port=8000)