mirror of
https://github.com/run-llama/LlamaIndexTS.git
synced 2026-07-16 07:14:29 -04:00
feat: support SSE for MCP tools adapter (#1882)
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
---
|
||||
"@llamaindex/tools": patch
|
||||
---
|
||||
|
||||
Support SSE for MCP tools adapter
|
||||
@@ -57,6 +57,41 @@ const researchAgent = agent({
|
||||
});
|
||||
```
|
||||
|
||||
## MCP tools
|
||||
|
||||
If you have a MCP server running, you can fetch tools from the server and use them in your agents.
|
||||
|
||||
```ts
|
||||
// 1. Import MCP tools adapter
|
||||
import { mcp } from "@llamaindex/tools";
|
||||
import { agent } from "llamaindex";
|
||||
|
||||
// 2. Initialize a MCP client
|
||||
// by npx
|
||||
const server = mcp({
|
||||
command: "npx",
|
||||
args: ["-y", "@modelcontextprotocol/server-filesystem", "."],
|
||||
verbose: true,
|
||||
});
|
||||
// or by SSE
|
||||
const server = mcp({
|
||||
url: "http://localhost:8000/mcp",
|
||||
verbose: true,
|
||||
});
|
||||
|
||||
// 3. Get tools from MCP server
|
||||
const tools = await server.tools();
|
||||
|
||||
// Now you can create an agent with the tools
|
||||
const agent = agent({
|
||||
name: "My Agent",
|
||||
systemPrompt: "You are a helpful assistant that can use the provided tools to answer questions.",
|
||||
llm: openai({ model: "gpt-4o" }),
|
||||
tools: tools,
|
||||
});
|
||||
```
|
||||
|
||||
|
||||
## Function tool
|
||||
|
||||
You can still use the `FunctionTool` class to define a tool.
|
||||
|
||||
@@ -9,6 +9,12 @@ async function main() {
|
||||
args: ["-y", "@modelcontextprotocol/server-filesystem", "."],
|
||||
verbose: true,
|
||||
});
|
||||
// You can also connect to the MCP server using SSE
|
||||
// See: https://modelcontextprotocol.io/docs/concepts/transports#server-sent-events-sse
|
||||
// const server = mcp({
|
||||
// url: "http://localhost:8000/mcp",
|
||||
// verbose: true,
|
||||
// });
|
||||
|
||||
try {
|
||||
// Create an agent that uses the MCP tools
|
||||
@@ -21,9 +27,7 @@ async function main() {
|
||||
});
|
||||
|
||||
// Run a task
|
||||
const response = await myAgent.run(
|
||||
"what are the files in the current directory?",
|
||||
);
|
||||
const response = await myAgent.run("What are the available tools?");
|
||||
|
||||
console.log("Agent response:", response.data);
|
||||
} finally {
|
||||
|
||||
@@ -2,6 +2,10 @@ import type { JSONValue } from "@llamaindex/core/global";
|
||||
import type { BaseToolWithCall } from "@llamaindex/core/llms";
|
||||
import { FunctionTool } from "@llamaindex/core/tools";
|
||||
import { Client } from "@modelcontextprotocol/sdk/client/index.js";
|
||||
import {
|
||||
SSEClientTransport,
|
||||
type SSEClientTransportOptions,
|
||||
} from "@modelcontextprotocol/sdk/client/sse.js";
|
||||
import {
|
||||
StdioClientTransport,
|
||||
type StdioServerParameters,
|
||||
@@ -13,7 +17,7 @@ interface ToolInput {
|
||||
[key: string]: unknown;
|
||||
}
|
||||
|
||||
type MCPClientOptions = StdioServerParameters & {
|
||||
type MCPCommonOptions = {
|
||||
/**
|
||||
* The prefix to add to the tool name
|
||||
*/
|
||||
@@ -32,11 +36,20 @@ type MCPClientOptions = StdioServerParameters & {
|
||||
verbose?: boolean;
|
||||
};
|
||||
|
||||
type StdioMCPClientOptions = StdioServerParameters & MCPCommonOptions;
|
||||
type SSEMCPClientOptions = SSEClientTransportOptions &
|
||||
MCPCommonOptions & {
|
||||
url: string;
|
||||
};
|
||||
|
||||
type MCPClientOptions = StdioMCPClientOptions | SSEMCPClientOptions;
|
||||
|
||||
class MCPClient {
|
||||
private mcp: Client;
|
||||
private transport: StdioClientTransport | null = null;
|
||||
private transport: StdioClientTransport | SSEClientTransport | null = null;
|
||||
private verbose: boolean;
|
||||
private toolNamePrefix?: string | undefined;
|
||||
private connected: boolean = false;
|
||||
|
||||
constructor(options: MCPClientOptions) {
|
||||
this.mcp = new Client({
|
||||
@@ -46,18 +59,34 @@ class MCPClient {
|
||||
|
||||
this.verbose = options.verbose ?? false;
|
||||
this.toolNamePrefix = options.toolNamePrefix;
|
||||
this.connectToSever(options);
|
||||
if ("url" in options) {
|
||||
this.transport = new SSEClientTransport(
|
||||
new URL(options.url),
|
||||
options as SSEClientTransportOptions,
|
||||
);
|
||||
} else {
|
||||
this.transport = new StdioClientTransport(
|
||||
options as StdioServerParameters,
|
||||
);
|
||||
}
|
||||
this.connected = false;
|
||||
}
|
||||
|
||||
async connectToSever(options: StdioServerParameters) {
|
||||
async connectToSever() {
|
||||
if (this.verbose) {
|
||||
console.log("Connecting to MCP server...");
|
||||
}
|
||||
this.transport = new StdioClientTransport(options);
|
||||
if (!this.transport) {
|
||||
throw new Error("Initialized with invalid options");
|
||||
}
|
||||
await this.mcp.connect(this.transport);
|
||||
this.connected = true;
|
||||
}
|
||||
|
||||
async listTools(): Promise<Tool[]> {
|
||||
private async listTools(): Promise<Tool[]> {
|
||||
if (!this.connected) {
|
||||
await this.connectToSever();
|
||||
}
|
||||
const tools = await this.mcp.listTools();
|
||||
return tools.tools;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user