Skip to main content
Glama

Remote MCP Server

MIT License
28
  • Linux
  • Apple

Начало работы с удаленными серверами MCP с использованием функций Azure (Node.js/TypeScript)

Это шаблон быстрого старта для простого создания и развертывания настраиваемого удаленного сервера MCP в облаке с использованием функций Azure. Вы можете клонировать/восстановить/запустить на локальной машине с отладкой и azd up , чтобы разместить его в облаке за пару минут. Сервер MCP защищен по умолчанию с помощью ключей и HTTP и предоставляет больше возможностей для OAuth с использованием EasyAuth и/или API Management, а также сетевой изоляции с использованием VNET.

Посмотрите видеообзор

Если вы ищете этот пример на других языках, ознакомьтесь с версиями .NET/C# и Python .

Ниже представлена схема архитектуры удаленного сервера MCP с использованием функций Azure:

Архитектурная схема

Предпосылки

Подготовьте местную среду

Для этого конкретного примера необходим эмулятор хранилища Azure, поскольку мы будем сохранять и получать фрагменты из хранилища BLOB-объектов.

  1. Старт Азурита
    docker run -p 10000:10000 -p 10001:10001 -p 10002:10002 \ mcr.microsoft.com/azure-storage/azurite

Обратите внимание, если вы используете Azurite из расширения VS Code, вам необходимо запустить Azurite: Start now, иначе вы увидите ошибки.

Запустите свой MCP-сервер локально из терминала

  1. Установить зависимости
    npm install
  2. Построить проект
    npm run build
  3. Запустите хост функций локально:
    func start

Обратите внимание, что по умолчанию это будет использовать маршрут webhooks: /runtime/webhooks/mcp/sse . Позже мы будем использовать это в Azure для установки ключа для вызовов клиент/хост: /runtime/webhooks/mcp/sse?code=<system_key>

Используйте локальный сервер MCP из клиента/хоста

VS Code - Правки второго пилота

  1. Добавьте MCP-сервер из палитры команд и добавьте URL-адрес к конечной точке SSE вашего работающего приложения-функции:
    http://0.0.0.0:7071/runtime/webhooks/mcp/sse
  2. Выберите HTTP (Server-Sent-Events) в качестве типа добавляемого сервера MCP.
  3. Введите URL-адрес конечной точки SSE вашего работающего приложения-функции.
  4. Введите идентификатор сервера. (Это может быть любое имя по вашему желанию)
  5. Выберите, хотите ли вы запустить это в настройках пользователя (доступно для всех ваших приложений) или в настройках рабочей области (доступно только для этого приложения)
  6. Выведите список серверов MCP из палитры команд и запустите сервер. Предыдущий шаг мог уже запустить ваш локальный сервер. Если так, вы можете пропустить этот шаг.
  7. В режиме чат-агента Copilot введите запрос для запуска инструмента, например, выберите какой-либо код и введите этот запрос.
    Say Hello
    Save this snippet as snippet1
    Retrieve snippet1 and apply to newFile.ts
  8. При появлении запроса на запуск инструмента дайте согласие, нажав «Продолжить».
  9. Закончив, нажмите Ctrl+C в окне терминала, чтобы остановить хост-процесс func.exe , а затем выведите список серверов MCP из палитры команд и остановите локальный сервер.

Инспектор МКП

  1. В новом окне терминала установите и запустите MCP Inspector.
    npx @modelcontextprotocol/inspector node build/index.js
  2. Если вы ранее остановили приложение-функцию, запустите хост-функцию локально:
    func start
  3. Удерживая клавишу CTRL, щелкните, чтобы загрузить веб-приложение MCP Inspector с URL-адреса, отображаемого приложением (например, http://0.0.0.0:5173/#resources ).
  4. Установите тип транспорта на SSE
  5. Укажите URL-адрес конечной точки SSE вашего работающего приложения-функции и подключитесь :
    http://0.0.0.0:7071/runtime/webhooks/mcp/sse
  6. Список инструментов . Щелкните по инструменту и запустите инструмент .
  7. Когда вы закончите, нажмите Ctrl+C в окне терминала, чтобы остановить хост-процесс func.exe , и нажмите Ctrl+C в окне терминала, чтобы остановить хост-процесс @modelcontextprotocol/inspector .

Развертывание в Azure для удаленного MCP

При желании вы можете согласиться на использование VNet в образце. (Если вы выберете этот вариант, сделайте это до azd up )

azd env set VNET_ENABLED true

Запустите эту команду azd , чтобы предоставить приложению-функции все необходимые ресурсы Azure и развернуть свой код:

azd up

Примечание. API Management можно использовать для повышения безопасности и политик на вашем сервере MCP, австроенную аутентификацию App Service можно использовать для настройки вашего любимого поставщика OAuth, включая Entra.

Подключитесь к удаленному приложению сервера MCP с клиента

Вашему клиенту понадобится ключ для вызова новой размещенной конечной точки SSE, которая будет иметь вид https://<funcappname>.azurewebsites.net/runtime/webhooks/mcp/sse . Размещенная функция требует системный ключ по умолчанию, который можно получить на портале или в CLI ( az functionapp keys list --resource-group <resource_group> --name <function_app_name> ). Получите системный ключ с именем mcp_extension .

Подключитесь к удаленному серверу MCP в MCP Inspector

Для MCP Inspector вы можете включить ключ в URL:

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

Подключение к удаленному серверу MCP в VS Code - GitHub Copilot

Для GitHub Copilot в VS Code вам следует задать ключ как заголовок x-functions-key в mcp.json , и вы должны использовать https://<funcappname>.azurewebsites.net/runtime/webhooks/mcp/sse для URL. Следующий пример взят из файла mcp.json , включенного в этот репозиторий, и использует входные данные для запроса на ввод ключа при запуске сервера из VS Code. Ваш файл mcp.json выглядит следующим образом:

{ "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. Нажмите кнопку Пуск на сервере remote-mcp-function внутри файла mcp.json :
  2. Введите имя приложения-функции, созданного на портале Azure, при появлении соответствующего запроса от VS Code.
  3. Введите Azure Functions MCP Extension System Key в приглашение. Вы можете скопировать его из портала Azure для своего функционального приложения, перейдя в пункт меню Functions, затем App Keys и скопировав ключ mcp_extension из System Keys.
  4. В режиме чат-агента Copilot введите запрос для запуска инструмента, например, выберите какой-либо код и введите этот запрос.
    Say Hello
    Save this snippet as snippet1
    Retrieve snippet1 and apply to newFile.ts

Повторно разверните свой код

Вы можете запускать команду azd up столько раз, сколько необходимо для подготовки ресурсов Azure и развертывания обновлений кода в вашем функциональном приложении.

[!ПРИМЕЧАНИЕ] Развернутые файлы кода всегда перезаписываются последним пакетом развертывания.

Очистите ресурсы

Закончив работу с приложением-функцией и связанными с ним ресурсами, вы можете использовать эту команду, чтобы удалить приложение-функцию и связанные с ним ресурсы из Azure и избежать дальнейших затрат:

azd down

Исходный код

Код функции для конечных точек getSnippet и saveSnippet определен в файлах TypeScript в каталоге src . Аннотации функций MCP раскрывают эти функции как инструменты сервера MCP.

Ниже показан код для нескольких примеров сервера MCP (получение строки, получение объекта, сохранение объекта):

// 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 });

Обратите внимание, что файл host.json также содержит ссылку на экспериментальный пакет, который необходим для приложений, использующих эту функцию:

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

Следующие шаги

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
    JavaScript
    MIT License
  • -
    security
    A
    license
    -
    quality
    An MCP server to create secure code sandbox environment for executing code within Docker containers.
    Last updated -
    69
    Go
    MIT License
    • Linux
    • Apple
  • -
    security
    F
    license
    -
    quality
    A personal MCP server for securely storing and accessing API keys across projects using the macOS Keychain, letting AI assistants and applications retrieve credentials through natural language.
    Last updated -
    10
    TypeScript
    • Apple
  • -
    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 -
    Python
    Apache 2.0

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