From bbe2448bb3d90459070659ae342f1052e150053f Mon Sep 17 00:00:00 2001 From: Liam Sommer Date: Tue, 20 Oct 2026 16:34:07 +0200 Subject: [PATCH 1/2] SAS-2301: added OAuth information to MCP Server docs --- .../genai/v2/reference-guide/agent-editor.md | 4 +- .../reference-guide/mcp-modules/mcp-server.md | 45 +++++++++++++++++++ 2 files changed, 48 insertions(+), 1 deletion(-) diff --git a/content/en/docs/genai/v2/reference-guide/agent-editor.md b/content/en/docs/genai/v2/reference-guide/agent-editor.md index 4e640ed1a05..e282aad906c 100644 --- a/content/en/docs/genai/v2/reference-guide/agent-editor.md +++ b/content/en/docs/genai/v2/reference-guide/agent-editor.md @@ -299,7 +299,9 @@ In the published MCP service document, configure the following fields: * **Version**: Enter a version for the MCP service in semantic versioning format. This defaults to `1.0.0`. * **Endpoint**: Enter the path to append to the app URL. External MCP clients use this endpoint to connect to the service. The endpoint path may only contain lowercase letters, numbers, hyphens, underscores, and forward slashes. * **Protocol version**: Select the MCP protocol version that connecting clients must support. This defaults to `v2025_03_26`. -* **Requires authentication**: Select whether MCP clients must be authenticated. Mendix recommends setting up authentication if the Mendix application is reachable outside of your local environment. If set to **No**, the MCP service is accessible to anyone without authentication. When authentication is required, select a microflow that authenticates incoming requests. The microflow input can only be `System.HttpRequest` and/or `MCPServer.MCcperver`, and its output must be `System.User`. Return empty if authentication fails. +* **Requires authentication**: Select whether MCP clients must be authenticated. Mendix recommends setting up authentication if the Mendix application is reachable outside of your local environment. If set to **No**, the MCP service is accessible to anyone without authentication. When authentication is required, select a microflow that authenticates incoming requests. The microflow input can only be `System.HttpRequest` and/or `MCPServer.McpServer`, and its output must be `System.User`. Return empty if authentication fails. +* **Authorization server URL**: Optionally, when authentication is required, enter the issuer URL of the OAuth authorization server where MCP clients obtain access tokens. Your authentication microflow must validate the tokens. For more information, see [Enable OAuth](/agents/agents-kit-2/reference-guide/mcp-modules/mcp-server/#oauth) in the MCP Server module documentation. +* **Scopes**: Optionally, when an authorization server URL is set, enter the scopes that MCP clients should request, separated by spaces. To add tools, click **New** in the **Tools** section and configure the following fields: diff --git a/content/en/docs/genai/v2/reference-guide/mcp-modules/mcp-server.md b/content/en/docs/genai/v2/reference-guide/mcp-modules/mcp-server.md index 1ec484c0bc9..2e91c469df4 100644 --- a/content/en/docs/genai/v2/reference-guide/mcp-modules/mcp-server.md +++ b/content/en/docs/genai/v2/reference-guide/mcp-modules/mcp-server.md @@ -78,6 +78,35 @@ Within your microflow, you can implement your custom logic to authenticate the u The `User` returned in the microflow is used for all subsequent prompt and tool microflows within the same session. This makes the `currentUser` and `currentSession` variables available, allowing you to apply entity access for user-based access control based on the default Mendix entity access settings. +If authentication fails, return empty instead of throwing an error. An empty return value results in a `401 Unauthorized` response, while an error results in a `500 Internal Server Error` response. + +#### Enable OAuth {#oauth} + +MCP clients that support [MCP authorization](https://modelcontextprotocol.io/specification/2025-11-25/basic/authorization), such as Visual Studio Code, can sign in users at an OAuth 2.0 authorization server (identity provider) and send the access token to the MCP Server. To let clients discover where to obtain a token, set the following optional parameters in the `Create MCP Server` action: + +* `AuthorizationServerUrl`: The issuer URL of the authorization server, for example, `https://login.microsoftonline.com//v2.0` for Microsoft Entra ID. This parameter requires an authentication microflow. +* `Scopes` (optional): The scopes that clients should request, separated by spaces, for example, `openid email`. This parameter requires `AuthorizationServerUrl`. Mendix recommends setting it, because without it, many clients request all scopes that the authorization server offers, which the authorization server may reject. + +When `AuthorizationServerUrl` is set, the MCP Server does the following: + +* It publishes [Protected Resource Metadata (RFC 9728)](https://datatracker.ietf.org/doc/html/rfc9728#name-protected-resource-metadata) at `//.well-known/oauth-protected-resource`. The metadata contains the MCP endpoint as `resource`, the authorization server, the scopes, and the server name. +* It adds a `WWW-Authenticate` header to `401 Unauthorized` responses. The header refers to the metadata URL and includes the scopes. + +The MCP Server module does not validate access tokens itself. Your authentication microflow must do this for every request: + +1. Read the `Authorization` header from `System.HttpRequest`. If it is missing return empty, so that the client starts the sign-in flow. +2. Validate the token. Depending on the authorization server, you can do this in one of the following ways: + * Call the token introspection endpoint ([RFC 7662](https://datatracker.ietf.org/doc/html/rfc7662#section-2)) of the authorization server, for example, with a **Call REST service** activity. + * Use the [OIDC SSO](/appstore/modules/oidc/) module, which supports validating tokens against the signing keys of the authorization server. This is required for authorization servers without an introspection endpoint, such as Microsoft Entra ID. For example use the `DecodeVerifyJWTPlainText` action to verify and get the JWT token. Note that the `APIAuthentication` action is currently not supported when called from the MCP Server module. +3. Check that the token is active and not expired, and that the audience (`aud`) is the value that the authorization server issues for your MCP Server. Otherwise, your MCP Server accepts tokens that were issued for other applications. Based on your requirements, check other fields such as scopes or issuer. +4. Return the `System.User` that belongs to the token, for example, by retrieving the user by name based on the `preferred_username` claim or creating a new user. + +{{% alert color="info" %}} +The authentication microflow runs for every request, including several requests when the client connects. If your microflow calls an external service, such as an introspection endpoint, consider the additional response time or implement custom logic for expiry state management. +{{% /alert %}} + +The MCP client must be registered at the authorization server. Clients use [dynamic client registration](https://datatracker.ietf.org/doc/html/rfc7591) if the authorization server allows it. Otherwise, register the client at the authorization server and enter its client ID in the MCP client when asked. + #### Protocol Version When creating an MCP server, you need to specify a `ProtocolVersion`. On the official MCP documentation, you can review the differences between the protocol versions in the [changelog](https://modelcontextprotocol.io/specification/2025-03-26/changelog). The latest version of the MCP Server module only supports `v2025-03-26` and the Streamable HTTP transport. MCP clients that need to connect to a Mendix MCP server must support the same version. Note that Mendix follows the offered capabilities of the MCP Java SDK. @@ -138,6 +167,22 @@ Remove-Item -Path "$env:LocalAppData\npm-cache\_npx" -Recurse -Force npm cache clean --force ``` +### MCP Client Does Not Start the OAuth Sign-In + +If the client receives a `401 Unauthorized` response but does not start the sign-in flow, check the following: + +* `AuthorizationServerUrl` is set and the MCP server was restarted afterward. The metadata URL `//.well-known/oauth-protected-resource` must return the authorization server. +* The authentication microflow returns empty instead of throwing an error when no valid token is sent. +* The client configuration does not contain a fixed `Authorization` header, which would be sent instead of the OAuth token. + +### Authorization Server Rejects the Sign-In + +If the authorization server reports invalid scopes, set the `Scopes` parameter of the `Create MCP Server` action, so that the client only requests these scopes. Make sure that the scopes are assigned to the client at the authorization server. + +### Microsoft Entra ID Error `AADSTS9010010` {#entra-id} + +If Microsoft Entra ID rejects the request with error `AADSTS9010010: the resource parameter provided in the request doesn't match with the requested scopes.`, then the `resource` parameter ([RFC 8707](https://datatracker.ietf.org/doc/html/rfc8707#name-resource-parameter)) does not match the Application ID URI of the scope. To avoid this, set in the Azure portal the Application ID URI to the MCP endpoint, for example, `https://mymendixapp.com//mcp`. This requires that the domain of your app is a verified domain in your tenant. + ### Conflicted Lib Error After Module Import If you encounter an error caused by conflicting Java libraries, such as `java.lang.NoSuchMethodError: 'com.fasterxml.jackson.annotation.OptBoolean com.fasterxml.jackson.annotation.JsonProperty.isRequired()'`, try synchronizing all dependencies (**App** > **Synchronize dependencies**) and then restart your application. From 9a4f83aad62679597865c556f09b4d9f76466d47 Mon Sep 17 00:00:00 2001 From: linaaaf <90840263+linaaaf@users.noreply.github.com> Date: Wed, 21 Oct 2026 17:24:45 +0200 Subject: [PATCH 2/2] Small text change For better readability --- .../en/docs/genai/v2/reference-guide/mcp-modules/mcp-server.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/en/docs/genai/v2/reference-guide/mcp-modules/mcp-server.md b/content/en/docs/genai/v2/reference-guide/mcp-modules/mcp-server.md index 2e91c469df4..d5d7eaea86a 100644 --- a/content/en/docs/genai/v2/reference-guide/mcp-modules/mcp-server.md +++ b/content/en/docs/genai/v2/reference-guide/mcp-modules/mcp-server.md @@ -94,7 +94,7 @@ When `AuthorizationServerUrl` is set, the MCP Server does the following: The MCP Server module does not validate access tokens itself. Your authentication microflow must do this for every request: -1. Read the `Authorization` header from `System.HttpRequest`. If it is missing return empty, so that the client starts the sign-in flow. +1. Read the `Authorization` header from `System.HttpRequest`. If missing, return empty to initiate the client sign-in flow. 2. Validate the token. Depending on the authorization server, you can do this in one of the following ways: * Call the token introspection endpoint ([RFC 7662](https://datatracker.ietf.org/doc/html/rfc7662#section-2)) of the authorization server, for example, with a **Call REST service** activity. * Use the [OIDC SSO](/appstore/modules/oidc/) module, which supports validating tokens against the signing keys of the authorization server. This is required for authorization servers without an introspection endpoint, such as Microsoft Entra ID. For example use the `DecodeVerifyJWTPlainText` action to verify and get the JWT token. Note that the `APIAuthentication` action is currently not supported when called from the MCP Server module.