Skip to content

Latest commit

 

History

History

README.md

MCP Server: Outlook Email

This is an MCP server that sends an email through Outlook. It also covers authentication scenarios.

Install

Install in VS Code Install in VS Code Insiders Install in Visual Studio

Prerequisites

What's Included

  • Outlook Email MCP server runs in the following scenarios:

    • OAuth authentication with Azure API Management as a remote MCP server
    • API key authentication with Azure Functions as a remote MCP server
    • No authentication as a locally running MCP server
  • Outlook Email MCP server includes:

    Building Block Name Description Usage
    Tools send_email Send an Email to recipients. #send_email

Getting Started

Getting repository root

  1. Get the repository root.

    # bash/zsh
    REPOSITORY_ROOT=$(git rev-parse --show-toplevel)
    # PowerShell
    $REPOSITORY_ROOT = git rev-parse --show-toplevel

Registering an app on Entra ID

This section is for running the MCP server on your local machine or in a local container. If you deploy this MCP server to Azure, you can skip this section.

  1. Run the following script.

    # bash/zsh
    cd $REPOSITORY_ROOT/outlook-email
    ./register-app.sh
    # PowerShell
    cd $REPOSITORY_ROOT/outlook-email
    ./Register-App.ps1
  2. Take notes for tenant ID, client ID and client secret values.

Running MCP server

On a local machine

  1. Run the MCP server app.

    cd $REPOSITORY_ROOT/outlook-email
    dotnet run --project ./src/McpSamples.OutlookEmail.HybridApp

    Make sure take note the absolute directory path of the McpSamples.OutlookEmail.HybridApp project.

    Parameters:

    • --http: The switch that indicates to run this MCP server as a streamable HTTP type. When this switch is added, the MCP server URL is http://localhost:5260.
    • --tenant-id/-t: The tenant ID for sign-in.
    • --client-id/-c: The client ID for sign-in.
    • --client-secret/-s: The client secret for sign-in.

    With these parameters, you can run the MCP server like:

    dotnet run --project ./src/McpSamples.OutlookEmail.HybridApp -- --http -t "{{TENANT_ID}}" -c "{{CLIENT_ID}}" -s "{{CLIENT_SECRET}}"

    Instead of providing those tenant ID, client ID and client secret values through the command-line, they can be stored as the user secrets.

    dotnet user-secrets --project ./src/McpSamples.OutlookEmail.HybridApp set EntraId:TenantId "{{TENANT_ID}}"
    dotnet user-secrets --project ./src/McpSamples.OutlookEmail.HybridApp set EntraId:ClientId "{{CLIENT_ID}}"
    dotnet user-secrets --project ./src/McpSamples.OutlookEmail.HybridApp set EntraId:ClientSecret "{{CLIENT_SECRET}}"

On a local machine as a Function app

  1. Rename local.settings.sample.json to local.settings.json.

    # bash/zsh
    cp $REPOSITORY_ROOT/outlook-email/src/McpSamples.OutlookEmail.HybridApp/local.settings.sample.json \
       $REPOSITORY_ROOT/outlook-email/src/McpSamples.OutlookEmail.HybridApp/local.settings.json
    # PowerShell
    Copy-Item -Path $REPOSITORY_ROOT/outlook-email/src/McpSamples.OutlookEmail.HybridApp/local.settings.sample.json `
              -Destination $REPOSITORY_ROOT/outlook-email/src/McpSamples.OutlookEmail.HybridApp/local.settings.json -Force
  2. Open local.settings.json and replace {{TENANT_ID}}, {{CLIENT_ID}} and {{CLIENT_SECRET}} with the tenant ID, client ID and client secret values respectively.

    {
      "IsEncrypted": false,
      "Values": {
        "FUNCTIONS_WORKER_RUNTIME": "dotnet-isolated",
        "AzureWebJobsFeatureFlags": "DisableDiagnosticEventLogging",
    
        "UseHttp": "true",
    
        "EntraId__TenantId": "{{TENANT_ID}}",
        "EntraId__ClientId": "{{CLIENT_ID}}",
        "EntraId__ClientSecret": "{{CLIENT_SECRET}}",
        "EntraId__UseManagedIdentity": false
      }
    }
  3. Run the MCP server app.

    cd $REPOSITORY_ROOT/outlook-email/src/McpSamples.OutlookEmail.HybridApp
    func start

In a container

  1. Build the MCP server app as a container image.

    cd $REPOSITORY_ROOT
    docker build -f Dockerfile.outlook-email -t outlook-email:latest .
  2. Run the MCP server app in a container.

    docker run -i --rm -p 8080:8080 outlook-email:latest

    Alternatively, use the container image from the container registry.

    docker run -i --rm -p 8080:8080 ghcr.io/microsoft/mcp-dotnet-samples/outlook-email:latest

    Parameters:

    • --http: The switch that indicates to run this MCP server as a streamable HTTP type. When this switch is added, the MCP server URL is http://localhost:8080.
    • --tenant-id/-t: The tenant ID for sign-in.
    • --client-id/-c: The client ID for sign-in.
    • --client-secret/-s: The client secret for sign-in.

    With these parameters, you can run the MCP server like:

    # use local container image
    docker run -i --rm -p 8080:8080 outlook-email:latest --http -t "{{TENANT_ID}}" -c "{{CLIENT_ID}}" -s "{{CLIENT_SECRET}}"
    # use container image from the container registry
    docker run -i --rm -p 8080:8080 ghcr.io/microsoft/mcp-dotnet-samples/outlook-email:latest --http -t "{{TENANT_ID}}" -c "{{CLIENT_ID}}" -s "{{CLIENT_SECRET}}"

On Azure

  1. IMPORTANT Check whether you have the necessary permissions:

  2. Navigate to the directory.

    cd $REPOSITORY_ROOT/outlook-email
  3. Login to Azure.

    # Login with Azure Developer CLI
    azd auth login
  1. Deploy the MCP server app to Azure.

    azd up

    While provisioning and deploying, you'll be asked to provide subscription ID, location, environment name.

  2. After the deployment is complete, get the information by running the following commands:

    • Azure Functions Apps FQDN:

      azd env get-value AZURE_RESOURCE_MCP_OUTLOOK_EMAIL_FQDN
    • Azure API Management FQDN:

      azd env get-value AZURE_RESOURCE_MCP_OUTLOOK_EMAIL_GATEWAY_FQDN

Connect MCP server to an MCP host/client

VS Code + Agent Mode + Local MCP server

  1. Copy mcp.json to the repository root.

    For locally running MCP server (STDIO):

    mkdir -p $REPOSITORY_ROOT/.vscode
    cp $REPOSITORY_ROOT/outlook-email/.vscode/mcp.stdio.local.json \
       $REPOSITORY_ROOT/.vscode/mcp.json
    New-Item -Type Directory -Path $REPOSITORY_ROOT/.vscode -Force
    Copy-Item -Path $REPOSITORY_ROOT/outlook-email/.vscode/mcp.stdio.local.json `
              -Destination $REPOSITORY_ROOT/.vscode/mcp.json -Force

    For locally running MCP server (HTTP):

    mkdir -p $REPOSITORY_ROOT/.vscode
    cp $REPOSITORY_ROOT/outlook-email/.vscode/mcp.http.local.json \
       $REPOSITORY_ROOT/.vscode/mcp.json
    New-Item -Type Directory -Path $REPOSITORY_ROOT/.vscode -Force
    Copy-Item -Path $REPOSITORY_ROOT/outlook-email/.vscode/mcp.http.local.json `
              -Destination $REPOSITORY_ROOT/.vscode/mcp.json -Force

    For locally running MCP server as Function app (HTTP):

    mkdir -p $REPOSITORY_ROOT/.vscode
    cp $REPOSITORY_ROOT/outlook-email/.vscode/mcp.http.local-func.json \
       $REPOSITORY_ROOT/.vscode/mcp.json
    New-Item -Type Directory -Path $REPOSITORY_ROOT/.vscode -Force
    Copy-Item -Path $REPOSITORY_ROOT/outlook-email/.vscode/mcp.http.local-func.json `
              -Destination $REPOSITORY_ROOT/.vscode/mcp.json -Force

    For locally running MCP server in a container (STDIO):

    mkdir -p $REPOSITORY_ROOT/.vscode
    cp $REPOSITORY_ROOT/outlook-email/.vscode/mcp.stdio.container.json \
       $REPOSITORY_ROOT/.vscode/mcp.json
    New-Item -Type Directory -Path $REPOSITORY_ROOT/.vscode -Force
    Copy-Item -Path $REPOSITORY_ROOT/outlook-email/.vscode/mcp.stdio.container.json `
              -Destination $REPOSITORY_ROOT/.vscode/mcp.json -Force

    For locally running MCP server in a container (HTTP):

    mkdir -p $REPOSITORY_ROOT/.vscode
    cp $REPOSITORY_ROOT/outlook-email/.vscode/mcp.http.container.json \
       $REPOSITORY_ROOT/.vscode/mcp.json
    New-Item -Type Directory -Path $REPOSITORY_ROOT/.vscode -Force
    Copy-Item -Path $REPOSITORY_ROOT/outlook-email/.vscode/mcp.http.container.json `
              -Destination $REPOSITORY_ROOT/.vscode/mcp.json -Force

    For remotely running MCP server as Function app (HTTP):

    mkdir -p $REPOSITORY_ROOT/.vscode
    cp $REPOSITORY_ROOT/outlook-email/.vscode/mcp.http.remote-func.json \
       $REPOSITORY_ROOT/.vscode/mcp.json
    New-Item -Type Directory -Path $REPOSITORY_ROOT/.vscode -Force
    Copy-Item -Path $REPOSITORY_ROOT/outlook-email/.vscode/mcp.http.remote-func.json `
              -Destination $REPOSITORY_ROOT/.vscode/mcp.json -Force

    For remotely running MCP server via API Management (HTTP):

    mkdir -p $REPOSITORY_ROOT/.vscode
    cp $REPOSITORY_ROOT/outlook-email/.vscode/mcp.http.remote-apim.json \
       $REPOSITORY_ROOT/.vscode/mcp.json
    New-Item -Type Directory -Path $REPOSITORY_ROOT/.vscode -Force
    Copy-Item -Path $REPOSITORY_ROOT/outlook-email/.vscode/mcp.http.remote-apim.json `
              -Destination $REPOSITORY_ROOT/.vscode/mcp.json -Force
  2. Open Command Palette by typing F1 or Ctrl+Shift+P on Windows or Cmd+Shift+P on Mac OS, and search MCP: List Servers.

  3. Choose outlook-email then click Start Server.

  4. When prompted, enter the following values:

    • The absolute directory path of the McpSamples.OutlookEmail.HybridApp project.
    • The FQDN of Azure Container Apps.
    • The FQDN of Azure Functions Apps.
    • Tenant ID.
    • Client ID.
    • Client secret.
  5. Enter prompt like:

    Send an email to abc@contoso.com from xyz@contoso.com with the subject of "lorem ipsum" and body of "hello world".
    
  6. Confirm the result.