Add MCP Server Quickstart - #1179
Conversation
There was a problem hiding this comment.
Pull request overview
Adds new Duende IdentityServer documentation covering an MCP Server demo that uses Dynamic Client Registration (DCR), plus a Samples landing page entry that links to the corresponding GitHub sample.
Changes:
- Added a new quickstart: “Connecting an MCP Server and Client with DCR”
- Added a new Samples page: “MCP Server and Client” with a LinkCard to the demo repo
- Cross-linked the quickstart and the sample page
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 3 comments.
| File | Description |
|---|---|
| astro/src/content/docs/identityserver/samples/mcp-server.mdx | New samples page for the MCP demo, with links to DCR docs and the GitHub sample. |
| astro/src/content/docs/identityserver/quickstarts/8-mcp.mdx | New end-to-end quickstart describing IdentityServer + MCP Server + console client setup using DCR. |
Suppressed comments (4)
astro/src/content/docs/identityserver/quickstarts/8-mcp.mdx:29
- Grammar: "The below steps … adds" should be "The steps below … add".
The IdentityServer project needs to be configured to use DCR to allow clients at runtime. The below steps disable the static clients and adds DCR. Add a new Duende IdentityServer InMemory project to its own directory inside the `mcp-quickstart` directory you created above.
astro/src/content/docs/identityserver/quickstarts/8-mcp.mdx:101
- Typo in the code comment: "metadatada" should be "metadata".
// this will add the default dynamic client registration endpoint to the discovery/metadatada documents
astro/src/content/docs/identityserver/quickstarts/8-mcp.mdx:170
- Minor typo/formatting in the snippet comment: add a space after
//for readability/consistency.
//Add this line
astro/src/content/docs/identityserver/quickstarts/8-mcp.mdx:492
- The XML doc comment block is malformed (it closes
</summary>without opening<summary>) and the<param>names don’t match the method signature (authContext, notauthorizationUrl/redirectUri). Since this is a copy/paste snippet, it’s worth keeping it correct.
/// Handles the OAuth authorization URL by starting a local HTTP server and opening a browser.
/// This implementation demonstrates how SDK consumers can provide their own authorization flow.
/// </summary>
/// <param name="authorizationUrl">The authorization URL to open in the browser.</param>
/// <param name="redirectUri">The redirect URI where the authorization code will be sent.</param>
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
maartenba
left a comment
There was a problem hiding this comment.
Left a bunch of comments, roughly two groups:
- The reader arrives wanting to secure AI tools, not learn about DCR per se (it's a means to an end). Flipping to "here's how to secure your MCP server with IdentityServer (using DCR under the hood)"
- Elaboration on some concepts. It's not the easiest topic and I think we may be glossing over a couple of things currently.
- (OK three groups) Some formatting/Astro suggestions.
| @@ -0,0 +1,596 @@ | |||
| --- | |||
| title: "Connecting an MCP Server and Client with DCR" | |||
There was a problem hiding this comment.
Quickstarts is a good location, we can move it elsewhere when needed.
| The console client will need to: | ||
|
|
||
| 1. Use the `ModelContextProtocol` NuGet package to create an `HttpClientTransport` object to communicate with the MCP Server. | ||
| 1. Include a `RedirectUri` back to itself after the user signs in. |
There was a problem hiding this comment.
Why is this redirect needed? Probably elaborate a little bit.
| AuthorizationCallbackHandler = HandleAuthorizationUrlAsync, | ||
| DynamicClientRegistration = new DynamicClientRegistrationOptions | ||
| { | ||
| ClientName = "ProtectedMcpClient" | ||
| }, | ||
| Scopes = ["mcp:tools"], |
| /// <param name="cancellationToken">The cancellation token.</param> | ||
| /// <returns>The authorization code extracted from the callback, or null if the operation failed.</returns> | ||
| // static async Task<string?> HandleAuthorizationUrlAsync(Uri authorizationUrl, Uri redirectUri, CancellationToken cancellationToken) | ||
| static async Task<AuthorizationResult?> HandleAuthorizationUrlAsync(AuthorizationCallbackContext authContext, CancellationToken cancellationToken) |
There was a problem hiding this comment.
Does this need elaboration in text?
| ### Run the Samples | ||
|
|
||
| Start the IdentityServer and MCP Server applications, then run the console client. When prompted to sign in for the console client, use username `bob` with password `bob` to sign in. The console will output the response from the MCP Server after it self-registers. | ||
|
|
There was a problem hiding this comment.
Maybe repeat with a list what happened behind the scenes? (client requested server, server said need auth via IdP URL, client sees it can self register with DCR, self registers client, then does interactive auth in the browser with new client ID, then makes request to server, ...)
| @@ -0,0 +1,596 @@ | |||
| --- | |||
| title: "Connecting an MCP Server and Client with DCR" | |||
There was a problem hiding this comment.
Make the title of the page "Dynamic Client Registration" while you can use a label in the sidebar to have it be DCR
There was a problem hiding this comment.
Frame it from AI/MCP perspective, DCR is secondary
| _ = app.MapRazorPages() | ||
| .RequireAuthorization(); | ||
|
|
||
| //Add this line |
There was a problem hiding this comment.
Astro code blocks can highlight lines without comments like this. I think it is fine right now, but just a thought.
| } | ||
| ``` | ||
|
|
||
| #### Hard Code Application Url |
There was a problem hiding this comment.
The use of "Hard Code" here is odd. "Setting the Application Url for Demo Purposes"
|
|
||
| #### Configure MCP Tools | ||
|
|
||
| Create a new directory called `McpTools` and add a `WeatherTools.cs` C# file. This will be the API called by our clients. The code for the file is below. |
There was a problem hiding this comment.
"Create a new directory within the project..."
| } | ||
| ``` | ||
|
|
||
| ### Run the Samples |
There was a problem hiding this comment.
It would be nice to see some of the console output from the MCP tool and the console client.
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Maarten Balliauw <maarten@balliauw.be>
This is the documentation update for https://github.com/DuendeSoftware/customer-success/issues/864