콘텐츠로 이동

03-실전

03 — 30분 워크스루: 사내 위키 검색 MCP

섹션 제목: “03 — 30분 워크스루: 사내 위키 검색 MCP”

사내 Confluence 검색을 Claude Code에 노출한다. 도구 1개: search_wiki(query, limit).

Terminal window
uv init wiki-mcp && cd wiki-mcp
uv venv && source .venv/bin/activate
uv add "mcp[cli]" httpx
touch wiki_mcp.py

examples/wiki_mcp.py 참고. 핵심만 옮기면:

from mcp.server.fastmcp import FastMCP
import httpx, os, sys, logging
logging.basicConfig(stream=sys.stderr, level=logging.INFO)
log = logging.getLogger("wiki-mcp")
mcp = FastMCP("wiki")
WIKI_BASE = os.environ["WIKI_BASE_URL"]
WIKI_TOKEN = os.environ["WIKI_TOKEN"]
@mcp.tool()
async def search_wiki(query: str, limit: int = 5) -> str:
"""사내 위키를 검색해 상위 결과의 제목과 URL을 반환한다.
Args:
query: 검색어
limit: 최대 결과 수 (기본 5, 최대 20)
"""
limit = max(1, min(limit, 20))
log.info("search query=%s limit=%d", query, limit)
async with httpx.AsyncClient(timeout=10) as cx:
r = await cx.get(
f"{WIKI_BASE}/api/search",
params={"q": query, "limit": limit},
headers={"Authorization": f"Bearer {WIKI_TOKEN}"},
)
r.raise_for_status()
hits = r.json().get("results", [])
if not hits:
return f"'{query}'에 대한 결과 없음."
lines = [f"- [{h['title']}]({h['url']})" for h in hits]
return "\n".join(lines)
if __name__ == "__main__":
mcp.run(transport="stdio")
Terminal window
export WIKI_BASE_URL="https://wiki.acme.internal"
export WIKI_TOKEN="..."
npx @modelcontextprotocol/inspector python wiki_mcp.py

브라우저에서:

  1. Connect 클릭 → green 확인
  2. Tools 탭 → search_wiki 보임
  3. 입력 {"query": "OMC", "limit": 3} → 결과 확인

여기서 막히면 stderr 로그를 본다(Inspector가 같이 보여줌).

Terminal window
claude mcp add --transport stdio \
--env "WIKI_BASE_URL=https://wiki.acme.internal" \
--env "WIKI_TOKEN=$WIKI_TOKEN" \
wiki -- python /abs/path/wiki_mcp.py

확인:

Terminal window
claude mcp list
claude /mcp # wiki: green, tools: 1

이제 Claude Code 안에서 “OMC 관련 사내 문서 찾아줘” 라고 하면 모델이 search_wiki를 호출한다(첫 호출 시 사용자 승인).

.mcp.json에 추가하고 커밋. 단, 토큰은 환경변수로:

{
"mcpServers": {
"wiki": {
"command": "python",
"args": ["${workspaceFolder}/tools/wiki_mcp.py"],
"env": {
"WIKI_BASE_URL": "${env:WIKI_BASE_URL}",
"WIKI_TOKEN": "${env:WIKI_TOKEN}"
}
}
}
}
  • get_page(page_id) — 본문 마크다운 반환 (읽기)
  • recent_changes(days) — 최근 변경 리스트 (읽기)
  • create_page첫 릴리스에서는 빼라. 쓰기는 보안 검토 후.
  1. stderr만 쓰는가? (stdout=프로토콜 전용)
  2. 환경변수 누락은 아닌가?
  3. 절대 경로 썼나?
  4. 토큰 만료 아닌가?
  5. timeout 너무 짧지 않은가? (LLM이 기다림)