대화에서 커넥터 사용하기
대화에서 커넥터 사용하기 (Using Connectors in Conversations)
Mistral AI 대화에서 Connectors, 내장 도구, 에이전트를 사용하는 방법을 다루는 레퍼런스 쿡북이에요. 총 8개의 레시피로, 기본 대화부터 커스텀 커넥터, OAuth 인증 커넥터, 전체 수명주기 예제까지 다양하게 다뤄요.
출처: 문서
본문
Mistral AI 대화에서 Connectors, 내장 도구(built-in tools), **에이전트(agents)**를 사용해 봅시다.
API 상태 (API status): Conversations는 client.beta.conversations를, Agents는 client.beta.agents를 사용해요. 이들은 베타(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(Recipe 1 참조) - 커스텀 커넥터 레시피를 위한 기존 커넥터 — Build a Database Advisor Agent를 보면 전체 커넥터 수명주기 예제를 볼 수 있고, Studio에서 만들 수도 있어요.
대화 응답 읽기 (Reading Conversation Responses)
이 쿡북의 모든 레시피는 모델의 텍스트 출력을 인쇄하는 작은 display_response 헬퍼를 사용해요. Conversations API는 outputs 목록을 반환하고, type == "message.output"인 각 출력이 모델의 답변을 담아요. 콘텐츠는 일반 문자열이거나 콘텐츠 청크 목록일 수 있어요.
Python:
def display_response(response) -> None:
for output in response.outputs:
if output.type == "message.output":
content = output.content
if isinstance(content, str):
print(content)
else:
text = "".join(
chunk.text if hasattr(chunk, "text") else str(chunk)
for chunk in content
)
print(text)
TypeScript:
function displayResponse(response: any): void {
for (const output of response.outputs ?? []) {
if (output.type === "message.output") {
const content = output.content;
if (typeof content === "string") {
console.log(content);
} else if (Array.isArray(content)) {
const text = content
.map((chunk: any) => chunk.text ?? String(chunk))
.join("");
console.log(text);
}
}
}
}
아래의 모든 레시피는 이 헬퍼를 참조해요. 프로젝트에 복사하거나 로직을 인라인해도 돼요.
레시피 (Recipes)
1. Hello world — 첫 대화 (first conversation)
목표 (Goal): 도구나 커넥터 없이 첫 메시지를 보내고 응답을 읽어 보아요.
언제 쓰나 (When to use):
- 설정이 끝에서 끝까지(end-to-end) 작동하는지 확인할 때
- 커넥터를 추가하기 전에 응답 구조에 익숙해질 때
Python:
import asyncio
from mistralai import Mistral
client = Mistral(api_key="your-api-key")
async def main() -> None:
response = await client.beta.conversations.start_async(
model="mistral-small-latest",
inputs=[
{"role": "user", "content": "What is the capital of France?"}
],
)
display_response(response)
asyncio.run(main())
TypeScript:
import Mistral from "@mistralai/mistralai";
const client = new Mistral({ apiKey: *** });
async function main(): Promise<void> {
const response = await client.beta.conversations.start({
model: "mistral-small-latest",
inputs: [
{ role: "user", content: "What is the capital of France?" },
],
});
displayResponse(response);
}
main();
curl:
curl -X POST "https://api.mistral.ai/v1/conversations" \
-H "Authorization: Bearer ${MIST...KEY}" \
-H "Content-Type: application/json" \
-d '{
"model": "mistral-small-latest",
"inputs": [{"role": "user", "content": "What is the capital of France?"}]
}'
출력 예시 (Example of output):
The capital of France is Paris.
작동 방식 (How it works):
conversations.start/start_async는 무상태(stateless) 대화 턴을 모델에 보내요.- 응답에는
outputs목록이 포함되고, 각각의type == "message.output"가 모델의 답변을 담아요. - 기본 대화에는 도구나 커넥터가 필요 없어요.
일반적인 오류와 해결책 (Common errors & fixes):
| Error | Cause | Fix |
|---|---|---|
401 Unauthorized |
Bad API key | Check MISTRAL_API_KEY |
422 Unprocessable Entity |
Invalid model name | Use a valid model like mistral-small-latest |
2. 웹 검색을 사용한 대화 (Conversation with web search)
목표 (Goal): 커스텀 커넥터 없이 모델에 실시간 웹 정보 접근권을 주어요.
언제 쓰나 (When to use):
- 사용자의 질문에 최신 정보(날씨, 뉴스, 현재 이벤트)가 필요할 때
- 커넥터를 만들거나 관리하지 않고 빠르게 통합하고 싶을 때
Python:
import asyncio
from mistralai import Mistral
client = Mistral(api_key="your-api-key")
async def main() -> None:
response = await client.beta.conversations.start_async(
model="mistral-small-latest",
inputs=[
{
"role": "user",
"content": "What is the current weather in Paris? Use web search.",
}
],
tools=[
{"type": "web_search"},
],
)
display_response(response)
asyncio.run(main())
TypeScript:
import Mistral from "@mistralai/mistralai";
const client = new Mistral({ apiKey: *** });
async function main(): Promise<void> {
const response = await client.beta.conversations.start({
model: "mistral-small-latest",
inputs: [
{
role: "user",
content: "What is the current weather in Paris? Use web search.",
},
],
tools: [
{ type: "web_search" },
],
});
displayResponse(response);
}
main();
curl:
curl -X POST "https://api.mistral.ai/v1/conversations" \
-H "Authorization: Bearer ${MIST...KEY}" \
-H "Content-Type: application/json" \
-d '{
"model": "mistral-small-latest",
"inputs": [{"role": "user", "content": "What is the current weather in Paris?"}],
"tools": [{"type": "web_search"}]
}'
출력 예시 (Example of output):
Based on current web search results, the weather in Paris today is 8°C with partly cloudy skies...
작동 방식 (How it works):
web_search는 내장 도구 유형이라 커넥터 생성이 필요 없어요.- 모델이 쿼리에 따라 검색을 호출할지 자율적으로 결정해요.
- 검색 결과가 모델의 응답에 자동으로 포함돼요.
일반적인 오류와 해결책 (Common errors & fixes):
| Error | Cause | Fix |
|---|---|---|
422 Unprocessable Entity |
Invalid tool type | Ensure the type is exactly "web_search" |
3. 커스텀 커넥터를 사용한 대화 (Conversation with a custom connector)
목표 (Goal): 대화에서 Connector를 사용해서 모델이 외부 도구를 호출하게 해요.
언제 쓰나 (When to use):
- 커넥터(예: DeepWiki)를 등록했고 모델이 그 도구를 사용하길 원할 때
- 도메인별 기능(코드 검색, 문서 조회, 액션 등)을 모델에 연결할 때
사전 준비사항 (Prereqs):
기존 커넥터 — Build a Database Advisor Agent를 보면 전체 커넥터 수명주기 예제를 볼 수 있고, Studio에서 만들 수도 있어요.
Python:
import asyncio
from mistralai import Mistral
client = Mistral(api_key="your-api-key")
async def main() -> None:
response = await client.beta.conversations.start_async(
model="mistral-small-latest",
inputs=[
{
"role": "user",
"content": "Using deepwiki, tell me about the structure of the sqlite/sqlite repository.",
}
],
tools=[
{
"type": "connector",
"connector_id": "my_deepwiki", # name or UUID
},
],
)
display_response(response)
asyncio.run(main())
TypeScript:
import Mistral from "@mistralai/mistralai";
const client = new Mistral({ apiKey: *** });
async function main(): Promise<void> {
const response = await client.beta.conversations.start({
model: "mistral-small-latest",
inputs: [
{
role: "user",
content:
"Using deepwiki, tell me about the structure of the sqlite/sqlite repository.",
},
],
tools: [
{
type: "connector",
connectorId: "my_deepwiki", // name or UUID
},
],
});
displayResponse(response);
}
main();
curl:
curl -X POST "https://api.mistral.ai/v1/conversations" \
-H "Authorization: Bearer ${MIST...KEY}" \
-H "Content-Type: application/json" \
-d '{
"model": "mistral-small-latest",
"inputs": [{"role": "user", "content": "Using deepwiki, tell me about the structure of the sqlite/sqlite repository."}],
"tools": [{"type": "connector", "connector_id": "my_deepwiki"}]
}'
출력 예시 (Example of output):
The sqlite/sqlite repository is organized into several key directories:
- src/ — core SQLite source code
- ext/ — extensions
- test/ — test suite
...
작동 방식 (How it works):
connector_id필드는 커넥터의 name 또는 UUID를 받아요.- 모델이 MCP 서버가 노출하는 도구를 발견하고 호출할 것을 결정해요.
- 도구 호출과 결과는 서버 쪽에서 처리되어, 최종 응답만 보여요.
일반적인 오류와 해결책 (Common errors & fixes):
| Error | Cause | Fix |
|---|---|---|
404 Not Found (or graceful fallback) |
Connector name/ID doesn't exist — the API may return a 404 or handle gracefully | Verify with client.beta.connectors.get |
422 Unprocessable Entity |
Connector is inactive or MCP server unreachable | Check the MCP server URL |
4. 하나의 대화에서 여러 도구 결합 (Combining multiple tools in one conversation)
목표 (Goal): 모델에게 웹 검색 그리고 커스텀 커넥터를 동시에 접근하게 해요.
언제 쓰나 (When to use):
- 모델이 여러 옵션 중 작업에 가장 좋은 도구를 선택하길 원할 때
- 다중 기능 어시스턴트(예: 웹 검색 + 내부 문서 쿼리)를 구축할 때
사전 준비사항 (Prereqs):
기존 커넥터.
Python:
import asyncio
from mistralai import Mistral
client = Mistral(api_key="your-api-key")
async def main() -> None:
response = await client.beta.conversations.start_async(
model="mistral-small-latest",
inputs=[
{
"role": "user",
"content": "What tools do you have access to? List them briefly.",
}
],
tools=[
{"type": "web_search"},
{
"type": "connector",
"connector_id": "my_deepwiki",
},
],
)
display_response(response)
asyncio.run(main())
TypeScript:
import Mistral from "@mistralai/mistralai";
const client = new Mistral({ apiKey: *** });
async function main(): Promise<void> {
const response = await client.beta.conversations.start({
model: "mistral-small-latest",
inputs: [
{
role: "user",
content: "What tools do you have access to? List them briefly.",
},
],
tools: [
{ type: "web_search" },
{
type: "connector",
connectorId: "my_deepwiki",
},
],
});
displayResponse(response);
}
main();
curl:
curl -X POST "https://api.mistral.ai/v1/conversations" \
-H "Authorization: Bearer ${MIST...KEY}" \
-H "Content-Type: application/json" \
-d '{
"model": "mistral-small-latest",
"inputs": [{"role": "user", "content": "What tools do you have access to? List them briefly."}],
"tools": [
{"type": "web_search"},
{"type": "connector", "connector_id": "my_deepwiki"}
]
}'
출력 예시 (Example of output):
I have access to the following tools:
1. Web Search — search the internet for real-time information
2. read_wiki_structure — explore repository wiki structure
3. read_wiki_contents — read specific wiki pages
4. ask_question — ask questions about a repository
작동 방식 (How it works):
tools배열은 내장 도구(web_search)와 커스텀 커넥터를 어떤 조합으로든 받아요.- 각 커넥터는 자체 MCP 도구 세트를 노출하고, 모델은 그 모두를 봐요.
- 모델이 사용자 질문에 따라 호출할 도구를 결정해요.
일반적인 오류와 해결책 (Common errors & fixes):
| Error | Cause | Fix |
|---|---|---|
422 Unprocessable Entity |
Duplicate connector IDs in the tools array | Each connector should appear only once |
5. 커넥터 도구 필터링 — include / exclude
목표 (Goal): 커넥터에서 어떤 MCP 도구를 모델에 보이게 할지 제어해요.
언제 쓰나 (When to use):
- 커넥터가 많은 도구를 노출하지만 일부만 필요할 때
- 모델이 특정 도구(예: 쓰기/삭제 연산)를 호출하지 못하게 하고 싶을 때
- 도구 노이즈를 줄여서 모델 정확도를 높이고 싶을 때
사전 준비사항 (Prereqs):
기존 커넥터와 그것이 노출하는 도구 이름에 대한 지식.
참고 (Note): include 또는 exclude 중 하나만 사용하세요. 둘을 동시에 쓰면 안 됩니다.
특정 도구 제외 (Excluding specific tools)
Python:
import asyncio
from mistralai import Mistral
client = Mistral(api_key="your-api-key")
async def main() -> None:
response = await client.beta.conversations.start_async(
model="mistral-small-latest",
inputs=[
{
"role": "user",
"content": "What tools do you have access to? List their names.",
}
],
tools=[
{
"type": "connector",
"connector_id": "my_deepwiki",
"tool_configuration": {
"exclude": ["read_wiki_structure"],
},
},
],
)
display_response(response)
asyncio.run(main())
TypeScript:
import Mistral from "@mistralai/mistralai";
const client = new Mistral({ apiKey: *** });
async function main(): Promise<void> {
const response = await client.beta.conversations.start({
model: "mistral-small-latest",
inputs: [
{
role: "user",
content: "What tools do you have access to? List their names.",
},
],
tools: [
{
type: "connector",
connectorId: "my_deepwiki",
toolConfiguration: {
exclude: ["read_wiki_structure"],
},
},
],
});
displayResponse(response);
}
main();
curl:
curl -X POST "https://api.mistral.ai/v1/conversations" \
-H "Authorization: Bearer ${MIST...KEY}" \
-H "Content-Type: application/json" \
-d '{
"model": "mistral-small-latest",
"inputs": [{"role": "user", "content": "What tools do you have access to?"}],
"tools": [{
"type": "connector",
"connector_id": "my_deepwiki",
"tool_configuration": { "exclude": ["read_wiki_structure"] }
}]
}'
출력 (Output):
I have access to: read_wiki_contents, ask_question
특정 도구만 포함 (Including only specific tools)
Python:
import asyncio
from mistralai import Mistral
client = Mistral(api_key="your-api-key")
async def main() -> None:
response = await client.beta.conversations.start_async(
model="mistral-small-latest",
inputs=[
{
"role": "user",
"content": "What tools do you have access to? List their names.",
}
],
tools=[
{
"type": "connector",
"connector_id": "my_deepwiki",
"tool_configuration": {
"include": ["ask_question"],
},
},
],
)
display_response(response)
asyncio.run(main())
TypeScript:
import Mistral from "@mistralai/mistralai";
const client = new Mistral({ apiKey: *** });
async function main(): Promise<void> {
const response = await client.beta.conversations.start({
model: "mistral-small-latest",
inputs: [
{
role: "user",
content: "What tools do you have access to? List their names.",
},
],
tools: [
{
type: "connector",
connectorId: "my_deepwiki",
toolConfiguration: {
include: ["ask_question"],
},
},
],
});
displayResponse(response);
}
main();
curl:
curl -X POST "https://api.mistral.ai/v1/conversations" \
-H "Authorization: Bearer ${MIST...KEY}" \
-H "Content-Type: application/json" \
-d '{
"model": "mistral-small-latest",
"inputs": [{"role": "user", "content": "What tools do you have access to?"}],
"tools": [{
"type": "connector",
"connector_id": "my_deepwiki",
"tool_configuration": { "include": ["ask_question"] }
}]
}'
출력 예시 (Example of output):
I have access to: ask_question
작동 방식 (How it works):
tool_configuration.exclude는 나열된 도구를 커넥터에서 제거해요. 다른 도구는 모두 사용 가능하게 남아요.tool_configuration.include는 나열된 도구를 허용 목록에 넣어요. 다른 도구는 모두 숨겨져요.- 도구 이름은 MCP 서버가 노출하는 것과 정확히 일치해야 해요. 먼저 모델에게 (필터 없이) 도구 목록을 요청해서 정확한 이름을 발견하세요.
일반적인 오류와 해결책 (Common errors & fixes):
| Error | Cause | Fix |
|---|---|---|
422 Unprocessable Entity |
Tool name doesn't match any tool on the MCP server | List all tools first to get exact names |
400 Bad Request |
Both include and exclude provided |
Use only one at a time |
6. 커넥터로 에이전트 만들기 (Creating an agent with connectors)
목표 (Goal): 커넥터와 커스텀 지시사항이 미리 구성된 영구 에이전트를 만든 다음, 그것과 대화해요.
언제 쓰나 (When to use):
- 항상 특정 도구에 접근해야 하는 재사용 가능한 에이전트를 원할 때 — 매 호출에
tools배열을 전달할 필요 없어요. - 사용자가 전문화된 어시스턴트와 상호작용하는 제품 기능을 구축할 때
사전 준비사항 (Prereqs):
기존 커넥터.
Python:
import asyncio
from mistralai import Mistral
client = Mistral(api_key="your-api-key")
async def main() -> None:
agent_id: str | None = None
try:
# 1. Create the agent
agent = await client.beta.agents.create_async(
name="deepwiki_agent",
description="Agent with DeepWiki access for code repository exploration",
model="mistral-small-latest",
instructions="You are a helpful assistant that can explore code repositories using DeepWiki. Be concise.",
tools=[
{
"type": "connector",
"connector_id": "my_deepwiki",
},
],
)
agent_id = agent.id
print(f"Created agent: {agent.name} ({agent.id})")
# 2. Start a conversation using the agent
response = await client.beta.conversations.start_async(
agent_id=agent.id,
inputs=[
{
"role": "user",
"content": "What is the main purpose of the sqlite repository?",
}
],
)
display_response(response)
finally:
# 3. Cleanup
if agent_id:
await client.beta.agents.delete_async(agent_id=agent_id)
print(f"Deleted agent: {agent_id}")
asyncio.run(main())
TypeScript:
import Mistral from "@mistralai/mistralai";
const client = new Mistral({ apiKey: *** });
async function main(): Promise<void> {
let agentId: string | undefined;
try {
// 1. Create the agent
const agent = await client.beta.agents.create({
name: "deepwiki_agent",
description: "Agent with DeepWiki access for code repository exploration",
model: "mistral-small-latest",
instructions:
"You are a helpful assistant that can explore code repositories using DeepWiki. Be concise.",
tools: [
{
type: "connector",
connectorId: "my_deepwiki",
},
],
});
agentId = agent.id;
console.log(`Created agent: ${agent.name} (${agent.id})`);
// 2. Start a conversation using the agent
const response = await client.beta.conversations.start({
agentId: agent.id,
inputs: [
{
role: "user",
content: "What is the main purpose of the sqlite repository?",
},
],
});
displayResponse(response);
} finally {
// 3. Cleanup
if (agentId) {
await client.beta.agents.delete({ agentId });
console.log(`Deleted agent: ${agentId}`);
}
}
}
main();
curl:
# Create agent
curl -X POST "https://api.mistral.ai/v1/agents" \
-H "Authorization: Bearer ${MIST...KEY}" \
-H "Content-Type: application/json" \
-d '{
"name": "deepwiki_agent",
"description": "Agent with DeepWiki access",
"model": "mistral-small-latest",
"instructions": "You are a helpful assistant that can explore code repositories using DeepWiki. Be concise.",
"tools": [{"type": "connector", "connector_id": "my_deepwiki"}]
}'
# Start conversation with agent (use the agent ID from the response above)
curl -X POST "https://api.mistral.ai/v1/conversations" \
-H "Authorization: Bearer ${MIST...KEY}" \
-H "Content-Type: application/json" \
-d '{
"agent_id": "<agent-id>",
"inputs": [{"role": "user", "content": "What is the main purpose of the sqlite repository?"}]
}'
# Delete agent when done
curl -X DELETE "https://api.mistral.ai/v1/agents/<agent-id>" \
-H "Authorization: Bearer ${MIST...KEY}"
출력 예시 (Example of output):
Created agent: deepwiki_agent (b2c3d4e5-6789-01ab-cdef-234567890abc)
SQLite is a self-contained, serverless, zero-configuration SQL database engine...
Deleted agent: b2c3d4e5-6789-01ab-cdef-234567890abc
작동 방식 (How it works):
- 에이전트는 영구 구성이에요:
model+instructions+tools. agent_id로 대화를 시작하면 모델, 지시사항, 도구가 미리 로드되어 다시 전달할 필요 없어요.- 에이전트의
tools배열은 대화의tools매개변수와 동일한 형식을 사용해요. - 대화를 시작할 때
model대신agent_id를 사용하세요 — 둘을 함께 쓰면 안 됩니다. - 더 이상 필요 없을 때는
client.beta.agents.delete/delete_async로 에이전트를 삭제해요.
일반적인 오류와 해결책 (Common errors & fixes):
| Error | Cause | Fix |
|---|---|---|
404 Not Found |
The connector referenced in the agent's tools doesn't exist | Create the connector first |
422 Unprocessable Entity |
Both model and agent_id provided, or invalid tool format |
Use only agent_id when chatting with an agent |
7. OAuth 인증 커넥터 (Gmail) (OAuth-authenticated connectors)
목표 (Goal): Gmail처럼 OAuth2 인증이 필요한 커넥터를 사용해요.
언제 쓰나 (When to use):
- Gmail, Google Drive, Slack처럼 사용자 수준의 OAuth 토큰이 필요한 서비스와 통합할 때
- 모델이 사용자별 데이터에 접근하는 기능을 구축할 때
사전 준비사항 (Prereqs):
대상 서비스에 대한 유효한 OAuth2 액세스 토큰.
Python:
import asyncio
from mistralai import Mistral
client = Mistral(api_key="your-api-key")
async def main() -> None:
google_oauth_token = "your-google-oauth-token"
response = await client.beta.conversations.start_async(
model="mistral-small-latest",
inputs=[
{
"role": "user",
"content": "What's the latest email I received?",
}
],
tools=[
{
"type": "connector",
"connector_id": "gmail",
"authorization": {
"type": "oauth2-token",
"value": google_oauth_token,
},
},
],
)
display_response(response)
asyncio.run(main())
TypeScript:
import Mistral from "@mistralai/mistralai";
const client = new Mistral({ apiKey: *** });
async function main(): Promise<void> {
const googleOauthToken = "your-google-oauth-token";
const response = await client.beta.conversations.start({
model: "mistral-small-latest",
inputs: [
{
role: "user",
content: "What's the latest email I received?",
},
],
tools: [
{
type: "connector",
connectorId: "gmail",
authorization: ***
type: "oauth2-token",
value: googleOauthToken,
},
},
],
});
displayResponse(response);
}
main();
curl:
curl -X POST "https://api.mistral.ai/v1/conversations" \
-H "Authorization: Bearer ${MIST...KEY}" \
-H "Content-Type: application/json" \
-d '{
"model": "mistral-small-latest",
"inputs": [{"role": "user", "content": "What is the latest email I received?"}],
"tools": [{
"type": "connector",
"connector_id": "gmail",
"authorization": {
"type": "oauth2-token",
"value": "<your-google-oauth-token>"
}
}]
}'
출력 예시 (Example of output):
Your latest email is from John Doe with the subject "Q1 Report Review" received at 2:30 PM today...
작동 방식 (How it works):
authorization필드는 전역이 아니라 도구별로(per-tool) 전달돼요 — 서로 다른 커넥터가 서로 다른 토큰을 사용할 수 있어요.type: "oauth2-token"은 백엔드에게 토큰을 MCP 서버로 전달하라고 알려줘요.- 토큰은 Mistral이 저장하지 않아요 — 요청 기간 동안만 사용돼요.
gmail같은 내장 커넥터는 미리 등록되어 있어 직접 만들 필요 없어요.
일반적인 오류와 해결책 (Common errors & fixes):
| Error | Cause | Fix |
|---|---|---|
401 Unauthorized |
OAuth token is expired | Refresh the token and retry |
403 Forbidden |
Token doesn't have required scopes | Request the correct scopes (e.g., gmail.readonly) |
8. 전체 예제 — 커넥터 만들고, 대화하고, 정리하기 (Full example — create a connector, chat, 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="ephemeral_deepwiki",
description="Temporary connector for a one-off task",
server="https://mcp.deepwiki.com/mcp",
visibility="private",
)
connector_id = str(connector.id)
print(f"Created connector: {connector.name} ({connector.id})")
# 2. Use it in a simple conversation
response = await client.beta.conversations.start_async(
model="mistral-small-latest",
inputs=[
{
"role": "user",
"content": "Using deepwiki, summarize the sqlite/sqlite repo in one sentence.",
}
],
tools=[
{"type": "connector", "connector_id": "ephemeral_deepwiki"},
],
)
print("\nConversation response:")
display_response(response)
# 3. Use it alongside web search
response = await client.beta.conversations.start_async(
model="mistral-small-latest",
inputs=[
{
"role": "user",
"content": "Search the web for the latest SQLite release version, then use deepwiki to find where the version number is defined in the sqlite/sqlite repo.",
}
],
tools=[
{"type": "web_search"},
{"type": "connector", "connector_id": "ephemeral_deepwiki"},
],
)
print("\nMulti-tool response:")
display_response(response)
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: "ephemeral_deepwiki",
description: "Temporary connector for a one-off task",
server: "https://mcp.deepwiki.com/mcp",
visibility: "private",
});
connectorId = connector.id;
console.log(`Created connector: ${connector.name} (${connector.id})`);
// 2. Use it in a simple conversation
const response = await client.beta.conversations.start({
model: "mistral-small-latest",
inputs: [
{
role: "user",
content:
"Using deepwiki, summarize the sqlite/sqlite repo in one sentence.",
},
],
tools: [
{ type: "connector", connectorId: "ephemeral_deepwiki" },
],
});
console.log("\nConversation response:");
displayResponse(response);
// 3. Use it alongside web search
const multiResponse = await client.beta.conversations.start({
model: "mistral-small-latest",
inputs: [
{
role: "user",
content:
"Search the web for the latest SQLite release version, then use deepwiki to find where the version number is defined in the sqlite/sqlite repo.",
},
],
tools: [
{ type: "web_search" },
{ type: "connector", connectorId: "ephemeral_deepwiki" },
],
});
console.log("\nMulti-tool response:");
displayResponse(multiResponse);
} finally {
// 4. Always clean up
if (connectorId) {
const result = await client.beta.connectors.delete({ connectorId });
console.log(`\nCleaned up connector: ${result.message}`);
}
}
}
main();
출력 (Output):
Created connector: ephemeral_deepwiki (c3d4e5f6-...)
Conversation response:
SQLite is a self-contained, serverless SQL database engine used worldwide.
Multi-tool response:
The latest SQLite release is 3.45.1. The version number is defined in src/sqlite.h...
Cleaned up connector: Connector deleted successfully
작동 방식 (How it works):
try/finally패턴은 대화가 실패해도 커넥터가 항상 삭제되도록 보장해요.- 이 레시피는 커넥터 CRUD(전체 내용은 Build a Database Advisor Agent 참조)와 대화 사용을 결합해요.
- 두 번째 대화는 단일 요청 안에서 모델이 웹 검색과 커스텀 커넥터 사이를 지능적으로 라우팅하는 모습을 보여줘요.
요약 (Summary)
이 쿡북은 Mistral AI 대화에서 Connectors, 내장 도구, 에이전트를 사용하는 8가지 레시피를 다뤘어요. 기본 hello world부터 OAuth 인증 커넥터, 전체 create-chat-cleanup 수명주기 예제까지요.
이 쿡북이 다루는 내용 (What this cookbook covers):
- Conversations API로 대화 시작하기
- 대화에 웹 검색 추가하기
- 대화에서 커스텀 Connector 사용하기
- 하나의 대화에서 여러 도구 결합하기
- Connector가 노출하는 도구 필터링하기
- Connectors로 에이전트 만들기
- OAuth 인증 커넥터(Gmail)
- 전체 수명주기: Connector 만들고, 대화에서 사용하고, 정리하기
사용한 Mistral 기능 (Mistral features used):
- Conversations API (beta)
- Agents API (beta)
- Connectors (beta)
- Web search 내장 도구
기타 서비스 (Other services):
- DeepWiki — GitHub 저장소 탐색용 MCP 서버
- Gmail — OAuth2 인증 Connector
Connector를 Studio에서 확인할 수 있어요.