Основы
Давайте воспользуемся MCP-клиентом Neva для подключения к вашим MCP-серверам (и другим тоже).
Создание приложения
Создайте новое бинарное приложение:
cargo new neva-mcp-client
cd neva-mcp-client
Добавьте следующие зависимости в ваш Cargo.toml:
[dependencies]
neva = { version = "...", features = "client-full" }
tokio = { version = "1", features = ["full"] }
Вызов инструмента
Для начала вызовем инструмент, созданный в разделе основы сервера.
use neva::prelude::*;
#[tokio::main]
async fn main() -> Result<(), Error> {
let mut client = Client::new()
.with_options(|opt| opt
.with_stdio(
"cargo",
["run", "--manifest-path", "./neva-mcp-server/Cargo.toml"]));
client.connect().await?;
let args = ("name", "John");
let result = client.call_tool("hello", args).await?;
println!("{:?}", result.content);
client.disconnect().await
}
Здесь мы настраиваем MCP-клиент для подключения к серверу через stdio.
После подключения можно вызывать инструменты, получать запросы или читать ресурсы вплоть до отключения (или удаления клиента).
disconnect() — локальная операцияОн останавливает транспорт и ничего не отправляет по сети. В протоколе
нет прощального сообщения: notifications/cancelled без параметров, который
neva отправляла раньше, не проходит проверку по схеме самой спецификации, а о
том, что клиент ушёл, сервер и так узнаёт по закрытому соединению.
Получение промпта
Далее получим промпт, чтобы увидеть, как они работают на стороне клиента.
let args = ("lang", "Rust");
let prompt = client.get_prompt("hello_world_code", args).await?;
Чтение ресурса
Затем прочитаем ресурс, объявленный здесь.
let resource = client.read_resource("res://resource-1").await?;
Список инструментов, промптов и ресурсов
Наконец, вот как динамически изучить все доступные инструменты, промпты и ресурсы.
// Возвращает список инструментов
let tools = client
.list_tools(None)
.await?;
// Возвращает список ресурсов
let resources = client
.list_resources(None)
.await?;
// Возвращает список шаблонов ресурсов
let templates = client
.list_resource_templates(None)
.await?;
// Возвращает список промптов
let prompts = client
.list_prompts(None)
.await?;
Пагинация
Большие списки по умолчанию возвращаются постранично по 10 элементов.
Используйте значение next_cursor для получения следующих страниц:
// Первые 10
let resources = client
.list_resources(None)
.await?;
// Следующие 10
let resources = client
.list_resources(resources.next_cursor)
.await?;
// Ещё 10
let resources = client
.list_resources(resources.next_cursor)
.await?;
Списки на стороне сервера упорядочены детерминированно по имени, поэтому постраничный обход больше не может пропустить или продублировать запись. См. Порядок в списке.
Кэширование
Каждый результат-список — а также server/discover и resources/read —
несёт ttlMs и cacheScope. В MCP 2026-07-28 это обязательные члены, а
не опциональные подсказки, поэтому клиент всегда знает, как долго результат
остаётся актуальным и кому его можно показывать:
cacheScope | Смысл |
|---|---|
private | Кэшируется только для этого клиента (значение по умолчанию) |
public | Может использоваться разными клиентами |
Обучение на примерах
Полный пример доступен здесь.