Model Context Protocol capabilities
Attach an MCP server definition to one Agent and verify that its capabilities stay scoped to that session.
Understand how AML attaches an MCP descriptor to one <Agent /> and keeps that capability scoped. This page intentionally uses the repository’s non-networking mcp.tsx fixture.
Prerequisites
Section titled “Prerequisites”- an AML project configured through Getting started; the testing entrypoint is included in the SDK;
- no MCP server, credentials, or network access.
Complete source
Section titled “Complete source”import { Agent, AmlRuntime, defineMcpServer, Mcp } from "@aml-jsx/sdk"import { DeterministicAgentProvider } from "@aml-jsx/sdk/testing"
const projectServer = defineMcpServer({ name: "project", transport: { type: "streamable-http", url: "https://example.com/mcp", },})
const provider = new DeterministicAgentProvider({ respond(request) { if (request.prompt === "Inspect the project.") { return { text: request.mcpServers.length === 1 ? "MCP attached." : "MCP missing." } }
return { text: request.mcpServers.length === 0 ? "Sibling isolated." : "MCP leaked." } },})
const workflow = ( <> <Agent provider={provider}> <Mcp use={projectServer} /> Inspect the project. </Agent> <Agent provider={provider}>Summarize without capabilities.</Agent> </>)
console.log(await new AmlRuntime().evaluate(workflow))Run it
Section titled “Run it”Save the complete source as recipe.tsx in a project configured as shown in Getting started, then run the non-networking fixture directly:
npx vite-node recipe.tsxFrom an AML repository checkout, run the maintained fixture with:
npm run example -- mcpExpected output
Section titled “Expected output”MCP attached. Sibling isolated.How it works
Section titled “How it works”defineMcpServer()validates and freezes a named stdio or Streamable HTTP descriptor. It does not open a connection.<Mcp />attaches that exact descriptor to the nearest<Agent />.- The provider receives MCP metadata in the normalized Agent request. A real provider decides how to negotiate and relay the server.
- A sibling
<Agent />has no<Mcp />child, so it receives no MCP capability. Capability scope follows the authored tree.
Live transport shapes
Section titled “Live transport shapes”AML supports these descriptor shapes, but a live example also needs a compatible Agent provider, server, executable, credentials, and policy:
const localServer = defineMcpServer({ name: "local-tools", transport: { type: "stdio", command: "my-mcp-server", args: ["--project", "/absolute/project"], env: { MCP_LOG_LEVEL: "warn" }, },})
const remoteServer = defineMcpServer({ name: "remote-tools", transport: { type: "streamable-http", url: "https://mcp.example.invalid/mcp", headers: { Authorization: `Bearer ${process.env.MCP_TOKEN ?? ""}` }, },})These snippets describe valid AML transport data; they are not runnable against the placeholder executable or domain. Never hard-code a real token into a descriptor committed to source.
Failure and security notes
Section titled “Failure and security notes”- The server name must be non-empty and normalized; transport URLs must be absolute
http:orhttps:URLs. - An Agent provider may reject a transport, unavailable executable, unsupported server, disallowed name, or failed authentication.
- Use
allowedMcpServersinAmlRuntimeto constrain explicit names when the workflow is user-authored. - Treat remote MCP tools as external capabilities with their own trust, data egress, and prompt-injection risks. Allowlist servers and inspect the tools they expose.
- A Sandbox does not automatically make a remote MCP server trustworthy; network and credential policy remain deployment concerns.