From b8924ba10b2871c119bbaa473e24bafe39279d1a Mon Sep 17 00:00:00 2001 From: Art Berger Date: Tue, 17 Mar 2026 10:14:52 -0400 Subject: [PATCH 1/3] add connect time docs - enhance MCP auth docs with info about connect time - add tests Signed-off-by: Art Berger --- .../pages/agentgateway/mcp/mcp-auth-about.md | 18 +++- .../pages/agentgateway/mcp/mcp-auth-setup.md | 82 ++++++++++++++++++- assets/agw-docs/snippets/keycloak.md | 51 ++++++++++-- .../docs/kubernetes/latest/mcp/auth/setup.md | 12 +++ .../docs/kubernetes/main/mcp/auth/setup.md | 12 +++ .../docs/standalone/latest/mcp/mcp-authn.md | 2 + content/docs/standalone/main/mcp/mcp-authn.md | 2 + 7 files changed, 165 insertions(+), 14 deletions(-) diff --git a/assets/agw-docs/pages/agentgateway/mcp/mcp-auth-about.md b/assets/agw-docs/pages/agentgateway/mcp/mcp-auth-about.md index 1dc757a97..4ef321135 100644 --- a/assets/agw-docs/pages/agentgateway/mcp/mcp-auth-about.md +++ b/assets/agw-docs/pages/agentgateway/mcp/mcp-auth-about.md @@ -8,8 +8,16 @@ The MCP OAuth specification extends the standard OAuth 2.0 Authorization Code Fl ## Challenges +Learn about some common challenges with MCP auth. + +### Non-compliance to MCP OAuth spec {#non-compliance} + Most IdPs do not comply to the MCP OAuth specification and therefore do not expose the resource and authorization server metadata in a format that an MCP client can understand. Because of that, clients cannot dynamically register with the IdP to obtain their client ID. Instead, they must manually register with each IdP that they want to use. In cases where MCP clients, IdPs, and MCP servers are not in the same environment or are owned by different teams and organizations, pre-registration of clients can become unfeasible. +### Connect-time authentication {#connect-time} + +When MCP clients connect directly to remote MCP servers, each server handles its own OAuth independently. A developer working in an IDE like Cursor or Claude Code might have their agent call a tool, only for an OAuth pop-up to interrupt the session. The developer loses context, and faces another pop-up when the agent calls a tool on a different server. Each server might use a different identity provider, and none of them enforce corporate Single Sign-On (SSO). + ## Agentgateway to fill in the gaps Instead of pre-registering MCP clients, you can use agentgateway to register MCP clients dynamically with your IdP. The agentgateway proxy implements the MCP OAuth 2.0 specification, and can therefore facilitate the client registration process on behalf of the MCP client by translating the MCP OAuth information into configuration that the IdP understands. @@ -18,7 +26,7 @@ The MCP OAuth flow that is facilitated by the agentgateway proxy includes the fo 1. **Initialization**: In the initialization phase, the MCP client tries to connect to a protected MCP server. This connection fails with a 401 HTTP response. 2. **Discovery**: The MCP client discovers the OAuth authorization server that protects the MCP server and required scopes to access the MCP server by using agentgateway. 3. **Client registration**: The agentgateway proxy registers the client with the IdP and returns the client ID. -4. **Authentication**: The MCP client is redirected to the IdP for login. After successful login, the client receives a JWT access token. +4. **Authentication**: The MCP client is redirected to the IdP for login. After successful login, the client receives a JWT access token. This authentication happens at "connect time" with agentgateway, not each "request time" when the client calls a tool. 5. **MCP server access**: The client uses the JWT token to access the MCP server and its tools. Review the following diagram to learn about the steps that are involved in each phase: @@ -71,6 +79,14 @@ sequenceDiagram For more information, see the [JWT auth docs]({{< link-hextra path="/mcp/mcp-access/">}}). +### Benefits + +Agentgateway's approach provides the following benefits. + +- **No mid-session interruptions**: Tool calls succeed immediately because the client already authenticated when it connected. +- **Single sign-on**: One login through your enterprise IdP grants access to all MCP servers behind the gateway. +- **Consistent policy enforcement**: Authentication and authorization policies are applied uniformly at the gateway, rather than depending on each MCP server to implement its own security. + ## Setup Try out MCP auth with Keycloak and a sample MCP server. Start with [setting up Keycloak]({{< link-hextra path="/mcp/auth/keycloak/" >}}). diff --git a/assets/agw-docs/pages/agentgateway/mcp/mcp-auth-setup.md b/assets/agw-docs/pages/agentgateway/mcp/mcp-auth-setup.md index 1ddde08a8..de7874203 100644 --- a/assets/agw-docs/pages/agentgateway/mcp/mcp-auth-setup.md +++ b/assets/agw-docs/pages/agentgateway/mcp/mcp-auth-setup.md @@ -14,7 +14,7 @@ For more information, see the [JWT auth docs]({{< link-hextra path="/mcp/mcp-acc 2. Follow the steps to set up an [MCP server with a fetch tool]({{< link-hextra path="/mcp/static-mcp/" >}}). 3. Follow the steps to [set up Keycloak]({{< link-hextra path="/mcp/auth/keycloak/" >}}). 4. Install the experimental channel Gateway API. - ```sh + ```sh {paths="mcp-auth-setup"} kubectl apply --server-side -f https://github.com/kubernetes-sigs/gateway-api/releases/download/v{{< reuse "agw-docs/versions/k8s-gw-version.md" >}}/experimental-install.yaml ``` @@ -23,7 +23,7 @@ For more information, see the [JWT auth docs]({{< link-hextra path="/mcp/mcp-acc With Keycloak deployed and your MCP backend configured, you can now create an {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} that enforces authentication for the MCP backend. 1. Create an {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} with MCP authentication configuration. - ```yaml + ```yaml {paths="mcp-auth-setup"} kubectl apply -f - <}} kind: {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} @@ -87,12 +87,32 @@ With Keycloak deployed and your MCP backend configured, you can now create an {{ | `resourceMetadat.bearerMethodsSupported` | Methods to provide the bearer token when authenticating with the server. In this example, the bearer token can be provided as a header, query parameter, or as part of the body. | 2. Verify that the policy was accepted. - ```sh + ```sh {paths="mcp-auth-setup"} kubectl get {{< reuse "agw-docs/snippets/trafficpolicy.md" >}} mcp-echo-authn -o yaml ``` +{{< doc-test paths="mcp-auth-setup" >}} +YAMLTest -f - <<'EOF' +- name: wait for mcp-echo-authn policy to be accepted + wait: + target: + apiVersion: agentgateway.dev/v1alpha1 + kind: AgentgatewayPolicy + metadata: + namespace: default + name: mcp-echo-authn + jsonPath: "$.status.ancestors[0].conditions[?(@.type=='Accepted')].status" + jsonPathExpectation: + comparator: equals + value: "True" + polling: + timeoutSeconds: 60 + intervalSeconds: 2 +EOF +{{< /doc-test >}} + 3. Update the HTTPRoute that routes incoming traffic to the MCP server to include the discovery paths for the MCP resource and authorization server. This way, the agentgateway proxy can retrieve the resource and authorization server metadata during the MCP auth flow. - ```yaml + ```yaml {paths="mcp-auth-setup"} kubectl apply -f - <}} +YAMLTest -f - <<'EOF' +- name: wait for mcp HTTPRoute to be accepted + wait: + target: + kind: HTTPRoute + metadata: + namespace: default + name: mcp + jsonPath: "$.status.parents[0].conditions[?(@.type=='Accepted')].status" + jsonPathExpectation: + comparator: equals + value: "True" + polling: + timeoutSeconds: 60 + intervalSeconds: 2 +- name: unauthenticated MCP request returns 401 (connect-time auth enforced) + http: + url: "http://${INGRESS_GW_ADDRESS}:80/mcp" + method: GET + source: + type: local + expect: + statusCode: 401 + headers: + - name: www-authenticate + comparator: contains + value: resource_metadata + retries: 3 +- name: resource metadata discovery returns 200 + http: + url: "http://${INGRESS_GW_ADDRESS}:80/.well-known/oauth-protected-resource/mcp" + method: GET + source: + type: local + expect: + statusCode: 200 + bodyJsonPath: + - path: "$.resource" + comparator: contains + value: "/mcp" + retries: 3 +EOF +{{< /doc-test >}} + ## Verify MCP auth 1. Open the MCP inspector. @@ -197,6 +262,15 @@ With Keycloak deployed and your MCP backend configured, you can now create an {{ {{< reuse-image src="img/oauth-connect-to-server.png" >}} {{< reuse-image-dark srcDark="img/oauth-connect-to-server-dark.png" >}} +5. Verify that tool calls work without re-authentication. Because the client authenticates at connect time, tool calls succeed immediately without any additional login prompts. + 1. From the menu bar, click the **Tools** tab. + 2. Click **List Tools** and select the `fetch` tool. + 3. In the **url** field, enter a website URL, such as `https://example.com/`. + 4. Click **Run Tool**. + 5. Verify that the tool call succeeds and returns the fetched content. No additional authentication is required because the token from the initial connection is reused for all tool calls within the session. + + {{< reuse-image src="img/mcp-inspector-fetch.png" >}} + {{< reuse-image-dark srcDark="img/mcp-inspector-fetch-dark.png" >}} ## Clean up diff --git a/assets/agw-docs/snippets/keycloak.md b/assets/agw-docs/snippets/keycloak.md index 963e1c8f9..f0fabfecd 100644 --- a/assets/agw-docs/snippets/keycloak.md +++ b/assets/agw-docs/snippets/keycloak.md @@ -9,19 +9,52 @@ The following steps install Keycloak in your cluster, and configure two user cre Install and configure Keycloak: 1. Create a namespace for your Keycloak deployment. - ```shell + ```shell {paths="setup-keycloak"} kubectl create namespace keycloak ``` 2. Create the Keycloak deployment. - ```shell + ```shell {paths="setup-keycloak"} kubectl -n keycloak apply -f https://raw.githubusercontent.com/solo-io/gloo-mesh-use-cases/main/policy-demo/oidc/keycloak.yaml ``` 3. Wait for the Keycloak rollout to finish. - ```shell + ```shell {paths="setup-keycloak"} kubectl -n keycloak rollout status deploy/keycloak ``` + +{{< doc-test paths="setup-keycloak" >}} +YAMLTest -f - <<'EOF' +- name: wait for keycloak deployment to be ready + wait: + target: + kind: Deployment + metadata: + namespace: keycloak + name: keycloak + jsonPath: "$.status.availableReplicas" + jsonPathExpectation: + comparator: greaterThan + value: 0 + polling: + timeoutSeconds: 120 + intervalSeconds: 5 +- name: wait for keycloak service LB address + wait: + target: + kind: Service + metadata: + namespace: keycloak + name: keycloak + jsonPath: "$.status.loadBalancer.ingress[0].ip" + jsonPathExpectation: + comparator: exists + polling: + timeoutSeconds: 300 + intervalSeconds: 5 +EOF +{{< /doc-test >}} + 4. Set the Keycloak endpoint details from the load balancer service. If you are running locally in kind and need a local IP address for the load balancer service, consider using [`cloud-provider-kind`](https://github.com/kubernetes-sigs/cloud-provider-kind). - ```shell + ```shell {paths="setup-keycloak"} export ENDPOINT_KEYCLOAK=$(kubectl -n keycloak get service keycloak -o jsonpath='{.status.loadBalancer.ingress[0].ip}{.status.loadBalancer.ingress[0].hostname}'):8080 export HOST_KEYCLOAK=$(echo ${ENDPOINT_KEYCLOAK} | cut -d: -f1) export PORT_KEYCLOAK=$(echo ${ENDPOINT_KEYCLOAK} | cut -d: -f2) @@ -29,13 +62,13 @@ Install and configure Keycloak: echo $KEYCLOAK_URL ``` 5. Set the Keycloak admin token. If you see a parsing error, try running the `curl` command by itself. You might notice that your internet provider or network rules are blocking the requests. If so, you can update your security settings or change the network so that the request can be processed. - ```shell + ```shell {paths="setup-keycloak"} export KEYCLOAK_TOKEN=$(curl -d "client_id=admin-cli" -d "username=admin" -d "password=admin" -d "grant_type=password" "$KEYCLOAK_URL/realms/master/protocol/openid-connect/token" | jq -r .access_token) echo $KEYCLOAK_TOKEN ``` 6. Use the admin token to configure Keycloak with the two users for testing purposes. If you get a `401 Unauthorized` error, run the previous command and try again. - ```shell + ```shell {paths="setup-keycloak"} # Create initial token to register the client read -r client token <<<$(curl -H "Authorization: Bearer ${KEYCLOAK_TOKEN}" -X POST -H "Content-Type: application/json" -d '{"expiration": 0, "count": 1}' $KEYCLOAK_URL/admin/realms/master/clients-initial-access | jq -r '[.id, .token] | @tsv') export KEYCLOAK_CLIENT=${client} @@ -107,7 +140,7 @@ You might integrate OIDC with your apps. In such cases, you might need particula The following instructions assume that you are still logged into the **Administration Console** from the previous step. 1. Confirm that you have the following environmental variables set. If not, refer to [Step 1: Install Keycloak](#install) section. - ```shell + ```shell {paths="setup-keycloak"} echo $KEYCLOAK_URL ``` @@ -115,10 +148,10 @@ The following instructions assume that you are still logged into the **Administr 1. From the sidebar menu options, click **Realm Settings**. 2. From the **General** tab, scroll down to the **Endpoints** section and open the **OpenID Endpoint Configuration** link. In a new tab, your browser opens to a URL similar to `http://$KEYCLOAK_URL:8080/realms/master/.well-known/openid-configuration`. 3. In the OpenID configuration, search for the `issuer` field. Save the value as an environment variable, such as the following example. - ```sh + ```sh {paths="setup-keycloak"} export KEYCLOAK_ISSUER=$KEYCLOAK_URL/realms/master ``` 4. In the OpenID configuration, search for the `jwks_uri` field, and copy the path without the Keycloak URL that you retrieved earlier. For example, the path might be set to `/realms/master/protocol/openid-connect/certs`. - ```shell + ```shell {paths="setup-keycloak"} export KEYCLOAK_JWKS_PATH=/realms/master/protocol/openid-connect/certs ``` \ No newline at end of file diff --git a/content/docs/kubernetes/latest/mcp/auth/setup.md b/content/docs/kubernetes/latest/mcp/auth/setup.md index 75e78a810..0d92b285d 100644 --- a/content/docs/kubernetes/latest/mcp/auth/setup.md +++ b/content/docs/kubernetes/latest/mcp/auth/setup.md @@ -1,6 +1,18 @@ --- title: Set up MCP auth weight: 40 +test: + mcp-auth-setup: + - file: content/docs/kubernetes/latest/install/helm.md + path: standard + - file: content/docs/kubernetes/latest/setup/gateway.md + path: all + - file: content/docs/kubernetes/latest/mcp/static-mcp.md + path: setup-mcp-server + - file: content/docs/kubernetes/latest/mcp/auth/keycloak.md + path: setup-keycloak + - file: content/docs/kubernetes/latest/mcp/auth/setup.md + path: mcp-auth-setup --- {{< reuse "agw-docs/pages/agentgateway/mcp/mcp-auth-setup.md" >}} diff --git a/content/docs/kubernetes/main/mcp/auth/setup.md b/content/docs/kubernetes/main/mcp/auth/setup.md index 75e78a810..1ad1df287 100644 --- a/content/docs/kubernetes/main/mcp/auth/setup.md +++ b/content/docs/kubernetes/main/mcp/auth/setup.md @@ -1,6 +1,18 @@ --- title: Set up MCP auth weight: 40 +test: + mcp-auth-setup: + - file: content/docs/kubernetes/main/install/helm.md + path: experimental + - file: content/docs/kubernetes/main/setup/gateway.md + path: all + - file: content/docs/kubernetes/main/mcp/static-mcp.md + path: setup-mcp-server + - file: content/docs/kubernetes/main/mcp/auth/keycloak.md + path: setup-keycloak + - file: content/docs/kubernetes/main/mcp/auth/setup.md + path: mcp-auth-setup --- {{< reuse "agw-docs/pages/agentgateway/mcp/mcp-auth-setup.md" >}} diff --git a/content/docs/standalone/latest/mcp/mcp-authn.md b/content/docs/standalone/latest/mcp/mcp-authn.md index e72aabfb8..1cff51945 100644 --- a/content/docs/standalone/latest/mcp/mcp-authn.md +++ b/content/docs/standalone/latest/mcp/mcp-authn.md @@ -9,6 +9,8 @@ prev: /mcp/connect MCP authentication enables OAuth 2.0 protection for MCP servers, helping to implement the [MCP Authorization specification](https://modelcontextprotocol.io/specification/draft/basic/authorization). Agentgateway can act as a resource server, validating JWT tokens and exposing protected resource metadata. +MCP authentication uses a connect-time model: the OAuth flow happens once when the client first connects, not on each tool call. After the initial authentication, the access token is reused for all subsequent requests within the session. For more information, see [About MCP auth]({{< link-hextra path="/mcp/auth/about/" >}}). + There are three deployment scenarios. ## Authorization Server Proxy diff --git a/content/docs/standalone/main/mcp/mcp-authn.md b/content/docs/standalone/main/mcp/mcp-authn.md index e72aabfb8..1cff51945 100644 --- a/content/docs/standalone/main/mcp/mcp-authn.md +++ b/content/docs/standalone/main/mcp/mcp-authn.md @@ -9,6 +9,8 @@ prev: /mcp/connect MCP authentication enables OAuth 2.0 protection for MCP servers, helping to implement the [MCP Authorization specification](https://modelcontextprotocol.io/specification/draft/basic/authorization). Agentgateway can act as a resource server, validating JWT tokens and exposing protected resource metadata. +MCP authentication uses a connect-time model: the OAuth flow happens once when the client first connects, not on each tool call. After the initial authentication, the access token is reused for all subsequent requests within the session. For more information, see [About MCP auth]({{< link-hextra path="/mcp/auth/about/" >}}). + There are three deployment scenarios. ## Authorization Server Proxy From 550797214adbdc2bbeb6d648c36489b2f231c9ed Mon Sep 17 00:00:00 2001 From: Art Berger Date: Tue, 17 Mar 2026 10:16:49 -0400 Subject: [PATCH 2/3] add eager auth keyword Signed-off-by: Art Berger --- assets/agw-docs/pages/agentgateway/mcp/mcp-auth-about.md | 2 +- content/docs/standalone/latest/mcp/mcp-authn.md | 2 +- content/docs/standalone/main/mcp/mcp-authn.md | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/assets/agw-docs/pages/agentgateway/mcp/mcp-auth-about.md b/assets/agw-docs/pages/agentgateway/mcp/mcp-auth-about.md index 4ef321135..1cb822549 100644 --- a/assets/agw-docs/pages/agentgateway/mcp/mcp-auth-about.md +++ b/assets/agw-docs/pages/agentgateway/mcp/mcp-auth-about.md @@ -26,7 +26,7 @@ The MCP OAuth flow that is facilitated by the agentgateway proxy includes the fo 1. **Initialization**: In the initialization phase, the MCP client tries to connect to a protected MCP server. This connection fails with a 401 HTTP response. 2. **Discovery**: The MCP client discovers the OAuth authorization server that protects the MCP server and required scopes to access the MCP server by using agentgateway. 3. **Client registration**: The agentgateway proxy registers the client with the IdP and returns the client ID. -4. **Authentication**: The MCP client is redirected to the IdP for login. After successful login, the client receives a JWT access token. This authentication happens at "connect time" with agentgateway, not each "request time" when the client calls a tool. +4. **Authentication**: The MCP client is redirected to the IdP for login. After successful login, the client receives a JWT access token. This authentication happens at "connect time" with agentgateway, not each "request time" when the client calls a tool. This type of connection is sometimes called "eager auth." 5. **MCP server access**: The client uses the JWT token to access the MCP server and its tools. Review the following diagram to learn about the steps that are involved in each phase: diff --git a/content/docs/standalone/latest/mcp/mcp-authn.md b/content/docs/standalone/latest/mcp/mcp-authn.md index 1cff51945..5d4e006a7 100644 --- a/content/docs/standalone/latest/mcp/mcp-authn.md +++ b/content/docs/standalone/latest/mcp/mcp-authn.md @@ -9,7 +9,7 @@ prev: /mcp/connect MCP authentication enables OAuth 2.0 protection for MCP servers, helping to implement the [MCP Authorization specification](https://modelcontextprotocol.io/specification/draft/basic/authorization). Agentgateway can act as a resource server, validating JWT tokens and exposing protected resource metadata. -MCP authentication uses a connect-time model: the OAuth flow happens once when the client first connects, not on each tool call. After the initial authentication, the access token is reused for all subsequent requests within the session. For more information, see [About MCP auth]({{< link-hextra path="/mcp/auth/about/" >}}). +MCP authentication uses a connect-time model: the OAuth flow happens once when the client first connects, not on each tool call. This type of connection is sometimes called "eager auth." After the initial authentication, the access token is reused for all subsequent requests within the session. For more information, see [About MCP auth]({{< link-hextra path="/mcp/auth/about/" >}}). There are three deployment scenarios. diff --git a/content/docs/standalone/main/mcp/mcp-authn.md b/content/docs/standalone/main/mcp/mcp-authn.md index 1cff51945..5d4e006a7 100644 --- a/content/docs/standalone/main/mcp/mcp-authn.md +++ b/content/docs/standalone/main/mcp/mcp-authn.md @@ -9,7 +9,7 @@ prev: /mcp/connect MCP authentication enables OAuth 2.0 protection for MCP servers, helping to implement the [MCP Authorization specification](https://modelcontextprotocol.io/specification/draft/basic/authorization). Agentgateway can act as a resource server, validating JWT tokens and exposing protected resource metadata. -MCP authentication uses a connect-time model: the OAuth flow happens once when the client first connects, not on each tool call. After the initial authentication, the access token is reused for all subsequent requests within the session. For more information, see [About MCP auth]({{< link-hextra path="/mcp/auth/about/" >}}). +MCP authentication uses a connect-time model: the OAuth flow happens once when the client first connects, not on each tool call. This type of connection is sometimes called "eager auth." After the initial authentication, the access token is reused for all subsequent requests within the session. For more information, see [About MCP auth]({{< link-hextra path="/mcp/auth/about/" >}}). There are three deployment scenarios. From c58d560bce656c06f596054c8a0516102f88e59d Mon Sep 17 00:00:00 2001 From: Art Berger Date: Tue, 17 Mar 2026 10:28:40 -0400 Subject: [PATCH 3/3] standalone Signed-off-by: Art Berger --- content/docs/kubernetes/latest/mcp/auth/setup.md | 2 +- .../docs/standalone/latest/configuration/security/mcp-authn.md | 2 ++ .../docs/standalone/main/configuration/security/mcp-authn.md | 2 ++ 3 files changed, 5 insertions(+), 1 deletion(-) diff --git a/content/docs/kubernetes/latest/mcp/auth/setup.md b/content/docs/kubernetes/latest/mcp/auth/setup.md index 0d92b285d..59767534e 100644 --- a/content/docs/kubernetes/latest/mcp/auth/setup.md +++ b/content/docs/kubernetes/latest/mcp/auth/setup.md @@ -4,7 +4,7 @@ weight: 40 test: mcp-auth-setup: - file: content/docs/kubernetes/latest/install/helm.md - path: standard + path: experimental - file: content/docs/kubernetes/latest/setup/gateway.md path: all - file: content/docs/kubernetes/latest/mcp/static-mcp.md diff --git a/content/docs/standalone/latest/configuration/security/mcp-authn.md b/content/docs/standalone/latest/configuration/security/mcp-authn.md index 4a0954803..2b637ee63 100644 --- a/content/docs/standalone/latest/configuration/security/mcp-authn.md +++ b/content/docs/standalone/latest/configuration/security/mcp-authn.md @@ -8,6 +8,8 @@ Attach to: MCP authentication enables OAuth 2.0 protection for MCP servers, helping to implement the [MCP Authorization specification](https://modelcontextprotocol.io/specification/draft/basic/authorization). Agentgateway can act as a resource server, validating JWT tokens and exposing protected resource metadata. +MCP authentication uses a connect-time model: the OAuth flow happens once when the client first connects, not on each tool call. After the initial authentication, the access token is reused for all subsequent requests within the session. + > [!NOTE] > {{< reuse "agw-docs/snippets/mcp-policy-note.md" >}} diff --git a/content/docs/standalone/main/configuration/security/mcp-authn.md b/content/docs/standalone/main/configuration/security/mcp-authn.md index 4a0954803..2b637ee63 100644 --- a/content/docs/standalone/main/configuration/security/mcp-authn.md +++ b/content/docs/standalone/main/configuration/security/mcp-authn.md @@ -8,6 +8,8 @@ Attach to: MCP authentication enables OAuth 2.0 protection for MCP servers, helping to implement the [MCP Authorization specification](https://modelcontextprotocol.io/specification/draft/basic/authorization). Agentgateway can act as a resource server, validating JWT tokens and exposing protected resource metadata. +MCP authentication uses a connect-time model: the OAuth flow happens once when the client first connects, not on each tool call. After the initial authentication, the access token is reused for all subsequent requests within the session. + > [!NOTE] > {{< reuse "agw-docs/snippets/mcp-policy-note.md" >}}