Перейти к основному содержимому

HTTP-транспорт

Помимо stdio, Neva поддерживает потоковый HTTP-транспорт — двунаправленный транспортный уровень поверх HTTP, обеспечивающий удалённые подключения к MCP-серверу.

Базовая настройка

Для запуска сервера на потоковом HTTP используйте with_http() в параметрах:

use neva::prelude::*;

#[tokio::main]
async fn main() {
App::new()
.with_options(|opt| opt
.with_http(|http| http
.bind("127.0.0.1:3000")))
.run()
.await;
}

Это запустит HTTP-сервер на 127.0.0.1:3000 с конечной точкой /mcp по умолчанию.

Кастомная конечная точка

Путь конечной точки MCP можно изменить с помощью with_endpoint():

App::new()
.with_options(|opt| opt
.with_http(|http| http
.bind("127.0.0.1:3000")
.with_endpoint("/my-mcp")))
.run()
.await;

Конфигурация HTTP по умолчанию

Для быстрого старта используйте with_default_http(), который привязывается к 127.0.0.1:3000 с конечной точкой по умолчанию:

App::new()
.with_options(|opt| opt.with_default_http())
.run()
.await;

TLS

Для включения HTTPS настройте TLS с помощью метода with_tls():

let http = HttpServer::new("localhost:7878")
.with_tls(|tls| tls
.with_dev_cert(DevCertMode::Auto));

App::new()
.with_options(|opt| opt.set_http(http))
.run()
.await;

DevCertMode::Auto автоматически генерирует самоподписанный сертификат для локальной разработки. В продакшене используйте собственный сертификат и файл ключа.

JWT-аутентификация

Neva поддерживает аутентификацию по токену Bearer через JWT для HTTP-транспорта.

Для включения используйте with_auth() внутри with_http():

let secret = std::env::var("JWT_SECRET")
.expect("JWT_SECRET must be set");

App::new()
.with_options(|opt| opt
.with_http(|http| http
.with_auth(|auth| auth
.validate_exp(false)
.with_aud(["my-service"])
.with_iss(["my-issuer"])
.set_decoding_key(secret.as_bytes()))))
.run()
.await;

Параметры конфигурации аутентификации

МетодОписание
set_decoding_key()Секретный или публичный ключ для проверки подписи JWT
with_aud()Принимаемые значения audience токена
with_iss()Принимаемые значения issuer токена
validate_exp()Проверять ли срок действия токена (по умолчанию true)

Управление доступом на основе ролей

После настройки аутентификации можно ограничить доступ к отдельным инструментам, запросам и ресурсам с помощью атрибутов roles и permissions:

/// Доступно всем
#[tool]
async fn public_tool(name: String) {
tracing::info!("Running public tool for {name}");
}

/// Только для пользователей с ролью "admin"
#[tool(roles = ["admin"])]
async fn admin_tool(name: String) {
tracing::info!("Running admin tool for {name}");
}

/// Только для пользователей с ролью "admin" и правом "read"
#[prompt(roles = ["admin"], permissions = ["read"])]
async fn restricted_prompt(topic: String) -> PromptMessage {
PromptMessage::user()
.with(format!("Restricted topic: {topic}"))
}

/// Только для пользователей с правом "read"
#[resource(uri = "res://restricted/{name}", permissions = ["read"])]
async fn restricted_resource(uri: Uri, name: String) -> (String, String) {
(uri.to_string(), name)
}

Роли и права извлекаются из claims JWT-токена. При несоответствии требованиям доступ отклоняется с ошибкой 403 Forbidden.

Блокирующий запуск

Для сценариев, где необходима синхронная точка входа (например, встраивание в неасинхронный контекст), вместо .run().await можно использовать run_blocking():

fn main() {
App::new()
.with_options(|opt| opt.with_default_http())
.run_blocking();
}

Тестирование с MCP Inspector

Для тестирования потокового HTTP-сервера через MCP Inspector сначала запустите сервер:

cargo run

Затем откройте Inspector и подключитесь к http://127.0.0.1:3000/mcp.

Обучение на примерах