Fulfill input rounds and listen statelesslyA modern operation may request roots, sampling, or elicitation before it completes; generated clients handle roots and host-callback elicitation while leaving sampling undeclared. Modern notifications arrive through a fresh subscriptions/listen POST.rustacademyacademy/topics/mcp-modern-roundtrips-listeningwebsite/content-src/academy/course.mjsacademyFulfill input rounds and listen statelessly
A modern operation may request roots, sampling, or elicitation before it completes; generated clients handle roots and host-callback elicitation while leaving sampling undeclared. Modern notifications arrive through a fresh subscriptions/listen POST.
startListening()10 focused minutesNot started
Unit example (nearest native match)
See the idea in context
let transport = AxMCPStreamableHTTPTransport::new(endpoint, json!({}))?;
let mcp = Arc::new(Mutex::new(AxMCPClient::new(
Box::new(transport),
json!({"namespace":"inventory"}),
)));
let context = AxExecutionContext::new(vec![mcp.clone()], vec![])?;
let catalog = mcp.lock().unwrap().inspect_catalog(false)?;
println!("MCP catalog: {} tools, {} resources, {} templates",
catalog.tools.len(), catalog.resources.len(),
catalog.resource_templates.len());
let mut program = ax("request:string -> answer:string")?.with_execution_context(context)?;
let mut llm = OpenAICompatibleClient::new(key, "gpt-5.4-mini");
println!("{}", program.forward(
&mut llm, json!({"request":"Reindex inventory."}),
)?);
mcp.lock().unwrap().close()?;
Run itIn your own project
cargo add axllm
use axllm::{ai, ax};
use serde_json::json;
let llm = ai("openai", json!({"apiKey": std::env::var("OPENAI_API_KEY")?}))?;
let classify = ax("review:string -> sentiment:class \"positive, negative, neutral\"")?;
Set OPENAI_APIKEY in your environment before running provider-backed code.
In the ax repo
From a clone of the ax repo:
npm run example -- rust src/examples/rust/mcp/native_mcp_tools.rs