Skip to content

Commit c465356

Browse files
authored
Merge pull request #1621 from sberyozkin/polish_secure_mcp_cmd_demo
More secure mcp cmd demo polishing
2 parents 2359925 + 0a84438 commit c465356

File tree

3 files changed

+17
-20
lines changed

3 files changed

+17
-20
lines changed

samples/secure-mcp-cmd-client-server/README.md

Lines changed: 12 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,14 @@
11
# Secure MCP command line client-server example using the SSE transport protocol with Keycloak and AI Gemini.
22

3-
This sample showcases how Quarkus MCP client can acquire OAuth2 client_credential grant tokens from Keycloak and use them to access secure Quarkus MCP server using the [SSE transport protocol](https://modelcontextprotocol.io/docs/concepts/transports#server-sent-events-sse) protocol.
3+
This sample showcases how Quarkus MCP client can acquire OAuth2 client_credentials grant tokens from Keycloak and use them to access secure Quarkus MCP server using the [SSE transport protocol](https://modelcontextprotocol.io/docs/concepts/transports#server-sent-events-sse) protocol.
44

5-
Quarkus MCP server gives the LLM a tool that can return a name of the logged-in user. AI Gemini uses this tool to create a poem about Java for the logged-in user.
6-
7-
# AI Gemini API key
8-
9-
Get [AI Gemini API key](https://aistudio.google.com/app/apikey). Use it to either set an `AI_GEMINI_API_KEY` environment property or update the `quarkus.langchain4j.ai.gemini.api-key=${ai_gemini_api_key}` property in `application.properties` by replacing `${ai_gemini_api_key}` with the API key value.
5+
Quarkus MCP server gives the LLM a tool that can return a name of the service account. AI Gemini uses this tool to include a service account name in a poem about Java.
106

117
# Running the sample in dev mode
128

139
### MCP server
1410

15-
Start the mcp server component in the `secure-mcp-server` directory using `mvn quarkus:dev`.
11+
Start the mcp server component in the `secure-mcp-cmd-server` directory using `mvn quarkus:dev`.
1612

1713
This will start the server on port 8080 and launch a Keycloak container on port 8081. Keycloak dev service creates a `quarkus` realm with a `quarkus-mcp-server` client.
1814

@@ -25,32 +21,32 @@ Keycloak `quarkus` realm configuration must be updated to support MCP server req
2521
Keycloak dev service has already created the `quarkus-mcp-server` client in the `quarkus` realm and is available on 8081 port. Go to `http://localhost:8081`, login as `admin:admin` and select the `quarkus` realm.
2622

2723
Create two more clients, `quarkus-mcp-client` that will represent Quarkus MCP client, and `quarkus-mcp-service` that will represent a protected REST server that the MCP `quarkus-mcp-server` server will call to complete the tool action.
28-
Make sure both client only have `Client Authentication` and `Service Accounts Roles` client capabilities enabled.
24+
Make sure both clients only have `Client Authentication` and `Service Accounts Roles` client capabilities enabled.
2925

3026
Copy the secret of the `quarkus-mcp-client`, you will need it later to run Quarkus MCP client.
3127

32-
Create two `Optional` client scopes, `quarkus-mcp-server-scope` and `quarkus-mcp-service-scope`, and create the `Audience` mapper for each of these scopes, selecting `quarkus-mcp-server` and `quarkus-mcp-client` clients as audiences respectively.
28+
Create two `Optional` client scopes, `quarkus-mcp-server-scope` and `quarkus-mcp-service-scope`, and create the `Audience` mapper for each of these scopes, selecting `quarkus-mcp-server` and `quarkus-mcp-client` clients as included client audiences respectively.
3329

3430
Add `Optional` `quarkus-mcp-server` client scope to the `quarkus-mcp-client` client and `Optional` `quarkus-mcp-service` client scope to the `quarkus-mcp-server` client.
3531

3632
Finally, update the `quarkus-mcp-server` capabilities to support `Standard Token Exchange`.
3733

38-
This Keycloak configuration enables Quarkus MCP client to request an access token that can be used to access the Quarkus MCP server only but not the protected REST server. It also allows Quarkus MCP server to exchange the token targeted at it for another token that will only be valid for accessing the protected REST server.
34+
This Keycloak configuration enables Quarkus MCP client to request an access token that can be used to access the Quarkus MCP server only. It also allows Quarkus MCP server to exchange the token targeted at it for another token that will only be valid for accessing the protected REST server.
3935

4036
### MCP Client
4137

42-
Make sure AI Gemini API key is available to the MCP client by exporting it as an environment property:
38+
Make sure the MCP server is started and the Keycloak configuration is done.
39+
40+
Get [AI Gemini API key](https://aistudio.google.com/app/apikey) and export it as an `AI_GEMINI_API_KEY` environment property:
4341

4442
```shell
45-
export ai_gemini_api_key=your_ai_gemini_api_key
43+
export AI_GEMINI_API_KEY=your_ai_gemini_api_key
4644
```
4745

48-
Also make sure the MCP server is started and the Keycloak configuration is done.
49-
50-
Export the Keycloak `quarkus-mcp-client` secret that you copied when configuring Keycloak as an environment property:
46+
Export the Keycloak `quarkus-mcp-client` secret that you copied when configuring Keycloak as an `OIDC_CLIENT_SECRET` environment property:
5147

5248
```shell
53-
export oidc_client_secret=keycloak_quarkus_mcp_client_secret
49+
export OIDC_CLIENT_SECRET=keycloak_quarkus_mcp_client_secret
5450
```
5551

5652
Package the application and run it:

samples/secure-mcp-cmd-client-server/secure-mcp-cmd-client/src/main/java/io/quarkiverse/langchain4j/sample/PoemService.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@
88
public interface PoemService {
99
@UserMessage("""
1010
Write a short 1 paragraph poem in {language} about a Java programming language.
11-
Please use the service account name when creating the poem.""")
11+
Provide a translation to English if the original poem language is not English.
12+
Dedicate the poem to the service account, refer to this account by its name.""")
1213
@McpToolBox("service-account-name")
1314
String writePoem(String language);
1415
}

samples/secure-mcp-cmd-client-server/secure-mcp-cmd-server/src/main/resources/application.properties

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# MCP server
2-
quarkus.mcp.server.server-info.name=User Name Provider
2+
quarkus.mcp.server.server-info.name=Service Account Name Provider
33
quarkus.mcp.server.traffic-logging.enabled=true
44
quarkus.mcp.server.traffic-logging.text-limit=1000
55

@@ -20,7 +20,7 @@ quarkus.keycloak.devservices.container-memory-limit=1250M
2020
quarkus.keycloak.devservices.image-name=quay.io/keycloak/keycloak:26.3.1
2121
quarkus.keycloak.devservices.port=8081
2222

23-
# MCP server tool uses REST Client to access a protected REST server to complete a user name request.
23+
# MCP server tool uses REST Client to access a protected REST server to complete a service account name request.
2424
# REST server expects tokens that contain a `quarkus-mcp-service` audience to prove they are intended for the REST server only.
2525
# Therefore, instead of propagating the token whose audience is this MCP `quarkus-mcp-server` server,
2626
# the token is exchanged to create a new token with the correct target audience set to `quarkus-mcp-service`.
@@ -39,7 +39,7 @@ quarkus.oidc-client.grant-options.exchange.subject_token_type=urn:ietf:params:oa
3939
# REST client which accesses a protected REST server, by propagating the exchanged token
4040
io.quarkiverse.langchain4j.sample.ServiceAccountNameRestClient/mp-rest/url=http://localhost:8080/service-account-name
4141

42-
# OIDC `user-name-service` tenant that secures a protected REST server.
42+
# OIDC `service-account-name-rest-server` tenant that secures a protected REST server.
4343
# It enforces that all tokens that reach it have a `quarkus-mcp-service` audience.
4444
quarkus.oidc.service-account-name-rest-server.auth-server-url=${quarkus.oidc.auth-server-url}
4545
quarkus.oidc.service-account-name-rest-server.token.audience=quarkus-mcp-service

0 commit comments

Comments
 (0)