Skip to main content
Glama

Remote MCP Server

MIT License
37
  • Linux
  • Apple

Getting Started with Remote MCP Servers using Azure Functions (Node.js/TypeScript)

This is a quickstart template to easily build and deploy a custom remote MCP server to the cloud using Azure functions. You can clone/restore/run on your local machine with debugging, and azd up to have it in the cloud in a couple minutes. The MCP server is secured by design using keys and HTTPs, and allows more options for OAuth using EasyAuth and/or API Management as well as network isolation using VNET.

Watch the video overview

If you're looking for this sample in more languages check out the .NET/C# and Python versions.

Below is the architecture diagram for the Remote MCP Server using Azure Functions:

Architecture Diagram

Prerequisites

Prepare your local environment

An Azure Storage Emulator is needed for this particular sample because we will save and get snippets from blob storage.

  1. Start Azurite
    docker run -p 10000:10000 -p 10001:10001 -p 10002:10002 \ mcr.microsoft.com/azure-storage/azurite

Note if you use Azurite coming from VS Code extension you need to run Azurite: Start now or you will see errors.

Run your MCP Server locally from the terminal

  1. Install dependencies
    npm install
  2. Build the project
    npm run build
  3. Start the Functions host locally:
    func start

Note by default this will use the webhooks route: /runtime/webhooks/mcp/sse. Later we will use this in Azure to set the key on client/host calls: /runtime/webhooks/mcp/sse?code=<system_key>

Use the local MCP server from within a client/host

VS Code - Copilot Edits

  1. Add MCP Server from command palette and add URL to your running Function app's SSE endpoint:
    http://0.0.0.0:7071/runtime/webhooks/mcp/sse
  2. Select HTTP (Server-Sent-Events) for the type of MCP server to add.
  3. Enter the URL to your running function app's SSE endpoint
  4. Enter the server ID. (This can be any name you want)
  5. Choose if you want to run this in your User settings (available to all apps for you) or to your Workspace settings (available to this app, only)
  6. List MCP Servers from command palette and start the server. The previous step may have already started your local server. If so, you can skip this step.
  7. In Copilot chat agent mode enter a prompt to trigger the tool, e.g., select some code and enter this prompt
    Say Hello
    Save this snippet as snippet1
    Retrieve snippet1 and apply to newFile.ts
  8. When prompted to run the tool, consent by clicking Continue
  9. When you're done, press Ctrl+C in the terminal window to stop the func.exe host process, and List MCP Servers from command palette and stop the local server.

MCP Inspector

  1. In a new terminal window, install and run MCP Inspector
    npx @modelcontextprotocol/inspector node build/index.js
  2. If you stopped your function app previously, start the Functions host locally:
    func start
  3. CTRL click to load the MCP Inspector web app from the URL displayed by the app (e.g. http://0.0.0.0:5173/#resources)
  4. Set the transport type to SSE
  5. Set the URL to your running Function app's SSE endpoint and Connect:
    http://0.0.0.0:7071/runtime/webhooks/mcp/sse
  6. List Tools. Click on a tool and Run Tool.
  7. When you're done, press Ctrl+C in the terminal window to stop the func.exe host process, and press Ctrl+C in the terminal window to stop the @modelcontextprotocol/inspector host process.

Verify local blob storage in Azurite

After testing the snippet save functionality locally, you can verify that blobs are being stored correctly in your local Azurite storage emulator.

Using Azure Storage Explorer

  1. Open Azure Storage Explorer
  2. In the left panel, expand Emulator & AttachedStorage Accounts(Emulator - Default Ports) (Key)
  3. Navigate to Blob Containerssnippets
  4. You should see any saved snippets as blob files in this container
  5. Double-click on any blob to view its contents and verify the snippet data was saved correctly

Using Azure CLI (Alternative)

If you prefer using the command line, you can also verify blobs using Azure CLI with the storage emulator:

# List blobs in the snippets container az storage blob list --container-name snippets --connection-string "DefaultEndpointsProtocol=http;AccountName=devstoreaccount1;AccountKey=Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw==;BlobEndpoint=http://127.0.0.1:10000/devstoreaccount1;"
# Download a specific blob to view its contents az storage blob download --container-name snippets --name <blob-name> --file <local-file-path> --connection-string "DefaultEndpointsProtocol=http;AccountName=devstoreaccount1;AccountKey=Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw==;BlobEndpoint=http://127.0.0.1:10000/devstoreaccount1;"

This verification step ensures your MCP server is correctly interacting with the local storage emulator and that the blob storage functionality is working as expected before deploying to Azure.

Deploy to Azure for Remote MCP

Optionally, you can opt-in to a VNet being used in the sample. (If you choose this, do this before azd up)

azd env set VNET_ENABLED true

Run this azd command to provision the function app, with any required Azure resources, and deploy your code:

azd up

Note API Management can be used for improved security and policies over your MCP Server, and App Service built-in authentication can be used to set up your favorite OAuth provider including Entra.

Connect to your remote MCP server function app from a client

Your client will need a key in order to invoke the new hosted SSE endpoint, which will be of the form https://<funcappname>.azurewebsites.net/runtime/webhooks/mcp/sse. The hosted function requires a system key by default which can be obtained from the portal or the CLI (az functionapp keys list --resource-group <resource_group> --name <function_app_name>). Obtain the system key named mcp_extension.

Connect to remote MCP server in MCP Inspector

For MCP Inspector, you can include the key in the URL:

https://<funcappname>.azurewebsites.net/runtime/webhooks/mcp/sse?code=<your-mcp-extension-system-key>

Connect to remote MCP server in VS Code - GitHub Copilot

For GitHub Copilot within VS Code, you should set the key as the x-functions-key header in mcp.json, and you would use https://<funcappname>.azurewebsites.net/runtime/webhooks/mcp/sse for the URL. The following example is from the mcp.json file included in this repository and uses an input to prompt you to provide the key when you start the server from VS Code. Your mcp.json file looks like this:

{ "inputs": [ { "type": "promptString", "id": "functions-mcp-extension-system-key", "description": "Azure Functions MCP Extension System Key", "password": true }, { "type": "promptString", "id": "functionapp-name", "description": "Azure Functions App Name" } ], "servers": { "remote-mcp-function": { "type": "sse", "url": "https://${input:functionapp-name}.azurewebsites.net/runtime/webhooks/mcp/sse", "headers": { "x-functions-key": "${input:functions-mcp-extension-system-key}" } }, "local-mcp-function": { "type": "sse", "url": "http://0.0.0.0:7071/runtime/webhooks/mcp/sse" } } }
  1. Click Start on the server remote-mcp-function, inside the mcp.json file:
  2. Enter the name of the function app that you created in the Azure Portal, when prompted by VS Code.
  3. Enter the Azure Functions MCP Extension System Key into the prompt. You can copy this from the Azure portal for your function app by going to the Functions menu item, then App Keys, and copying the mcp_extension key from the System Keys.
  4. In Copilot chat agent mode enter a prompt to trigger the tool, e.g., select some code and enter this prompt
    Say Hello
    Save this snippet as snippet1
    Retrieve snippet1 and apply to newFile.ts

Redeploy your code

You can run the azd up command as many times as you need to both provision your Azure resources and deploy code updates to your function app.

Note

Deployed code files are always overwritten by the latest deployment package.

Clean up resources

When you're done working with your function app and related resources, you can use this command to delete the function app and its related resources from Azure and avoid incurring any further costs:

azd down

Source Code

The function code for the getSnippet and saveSnippet endpoints are defined in the TypeScript files in the src directory. The MCP function annotations expose these functions as MCP Server tools.

This shows the code for a few MCP server examples (get string, get object, save object):

// Hello function - responds with hello message export async function mcpToolHello(context: InvocationContext): Promise<string> { return "Hello I am MCP Tool!"; } // Register the hello tool app.mcpTool('hello', { toolName: 'hello', description: 'Simple hello world MCP Tool that responses with a hello message.', handler: mcpToolHello }); // GetSnippet function - retrieves a snippet by name export async function getSnippet(_message: unknown, context: InvocationContext): Promise<string> { console.info('Getting snippet'); // Get snippet name from the tool arguments const mcptoolargs = context.triggerMetadata.mcptoolargs as { snippetname?: string }; const snippetName = mcptoolargs?.snippetname; console.info(`Snippet name: ${snippetName}`); if (!snippetName) { return "No snippet name provided"; } // Get the content from blob binding - properly retrieving from extraInputs const snippetContent = context.extraInputs.get(blobInputBinding); if (!snippetContent) { return `Snippet '${snippetName}' not found`; } console.info(`Retrieved snippet: ${snippetName}`); return snippetContent as string; } // Register the GetSnippet tool app.mcpTool('getsnippet', { toolName: GET_SNIPPET_TOOL_NAME, description: GET_SNIPPET_TOOL_DESCRIPTION, toolProperties: [ { propertyName: SNIPPET_NAME_PROPERTY_NAME, propertyValue: PROPERTY_TYPE, description: SNIPPET_NAME_PROPERTY_DESCRIPTION, } ], extraInputs: [blobInputBinding], handler: getSnippet }); // SaveSnippet function - saves a snippet with a name export async function saveSnippet(_message: unknown, context: InvocationContext): Promise<string> { console.info('Saving snippet'); // Get snippet name and content from the tool arguments const mcptoolargs = context.triggerMetadata.mcptoolargs as { snippetname?: string; snippet?: string; }; const snippetName = mcptoolargs?.snippetname; const snippet = mcptoolargs?.snippet; if (!snippetName) { return "No snippet name provided"; } if (!snippet) { return "No snippet content provided"; } // Save the snippet to blob storage using the output binding context.extraOutputs.set(blobOutputBinding, snippet); console.info(`Saved snippet: ${snippetName}`); return snippet; } // Register the SaveSnippet tool app.mcpTool('savesnippet', { toolName: SAVE_SNIPPET_TOOL_NAME, description: SAVE_SNIPPET_TOOL_DESCRIPTION, toolProperties: [ { propertyName: SNIPPET_NAME_PROPERTY_NAME, propertyValue: PROPERTY_TYPE, description: SNIPPET_NAME_PROPERTY_DESCRIPTION, }, { propertyName: SNIPPET_PROPERTY_NAME, propertyValue: PROPERTY_TYPE, description: SNIPPET_PROPERTY_DESCRIPTION, } ], extraOutputs: [blobOutputBinding], handler: saveSnippet });

Note that the host.json file also includes a reference to the experimental bundle, which is required for apps using this feature:

"extensionBundle": { "id": "Microsoft.Azure.Functions.ExtensionBundle.Experimental", "version": "[4.*, 5.0.0)" }

Next Steps

-
security - not tested
A
license - permissive license
-
quality - not tested

hybrid server

The server is able to function both locally and remotely, depending on the configuration or use case.

키, HTTPS, OAuth 및 네트워크 격리 옵션을 통한 보안 통신으로 코드 조각을 저장하고 검색할 수 있는 Azure Functions를 사용하는 클라우드 기반 사용자 지정 MCP 서버입니다.

  1. 필수 조건
    1. 지역 환경을 준비하세요
      1. 터미널에서 로컬로 MCP 서버를 실행하세요.
        1. 클라이언트/호스트 내에서 로컬 MCP 서버를 사용합니다.
          1. VS 코드 - Copilot 편집
          2. MCP 검사관
        2. 원격 MCP를 위해 Azure에 배포
          1. 클라이언트에서 원격 MCP 서버 기능 앱에 연결
            1. MCP Inspector에서 원격 MCP 서버에 연결
            2. VS Code에서 원격 MCP 서버에 연결 - GitHub Copilot
          2. 코드를 다시 배포하세요
            1. 자원 정리
              1. 소스 코드
                1. 다음 단계

                  Related MCP Servers

                  • A
                    security
                    A
                    license
                    A
                    quality
                    A MCP server for managing and storing code snippets in various programming languages, allowing users to create, list, and delete snippets via a standardized interface.
                    Last updated -
                    3
                    4
                    7
                    JavaScript
                    MIT License
                  • -
                    security
                    A
                    license
                    -
                    quality
                    An MCP server for interacting with Azure. Contains some common Compute and Networking actions, and extensible to add many more.
                    Last updated -
                    1
                    Python
                    Apache 2.0
                  • A
                    security
                    F
                    license
                    A
                    quality
                    An MCP server that provides seamless interaction with Azure DevOps Git repositories, enabling users to manage repositories, branches, pull requests, and pipelines through natural language.
                    Last updated -
                    8
                    0
                    3
                    TypeScript
                  • -
                    security
                    A
                    license
                    -
                    quality
                    This project builds a read-only MCP server. For full read, write, update, delete, and action capabilities and a simplified setup, check out our free CData MCP Server for Azure Data Catalog (beta): https://www.cdata.com/download/download.aspx?sku=GNZK-V&type=beta
                    Last updated -
                    MIT License
                    • Linux
                    • Apple

                  View all related MCP servers

                  MCP directory API

                  We provide all the information about MCP servers via our MCP API.

                  curl -X GET 'https://glama.ai/api/mcp/v1/servers/Azure-Samples/remote-mcp-functions-typescript'

                  If you have feedback or need assistance with the MCP directory API, please join our Discord server