도구를 에이전트에 사용하기

도구(Tools)는 에이전트(Agents)나 워크플로우(Workflows)가 실행할 수 있는 타입이 지정된 함수입니다. 각 도구는 입력 값을 정의하는 스키마, 실제 동작을 수행하는 실행 함수(executor), 그리고 필요에 따라 통합 기능에 접근할 수 있는 옵션을 포함합니다.

Mastra에서는 에이전트에 도구를 제공하는 두 가지 방식이 있습니다.

  • 직접 할당: 에이전트가 초기화될 때 고정된 도구를 지정하는 방식

  • 함수 기반: 실행 시점의 컨텍스트에 따라 동적으로 도구를 제공하는 방식

도구 만들기

다음은 도구를 만드는 기본 예제입니다.

src/mastra/tools/weatherInfo.ts:

import { createTool } from "@mastra/core/tools";
import { z } from "zod";
 
export const weatherInfo = createTool({
  id: "Get Weather Information",  // 도구 식별자
  inputSchema: z.object({
    city: z.string(),             // 입력으로 'city' 문자열을 받음
  }),
  description: `지정된 도시의 현재 날씨 정보를 가져오는 도구입니다.`,
  execute: async ({ context: { city } }) => {
    // 실제 도구 로직을 여기에 구현 (예: API 호출)
    console.log("도구를 사용해", city, "의 날씨 정보를 가져오는 중입니다.");
    return { temperature: 20, conditions: "맑음" }; // 예시 응답값
  },
});

도구 생성과 설계에 대한 자세한 내용은 Tools Overview문서를 참고하세요.

에이전트에 도구 추가하기

에이전트가 특정 도구를 사용할 수 있도록 하려면, 에이전트 설정의 tools 속성에 해당 도구를 추가하면 됩니다.

src/mastra/agents/weatherAgent.ts:

import { Agent } from "@mastra/core/agent";
import { openai } from "@ai-sdk/openai";
import { weatherInfo } from "../tools/weatherInfo";
 
export const weatherAgent = new Agent({
  name: "Weather Agent",  // 에이전트 이름
  instructions:
    "당신은 현재 날씨 정보를 알려주는 친절한 어시스턴트입니다. 날씨에 대한 질문을 받으면 weather information 도구를 사용해 데이터를 가져오세요.",
  model: openai("gpt-4o-mini"),  // 사용하는 언어 모델
  tools: {
    weatherInfo,  // 연결된 도구
  },
});

이제 에이전트를 호출하면, 주어진 지침과 사용자 프롬프트에 따라 적절한 도구를 사용할지 여부를 스스로 판단하게 됩니다.

에이전트에 MCP 도구 추가하기

MCP (Model Context Protocol)는 AI 모델이 외부 도구나 리소스를 표준화된 방식으로 탐색하고 상호작용할 수 있게 해주는 프로토콜입니다. Mastra 에이전트를 MCP 서버에 연결하면 제3자가 제공하는 도구를 사용할 수 있습니다.

MCP의 개념과 클라이언트 및 서버 설정 방법에 대한 자세한 내용은 MCP Overview를 참고하세요.

설치

먼저 Mastra MCP 패키지를 설치합니다:

npm install @mastra/mcp@latest

MCP 도구 사용하기

사용 가능한 MCP 서버 레지스트리가 매우 다양하기 때문에 Mastra는 여러분이 적합한 MCP 서버를 쉽게 찾을 수 있도록 MCP 레지스트리 목록(MCP Registry Registry) 을 제공합니다.

에이전트와 사용할 서버가 있으면, Mastra MCPClient를 불러와서 서버 설정을 하면 됩니다.

src/mastra/mcp.ts:

import { MCPClient } from "@mastra/mcp";

// MCPClient를 설정하여 서버에 연결
export const mcp = new MCPClient({
  servers: {
    filesystem: {
      command: "npx",
      args: [
        "-y",
        "@modelcontextprotocol/server-filesystem",
        "/Users/username/Downloads",
      ],
    },
  },
});

이제 에이전트에 MCP 도구를 연결합니다:

src/mastra/agents/mcpAgent.ts:

import { Agent } from "@mastra/core/agent";
import { openai } from "@ai-sdk/openai";
import { mcp } from "../mcp";

// MCP 클라이언트에서 가져온 도구를 에이전트에 추가
const agent = new Agent({
  name: "Agent with MCP Tools",
  instructions: "연결된 MCP 서버에서 제공하는 도구를 사용할 수 있습니다.",
  model: openai("gpt-4o-mini"),
  tools: await mcp.getTools(),
});

같은 저장소에서 연결해야 하는 MCP 서버를 사용하는 에이전트를 생성할 때는 경쟁 상태(race condition)를 방지하기 위해 항상 함수 기반 도구를 사용하세요.

src/mastra/agents/selfReferencingAgent.ts:

import { Agent } from "@mastra/core/agent";
import { MCPServer } from "@mastra/mcp";
import { MCPClient } from "@mastra/mcp";
import { openai } from "@ai-sdk/openai";

const myAgent = new Agent({
  name: "My Agent",
  description: "HTTP MCP 서버의 도구를 사용할 수 있는 에이전트",
  instructions: "원격 계산 도구를 사용할 수 있습니다.",
  model: openai("gpt-4o-mini"),
  tools: async () => {
    // 초기화 시점이 아닌 실행 시점에 도구를 불러옵니다
    const mcpClient = new MCPClient({
      servers: {
        myServer: {
          url: new URL("http://localhost:4111/api/mcp/mcpServer/mcp"),
        },
      },
    });
    return await mcpClient.getTools();
  },
});

// 도구가 서버 시작 이후에 로딩되므로 충돌 없이 작동함
export const mcpServer = new MCPServer({
  name: "My MCP Server",
  agents: {
    myAgent,
  },
});

MCPClient 구성 및 정적 MCP 서버 구성과 동적 MCP 서버 구성의 차이점에 대한 자세한 내용은 MCP 개요를 참조하세요.

MCP 리소스 액세스

도구 외에도 MCP 서버는 리소스, 즉 애플리케이션에서 검색하고 사용할 수 있는 데이터나 콘텐츠도 노출할 수 있습니다.

src/mastra/resources.ts:

import { mcp } from "./mcp";

// 연결된 모든 MCP 서버에서 리소스 목록 가져오기
const resources = await mcp.getResources();

// 특정 서버의 리소스 접근
if (resources.filesystem) {
  const resource = resources.filesystem.find(
    (r) => r.uri === "filesystem://Downloads",
  );
  console.log(`Resource: ${resource?.name}`);
}

각 리소스는 URI, 이름, 설명, MIME 타입을 가지고 있습니다. getResources() 메소드는 오류를 적절히 처리합니다 - 서버가 실패하거나 리소스를 지원하지 않는 경우 결과에서 제외됩니다.

MCP 프롬프트 액세스

MCP 서버는 프롬프트도 노출할 수 있는데, 이는 에이전트를 위한 구조화된 메시지 템플릿이나 대화 컨텍스트를 나타냅니다.

프롬프트 목록 조회

src/mastra/prompts.ts:

import { mcp } from "./mcp";
 
// 연결된 모든 MCP 서버에서 프롬프트 가져오기
const prompts = await mcp.prompts.list();
 
// 특정 서버에서 프롬프트 액세스
if (prompts.weather) {
  const prompt = prompts.weather.find(
    (p) => p.name === "current"
  );
  console.log(`Prompt: ${prompt?.name}`);
}

각 프롬프트는 이름, 설명, 그리고 (선택적) 버전을 가지고 있습니다.

프롬프트 및 메시지 검색

src/mastra/prompts.ts:

const { prompt, messages } = await mcp.prompts.get({ serverName: "weather", name: "current" });
console.log(prompt);    // { name: "current", version: "v1", ... }
console.log(messages);  // [ { role: "assistant", content: { type: "text", text: "..." } }, ... ]

MCPServer를 통해 에이전트를 도구로 노출하기

MCP 서버의 도구를 사용하는 것 외에도, Mastra 에이전트 자체를 Mastra의 MCPServer를 사용하여 MCP 호환 클라이언트에게 도구로 노출할 수 있습니다.

Agent 인스턴스가 MCPServer 구성에 제공되면:

  • 자동으로 호출 가능한 도구로 변환됩니다.

  • 도구의 이름은 ask_<agentKey>가 되며, 여기서 <agentKey>MCPServeragents 구성에 에이전트를 추가할 때 사용한 식별자입니다.

  • 에이전트의 description 속성(비어있지 않은 문자열이어야 함)이 도구의 설명을 생성하는 데 사용됩니다.

이를 통해 다른 AI 모델이나 MCP 클라이언트가 마치 표준 도구인 것처럼 Mastra 에이전트와 상호작용할 수 있으며, 일반적으로 질문을 "묻는" 방식으로 작동합니다.

에이전트가 포함된 MCPServer 구성 예제:

src/mastra/mcp.ts:

import { Agent } from "@mastra/core/agent";
import { MCPServer } from "@mastra/mcp";
import { openai } from "@ai-sdk/openai";
import { weatherInfo } from "../tools/weatherInfo";
import { generalHelper } from "../agents/generalHelper"; 

const server = new MCPServer({
  name: "My Custom Server with Agent-Tool",
  version: "1.0.0",
  tools: {
    weatherInfo,
  },
  agents: { generalHelper }, // 'ask_generalHelper' 도구를 노출합니다
});

에이전트가 MCPServer에 의해 도구로 성공적으로 변환되려면, 생성자 구성에서 description 속성이 비어있지 않은 문자열로 설정되어야 합니다. 설명이 누락되거나 비어있으면 MCPServer는 초기화 중에 오류를 발생시킵니다.

MCPServer 설정 및 구성에 대한 자세한 내용은 MCPServer 참조 문서를 참조하세요.


2025년 7월 26일 기준 번역
by dongne.lab@gmail.com

Updated on