Skip to content

Latest commit

 

History

History
221 lines (150 loc) · 9.19 KB

File metadata and controls

221 lines (150 loc) · 9.19 KB

MCP Service Account Authentication Example

Complexity: 🟨 Intermediate

This example demonstrates how to use the NVIDIA NeMo Agent Toolkit with MCP servers that support service account authentication. Service account authentication enables headless, automated workflows without requiring browser-based user interaction.

It is recommended to read the MCP Service Account Authentication documentation first.

Overview

Service account authentication uses OAuth2 client credentials flow instead of the interactive authorization code flow. This makes it ideal for:

  • CI/CD Pipelines: Automated testing and deployment
  • Backend Services: Server-to-server communication
  • Batch Processing: Scheduled jobs and data processing
  • Container Deployments: Containerized applications
  • Any Headless Scenario: Where browser interaction is not possible

Authentication Patterns

This example demonstrates two service account authentication patterns:

  1. Dual Authentication (Jira example): Requires both an OAuth2 service account token AND a service token

    • Used by enterprise data MCP servers (such as Jira, GitLab)
    • MCP server validates the OAuth2 service account token and uses the service token (service-specific token such as Jira service token or GitLab service token) to access backend APIs
    • Two authentication headers sent with each request
  2. Single Authentication (Jama Cache example): Requires only an OAuth2 service account token

    • Used by custom MCP servers without service token delegation
    • MCP server validates only the OAuth2 service account token
    • Simpler authentication flow with one authentication header

Prerequisites

  1. MCP Server Access: Access to an MCP server that supports service account authentication (for example, corporate Jira system via MCP)

  2. Service Account Credentials:

    • OAuth2 client ID and client secret
    • OAuth2 token endpoint URL
    • Required OAuth2 scopes
    • Optional: service-specific tokens (for example, Jira service account token)

Install this Workflow

Install this example:

uv pip install -e examples/MCP/service_account_auth_mcp

Configuration

This example includes two configuration files demonstrating different service account authentication patterns:

  1. config-mcp-service-account-jira.yml: Demonstrates dual authentication (OAuth2 service account token + service token)
  2. config-mcp-service-account-jama.yml: Demonstrates single authentication (OAuth2 service account token only)

Choose the configuration pattern that matches your MCP server's requirements.

Environment Setup

Required Environment Variables (Both Patterns)

Set these environment variables for your OAuth2 service account:

# OAuth2 client credentials (required for both patterns)
export SERVICE_ACCOUNT_CLIENT_ID="your-client-id"
export SERVICE_ACCOUNT_CLIENT_SECRET="your-client-secret"

# Service account token endpoint (required for both patterns)
export SERVICE_ACCOUNT_TOKEN_URL="https://auth.example.com/service_account/token"

# Service account scopes - space-separated (required for both patterns)
export SERVICE_ACCOUNT_SCOPES="service-account-scope-jama_cache service-account-scope-jira"

Pattern 1: Single Authentication (Jama Cache Example)

For custom MCP servers that only require OAuth2 service account token validation:

# MCP server URL
export CORPORATE_MCP_SERVICE_ACCOUNT_JAMA_URL="https://mcp.example.com/jama/mcp"

Pattern 2: Dual Authentication (Jira Example)

For enterprise MCP servers that require both OAuth2 service account token and service token:

# MCP server URL
export CORPORATE_MCP_SERVICE_ACCOUNT_JIRA_URL="https://mcp.example.com/jira/mcp"

# Service-specific token for accessing backend APIs (static token)
export JIRA_SERVICE_TOKEN="your-jira-service-token"

# Optional: Custom header name for service token (defaults to X-Service-Account-Token)
export SERVICE_TOKEN_HEADER="X-Service-Account-Token"

:::{tip} Advanced: Dynamic Service Token

Instead of providing a static token via environment variable, you can configure a custom Python function to fetch the service token dynamically at runtime.

Function signature: async def get_service_token(**kwargs) -> str | tuple[str, str]

The function can access Context.get() for runtime context and receive additional arguments via the kwargs field in the config. This is useful for enterprise environments with dynamic token management (e.g., fetching from secure vaults).

Example in config:

service_token:
  function: "my_module.get_service_token"
  kwargs:
    vault_path: "secrets_jira"
  header: X-Service-Account-Token

:::

:::{important} All environment variables here are for demonstration purposes. You must set the environment variables for your actual service account and MCP server URL. :::

:::{warning} Do not commit these environment variables to version control. :::

Run the Workflow

After setting the required environment variables, run the workflow with the appropriate configuration file:

Single Authentication Pattern (Jama Cache)

nat run --config_file examples/MCP/service_account_auth_mcp/configs/config-mcp-service-account-jama.yml \
    --input "What Jama releases are available?"

Dual Authentication Pattern (Jira - Static Token)

nat run --config_file examples/MCP/service_account_auth_mcp/configs/config-mcp-service-account-jira.yml \
    --input "What is status of jira ticket OCSW-2116?"

Dual Authentication Pattern (Jira - Dynamic Function)

This example demonstrates fetching the service token dynamically via a Python function instead of reading from environment variables:

nat run --config_file examples/MCP/service_account_auth_mcp/configs/config-mcp-service-account-jira-function.yml \
    --input "What is status of jira ticket OCSW-2116?"

The function is defined in examples/MCP/service_account_auth_mcp/src/nat_service_account_auth_mcp/scripts/service_tokens.py and demonstrates how to implement dynamic token retrieval. In production, you would replace this with logic to fetch tokens from secure vaults or token services.

Expected Behavior

When using service account authentication:

  1. No Browser Interaction: The workflow runs completely headless without opening a browser
  2. Automatic Token Acquisition: OAuth2 tokens are automatically obtained using client credentials
  3. Token Caching: Tokens are cached and reused until they near expiration (5-minute buffer by default)
  4. Automatic Refresh: Tokens are refreshed automatically before expiry
  5. Silent Failure Recovery: Transient authentication errors trigger automatic retry with fresh tokens

Troubleshooting

For common issues and solutions, refer to the Troubleshooting section in the Service Account Authentication documentation.

Adapting This Example

Choosing the Right Pattern

First, determine which authentication pattern your MCP server requires:

  • Use Single Authentication (Jama Cache pattern) if your MCP server:

    • Only validates OAuth2 service account tokens
    • Does not require service tokens
    • Is a custom MCP server without backend system delegation
  • Use Dual Authentication (Jira pattern) if your MCP server:

    • Requires both OAuth2 service account token validation and service tokens
    • Delegates access to backend systems (such as Jira, GitLab)
    • Needs dual-header authentication

Adapting the Configuration

To use this example with your own service:

  1. Choose the appropriate configuration file as your starting point
  2. Update the environment variables to match your service's requirements
  3. Modify the MCP server URL in the configuration file
  4. For dual authentication, configure the service token header name and service token
  5. Adjust the token prefix if your service uses a different format

For detailed configuration options and authentication patterns, refer to the MCP Service Account Authentication documentation.

See Also