> For the complete documentation index, see [llms.txt](/llms.txt).
> A full single-fetch corpus is available at [llms-full.txt](/llms-full.txt).
---
title: Model Context Protocol
description: Connect external MCP servers to AGNT5 agents, or expose AGNT5 tools and agents over a local MCP server.
last_verified: 2026-07-24
---



**Model Context Protocol (MCP)** is an open standard for connecting AI systems to external tools and data sources. AGNT5 supports it in both directions:

- **`MCPClient`** pulls tools from any external MCP server into your agents.
- **`MCPServer`** publishes your AGNT5 tools, agents, workflows, and prompts so any MCP-compatible client can call them.

## Connect external MCP servers

`MCPClient` connects to one or more MCP servers, discovers their tools, and converts those tools into AGNT5 `Tool` objects.



**Python:**

```python
from agnt5 import Agent
from agnt5.mcp import MCPClient

mcp = MCPClient(id="deepwiki-client")
mcp.add_streamable_http_server("deepwiki", "https://mcp.deepwiki.com/mcp")
await mcp.connect()

agent = Agent(
    name="researcher",
    model="openai/gpt-4o-mini",
    instructions="Use available tools to answer questions about code repositories.",
    tools=mcp.get_tools(),
)

result = await agent.run("What is CPython and what is it written in?")
print(result.output)

await mcp.disconnect()
```

Use `async with` when you want the client to connect and disconnect around one block:

```python
from agnt5 import Agent
from agnt5.mcp import MCPClient

mcp = MCPClient(id="deepwiki-client")
mcp.add_streamable_http_server("deepwiki", "https://mcp.deepwiki.com/mcp")

async with mcp:
    agent = Agent(
        name="researcher",
        model="openai/gpt-4o-mini",
        instructions="Use available tools to answer questions about code repositories.",
        tools=mcp.get_tools(),
    )
    result = await agent.run("What is CPython and what is it written in?")
    print(result.output)
```





**TypeScript:**

```typescript
const mcp = new MCPClient('deepwiki-client');
mcp.addStreamableHttpServer('deepwiki', 'https://mcp.deepwiki.com/mcp');
await mcp.connect();

const agent = new Agent({
  name: 'researcher',
  model: LM.openai(),
  modelName: 'openai/gpt-4o-mini',
  instructions: 'Use available tools to answer questions about code repositories.',
  tools: mcp.getTools(),
});

const result = await agent.run('What is CPython and what is it written in?');
console.log(result.output);

await mcp.disconnect();
```

There is no `async with`-style block scoping in the TypeScript SDK — call `connect()`/`disconnect()` explicitly, or wrap in `try`/`finally`:

```typescript
const mcp = new MCPClient('deepwiki-client');
mcp.addStreamableHttpServer('deepwiki', 'https://mcp.deepwiki.com/mcp');

try {
  await mcp.connect();

  const agent = new Agent({
    name: 'researcher',
    model: LM.openai(),
    modelName: 'openai/gpt-4o-mini',
    instructions: 'Use available tools to answer questions about code repositories.',
    tools: mcp.getTools(),
  });
  const result = await agent.run('What is CPython and what is it written in?');
  console.log(result.output);
} finally {
  await mcp.disconnect();
}
```





**Go:**

```go
const mcp = new MCPClient("tools");

mcp.addStreamableHttpServer("deepwiki", "https://mcp.deepwiki.com/mcp");
mcp.addSseServer("internal-tools", "https://example.com/sse", {
  Authorization: "Bearer ...",
});
mcp.addStdioServer("local", "npx", ["-y", "my-mcp-server"]);
```

Go's `MCPClient` wraps exactly one transport per client — there's no multi-server registry with `add_*_server` helpers. Connect to multiple servers by constructing one `agnt5.NewMCPClient` per transport:

```go
stdioTransport, err := agnt5.NewStdioMCPTransport(ctx, "npx", "-y", "my-mcp-server")
localClient, err := agnt5.NewMCPClient(stdioTransport)

sseTransport := agnt5.NewSSEMCPTransport("https://example.com/sse", map[string]string{
    "Authorization": "Bearer ...",
})
remoteClient, err := agnt5.NewMCPClient(sseTransport)
```

## Work with MCP tools

After `connect()`, the client caches discovered tools.

<ForLang lang="python">

Call a tool directly when you know the server name:

```python
result = await mcp.call_tool("deepwiki", "ask_question", {
    "repoName": "python/cpython",
    "question": "What is CPython?",
})

print(result.get_text())
```

Call by tool name when the server does not matter:

```python
result = await mcp.call_tool_auto("ask_question", {
    "repoName": "python/cpython",
    "question": "What language is CPython written in?",
})

print(result.get_text())
```

Common client methods:

| Method | What it does |
|---|---|
| `connect()` / `disconnect()` | Open and close connections to all configured servers |
| `get_tools()` | Return discovered MCP tools as AGNT5 `Tool` objects for `Agent(tools=...)` |
| `list_tools()` | List every discovered tool with its source server |
| `list_server_tools(server)` | List tools from one server |
| `call_tool(server, name, args)` | Call a tool on a specific server |
| `call_tool_auto(name, args)` | Call the first matching tool name across connected servers |
| `is_connected(server)` | Check whether one server is connected |
| `connected_servers()` | Return connected server names |





**TypeScript:**

Call a tool directly when you know the server name:

```typescript
const result = await mcp.callTool('deepwiki', 'ask_question', {
  repoName: 'python/cpython',
  question: 'What is CPython?',
});

console.log(result.content.map((c) => c.text).join('\n'));
```

Call by tool name when the server does not matter:

```typescript
const result = await mcp.callToolAuto('ask_question', {
  repoName: 'python/cpython',
  question: 'What language is CPython written in?',
});

console.log(result.content.map((c) => c.text).join('\n'));
```

`CallToolResult` doesn't have a `getText()` helper in the TypeScript SDK — read `result.content` directly.

Common client methods:

| Method | What it does |
|---|---|
| `connect()` / `disconnect()` | Open and close connections to all configured servers |
| `getTools()` | Return discovered MCP tools as AGNT5 `Tool` objects for `Agent({ tools: ... })` |
| `listTools()` | List every discovered tool with its source server |
| `listServerTools(server)` | List tools from one server |
| `callTool(server, name, args)` | Call a tool on a specific server |
| `callToolAuto(name, args)` | Call the first matching tool name across connected servers |
| `isConnected(server)` | Check whether one server is connected |
| `connectedServers()` | Return connected server names |





**Go:**

Call a tool by name directly — since a Go client wraps one transport, there's no server-name or "auto" distinction to make.

```go
result, err := mcp.CallTool(ctx, "ask_question", map[string]any{
    "repoName": "python/cpython",
    "question": "What is CPython?",
})

for _, block := range result.Content {
    fmt.Println(block["text"])
}
```

Client methods:

| Method | What it does |
|---|---|
| `ListTools(ctx) ([]MCPTool, error)` | List tools discovered from the wrapped transport |
| `CallTool(ctx, name, arguments) (MCPCallToolResult, error)` | Call a tool by name |
| `Close() error` | Close the underlying transport |

There's no `ListResources`/multi-server methods like `list_server_tools`/`connected_servers` — those only make sense for Python/TypeScript's multi-server client. `MCPCallToolResult` has no `GetText()` helper — read `.Content` (a `[]map[string]any`) or `.IsError`/`.Raw` directly.



<Callout type="info">Always call `connect()` first. The tool list is built from the cache populated during connection.</Callout>

## Expose AGNT5 over MCP

`MCPServer` runs the protocol in reverse: it publishes AGNT5 primitives so MCP-compatible clients can call them. Use stdio for local developer workflows in Claude Desktop, Cursor, VS Code, and similar clients. Use Streamable HTTP when you want to host the server behind an HTTP endpoint.



**Python:**

```python
from agnt5 import Agent
from agnt5.mcp import MCPServer
from agnt5.tool import tool

@tool
async def greet(ctx, name: str) -> str:
    """Greet someone by name."""
    return f"Hello, {name}!"

assistant = Agent(
    name="assistant",
    model="openai/gpt-4o-mini",
    instructions="Help the user.",
)

server = MCPServer(
    id="my-server",
    name="My AGNT5 Server",
    version="1.0.0",
    tools={"greet": greet},
    agents={"assistant": assistant},
)

await server.run_stdio()
```

You can register primitives when constructing the server or add them later:

```python
server.add_tool("search", search_tool)
server.add_agent("analyst", analyst_agent)
server.add_workflow("pipeline", my_workflow)
```





**TypeScript:**

```typescript
const greet = tool(
  'greet',
  {
    description: 'Greet someone by name.',
    inputSchema: {
      type: 'object',
      properties: { name: { type: 'string' } },
      required: ['name'],
    },
  },
  async (ctx: Context, args: { name: string }) => `Hello, ${args.name}!`,
);

const assistant = new Agent({
  name: 'assistant',
  model: LM.openai(),
  modelName: 'openai/gpt-4o-mini',
  instructions: 'Help the user.',
});

const server = new MCPServer({
  id: 'my-server',
  name: 'My AGNT5 Server',
  version: '1.0.0',
  tools: { greet: greet._tool },
  agents: { assistant },
});

await server.runStdio();
```

`tool()` returns a callable wrapper for use elsewhere in your code; `MCPServer` needs the underlying `Tool` instance, which the wrapper exposes as `._tool`.

You can register primitives when constructing the server or add them later:

```typescript
server.addTool('search', searchTool._tool);
server.addAgent('analyst', analystAgent);
server.addWorkflow('pipeline', myWorkflow);
```





**Go:**

Not yet available in the Go SDK — there's no `MCPServer` type. `agnt5.NewMCPClient` and its transports are client-only; you can't publish AGNT5 tools, agents, workflows, or prompts as an MCP server from Go yet.



## Server transports

| Method | Python | TypeScript | Go |
|---|---|---|---|
| `run_stdio()` / `runStdio()` | Available | Available | Not available |
| `run_http(host, port, path)` / `runHTTP()` | Available | Available | Not available |

Server-side legacy SSE hosting is not exposed. Current MCP remote hosting should use Streamable HTTP.

## Next steps

- [Tools](/docs/build/tools.md): define AGNT5 tools that agents and MCP clients can call.
- [Agents](/docs/build/agents.md): attach imported MCP tools to an agent loop.
- [AI providers](/docs/integrations/ai-providers.md): configure model credentials for agents that use MCP tools.
- [Local development](/docs/build/local-development.md): run and test AGNT5 code from your laptop.
