Skip to content

Model Context Protocol capabilities

Attach an MCP server definition to one Agent and verify that its capabilities stay scoped to that session.

No credentials neededNo live MCP connection

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.

  • an AML project configured through Getting started; the testing entrypoint is included in the SDK;
  • no MCP server, credentials, or network access.
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))

Save the complete source as recipe.tsx in a project configured as shown in Getting started, then run the non-networking fixture directly:

Terminal
npx vite-node recipe.tsx

From an AML repository checkout, run the maintained fixture with:

Terminal
npm run example -- mcp
MCP attached. Sibling isolated.
  1. defineMcpServer() validates and freezes a named stdio or Streamable HTTP descriptor. It does not open a connection.
  2. <Mcp /> attaches that exact descriptor to the nearest <Agent />.
  3. The provider receives MCP metadata in the normalized Agent request. A real provider decides how to negotiate and relay the server.
  4. A sibling <Agent /> has no <Mcp /> child, so it receives no MCP capability. Capability scope follows the authored tree.

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.

  • The server name must be non-empty and normalized; transport URLs must be absolute http: or https: URLs.
  • An Agent provider may reject a transport, unavailable executable, unsupported server, disallowed name, or failed authentication.
  • Use allowedMcpServers in AmlRuntime to 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.