> ## Documentation Index
> Fetch the complete documentation index at: https://praison.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# MCP Tools

> Connect AI agents to any MCP server with automatic transport selection

Connect agents to Model Context Protocol (MCP) servers to give them access to external tools, data, and services.

```mermaid theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
graph LR
    subgraph "MCP Integration"
        A[🤖 Agent] --> B[🔌 MCP]
        B --> C{Auto-detect}
        C -->|URL ends /sse| D[📡 SSE]
        C -->|other URLs| E[🌊 HTTP-Streaming]
        D --> F[✅ MCP Server]
        E --> F
    end

    classDef agent fill:#8B0000,stroke:#7C90A0,color:#fff
    classDef transport fill:#189AB4,stroke:#7C90A0,color:#fff
    classDef result fill:#10B981,stroke:#7C90A0,color:#fff
    classDef detect fill:#F59E0B,stroke:#7C90A0,color:#fff

    class A agent
    class B,D,E transport
    class C detect
    class F result
    classDef agent fill:#8B0000,color:#fff
    classDef tool fill:#189AB4,color:#fff

```

## Quick Start

**1. Simple Usage**

```typescript theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
import { Agent, MCP } from 'praisonai';

const mcp = new MCP('http://127.0.0.1:8080/sse');
await mcp.initialize();
```

**2. With Configuration**

```typescript theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
const toolFunctions = Object.fromEntries(
  [...mcp].map(tool => [tool.name, async (args: any) => tool.execute(args)])
);

const agent = new Agent({
  instructions: 'You are a helpful assistant with access to MCP tools.',
  name: 'MCPAgent',
  tools: mcp.toOpenAITools(),
  toolFunctions,
});

const response = await agent.runSync('What tools are available?');
console.log(response);

await mcp.close();
```

***

## Transport Selection

The `MCP` class picks the right transport automatically — no config objects needed.

```mermaid theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
graph TB
    Start([URL provided]) --> Auto{transport = ?}
    Auto -->|'auto' default| Detect{URL ends with /sse?}
    Auto -->|'sse'| SSE[SSE transport]
    Auto -->|'http-streaming'| HTTP[HTTP-Streaming transport]
    Detect -->|Yes| SSE
    Detect -->|No| HTTP

    classDef detect fill:#F59E0B,stroke:#7C90A0,color:#fff
    classDef transport fill:#189AB4,stroke:#7C90A0,color:#fff
    classDef start fill:#8B0000,stroke:#7C90A0,color:#fff

    class Start start
    class Auto,Detect detect
    class SSE,HTTP transport
```

| URL pattern | `transport` param | Transport used |
| - | - | - |
| `http://host/sse` | `'auto'` (default) | SSE |
| `http://host/api` | `'auto'` (default) | HTTP-Streaming |
| any URL | `'sse'` | SSE (forced) |
| any URL | `'http-streaming'` | HTTP-Streaming (forced) |

> [!WARNING]
>
> Auto-detection is **suffix-based**: only URLs that end exactly with `/sse` select SSE. A URL like `https://api.example.com/sse/v2` will **not** auto-select SSE — pass `'sse'` explicitly.

***

## Examples

> [tab] Auto (default)
>
> ```typescript theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
> import { Agent, MCP } from 'praisonai-ts';
>
> async function main() {
>   // URL ends with /sse → auto-selects SSE
>   const mcp = new MCP('http://127.0.0.1:8080/sse');
>   await mcp.initialize();
>   console.log(`Transport: ${mcp.transportType}`); // 'sse'
>
>   const toolFunctions = Object.fromEntries(
>     [...mcp].map(tool => [tool.name, async (args: any) => tool.execute(args)])
>   );
>
>   const agent = new Agent({
>     instructions: 'You are a helpful assistant.',
>     name: 'AutoMCPAgent',
>     tools: mcp.toOpenAITools(),
>     toolFunctions,
>   });
>
>   const response = await agent.runSync('What tools are available?');
>   console.log(response);
>
>   await mcp.close();
> }
>
> main().catch(console.error);
> ```

> [tab] Explicit SSE
>
> ```typescript theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
> import { Agent, MCP } from 'praisonai-ts';
>
> async function main() {
>   // Force SSE regardless of URL pattern
>   const mcp = new MCP('http://127.0.0.1:8080/api', 'sse');
>   await mcp.initialize();
>   console.log(`Transport: ${mcp.transportType}`); // 'sse'
>
>   const toolFunctions = Object.fromEntries(
>     [...mcp].map(tool => [tool.name, async (args: any) => tool.execute(args)])
>   );
>
>   const agent = new Agent({
>     instructions: 'You are a helpful assistant.',
>     name: 'SSEMCPAgent',
>     tools: mcp.toOpenAITools(),
>     toolFunctions,
>   });
>
>   const response = await agent.runSync('List available tools');
>   console.log(response);
>
>   await mcp.close();
> }
>
> main().catch(console.error);
> ```

> [tab] HTTP-Streaming
>
> ```typescript theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
> import { Agent, MCP } from 'praisonai-ts';
>
> async function main() {
>   // Force HTTP-Streaming
>   const mcp = new MCP('http://127.0.0.1:8080/stream', 'http-streaming');
>   await mcp.initialize();
>   console.log(`Transport: ${mcp.transportType}`); // 'http-streaming'
>
>   const toolFunctions = Object.fromEntries(
>     [...mcp].map(tool => [tool.name, async (args: any) => tool.execute(args)])
>   );
>
>   const agent = new Agent({
>     instructions: 'You are a helpful assistant.',
>     name: 'HTTPMCPAgent',
>     tools: mcp.toOpenAITools(),
>     toolFunctions,
>   });
>
>   const response = await agent.runSync('What can you do?');
>   console.log(response);
>
>   await mcp.close();
> }
>
> main().catch(console.error);
> ```

> [tab] Debug mode
>
> ```typescript theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
> import { Agent, MCP } from 'praisonai-ts';
>
> async function main() {
>   // Enable debug logging to see transport selection details
>   const mcp = new MCP('http://127.0.0.1:8080/sse', 'auto', true);
>   await mcp.initialize();
>   // Logs: "MCP client initialized for URL: ... with transport: sse"
>   // Logs: "Initialized MCP with N tools using sse transport"
>
>   const agent = new Agent({
>     instructions: 'You are a helpful assistant.',
>     name: 'DebugMCPAgent',
>     tools: mcp.toOpenAITools(),
>     toolFunctions: Object.fromEntries(
>       [...mcp].map(tool => [tool.name, async (args: any) => tool.execute(args)])
>     ),
>   });
>
>   const response = await agent.runSync('Hello!');
>   console.log(response);
>
>   await mcp.close();
> }
>
> main().catch(console.error);
> ```

***

## Configuration Options

| Option | Type | Default | Description |
| - | - | - | - |
| `url` | `string` | required | MCP server URL |
| `transport` | `TransportType` | `'auto'` | One of `'auto' \| 'sse' \| 'http-streaming'` |
| `debug` | `boolean` | `false` | Log transport selection and tool count |

```typescript theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
import { MCP, TransportType } from 'praisonai-ts';

const mcp = new MCP(
  'http://127.0.0.1:8080/stream',  // url
  'http-streaming',                  // transport
  true                               // debug
);
```

***

## Instance API

| Method / Property | Returns | Description |
| - | - | - |
| `initialize()` | `Promise<void>` | Connect and load tools from the server |
| `close()` | `Promise<void>` | Disconnect and release resources |
| `toOpenAITools()` | `OpenAITool[]` | Convert tools to OpenAI function-call format |
| `[...mcp]` | `MCPTool[]` | Iterate over available tools |
| `mcp.tools` | `MCPTool[]` | Array of loaded tools (after `initialize()`) |
| `mcp.isConnected` | `boolean` | `true` after `initialize()`, `false` after `close()` |
| `mcp.transportType` | `string` | `'sse'`, `'http-streaming'`, or `'not initialized'` |

***

## New Exports

```typescript theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
import { 
  MCP,                    // Unified MCP client (use this)
  TransportType,          // 'auto' | 'sse' | 'http-streaming'
  HTTPStreamingTransport, // Low-level transport (advanced use)
  MCPHttpStreaming,       // Standalone HTTP-Streaming client
  MCPTool,               // Tool type
  MCPToolInfo            // Tool info type
} from 'praisonai-ts';
```

***

## Parity `MCP` Class (multi-server)

The `MCP` class exported from `praisonai` manages **multiple named MCP servers** and delegates to the real `MCPClient` (stdio / HTTP / SSE). It mirrors Python's `praisonaiagents.mcp` and uses a `connect` / `callTool` API keyed by server name.

> [!NOTE]
>
> Before **v1.7.4**, this parity `MCP.callTool()` returned `null` and silently no-op'd every call. As of v1.7.4 it delegates to a live `MCPClient` connection.

```typescript theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
import { MCP } from 'praisonai';

const mcp = new MCP();

// Connect a named server (config is passed to MCPClient)
await mcp.connect('search', {
  transport: 'stdio',
  command: 'npx',
  args: ['-y', '@modelcontextprotocol/server-everything'],
});

// Call a tool on that server
const result = await mcp.callTool('search', 'echo', { message: 'hello' });
console.log(result);

console.log(mcp.listServers()); // ['search']

await mcp.disconnect('search');
```

| Method | Returns | Description |
| - | - | - |
| `connect(name, config)` | `Promise<void>` | Connect a named server. `config` matches `MCPClientConfig` |
| `callTool(server, tool, args)` | `Promise<any>` | Call `tool` on the named `server` with `args` |
| `disconnect(name)` | `Promise<void>` | Disconnect and remove the named server |
| `listServers()` | `string[]` | Names of connected servers |

> [!WARNING]
>
> Call `connect(name, config)` before `callTool(name, ...)`. Calling a tool on an unconnected server throws `MCP server '<name>' is not connected`.

***

## AI SDK-style: `createMCP()`

`createMCP()` from `'praisonai/ai'` is the AI SDK-style client with full transport support.

```typescript theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
import { createMCP } from 'praisonai/ai';

const client = await createMCP({
  transport: {
    type: 'stdio',
    command: 'my-mcp-server',
    args: ['--flag'],
    env: { API_KEY: '...' },
  },
});

const tools = await client.tools();
await client.close();
```

### Transport types

`MCPTransportConfig` is a discriminated union on `type`.

| `type` | Fields | Notes |
| - | - | - |
| `'stdio'` | `command`, `args?`, `env?` | Spawns a local server; env merged with `process.env`. |
| `'sse'` | `url`, `headers?`, `authProvider?` | `authProvider` is now forwarded (previously dropped, breaking OAuth). |
| `'http'` | `url`, `headers?`, `authProvider?` | Streamable HTTP transport. |
| `'websocket'` | `url`, `headers?` | WebSocket transport. |

### MCPConfig

| Option | Type | Default | Description |
| - | - | - | - |
| `transport` | `MCPTransportConfig` | required | Transport configuration |
| `name` | `string` | `'praisonai-ts-mcp'` | Client name |
| `version` | `string` | `'1.0.0'` | Client version |
| `onUncaughtError` | `(error: unknown) => void` | — | Callback for uncaught errors |

### MCPClient methods

| Method | Returns | Description |
| - | - | - |
| `tools()` | `Promise<Record<string, MCPTool>>` | Load tools from the server |
| `listResources()` | `Promise<MCPResource[]>` | List available resources |
| `readResource(uri)` | `Promise<MCPResourceContent>` | Read a resource |
| `listPrompts()` | `Promise<MCPPrompt[]>` | List available prompts |
| `getPrompt(name, args?)` | `Promise<MCPPromptResult>` | Get a prompt |
| `close()` | `Promise<void>` | Close the connection |

> [!WARNING]
>
> `createMCP()` no longer returns an empty client when the underlying transport fails. Connection errors, unknown transport types, and missing binaries now throw — an agent that used to silently get zero tools now fails loudly with the real error.

***

## Best Practices

> [accordion] Always call close() when done
>
> MCP connections stay open until explicitly closed. Always call `await mcp.close()` to release resources, especially in long-running applications or when switching servers.
>
> ```typescript theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
> const mcp = new MCP('http://localhost:8080/sse');
> try {
>   await mcp.initialize();
>   // ... use the agent
> } finally {
>   await mcp.close();
> }
> ```

> [accordion] Use debug=true when connecting a new server
>
> Enable debug mode when first wiring up a new MCP server. It logs the selected transport and number of tools loaded, making misconfiguration easy to spot.
>
> ```typescript theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
> const mcp = new MCP('http://localhost:8080/api', 'auto', true);
> await mcp.initialize();
> // Console: "Initialized MCP with 5 tools using http-streaming transport"
> ```

> [accordion] Pass transport explicitly when URL patterns are ambiguous
>
> Auto-detection relies on the URL ending in `/sse`. If your server URL doesn't follow this convention, pass the transport explicitly to avoid surprises.
>
> ```typescript theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
> // This will use HTTP-Streaming even though it's an SSE server
> const wrong = new MCP('https://api.example.com/sse/v2');  // auto = http-streaming
>
> // Correct: pass transport explicitly
> const right = new MCP('https://api.example.com/sse/v2', 'sse');
> ```

> [accordion] Prefer MCP over MCPHttpStreaming for new code
>
> Use the unified `MCP` class for all new integrations. `MCPHttpStreaming` is a standalone client without auto-detection. Only use it if you specifically need direct HTTP-Streaming without the unified interface.

***

## Related

> [card] [MCP Security](https://praison.ai/docs/js/mcp-security.md)
>
> Secure MCP connections with authentication and rate limiting

> [card] [Python MCP Transports](https://praison.ai/docs/mcp/transports.md)
>
> Python equivalent — stdio, Streamable HTTP, WebSocket, SSE

> [card] [Tools](https://praison.ai/docs/js/tools.md)
>
> Tool system overview for TypeScript agents

> [card] [Agent](https://praison.ai/docs/js/agent.md)
>
> Agent configuration and capabilities


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.