Important
MCP(SQL 모델 컨텍스트 프로토콜) 서버는 데이터 API 작성기 버전 1.7에서 사용할 수 있습니다. 최신 기능 및 버그 수정의 경우 2.0 미리 보기 릴리스를 사용합니다.
MCP(SQL 모델 컨텍스트 프로토콜) 서버는 클라우드 호스팅 AI 서비스뿐만 아니라 MCP 호환 클라이언트에서 작동합니다. 환경이 의료, 국방, 금융, 에너지 및 해양 산업에서 공통적인 클라우드 LLM(대규모 언어 모델) 액세스를 제한하는 경우 Ollama 또는 유사한 도구를 통해 제공되는 로컬 모델을 연결할 수 있습니다. 이 가이드에서는 작은 로컬 모델을 안정적으로 만드는 설정, 필드 메타데이터 구성 및 프롬프트 패턴에 대해 설명합니다.
사전 요구 사항
- 하나 이상의 엔터티를 사용하여 데이터 API 작성기 CLI를 설치하고 구성했습니다. CLI를 설치합니다.
-
Ollama 및 도구 호출을 지원하는 모델(예:
qwen3:8b,llama3.1:8b) -
및
mcp패키지가 있는ollama. - 데이터가 있는 실행 중인 SQL Server 인스턴스입니다.
1단계: 필드 메타데이터 구성
필드 메타데이터는 로컬 모델 정확도를 위한 가장 중요한 구성 단계입니다. 필드 이름 및 설명이 없으면 에이전트는 엔터티 이름만 표시하고 열 이름을 잘못 추측합니다.
Warning
이 단계를 건너뛰면 기술적으로 작동하지만 도구 응답을 읽는 모든 모델에서 기능적으로 사용할 수 없는 MCP 서버가 생성됩니다. 모델에는 열에 대한 정보가 없습니다.
설명이 포함된 엔터티를 추가한 다음 제한된 열에 유효한 값을 포함하는 필드 설명을 추가합니다.
dab add ServerInventory \
--source dbo.ServerInventory \
--permissions "anonymous:read" \
--description "SQL Server instance inventory with version, environment, and sizing data"
dab update ServerInventory \
--fields.name InstanceName --fields.primary-key true \
--fields.description "SQL Server instance name (e.g., YOURSERVER01)"
dab update ServerInventory \
--fields.name Environment \
--fields.description "Deployment environment. Valid values: Prod, Dev, Test, UAT"
제한된 값, 매개 변수 설명 및 스크립팅 패턴을 포함한 전체 CLI 참조 및 모범 사례는 엔터티에 설명 추가를 참조하세요.
메모
CLI는 dab update 쉼표로 인수 구분 기호로 처리합니다. 설명에 쉼표가 포함된 경우에는 대신 dab-config.json을 직접 편집하세요.
2단계: SQL MCP 서버 시작
dab start
SQL MCP Server는 http://localhost:5000/mcp 기본적으로 스트리밍 가능한 HTTP 전송을 사용하여 수신 대기합니다. MCP 프로토콜을 구현하는 모든 클라이언트는 이 엔드포인트에 연결할 수 있습니다.
3단계: 로컬 모델 연결
Ollama 모델을 SQL MCP Server에 연결하는 MCP 클라이언트를 빌드합니다. 다음 Python 예제에서는 MCP Python SDK 및 ollama 패키지를 사용합니다.
종속성 설치
pip install mcp ollama
최소한의 Python 실행용 코드
import asyncio
import json
from mcp import ClientSession
from mcp.client.streamable_http import streamable_http_client
import ollama
MCP_URL = "http://localhost:5000/mcp"
MODEL = "qwen3:8b"
async def get_schema(session: ClientSession) -> str:
"""Call describe_entities and format results for the system prompt."""
result = await session.call_tool("describe_entities", arguments={})
entities = json.loads(result.content[0].text)
lines = []
for entity in entities.get("entities", []):
fields = ", ".join(
f"{f['name']} ({f.get('description', 'no description')})"
for f in entity.get("fields", [])
)
lines.append(f"- {entity['name']}: {entity.get('description', '')}")
if fields:
lines.append(f" Fields: {fields}")
return "\n".join(lines)
async def run(user_question: str):
async with streamable_http_client(MCP_URL) as (read, write, _):
async with ClientSession(read, write) as session:
await session.initialize()
# Preinject schema into the system prompt
schema_text = await get_schema(session)
system_prompt = f"""You query a SQL database through MCP tools.
Available entities:
{schema_text}
Rules:
- Use the exact field names shown above.
- Answer count questions with the count only.
- Do not produce summaries unless asked.
- Do not invent example data. Only return data from tool responses.
- If no results, say "No results found" and stop.
"""
# Get available tools for Ollama
tools_result = await session.list_tools()
ollama_tools = [
{
"type": "function",
"function": {
"name": t.name,
"description": t.description or "",
"parameters": t.inputSchema,
},
}
for t in tools_result.tools
]
messages = [
{"role": "system", "content": system_prompt},
{"role": "user", "content": user_question},
]
# Chat loop: let the model call tools until it produces a final answer
while True:
response = ollama.chat(
model=MODEL, messages=messages, tools=ollama_tools
)
msg = response["message"]
messages.append(msg)
if not msg.get("tool_calls"):
print(msg["content"])
break
for tc in msg["tool_calls"]:
result = await session.call_tool(
tc["function"]["name"],
arguments=tc["function"]["arguments"],
)
messages.append(
{
"role": "tool",
"content": result.content[0].text,
}
)
asyncio.run(run("How many SQL 2019 servers are in production?"))
이 프레임워크는 스키마 사전 주입, 도구 검색, 여러 턴에 걸친 도구 호출, 그리고 최종 응답 추출까지 전체 과정을 처리합니다.
MODEL와 MCP_URL를 환경에 맞게 조정하세요.
시작 시 스키마 미리 인젝트
작은 로컬 모델(14B 매개 변수 미만)은 대화가 시작되기 전에 시스템 프롬프트에 스키마 메타데이터가 있을 때 보다 안정적인 도구 호출을 생성합니다. 대화 중 모델이 describe_entities를 스스로 호출하도록 두지 말고, 하네스 시작 시점에 이를 호출한 뒤 그 결과를 주입합니다.
사전 주입이 중요한 이유
| 접근 | 작은 모델을 사용하여 동작 |
|---|---|
| 동적 검색 | 모델은 먼저 호출 describe_entities 한 다음 결과를 해석한 다음 올바른 필드 이름으로 올바른 도구를 호출해야 합니다. 여러 실패 지점. |
| 사전 주입 | 모델에는 엔터티 이름, 필드 이름 및 설명이 즉시 표시됩니다. 첫 번째 시도에서 도구 호출을 수정합니다. |
이전 섹션의 하네스 예제에서는 이 패턴을 보여 줍니다. 이 함수는 get_schema() 시작 시 한 번 호출 describe_entities 하고 결과를 시스템 프롬프트에 형식을 지정합니다.
Tip
대규모 클라우드 모델(GPT-4o, Claude)은 일반적으로 사전 검색 없이 대화 중에 스키마를 검색합니다. 이 패턴은 14B 매개 변수 아래의 모델에 가장 유용합니다.
모델 응답 제한
모델은 올바른 도구를 호출하고, 올바른 데이터를 검색하고, 여전히 잘못된 답변을 생성할 수 있습니다. 예를 들어 모델은 "프로덕션 서버 수"를 묻는 질문에 16개의 행을 올바르게 검색한 다음, 숫자 16대신 환각된 예제가 포함된 40줄의 요약으로 응답할 수 있습니다.
시스템 프롬프트에 명시적 부정 규칙을 추가합니다.
Rules:
- Answer count questions with the count only.
- Do not produce summaries unless the user asks for one.
- Do not invent example data. Only return data from tool responses.
- If a tool returns no results, say "No results found" and stop.
도구 호출의 충실도와 답변 규율은 서로 다른 문제입니다. DAB는 도구 계층을 통해 정확한 데이터 검색을 보장합니다. 프롬프트 하네스는 모델이 결과를 표시하는 방식을 제어합니다.
Considerations
| 주제 | 세부 정보 |
|---|---|
| 하드웨어 | 도구 호출은 겸손한 하드웨어에서 작동합니다. 소비자 Nvidia GPU(8GB 비디오 RAM)의 8B 매개 변수 모델은 유용한 결과를 생성합니다. 일괄 처리 워크로드에 적합한 질문당 수십 초의 대기 시간을 예상합니다. |
| Batch 및 대화형 | 작은 모델은 대기 시간 허용 오차가 높은 일괄 처리(성능 보고서, 인벤토리 쿼리)에 적합합니다. |
| 도구 가용성 |
aggregate_records 는 버전 2.0 미리 보기 이상에서만 사용할 수 있습니다. 버전 1.7.x에서 개수 및 집계 쿼리는 모델이 일치하는 모든 행을 읽도록 강제합니다.
버전별 도구 가용성을 참조하세요. |
| 수송 | 로컬 모델은 스트리밍 가능한 HTTP를 통해 /mcp에 연결됩니다.
표준 입력/출력(stdio) 전송은 단일 프로세스 설정의 대안입니다. |
| 인증 | 로컬 개발의 경우 사용 권한을 사용합니다 anonymous . 프로덕션의 경우 사용자 환경에 적합한 인증 을 구성합니다. |