커넥터 도구 호출
커넥터 도구 호출 (Connectors Tool Calling)
대화를 거치지 않고 Connector의 개별 도구를 직접 호출하는 방법을 다루는 쿡북이에요. 이미 어느 도구를 호출할지 아는 경우, 원시 도구 출력이 필요한 경우, 파이프라인이나 디버깅을 구축할 때 유용하죠.
출처: 문서
본문
Connector의 개별 도구를 대화를 거치지 않고 직접 호출해 봅시다.
API 상태 (API status): 도구 호출은 client.beta.connectors.call_tool을 사용해요. 이는 베타(beta) 엔드포인트로 변경될 수 있어요.
사전 준비사항 (Prerequisites)
설치 (Install)
# Python
pip install mistralai
# or with uv
uv add mistralai
# TypeScript
pnpm add @mistralai/mistralai
필요한 환경 변수 (Required environment variables)
이 쿡북을 완료하려면 Mistral API 키가 필요해요. Studio에서 API keys 섹션으로 이동해서 새 API 키를 만들어요.
프로젝트 루트에 .env를 만들고 Mistral API 키를 추가해요.
MISTRAL_API_KEY=your-mistral-api-key
시작 전에 필요한 것 (What you need before starting)
- 작동하는
client(여기 참조) - 기존 커넥터 — Build a Database Advisor Agent를 보면 커넥터 수명주기의 전체 예제를 볼 수 있고, Studio에서 만들 수도 있어요.
직접 도구 호출을 쓸 시점 (When to Use Direct Tool Calling)
직접 도구 호출(call_tool)은 대화를 시작하지 않고 커넥터에서 단일 MCP 도구를 호출하게 해줘요. 다음 경우에 유용해요.
- 호출할 도구를 이미 아는 경우 — 모델이 결정할 필요가 없어요.
- 원시 도구 출력을 원하는 경우 — 예: 후속 처리를 위해 구조화된 데이터를 가져올 때.
- 파이프라인 구축 — 모델의 오케스트레이션에 의존하지 않고 도구 호출을 프로그래밍 방식으로 연결할 때.
- 디버깅 — 대화에서 사용하기 전에 커넥터의 도구가 올바르게 작동하는지 검증할 때.
모델이 호출할 도구를 자율적으로 선택해야 하는 시나리오에는 대신 Conversations API를 사용하세요.
레시피 (Recipes)
1. 클라이언트 초기화 (Initialize the Client)
사전 준비사항 (Prereqs): 환경이나 .env 파일에 MISTRAL_API_KEY가 설정되어 있어야 해요.
Python:
import os
from mistralai import Mistral
client = Mistral(api_key=os.environ["MISTRAL_API_KEY"])
TypeScript:
import Mistral from "@mistralai/mistralai";
const client = new Mistral({ apiKey: proces..._KEY });
curl:
# All subsequent curl examples assume these variables are set:
export MISTRAL_API_KEY="your-api-key"
export BASE_URL="https://api.mistral.ai"
출력 (Output): 없음 — 클라이언트는 사용할 준비가 됐어요.
일반적인 오류와 해결책 (Common errors & fixes):
| Error | Cause | Fix |
|---|---|---|
401 Unauthorized |
Invalid API key | Regenerate your key on the Mistral dashboard |
2. 커넥터 만들기 (Create a Connector)
목표 (Goal): 도구를 직접 호출할 수 있도록 커넥터를 등록해요.
언제 쓰나 (When to use):
- 도구를 호출하기 전 첫 번째 단계예요 — 타겟으로 할 커넥터가 필요해요.
- 이미 커넥터가 있다면 Recipe 3로 건너뛰세요.
사전 준비사항 (Prereqs): 초기화된 client (Recipe 1).
Python:
import asyncio
from mistralai import Mistral
client = Mistral(api_key="your-api-key")
async def main() -> None:
connector = await client.beta.connectors.create_async(
name="my_deepwiki",
description="DeepWiki MCP connector for code repository exploration",
server="https://mcp.deepwiki.com/mcp",
visibility="private",
)
print(f"ID: {connector.id}")
print(f"Name: {connector.name}")
asyncio.run(main())
TypeScript:
import Mistral from "@mistralai/mistralai";
const client = new Mistral({ apiKey: *** });
async function main(): Promise<void> {
const connector = await client.beta.connectors.create({
name: "my_deepwiki",
description: "DeepWiki MCP connector for code repository exploration",
server: "https://mcp.deepwiki.com/mcp",
visibility: "private",
});
console.log(`ID: ${connector.id}`);
console.log(`Name: ${connector.name}`);
}
main();
curl:
curl -X POST "${BASE_URL}/v1/connectors" \
-H "Authorization: Bearer ${MIST...KEY}" \
-H "Content-Type: application/json" \
-d '{
"name": "my_deepwiki",
"description": "DeepWiki MCP connector for code repository exploration",
"server": "https://mcp.deepwiki.com/mcp",
"visibility": "private"
}'
출력 (Output):
ID: a1b2c3d4-5678-90ab-cdef-1234567890ab
Name: my_deepwiki
작동 방식 (How it works):
- 커넥터 생성, 업데이트, 삭제의 전체 설명은 Build a Database Advisor Agent를 참조하세요.
- 도구를 호출하려면 먼저 커넥터가 생성되어 있어야 해요.
일반적인 오류와 해결책 (Common errors & fixes):
| Error | Cause | Fix |
|---|---|---|
409 Conflict |
A connector with this name already exists | Choose a different name or delete the existing one first |
3. 커넥터에서 도구 호출 (Call a Tool on a Connector)
목표 (Goal): Connector가 노출하는 특정 도구를 호출하고 원시 결과를 얻어요.
언제 쓰나 (When to use):
- 호출할 도구와 전달할 인자를 정확히 알 때
- 모델 해석 없이 원시 도구 출력을 원할 때
- 도구 호출을 연결하는 자동화된 파이프라인을 구축할 때
- 커넥터의 도구가 올바르게 응답하는지 디버깅하거나 검증할 때
사전 준비사항 (Prereqs):
- 이름이나 ID로 된 기존 커넥터
- 도구 이름과 예상 인자에 대한 지식. 대화에서 모델에게 도구 목록을 요청하거나,
client.beta.connectors.get으로 커넥터의tools필드를 확인해서 사용 가능한 도구를 발견할 수 있어요.
Python:
import asyncio
from mistralai import Mistral
client = Mistral(api_key="your-api-key")
async def main() -> None:
result = await client.beta.connectors.call_tool_async(
connector_id_or_name="my_deepwiki",
tool_name="read_wiki_structure",
arguments={"repoName": "sqlite/sqlite"},
)
print(f"Tool output:\n{result.content}")
asyncio.run(main())
TypeScript:
import Mistral from "@mistralai/mistralai";
const client = new Mistral({ apiKey: *** });
async function main(): Promise<void> {
const result = await client.beta.connectors.callTool({
connectorIdOrName: "my_deepwiki",
toolName: "read_wiki_structure",
arguments: { repoName: "sqlite/sqlite" },
});
console.log(`Tool output:\n${result.content}`);
}
main();
curl:
curl -X POST "${BASE_URL}/v1/connectors/my_deepwiki/call_tool" \
-H "Authorization: Bearer ${MIST...KEY}" \
-H "Content-Type: application/json" \
-d '{
"tool_name": "read_wiki_structure",
"arguments": {"repoName": "sqlite/sqlite"}
}'
출력 예시 (Example of output):
Tool output:
# sqlite/sqlite Wiki Structure
- Overview
- Architecture
- Build System
- SQL Language
- Core Components
- Parser
- Code Generator
- Virtual Machine
...
작동 방식 (How it works):
call_tool/call_tool_async는 커넥터를 통해 MCP 서버에 직접 요청을 보내서, 대화 모델을 완전히 우회해요.connector_id_or_name은 커넥터의 name 또는 UUID를 받아요.tool_name은 MCP 서버가 노출하는 도구 중 하나와 정확히 일치해야 해요.arguments는 도구가 기대하는 키-값 쌍의 딕셔너리/객체예요.- 응답에는 MCP 서버의 원시 출력이 담긴
content필드가 포함돼요.
4. 전체 예제 — 생성, 도구 호출, 정리 (Full Example — Create, Call a Tool, and Clean Up)
목표 (Goal): 커넥터를 만들고, 도구 중 하나를 직접 호출하고, 정리하는 끝에서 끝까지(end-to-end) 워크플로우.
언제 쓰나 (When to use):
- 도구 호출에 대한 통합 테스트
- 일회성 데이터 가져오기를 위한 임시(ephemeral) 커넥터
- 프로그래밍 방식 도구 호출 파이프라인의 템플릿
Python:
import asyncio
from mistralai import Mistral
client = Mistral(api_key="your-api-key")
async def main() -> None:
connector_id: str | None = None
try:
# 1. Create a connector
connector = await client.beta.connectors.create_async(
name="toolcall_deepwiki",
description="Temporary connector for direct tool calling",
server="https://mcp.deepwiki.com/mcp",
visibility="private",
)
connector_id = str(connector.id)
print(f"Created connector: {connector.name} ({connector.id})")
# 2. Call a tool directly
result = await client.beta.connectors.call_tool_async(
connector_id_or_name=str(connector.id),
tool_name="read_wiki_structure",
arguments={"repoName": "sqlite/sqlite"},
)
print(f"\nTool 'read_wiki_structure' output:\n{result.content[:500]}")
# 3. Call another tool
result = await client.beta.connectors.call_tool_async(
connector_id_or_name=str(connector.id),
tool_name="ask_question",
arguments={
"repoName": "sqlite/sqlite",
"question": "What is the purpose of the VDBE?",
},
)
print(f"\nTool 'ask_question' output:\n{result.content[:500]}")
finally:
# 4. Always clean up
if connector_id:
result = await client.beta.connectors.delete_async(
connector_id=connector_id,
)
print(f"\nCleaned up connector: {result.message}")
asyncio.run(main())
TypeScript:
import Mistral from "@mistralai/mistralai";
const client = new Mistral({ apiKey: *** });
async function main(): Promise<void> {
let connectorId: string | undefined;
try {
// 1. Create a connector
const connector = await client.beta.connectors.create({
name: "toolcall_deepwiki",
description: "Temporary connector for direct tool calling",
server: "https://mcp.deepwiki.com/mcp",
visibility: "private",
});
connectorId = connector.id;
console.log(`Created connector: ${connector.name} (${connector.id})`);
// 2. Call a tool directly
let result = await client.beta.connectors.callTool({
connectorIdOrName: connector.id,
toolName: "read_wiki_structure",
arguments: { repoName: "sqlite/sqlite" },
});
console.log(`\nTool 'read_wiki_structure' output:\n${result.content?.substring(0, 500)}`);
// 3. Call another tool
result = await client.beta.connectors.callTool({
connectorIdOrName: connector.id,
toolName: "ask_question",
arguments: {
repoName: "sqlite/sqlite",
question: "What is the purpose of the VDBE?",
},
});
console.log(`\nTool 'ask_question' output:\n${result.content?.substring(0, 500)}`);
} finally {
// 4. Always clean up
if (connectorId) {
const deleteResult = await client.beta.connectors.delete({ connectorId });
console.log(`\nCleaned up connector: ${deleteResult.message}`);
}
}
}
main();
curl:
# 1. Create a connector
curl -X POST "${BASE_URL}/v1/connectors" \
-H "Authorization: Bearer ${MIST...KEY}" \
-H "Content-Type: application/json" \
-d '{
"name": "toolcall_deepwiki",
"description": "Temporary connector for direct tool calling",
"server": "https://mcp.deepwiki.com/mcp",
"visibility": "private"
}'
# 2. Call a tool (use the connector name or ID)
curl -X POST "${BASE_URL}/v1/connectors/toolcall_deepwiki/call_tool" \
-H "Authorization: Bearer ${MIST...KEY}" \
-H "Content-Type: application/json" \
-d '{
"tool_name": "read_wiki_structure",
"arguments": {"repoName": "sqlite/sqlite"}
}'
# 3. Call another tool
curl -X POST "${BASE_URL}/v1/connectors/toolcall_deepwiki/call_tool" \
-H "Authorization: Bearer ${MIST...KEY}" \
-H "Content-Type: application/json" \
-d '{
"tool_name": "ask_question",
"arguments": {"repoName": "sqlite/sqlite", "question": "What is the purpose of the VDBE?"}
}'
# 4. Clean up (use the connector UUID from the create response)
curl -X DELETE "${BASE_URL}/v1/connectors/${CONNECTOR_ID}" \
-H "Authorization: Bearer ${MIST...KEY}"
요약 (Summary)
이 쿡북은 모델이 어떤 도구를 호출할지 결정하게 하지 않고, Connector의 개별 도구를 직접 호출하는 방법을 다뤘어요. 이미 필요한 도구를 알고 있고, 프로그래밍 방식으로 사용할 원시·구조화된 출력을 원할 때 직접 도구 호출이 유용해요.
이 쿡북이 다루는 내용 (What this cookbook covers):
- Mistral 클라이언트 초기화
- Connector 만들기
- Connector에서 특정 도구를 호출하고 원시 결과 얻기
- 전체 수명주기: Connector 만들고, 도구 호출하고, 정리하기
사용한 Mistral 기능 (Mistral features used):
- Connectors API — 직접 도구 호출 (beta)
기타 서비스 (Other services):
- DeepWiki — GitHub 저장소 탐색용 MCP 서버
Connector를 Studio에서 확인할 수 있어요.
더 알아보기 (Learn more)
- 원본 문서: Connectors Tool Calling