Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
64 commits
Select commit Hold shift + click to select a range
282da21
Re-format example config files to make diff more apparent
AnuradhaKaruppiah Sep 3, 2025
7c7442f
Initial changes in NAT to enable Protected MCP Server
AnuradhaKaruppiah Sep 3, 2025
11a9fd3
Minor docs enhancements
AnuradhaKaruppiah Sep 4, 2025
6ae33b6
Add a stub token verifier on the server side
AnuradhaKaruppiah Sep 5, 2025
883c3f8
Add auth config to the MCP client
AnuradhaKaruppiah Sep 5, 2025
47a2a77
Document the client and server auth config options
AnuradhaKaruppiah Sep 5, 2025
b694fff
Add notes on how client discovery happens
AnuradhaKaruppiah Sep 5, 2025
ef1740e
Minor doc updates
AnuradhaKaruppiah Sep 5, 2025
b905bda
Merge remote-tracking branch 'upstream/develop' into ak-mcp-auth
AnuradhaKaruppiah Sep 8, 2025
183dfc4
Update docs with AuthenticationRef
AnuradhaKaruppiah Sep 9, 2025
69b771e
Move MCP auth config to AuthenticationRef
AnuradhaKaruppiah Sep 9, 2025
bc5ae77
Merge remote-tracking branch 'upstream/develop' into ak-mcp-auth
AnuradhaKaruppiah Sep 9, 2025
8574a57
Add sample mcp auth config file
AnuradhaKaruppiah Sep 10, 2025
e070756
Config fixup
AnuradhaKaruppiah Sep 10, 2025
f137c73
Setup MCP session without auth for dynamic tool discovery
AnuradhaKaruppiah Sep 10, 2025
3bac053
Remove auth session from exit stack for now
AnuradhaKaruppiah Sep 10, 2025
4d779f3
Use httpx Auth for intercepting HTTP requests and adding the header
AnuradhaKaruppiah Sep 10, 2025
a434bdd
Enable auth for tool calls only
AnuradhaKaruppiah Sep 10, 2025
2e2a1cb
Drop auth session
AnuradhaKaruppiah Sep 10, 2025
5393fef
Remove auth support for SSE
AnuradhaKaruppiah Sep 10, 2025
218eb0a
Move MCP schema to model conversion code to an utils file
AnuradhaKaruppiah Sep 10, 2025
5975595
Update tool the in the mcp auth example
AnuradhaKaruppiah Sep 11, 2025
cec64da
Drop unnecessary NAT prefix from the class name
AnuradhaKaruppiah Sep 11, 2025
81e35cd
Refactor mcp-oauth2 files
AnuradhaKaruppiah Sep 12, 2025
323c142
Add MCP server in the Auth provider config
AnuradhaKaruppiah Sep 12, 2025
9c02c0a
Add a new MCP oauth2 provider
AnuradhaKaruppiah Sep 15, 2025
e9ffa4d
Minor fixups
AnuradhaKaruppiah Sep 16, 2025
d3011ad
Merge remote-tracking branch 'upstream/develop' into ak-mcp-auth
AnuradhaKaruppiah Sep 16, 2025
cf66e19
Some more fixes needed here
AnuradhaKaruppiah Sep 16, 2025
1250a6d
Move to using pydantic models defined in mcp auth.py
AnuradhaKaruppiah Sep 16, 2025
6360e8e
Add an option to effective scopes from the auth server
AnuradhaKaruppiah Sep 16, 2025
373e773
Add a lock for discovery, DCR and deletgate building
AnuradhaKaruppiah Sep 16, 2025
65cb9ed
Add unncessary key comp
AnuradhaKaruppiah Sep 16, 2025
2c9553c
Minor fixups
AnuradhaKaruppiah Sep 16, 2025
089f424
Rename auth provider files for consistency
AnuradhaKaruppiah Sep 16, 2025
a205310
Misc fixes for problems found during testing
AnuradhaKaruppiah Sep 16, 2025
d1500c6
Merge remote-tracking branch 'upstream/develop' into ak-mcp-auth
AnuradhaKaruppiah Sep 16, 2025
6e92f94
Update the MCP auth scratch pad
AnuradhaKaruppiah Sep 16, 2025
10e8789
Add a Dockerfile for launching the example auth server
AnuradhaKaruppiah Sep 16, 2025
79bd88c
Add notes in mcp-auth.md
AnuradhaKaruppiah Sep 16, 2025
89d03cd
Update MCP version to the latest
AnuradhaKaruppiah Sep 16, 2025
b9d3384
Update uv lock
AnuradhaKaruppiah Sep 16, 2025
c7bf652
Rename math servers to indicate they are protected
AnuradhaKaruppiah Sep 16, 2025
7822952
Update comments to indicate that this is a protected MCP server
AnuradhaKaruppiah Sep 16, 2025
718255e
Drop helper method from the authenticate model
AnuradhaKaruppiah Sep 16, 2025
d7a5351
Merge remote-tracking branch 'upstream/develop' into ak-mcp-auth
AnuradhaKaruppiah Sep 16, 2025
4ac39b7
Misc fixups
AnuradhaKaruppiah Sep 16, 2025
5b4eacd
Basic unit tests to catch breakages during auth dev
AnuradhaKaruppiah Sep 17, 2025
739688c
Style fixes
AnuradhaKaruppiah Sep 17, 2025
f4b59a0
More style fixes
AnuradhaKaruppiah Sep 17, 2025
f3cc020
Fix spelling
AnuradhaKaruppiah Sep 17, 2025
01568e8
Style fixes
AnuradhaKaruppiah Sep 17, 2025
9a68f00
Fix docs build
AnuradhaKaruppiah Sep 17, 2025
e4ab888
Pass auth request via provider config
AnuradhaKaruppiah Sep 17, 2025
90a2107
Update unit tests to match the src changes
AnuradhaKaruppiah Sep 17, 2025
eea3135
Remove auth request from the oauth2 flow provider
AnuradhaKaruppiah Sep 17, 2025
2a9bd97
Drop unnecessarty cleanup
AnuradhaKaruppiah Sep 17, 2025
7c59f86
Test fixup in response to review comments
AnuradhaKaruppiah Sep 17, 2025
2b071be
Ensure auth_server_url is configured when require_auth is specified
AnuradhaKaruppiah Sep 17, 2025
8b5d908
Add todo comments
AnuradhaKaruppiah Sep 17, 2025
daf300c
Don't yield the response on retry
AnuradhaKaruppiah Sep 17, 2025
e26c24c
Merge remote-tracking branch 'upstream/develop' into ak-mcp-auth
AnuradhaKaruppiah Sep 17, 2025
711ae67
Add tests to increase code coverage
AnuradhaKaruppiah Sep 17, 2025
e075842
Drop some superfluos tests
AnuradhaKaruppiah Sep 17, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/source/workflows/mcp/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,4 +29,5 @@ NeMo Agent toolkit [Model Context Protocol (MCP)](https://modelcontextprotocol.i

Connecting to Remote Tools <./mcp-client.md>
Serving NeMo Agent toolkit Functions <./mcp-server.md>
Authentication with MCP <./mcp-auth.md>
```
50 changes: 50 additions & 0 deletions docs/source/workflows/mcp/mcp-auth.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
<!--
SPDX-FileCopyrightText: Copyright (c) 2025, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
SPDX-License-Identifier: Apache-2.0

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->

# 🧪 Temporary MCP Auth Planning Notes (Experimental)
This is currently a scratch pad for planning MCP auth. It will be rewritten when all the components are ready.

## Phases of MCP auth implementation
1. [Completed] MCP client with new `mcp_oauth2` auth provider.
2. [Pending] MCP protected server with `TokenVerifier`.
3. [Pending] Changes for end-to-end MCP auth testing.

## Steps for testing MCP auth
1. Start the MCP server with auth enabled
```bash
nat mcp --config_file examples/MCP/simple_calculator_mcp/configs/config-mcp-server-auth.yml
```
This starts a protected MCP server on port 9901. This MCP server has a stub token verifier that will always return success without AS introspection.

2. Start a container with the example auth server from the MCP repo. This will start the auth server on port 9000.
```bash
docker build -t mcp-sample-as -f examples/MCP/simple_calculator_mcp/deploy_example_as/Dockerfile examples/MCP/simple_calculator_mcp/deploy_example_as/
docker run -p 9000:9000 mcp-sample-as
```
This starts the auth server on port 9000.

3. Start NAT UI and enable websocket

4. Run the workflow with MCP auth enabled client

```bash
nat serve --config_file examples/MCP/simple_calculator_mcp/configs/config-mcp-auth-dynamic.yml
```
This starts the workflow with a MCP client that uses the `mcp_oauth2` auth provider. This provider:
- Discovers the auth server endpoints.
- Registers a client with the auth server.
- Performs the OAuth2 authorization code flow using the `OAuth2AuthCodeFlowProvider`.
17 changes: 8 additions & 9 deletions docs/source/workflows/mcp/mcp-client.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,9 @@ limitations under the License.

Model Context Protocol (MCP) is an open protocol developed by Anthropic that standardizes how applications provide context to LLMs. You can read more about MCP [here](https://modelcontextprotocol.io/introduction).

You can use NeMo Agent toolkit as an MCP Client to connect to and use tools served by remote MCP servers.
You can use NeMo Agent toolkit as an MCP Host with one or more MCP Clients serving tools from remote MCP servers.

This guide will cover how to use NeMo Agent toolkit as an MCP Client. For more information on how to use NeMo Agent toolkit as an MCP Server, please refer to the [MCP Server](./mcp-server.md) documentation.
This guide will cover how to use NeMo Agent toolkit as an MCP Host with one or more MCP Clients. For more information on how to use NeMo Agent toolkit as an MCP Server, please refer to the [MCP Server](./mcp-server.md) documentation.

## Installation

Expand Down Expand Up @@ -75,6 +75,12 @@ class MCPToolConfig(FunctionBaseConfig, name="mcp_tool_wrapper"):
```
In addition to the URL of the server, the configuration also takes as a parameter the name of the MCP tool you want to use as a NeMo Agent toolkit function. This is required because MCP servers can serve multiple tools, and for this wrapper we want to maintain a one-to-one relationship between NeMo Agent toolkit functions and MCP tools. This means that if you want to include multiple tools from an MCP server you will configure multiple `mcp_tool_wrappers`.

Once configured, a Pydantic input schema will be generated based on the input schema provided by the MCP server. This input schema is included with the configured function and is accessible by any agent or function calling the configured `mcp_tool_wrapper` function. The `mcp_tool_wrapper` function can accept the following type of arguments as long as they satisfy the input schema:
* a validated instance of it's input schema
* a string that represents a valid JSON
* A python dictionary
* Keyword arguments

### 🧪 `mcp_client` Configuration (Experimental)

```python
Expand Down Expand Up @@ -179,13 +185,6 @@ functions:
```
STDIO mode support is experimental. Note that you should use `mcp_client` instead of `mcp_tool_wrapper` as the function type for `stdio` mode. `mcp_client` allows you to connect to a MCP server, dynamically discover the tools it serves, and register them as NeMo Agent toolkit functions. See `examples/MCP/simple_calculator_mcp/configs/config-mcp-date-stdio.yml` for a complete example.

Once configured, a Pydantic input schema will be generated based on the input schema provided by the MCP server. This input schema is included with the configured function and is accessible by any agent or function calling the configured `mcp_tool_wrapper` function. The `mcp_tool_wrapper` function can accept the following type of arguments as long as they satisfy the input schema:
* a validated instance of it's input schema
* a string that represents a valid JSON
* A python dictionary
* Keyword arguments


## Example
The simple calculator workflow can be configured to use remote MCP tools. Sample configuration is provided in the `config-mcp-math.yml` file.

Expand Down
2 changes: 1 addition & 1 deletion docs/source/workflows/mcp/mcp-server.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ limitations under the License.

Model Context Protocol (MCP) is an open protocol developed by Anthropic that standardizes how applications provide context to LLMs. You can read more about MCP [here](https://modelcontextprotocol.io/introduction).

This guide will cover how to use NeMo Agent toolkit as an MCP Server to publish tools using MCP. For more information on how to use NeMo Agent toolkit as an MCP Client, refer to the [MCP Client](./mcp-client.md) documentation.
This guide will cover how to use NeMo Agent toolkit as an MCP Server to publish tools using MCP. For more information on how to use NeMo Agent toolkit as an MCP Host with one or more MCP Clients, refer to the [MCP Client](./mcp-client.md) documentation.

## MCP Server Usage

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
# SPDX-FileCopyrightText: Copyright (c) 2024-2025, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
# SPDX-License-Identifier: Apache-2.0
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

functions:
current_datetime_local:
_type: current_datetime
mcp_protected_math:
_type: mcp_client
server:
transport: streamable-http
auth_provider: mcp_oauth2_dynamic
url: "http://localhost:9901/mcp"
tool_filter:
# skip react_agent and datetime tools from the math MCP server
- calculator_multiply
- calculator_inequality
- calculator_divide
- calculator_subtract

authentication:
mcp_oauth2_dynamic:
_type: mcp_oauth2
server_url: http://localhost:9901
redirect_uri: http://localhost:8000/auth/redirect

llms:
nim_llm:
_type: nim
model_name: meta/llama-3.1-70b-instruct
temperature: 0.0
max_tokens: 1024

workflow:
_type: react_agent
tool_names:
- calculator_multiply
- calculator_inequality
- calculator_divide
- calculator_subtract
- current_datetime_local
llm_name: nim_llm
verbose: true
retry_parsing_errors: true
max_retries: 3
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
# SPDX-FileCopyrightText: Copyright (c) 2024-2025, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
# SPDX-License-Identifier: Apache-2.0
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

functions:
current_datetime_local:
_type: current_datetime
mcp_protected_math:
_type: mcp_client
server:
transport: streamable-http
auth_provider: static_oauth2
url: "http://localhost:9901/mcp"
tool_filter:
# skip react_agent and datetime tools from the math MCP server
- calculator_multiply
- calculator_inequality
- calculator_divide
- calculator_subtract

authentication:
static_oauth2:
_type: oauth2_auth_code_flow
redirect_uri: http://localhost:8000/auth/redirect
authorization_url: http://localhost:5001/oauth/authorize
token_url: http://localhost:5001/oauth/token
token_endpoint_auth_method: client_secret_post
client_id: ${MCP_CLIENT_ID}
client_secret: ${MCP_CLIENT_SECRET}
scopes:
- openid
- profile
- email
use_pkce: false

llms:
nim_llm:
_type: nim
model_name: meta/llama-3.1-70b-instruct
temperature: 0.0
max_tokens: 1024
openai_llm:
_type: openai
model_name: gpt-3.5-turbo
max_tokens: 2000

workflow:
_type: react_agent
tool_names:
- calculator_multiply
- calculator_inequality
- calculator_divide
- calculator_subtract
- current_datetime_local
llm_name: nim_llm
verbose: true
retry_parsing_errors: true
max_retries: 3
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,12 @@ workflow:
# List all tools that are needed for the workflow from the two MCP servers
# get_current_time_mcp_tool is from the local mcp_server_time server
# calculator_multiply, calculator_divide, calculator_subtract, calculator_inequality are from the remote mcp_server_math server
tool_names: ["get_current_time_mcp_tool", "calculator_multiply", "calculator_divide", "calculator_subtract", "calculator_inequality"]
tool_names:
- calculator_multiply
- calculator_inequality
- calculator_divide
- calculator_subtract
- get_current_time_mcp_tool
llm_name: nim_llm
verbose: true
retry_parsing_errors: true
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,9 +63,9 @@ workflow:
tool_names:
- calculator_multiply
- calculator_inequality
- current_datetime
- calculator_divide
- calculator_subtract
- current_datetime
llm_name: nim_llm
verbose: true
parse_agent_response_max_retries: 3
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
# SPDX-FileCopyrightText: Copyright (c) 2024-2025, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
# SPDX-License-Identifier: Apache-2.0
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

# This is used to start a protected MCP math server with auth enabled.

general:
front_end:
_type: mcp
require_auth: true
auth_server_url: http://localhost:9000
required_scopes: ["user"]

functions:
calculator_multiply:
_type: calculator_multiply
calculator_inequality:
_type: calculator_inequality
calculator_divide:
_type: nat_simple_calculator/calculator_divide
current_datetime:
_type: current_datetime
calculator_subtract:
_type: calculator_subtract

llms:
nim_llm:
_type: nim
model_name: meta/llama-3.1-70b-instruct
temperature: 0.0
max_tokens: 1024
openai_llm:
_type: openai
model_name: gpt-3.5-turbo
max_tokens: 2000

workflow:
_type: react_agent
tool_names:
- calculator_multiply
- calculator_inequality
- current_datetime
- calculator_divide
- calculator_subtract
llm_name: nim_llm
verbose: true
parse_agent_response_max_retries: 3
47 changes: 47 additions & 0 deletions examples/MCP/simple_calculator_mcp/deploy_example_as/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# SPDX-FileCopyrightText: Copyright (c) 2025, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
# SPDX-License-Identifier: Apache-2.0
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

# ---- Base OS ----
FROM ubuntu:22.04

# ---- System deps ----
RUN apt-get update && apt-get upgrade -y \
&& apt-get install -y --no-install-recommends \
python3 python3-pip git ca-certificates \
&& rm -rf /var/lib/apt/lists/*

# Make python/pip the default names
RUN update-alternatives --install /usr/bin/python python /usr/bin/python3 1 \
&& update-alternatives --install /usr/bin/pip pip /usr/bin/pip3 1
ENV PIP_NO_CACHE_DIR=1 PYTHONUNBUFFERED=1

# ---- Install uv (to match your steps) ----
RUN pip install --no-cache-dir uv

# ---- Clone the MCP SDK repo ----
WORKDIR /opt
RUN git clone https://github.com/modelcontextprotocol/python-sdk.git mcp-sdk
WORKDIR /opt/mcp-sdk
RUN git checkout v1.14.0

# ---- Install the sample auth server (editable) ----
WORKDIR /opt/mcp-sdk/examples/servers/simple-auth
RUN uv pip install --system -e .

# ---- Network ----
EXPOSE 9000

# ---- Run the sample auth server ----
ENTRYPOINT ["mcp-simple-auth-as", "--port=9000"]
3 changes: 2 additions & 1 deletion packages/nvidia_nat_mcp/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ dependencies = [
# version when adding a new package. If unsure, default to using `~=` instead of `==`. Does not apply to nvidia-nat packages.
# Keep sorted!!!
"nvidia-nat~=1.3",
"mcp~=1.13",
"mcp~=1.14",
]
requires-python = ">=3.11,<3.14"
description = "Subpackage for MCP client integration in NeMo Agent toolkit"
Expand All @@ -45,3 +45,4 @@ nvidia-nat = { workspace = true }

[project.entry-points.'nat.components']
nat_mcp = "nat.plugins.mcp.register"
nat_mcp_auth = "nat.plugins.mcp.auth.register"
14 changes: 14 additions & 0 deletions packages/nvidia_nat_mcp/src/nat/plugins/mcp/auth/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# SPDX-FileCopyrightText: Copyright (c) 2025, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
# SPDX-License-Identifier: Apache-2.0
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
Loading