모델 컨텍스트 프로토콜

모델 컨텍스트 프로토콜 (Model Context Protocol, MCP)

langchain-mcp-adapters 패키지에 대한 레거시 MCP 문서입니다.

Model Context Protocol (MCP)는 애플리케이션이 LLM에 도구와 컨텍스트를 제공하는 방식을 표준화하는 개방형 프로토콜입니다. LangChain 에이전트는 @langchain/mcp-adapters 라이브러리를 사용해 MCP 서버에 정의된 도구를 사용할 수 있습니다.

퀵스타트 (Quickstart)

@langchain/mcp-adapters 라이브러리를 설치하세요:

```bash npm theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}} npm install @langchain/mcp-adapters ```
pnpm add @langchain/mcp-adapters
yarn add @langchain/mcp-adapters
bun add @langchain/mcp-adapters

@langchain/mcp-adapters는 에이전트가 하나 이상의 MCP 서버에 정의된 도구를 사용할 수 있게 해줍니다.

`MultiServerMCPClient`는 기본적으로 **상태가 없습니다(stateless)**. 각 도구 호출은 새로운 MCP `ClientSession`을 만들고 도구를 실행한 뒤 정리합니다.
import { MultiServerMCPClient } from "@langchain/mcp-adapters";  // [!code highlight]
import { ChatAnthropic } from "@langchain/anthropic";
import { createAgent } from "langchain";

const client = new MultiServerMCPClient({  // [!code highlight]
    math: {
        transport: "stdio",  // Local subprocess communication
        command: "node",
        // Replace with absolute path to your math_server.js file
        args: ["/path/to/math_server.js"],
    },
    weather: {
        transport: "http",  // HTTP-based remote server
        // Ensure you start your weather server on port 8000
        url: "http://localhost:8000/mcp",
    },
});

const tools = await client.getTools();  // [!code highlight]
const agent = createAgent({
    model: "claude-sonnet-5",
    tools,  // [!code highlight]
});

const mathResponse = await agent.invoke({
    messages: [{ role: "user", content: "what's (3 + 5) x 12?" }],
});

const weatherResponse = await agent.invoke({
    messages: [{ role: "user", content: "what is the weather in nyc?" }],
});
에이전트의 추론 단계와 함께 MCP 도구 호출을 [LangSmith](https://smith.langchain.com?utm_source=docs\&utm_medium=cta\&utm_campaign=langsmith-signup\&utm_content=oss-javascript-langchain-mcp)로 추적하세요. 설정은 [추적 퀵스타트](/langsmith/trace-with-langchain)를 참조하세요. [LangChain docs MCP 서버](/use-these-docs)는 `https://docs.langchain.com/mcp`에 있는 공개 HTTP 엔드포인트입니다. 에이전트를 연결해 커스텀 도구를 작성하지 않고 문서를 검색하고 읽을 수 있습니다. docs MCP 서버는 공개이며 API 키가 필요하지 않습니다. IDE와 코딩 에이전트 설정(Claude Code, Cursor 등)은 [Use docs programmatically](/use-these-docs)를 참조하세요.
import { MultiServerMCPClient } from "@langchain/mcp-adapters";  // [!code highlight]
import { createAgent } from "langchain";

const client = new MultiServerMCPClient({
    docs: {
        transport: "http",
        url: "https://docs.langchain.com/mcp",  // [!code highlight]
    },
});

const tools = await client.getTools();
const agent = createAgent({
    model: "claude-sonnet-5",
    tools,
});

const response = await agent.invoke({
    messages: [
        {
            role: "user",
            content: "How do I add short-term memory to a LangChain agent?",
        },
    ],
});

서버가 노출하는 도구는 다음과 같습니다:

도구 설명
search_docs_by_lang_chain 관련 가이드, how-to, 예시를 문서에서 검색합니다.
query_docs_filesystem_docs_by_lang_chain 가상 파일 시스템(rg, head, cat 및 관련 명령)을 통해 문서를 읽거나 검색합니다.
submit_feedback 문서 페이지에 문제를 보고합니다.

커스텀 서버 (Custom servers)

자체 MCP 서버를 만들려면 @modelcontextprotocol/sdk 라이브러리를 사용할 수 있습니다. 이 라이브러리는 도구를 정의하고 서버로 실행하는 간단한 방법을 제공합니다.

```bash npm theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}} npm install @modelcontextprotocol/sdk ```
pnpm add @modelcontextprotocol/sdk
yarn add @modelcontextprotocol/sdk
bun add @modelcontextprotocol/sdk

MCP 도구 서버로 에이전트를 테스트하려면 다음 예시를 사용하세요:

import { Server } from "@modelcontextprotocol/sdk/server/index.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import {
    CallToolRequestSchema,
    ListToolsRequestSchema,
} from "@modelcontextprotocol/sdk/types.js";

const server = new Server(
    {
        name: "math-server",
        version: "0.1.0",
    },
    {
        capabilities: {
            tools: {},
        },
    }
);

server.setRequestHandler(ListToolsRequestSchema, async () => {
    return {
        tools: [
        {
            name: "add",
            description: "Add two numbers",
            inputSchema: {
                type: "object",
                properties: {
                    a: {
                        type: "number",
                        description: "First number",
                    },
                    b: {
                        type: "number",
                        description: "Second number",
                    },
                },
                required: ["a", "b"],
            },
        },
        {
            name: "multiply",
            description: "Multiply two numbers",
            inputSchema: {
                type: "object",
                properties: {
                    a: {
                        type: "number",
                        description: "First number",
                    },
                    b: {
                        type: "number",
                        description: "Second number",
                    },
                },
                required: ["a", "b"],
            },
        },
        ],
    };
});

server.setRequestHandler(CallToolRequestSchema, async (request) => {
    switch (request.params.name) {
        case "add": {
            const { a, b } = request.params.arguments as { a: number; b: number };
            return {
                content: [
                {
                    type: "text",
                    text: String(a + b),
                },
                ],
            };
        }
        case "multiply": {
            const { a, b } = request.params.arguments as { a: number; b: number };
            return {
                content: [
                {
                    type: "text",
                    text: String(a * b),
                },
                ],
            };
        }
        default:
            throw new Error(`Unknown tool: ${request.params.name}`);
    }
});

async function main() {
    const transport = new StdioServerTransport();
    await server.connect(transport);
    console.error("Math MCP server running on stdio");
}

main();
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
import { SSEServerTransport } from "@modelcontextprotocol/sdk/server/sse.js";
import {
    CallToolRequestSchema,
    ListToolsRequestSchema,
} from "@modelcontextprotocol/sdk/types.js";
import express from "express";

const app = express();
app.use(express.json());

const server = new Server(
    {
        name: "weather-server",
        version: "0.1.0",
    },
    {
        capabilities: {
            tools: {},
        },
    }
);

server.setRequestHandler(ListToolsRequestSchema, async () => {
    return {
        tools: [
        {
            name: "get_weather",
            description: "Get weather for location",
            inputSchema: {
            type: "object",
            properties: {
                location: {
                type: "string",
                description: "Location to get weather for",
                },
            },
            required: ["location"],
            },
        },
        ],
    };
});

server.setRequestHandler(CallToolRequestSchema, async (request) => {
    switch (request.params.name) {
        case "get_weather": {
            const { location } = request.params.arguments as { location: string };
            return {
                content: [
                    {
                        type: "text",
                        text: `It's always sunny in ${location}`,
                    },
                ],
            };
        }
        default:
            throw new Error(`Unknown tool: ${request.params.name}`);
    }
});

app.post("/mcp", async (req, res) => {
    const transport = new SSEServerTransport("/mcp", res);
    await server.connect(transport);
});

const PORT = process.env.PORT || 8000;
app.listen(PORT, () => {
    console.log(`Weather MCP server running on port ${PORT}`);
});

전송 (Transports)

MCP는 클라이언트-서버 통신을 위한 여러 전송 메커니즘을 지원합니다.

HTTP

http 전송(또는 streamable-http라고도 함)은 클라이언트-서버 통신에 HTTP 요청을 사용합니다. 자세한 내용은 MCP HTTP 전송 사양을 참조하세요.

직접 실행하는 서버에는 로컬 URL을, 공개이고 API 키가 필요 없는 LangChain docs MCP 서버(https://docs.langchain.com/mcp) 같은 호스팅 URL을 사용하세요.

import { MultiServerMCPClient } from "@langchain/mcp-adapters";
import { createAgent } from "langchain";

const client = new MultiServerMCPClient({
    mcp: {
        transport: "http",
        // url: "http://localhost:8000/mcp", // Local server
        url: "https://docs.langchain.com/mcp", // Hosted server
    },
});

const tools = await client.getTools();
const agent = createAgent({ model: "openai:gpt-5.4", tools });
const response = await agent.invoke({
    messages: [
        {
            role: "user",
            content: "How do I connect LangChain to an MCP server over HTTP?",
        },
    ],
});

헤더 전달 (Passing headers)

HTTP로 MCP 서버에 연결할 때 연결 구성의 headers 필드를 사용해 커스텀 헤더(예: 인증 또는 추적용)를 포함할 수 있습니다. 이 예시는 LangChain docs MCP 서버를 사용합니다. 인증이 필요한 서버에는 헤더 값을 바꾸세요:

import { MultiServerMCPClient } from "@langchain/mcp-adapters";
import { createAgent } from "langchain";

const client = new MultiServerMCPClient({
    mcp: {
        transport: "http",
        url: "https://docs.langchain.com/mcp",
        headers: {  // [!code highlight]
            Authorization: "Bearer YOUR_TOKEN",  // [!code highlight]
            "X-Custom-Header": "custom-value",  // [!code highlight]
        },  // [!code highlight]
    },
});

const tools = await client.getTools();
const agent = createAgent({ model: "openai:gpt-5.4", tools });
const response = await agent.invoke({
    messages: [
        {
            role: "user",
            content: "How do I connect LangChain to an MCP server over HTTP?",
        },
    ],
});

인증 (Authentication)

@langchain/mcp-adapters 라이브러리는 내부적으로 공식 MCP TypeScript SDK를 사용하며, OAuthClientProvider 인터페이스를 구현해 커스텀 인증 메커니즘을 제공할 수 있습니다.

import { MultiServerMCPClient } from "@langchain/mcp-adapters";

const client = new MultiServerMCPClient({
    weather: {
        transport: "http",
        url: "http://localhost:8000/mcp",
        authProvider: authProvider, // [!code highlight]
    },
});

stdio

클라이언트가 서버를 하위 프로세스로 시작하고 표준 입력/출력으로 통신합니다. 로컬 도구와 단순한 구성에 가장 적합합니다.

const client = new MultiServerMCPClient({
    math: {
        transport: "stdio",
        command: "node",
        args: ["/path/to/math_server.js"],
    },
});

핵심 기능 (Core features)

도구 (Tools)

도구는 MCP 서버가 LLM이 작업을 수행하기 위해 호출할 수 있는 실행 가능한 함수를 노출하게 해줍니다. 예를 들어 데이터베이스 쿼리, API 호출, 외부 시스템과의 상호작용 등이 있습니다. LangChain은 MCP 도구를 LangChain 도구로 변환해 어떤 LangChain 에이전트나 워크플로에서도 바로 사용할 수 있게 합니다.

도구 로딩 (Loading tools)

client.getTools()를 사용해 MCP 서버에서 도구를 가져와 에이전트에 전달하세요:

import { MultiServerMCPClient } from "@langchain/mcp-adapters";
import { createAgent } from "langchain";

const client = new MultiServerMCPClient({...});
const tools = await client.getTools();  // [!code highlight]
const agent = createAgent({ model: "claude-sonnet-5", tools });

MCP 도구 실행이 실패하면(isError: trueCallToolResult) @langchain/mcp-adaptersToolException을 발생시킵니다. 이 오류를 처리하려면 도구 호출을 try/catch로 감싸세요. Python 어댑터와 달리 TypeScript 어댑터는 오류를 실패한 도구 메시지로 모델에 반환하지 않습니다.

구조화된 콘텐츠 (Structured content)

MCP 도구는 사람이 읽을 수 있는 텍스트 응답과 함께 구조화된 콘텐츠를 반환할 수 있습니다. 이는 도구가 모델에 표시되는 텍스트 외에도 기계가 파싱할 수 있는 데이터(JSON 같은)를 반환해야 할 때 유용합니다.

MCP 도구가 structuredContent를 반환하면 어댑터는 도구 메시지 artifact 배열에 mcp_structured_content 항목을 추가합니다. 도구 인터셉터를 사용해 구조화된 콘텐츠를 자동으로 처리하거나 변환할 수도 있습니다.

artifact에서 구조화된 콘텐츠 추출

에이전트를 호출한 뒤 응답의 도구 메시지에서 구조화된 콘텐츠에 접근할 수 있습니다:

import { MultiServerMCPClient } from "@langchain/mcp-adapters";
import { createAgent } from "langchain";

const client = new MultiServerMCPClient({...});
const tools = await client.getTools();
const agent = createAgent({ model: "claude-sonnet-5", tools });

const result = await agent.invoke({
    messages: [{ role: "user", content: "Get data from the server" }],
});

for (const message of result.messages) {
    if (message.type !== "tool" || !message.artifact) continue;
    for (const item of message.artifact) {
        if (item?.type === "mcp_structured_content") {
            console.log(item.data);
        }
    }
}

멀티모달 도구 콘텐츠 (Multimodal tool content)

MCP 도구는 응답에서 멀티모달 콘텐츠(이미지, 텍스트 등)를 반환할 수 있습니다. MCP 서버가 여러 파트(예: 텍스트와 이미지)가 있는 콘텐츠를 반환하면 어댑터는 이를 LangChain의 표준 콘텐츠 블록으로 변환합니다. ToolMessagecontentBlocks 속성으로 표준화된 표현에 접근할 수 있습니다:

```ts Google theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}} import { createAgent } from "langchain";

async function accessMultimodalToolContent(): Promise { const { MultiServerMCPClient } = await import("@langchain/mcp-adapters"); const client = new MultiServerMCPClient({}); const tools = await client.getTools(); const agent = createAgent({ model: "google-genai:gemini-3.6-flash", tools });

const result = await agent.invoke({
  messages: [
    { role: "user", content: "Take a screenshot of the current page" },
  ],
});

// Access multimodal content from tool messages
for (const message of result.messages) {
  if (message.type === "tool") {
    // Raw content in provider-native format
    console.log(`Raw content: ${message.content}`);

    // Standardized content blocks  // [!code highlight]
    for (const block of message.contentBlocks) {
      // [!code highlight]
      if (block.type === "text") {
        // [!code highlight]
        console.log(`Text: ${block.text}`); // [!code highlight]
      } else if (block.type === "image") {
        // [!code highlight]
        console.log(`Image URL: ${block.url}`); // [!code highlight]
        console.log(`Image base64: ${block.base64?.slice(0, 50)}...`); // [!code highlight]
      }
    }
  }
}

}


```ts OpenAI theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
import { createAgent } from "langchain";

async function accessMultimodalToolContent(): Promise<void> {
  const { MultiServerMCPClient } = await import("@langchain/mcp-adapters");
  const client = new MultiServerMCPClient({});
  const tools = await client.getTools();
  const agent = createAgent({ model: "openai:gpt-5.5", tools });

  const result = await agent.invoke({
    messages: [
      { role: "user", content: "Take a screenshot of the current page" },
    ],
  });

  // Access multimodal content from tool messages
  for (const message of result.messages) {
    if (message.type === "tool") {
      // Raw content in provider-native format
      console.log(`Raw content: ${message.content}`);

      // Standardized content blocks  // [!code highlight]
      for (const block of message.contentBlocks) {
        // [!code highlight]
        if (block.type === "text") {
          // [!code highlight]
          console.log(`Text: ${block.text}`); // [!code highlight]
        } else if (block.type === "image") {
          // [!code highlight]
          console.log(`Image URL: ${block.url}`); // [!code highlight]
          console.log(`Image base64: ${block.base64?.slice(0, 50)}...`); // [!code highlight]
        }
      }
    }
  }
}
import { createAgent } from "langchain";

async function accessMultimodalToolContent(): Promise<void> {
  const { MultiServerMCPClient } = await import("@langchain/mcp-adapters");
  const client = new MultiServerMCPClient({});
  const tools = await client.getTools();
  const agent = createAgent({ model: "anthropic:claude-sonnet-5", tools });

  const result = await agent.invoke({
    messages: [
      { role: "user", content: "Take a screenshot of the current page" },
    ],
  });

  // Access multimodal content from tool messages
  for (const message of result.messages) {
    if (message.type === "tool") {
      // Raw content in provider-native format
      console.log(`Raw content: ${message.content}`);

      // Standardized content blocks  // [!code highlight]
      for (const block of message.contentBlocks) {
        // [!code highlight]
        if (block.type === "text") {
          // [!code highlight]
          console.log(`Text: ${block.text}`); // [!code highlight]
        } else if (block.type === "image") {
          // [!code highlight]
          console.log(`Image URL: ${block.url}`); // [!code highlight]
          console.log(`Image base64: ${block.base64?.slice(0, 50)}...`); // [!code highlight]
        }
      }
    }
  }
}
import { createAgent } from "langchain";

async function accessMultimodalToolContent(): Promise<void> {
  const { MultiServerMCPClient } = await import("@langchain/mcp-adapters");
  const client = new MultiServerMCPClient({});
  const tools = await client.getTools();
  const agent = createAgent({ model: "openrouter:z-ai/glm-5.2", tools });

  const result = await agent.invoke({
    messages: [
      { role: "user", content: "Take a screenshot of the current page" },
    ],
  });

  // Access multimodal content from tool messages
  for (const message of result.messages) {
    if (message.type === "tool") {
      // Raw content in provider-native format
      console.log(`Raw content: ${message.content}`);

      // Standardized content blocks  // [!code highlight]
      for (const block of message.contentBlocks) {
        // [!code highlight]
        if (block.type === "text") {
          // [!code highlight]
          console.log(`Text: ${block.text}`); // [!code highlight]
        } else if (block.type === "image") {
          // [!code highlight]
          console.log(`Image URL: ${block.url}`); // [!code highlight]
          console.log(`Image base64: ${block.base64?.slice(0, 50)}...`); // [!code highlight]
        }
      }
    }
  }
}
import { createAgent } from "langchain";

async function accessMultimodalToolContent(): Promise<void> {
  const { MultiServerMCPClient } = await import("@langchain/mcp-adapters");
  const client = new MultiServerMCPClient({});
  const tools = await client.getTools();
  const agent = createAgent({ model: "fireworks:accounts/fireworks/models/glm-5p2", tools });

  const result = await agent.invoke({
    messages: [
      { role: "user", content: "Take a screenshot of the current page" },
    ],
  });

  // Access multimodal content from tool messages
  for (const message of result.messages) {
    if (message.type === "tool") {
      // Raw content in provider-native format
      console.log(`Raw content: ${message.content}`);

      // Standardized content blocks  // [!code highlight]
      for (const block of message.contentBlocks) {
        // [!code highlight]
        if (block.type === "text") {
          // [!code highlight]
          console.log(`Text: ${block.text}`); // [!code highlight]
        } else if (block.type === "image") {
          // [!code highlight]
          console.log(`Image URL: ${block.url}`); // [!code highlight]
          console.log(`Image base64: ${block.base64?.slice(0, 50)}...`); // [!code highlight]
        }
      }
    }
  }
}
import { createAgent } from "langchain";

async function accessMultimodalToolContent(): Promise<void> {
  const { MultiServerMCPClient } = await import("@langchain/mcp-adapters");
  const client = new MultiServerMCPClient({});
  const tools = await client.getTools();
  const agent = createAgent({ model: "baseten:zai-org/GLM-5.2", tools });

  const result = await agent.invoke({
    messages: [
      { role: "user", content: "Take a screenshot of the current page" },
    ],
  });

  // Access multimodal content from tool messages
  for (const message of result.messages) {
    if (message.type === "tool") {
      // Raw content in provider-native format
      console.log(`Raw content: ${message.content}`);

      // Standardized content blocks  // [!code highlight]
      for (const block of message.contentBlocks) {
        // [!code highlight]
        if (block.type === "text") {
          // [!code highlight]
          console.log(`Text: ${block.text}`); // [!code highlight]
        } else if (block.type === "image") {
          // [!code highlight]
          console.log(`Image URL: ${block.url}`); // [!code highlight]
          console.log(`Image base64: ${block.base64?.slice(0, 50)}...`); // [!code highlight]
        }
      }
    }
  }
}
import { createAgent } from "langchain";

async function accessMultimodalToolContent(): Promise<void> {
  const { MultiServerMCPClient } = await import("@langchain/mcp-adapters");
  const client = new MultiServerMCPClient({});
  const tools = await client.getTools();
  const agent = createAgent({ model: "ollama:north-mini-code-1.0", tools });

  const result = await agent.invoke({
    messages: [
      { role: "user", content: "Take a screenshot of the current page" },
    ],
  });

  // Access multimodal content from tool messages
  for (const message of result.messages) {
    if (message.type === "tool") {
      // Raw content in provider-native format
      console.log(`Raw content: ${message.content}`);

      // Standardized content blocks  // [!code highlight]
      for (const block of message.contentBlocks) {
        // [!code highlight]
        if (block.type === "text") {
          // [!code highlight]
          console.log(`Text: ${block.text}`); // [!code highlight]
        } else if (block.type === "image") {
          // [!code highlight]
          console.log(`Image URL: ${block.url}`); // [!code highlight]
          console.log(`Image base64: ${block.base64?.slice(0, 50)}...`); // [!code highlight]
        }
      }
    }
  }
}

이렇게 하면 기본 MCP 서버가 콘텐츠를 포맷하는 방식과 무관하게 프로바이더에 구애받지 않는 방식으로 멀티모달 도구 응답을 처리할 수 있습니다.

리소스 (Resources)

리소스는 MCP 서버가 파일, 데이터베이스 레코드, API 응답 같은 데이터를 노출하게 해주며 클라이언트가 읽을 수 있습니다.

리소스 로딩 (Loading resources)

client.listResources()로 리소스를 발견하고 client.readResource()로 내용을 읽으세요:

import { MultiServerMCPClient } from "@langchain/mcp-adapters";

const client = new MultiServerMCPClient({...});

// List resources from a server
const resourcesByServer = await client.listResources("server_name");  // [!code highlight]
for (const resource of resourcesByServer["server_name"] ?? []) {
    console.log(`URI: ${resource.uri}, MIME type: ${resource.mimeType}`);
}

// Read a specific resource by URI
const contents = await client.readResource(  // [!code highlight]
    "server_name",
    "file:///path/to/file.txt",
);
for (const content of contents) {
    console.log(`URI: ${content.uri}, MIME type: ${content.mimeType}`);
    if (content.text) console.log(content.text);
}

고급 기능 (Advanced features)

도구 인터셉터 (Tool interceptors)

MCP 서버는 별도의 프로세스로 실행됩니다. store, context, 에이전트 상태 같은 LangGraph 런타임 정보에는 접근할 수 없습니다. MultiServerMCPClientbeforeToolCallafterToolCall 훅을 사용해 도구 인자, 헤더, 또는 결과를 수정하세요:

import { MultiServerMCPClient } from "@langchain/mcp-adapters";

const client = new MultiServerMCPClient({
    mcpServers: {
        math: {
            transport: "stdio",
            command: "npx",
            args: ["-y", "@modelcontextprotocol/server-math"],
        },
    },
    beforeToolCall: ({ serverName, name, args }) => {  // [!code highlight]
        const nextArgs = { ...(args as Record<string, unknown>), injected: true };
        return {
            args: nextArgs,
            headers: { "X-Request-ID": crypto.randomUUID() },
        };
    },
    afterToolCall: (res) => {  // [!code highlight]
        if (res.name === "someTool") {
            return { result: ["modified-output", []] };
        }
        return { result: res.result };
    },
});

const tools = await client.getTools();
  • beforeToolCall: { args?, headers? }를 반환할 수 있습니다. 헤더는 HTTP와 SSE 전송에서 지원됩니다. Stdio 연결은 커스텀 헤더를 지원하지 않습니다.
  • afterToolCall: result[content, artifact] 튜플, ToolMessage, LangGraph Command, 또는 원래 결과인 { result }를 반환할 수 있습니다.

진행 알림 (Progress notifications)

onProgress로 오래 걸리는 도구 실행의 진행 업데이트를 구독하세요:

import { MultiServerMCPClient } from "@langchain/mcp-adapters";

const client = new MultiServerMCPClient({
    mcpServers: {
        everything: {
            transport: "stdio",
            command: "npx",
            args: ["-y", "@modelcontextprotocol/server-everything"],
        },
    },
    onProgress: (progress, source) => {  // [!code highlight]
        const pct =
            progress.percentage ??
            (progress.progress != null && progress.total
                ? Math.round((progress.progress / progress.total) * 100)
                : undefined);
        if (pct == null) return;
        const origin =
            source.type === "tool" ? `${source.server}/${source.name}` : "unknown";
        console.log(`[progress:${origin}] ${pct}%`);
    },
});

const tools = await client.getTools();

로깅 (Logging)

MCP 프로토콜은 서버의 로깅 알림을 지원합니다. onMessage로 구독하세요:

import { MultiServerMCPClient } from "@langchain/mcp-adapters";

const client = new MultiServerMCPClient({
    mcpServers: {
        everything: {
            transport: "stdio",
            command: "npx",
            args: ["-y", "@modelcontextprotocol/server-everything"],
        },
    },
    onMessage: (log, source) => {  // [!code highlight]
        console.log(`[${source.server}] ${log.level}: ${log.data}`);
    },
});

const tools = await client.getTools();

client.setLoggingLevel("debug") 또는 client.setLoggingLevel("server_name", "debug")로 서버 로깅 레벨을 설정할 수도 있습니다.

추가 리소스 (Additional resources)

더 알아보기