Model Context Protocol capabilities
Capability fixture
Terminal
Terminal
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”- Node.js
>=26; @aml-jsx/sdkand@aml-jsx/sdk/testing;- 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.