Skip to main content
Glama
roshano3o3

mcp-toolserver

by roshano3o3

mcp-toolserver

문서 검색, SQL, 산술, 코퍼스 int 루어 등 4개의 실제 도구를 제공하는 MCP 서버와, 그 서버에 연결하여 런타임에 도구를 발견하고 클로드를 연쇄 호출해 단일 도구로는 답할 수 없는 질문에 답하는 에이전트 클라이언트를 저장소입니다.

이 프로젝트가 보여주는 것

  • Model Context Protocol — AI 응용 프로그램이 외부 도구 및 데이터에 연결하는 방식을 표준화하는 개방형 프로토콜(Anthropic, 2024년 11월)입니다. 이 프로토콜이 없다면 모든 AI 앱은 모든 도구에 대해 맞춤 통합을, 모든 도구는 모든 AI 앱에 대한 맞춤 통합을 구축해야 하는 N×M 문제가 발생합니다. MCP는 이 문제를 N+M으로 해결합니다. 도구 제공자는 MCP 서버 하나만 만들면 MCP를 지원하는 모든 클라이언트가 별도의 통합 코드 없이 사용할 수 있습니다. 이 저장소는 그 형태의 작은 실제 예시입니다. 서버와 클라이언트는 서로의 내부 구현을 모르며, 오직 조약된 프로토콜만 알고 있습니다.

  • 동적 도구 발견 — 에이전트 클라이언트는 도구 목록을 하드코딩하지 않습니다. 연결 시점에 list_tools()( 를) 호출해 서버가 현재 제공하는 도구를 모두 Anthropic의 도구 사용 형식으로 변환합니다. 서버에서 도구를 추가 또는 제거하면 클라이언트는 자동으로 해당 변경을 수신하며, 클라이언트 코드는 변경할 필요가 없습니다.

  • 멀티 스텝 도구 체이닝 — 하나의 질문에 두 가지 도구를 순서대로 사용해야 하는 경우가 있습니다(재원을 조회한 후 그것으로 계산). 에이전트 루프가 이 과정을 스스로 처리합니다. Claude는 첫 번째 도구의 결과를 사용해 두 번째 도구를 호출하도록 결정합니다. 그렇게 하라는 지시 없이도 말입니다.

Related MCP server: Sentinel Core Agent

네 가지 도구

도구

시그니처

기능

search_documents

(query: str, top_k: int = 5) -> list[dict]

docmind의 처리된 PDF 코퍼스에 대한 시맨틱 검색(밀집 임베딩 + Chroma). 청크당 {text, source, page, score}를 반환합니다.

query_database

(sql: str) -> list[dict]

소규모 시드된 데모 회사 데이터베이스(employees, departments)에 대한 읽기 전용 SQL입니다. SELECT만 가능합니다 — 아래 안전 참고.

calculate

(expression: str) -> float

산술식 처리(+ - * / ** %, 소괄호)를 실행하며 코드 실행 경로가 없습니다 — 아래 안전 참고.

list_documents

() -> list[dict]

처리된 코퍼스의 목록을 문헌별로 제공합니다: {source, pages, chunks}.

각 도구의 docstring이 곧 해당 도구의 MCP 설명이 됩니다. LLM은 실제로 이 설명을 읽고 호출 시점을 결정하며, 소스를 훑어보는 사람이 아니라 LLM을 위해 작성됩니다.

라이브 데모 실행

아래 세 데모는 모두 실제 Claude API와 실제로 생성된 MCP 서버 하위 프로세스에 대한 실제 실행 결과입니다. 가짜 시뮬레이션이 아닙니다. 가장 흥미로운 케이스인 두 도구를 실제로 이어 쓰는 예시를 먼저 보여드립니다.

1. 멀티 스텝: query: 표준부터 시작 → calculate

"Engineering 부서의 평균 월급은 얼마이고, 12% 인사 시 총 비용은 얼마인가?"

Answer:
Here's the breakdown for the Engineering department:

| Metric | Value |
|---|---|
| Average Salary | $141,600 |
| Total Current Payroll | $708,000 |
| Cost of 12% Raise | $84,960 |
| New Total Payroll | $792,960 |

A 12% raise across all Engineering employees would cost an additional $84,960,
bringing the department's total payroll from $708,000 to $792,960.

Iterations: 3
Tool calls:
  1. query_database({'sql': "SELECT AVG(salary) as avg_salary, SUM(salary) as total_salary FROM employees WHERE department_id = (SELECT id FROM departments WHERE name = 'Engineering')"})
     -> [{'avg_salary': 141600.0, 'total_salary': 708000}]
  2. calculate({'expression': '708000 * 0.12'})
     -> 84960.0

claude는 SQL을 직접 작성하고, 결과를 읽고, 실제 산술식을 직접 작성해 실행했습니다 — 위의 도구 호출 입력은 Claude가 만든 것입니다. (직접 검증완료: 시드 데이터에 Engineering 직원 5명 급여의 합이 708,000달러, 5로 나누면 평균 141,600달러, 0.12를 곱하면 84,960달러.)

2. 단일 도구: query\is a database

"공학 부서 직원 수는 몇 명인가요?"

Answer:
There are 5 employees in the Engineering department.

Iterations: 2
Tool calls:
  1. query_database({'sql': "SELECT COUNT(*) as employee_count FROM employees e JOIN departments d ON e.department_id = d.id WHERE d.name = 'Engineering'"})
     -> [{'employee_count': 5}]

3. 단일 도구: search\is a documents

"corrective RAG 란 무엇인가?"

Answer:
## Corrective RAG (CRAG)

Corrective RAG (CRAG) is an enhanced version of standard Retrieval-Augmented
Generation (RAG) that adds a self-correction step after the initial retrieval
phase. [...] Standard (vanilla) RAG simply takes the top-k retrieved documents
and passes them directly to the language model generator -- regardless of
whether those documents actually answer the question. CRAG improves on this by
checking retrieval quality before generation.

[... full answer continues with the retrieve -> grade -> (generate | rewrite &
retry) flow and the latency/LLM-call tradeoff, condensed here for length ...]

Iterations: 2
Tool calls:
  1. search_documents({'query': 'corrective RAG'})
     -> [5 chunks from langgraph_agents.pdf and llm_evaluation.pdf, scores 0.44-0.58]

이 데모의 답변은 모델의 일반 지식이 아니라 실제 검색된 텍스트(docmind의 langgraph_agents.pdf)에 근거합니다. CRAG에 대한 일반 지식은 Claude도 있지만, 이 경우 사용하라고 요청하지 않았습니다.

안전성

query_database — 단일 방어가 아닌 계층형 방어:

  1. 애플리케이션 수준의 키워드/형상 검사 — SQLite로 전달되기 전에 단일 SELECT(또는 WITH ... SELECT) 문이 아닌 것을 거부합니다. INSERT, UPDATE, DELETE, DROP, ALTER, CREATE, ATTACH, DETACH, PRAGMA, VACUUM, REINDEX를 차단하며 ; 로 연결된 여러 문장은 즉시 거부합니다.

  2. SQLite 고유의 읽기 전용 모드 — 연결은 URI에 ?mode=ro 를 지정해 실제로 읽기 전용으로 열립니다. 이는 애플리케이션 코드가 아닌 SQLite엔진의 강제이므로, 1단계에 틈이 있어도 실제로 쓰기를 실행할 수 없는 최종 안전판입니다.

  3. 행 상한 설정 — 모든 쿼리는 SELECT * FROM (<query>) LIMIT 500 로 감싸이므로, 어떤 쿼리라도 쿼리 내용과 무관하게 500행 이상 반환할 수 없습니다.

  4. 벽시계시간 초과sqlite3 진행 처리기가 소요 시간을 확인하고 너무 오래 실행되면 문장을 중단합니다.

calculate — 핵심 화이트리스트(AWG) AST, eval() 아님: 식을 구문 분석(ast.parse(..., mode="eval") 단, 수동 우주 탐사) 후 허용된 노드 유형은 Constant(숫자), BinOp(+ - * / ** %), UnaryOp(+/-) 뿐입니다. 그 밖의 명사 조회, Call, Attribute는 탐색 어에 해당 브랜치가 없으므로 구조적으로 ValueError를 올립니다. 그렇기 때문에 calculate("__import__('os').system('...')") 조회 결과 실패하는 것입니다. 위험한 호출 목록인 블랙리스트와의 일치 검사하지 않고, 아예 Call 노드를 실행할 코드 경로가 없습니다.

설계 결정

  • 명시적 에이전트 루프를 사용했으며 “감독 SDK 베타 Tool Runner” 아님. 이 SD k에는 anthropic.lib.tools.mcp MCP 브리지로 MCP 각 도구를 Tool Runner에 직접 연결하는 기능이 있습니다. 본 프로젝트에서는 의도적으로 사용하지 않았습니다. 돌아오는 명시적인 검사 가능 반환 구조 — {answer, tool_calls: [{tool, input, output}], iterations} — 갖기 위해서는 각 회차의 수동 원장기록이 필요했습니다. Tool Runner는 정확히 이 프로젝트가 보여주고자 하는 메커니즘(루프 제어, 호출별 추적)을 감추게 됩니다.

  • streamable-http이 아닌 stdio 운송. 클라이언트는 서버를 하위 프로세스로 그때그때 생성하며, 같은 실행 경계 내에 있고 네트워크 홉이 없므로 stdio의 단순성(포트 통신 없음, 인증 필요 없음)솔이 적합합니다. streamable-http는 지원하지만(--transport streamable-http / MCP_TRANSPORT 환경 변수) 서버와 클라이언트가 실제로는 프로세스별 또는 컴퓨터별로 분리된 경우를 위한 것으로, 보안경화 되어 있지 않습니다(Limitations 참조).

  • 반복 횟수 상한 (8회). 최악의 비용/지연율에 상한을 설정합니다 — 이 문서의 재작성 상한과 같은 취지입니다. 위 3개 데모는 모두 2–3회 반복에서 완료되었으며, 8회는 정상 동작에서 초과되지 않도록 여유있는 상한이며, 실제로는 잘못 설계된 요청이나 불안정한 모델 동작을 잡기 위한 의도입니다.

docmind와의 관계

search_documentslist_documents는 docmind가 이미 구축한 Chroma 컬렉션에서 바로 읽기(DOCMIND_CHROMA_PATH, 기본적으로 같은 저장소의 docmind 프로젝트 data/chroma를 가리킴)를 수행하되, 쿼리 임베딩은 docmind가 ingest 시 사용한 것과 동일한 all-MiniTM-L6-v2 모델을 사용합니다. 접속 자체가 코드 수준에서 docmind 자체와 관련되어 있는 것은 아니며, 지정된 경로에 존재하는 색인 컬렉션에 Chroma가 어떻게 접속하는지 예시 일 뿐입니다. 그렇기에 이 저장소는 docmind의 코퍼스를 그대로 사용하는 진짜 두 번째 소비자이며, 복사본이 아닙니다. 즉 docmind의 리트리버 레벨이 FastAPI 백엔드 내부에 결합되어 있는 것이 아니라, 컬렉션이 위치한 경로를 아는 MCP 클라이언트라면 누구나 접근할 수 있음을 보여주는 작은 증거입니다.

알려진 제한 사항

  • 데모용 SQL은 작고 인공적입니다(직원 12명, 부서·4개) — 실제 규모 또는 공격적인 데이터베이스에 테스트되지 않았습니다.

  • SQL 키워드 블랙리스트는 실제 SQL 파서가 아닌 쿼리 텍스트에 대한 정규식입니다. 따라서 과도하게 많이 차단할 수도(실제로는 유효한 pragma_table_info()의 테이블 반환 함수 참조 방지하는 경우) 있고, 원리적으로 아무도 테스트하지 않은 구조는 빗금칠 수 있습니다만, 실제 후퇴는 블록리스트 완결성에 의존하지 않는 읽기 전용 연결 모드입니다.

  • calculate는 숫자 리터럴과 명시된 여섯 연산자만 지원하며, 함수(sqrt, sin, ...)와 변수를 지원하지 않습니다. 일반 표현식 엔진이라기보다 의도적으로 최소로 동작합니다.

  • MCP 서버는 인증이 없습니다. stdio(프로세스-로컬, 신뢰 경계 분리)에는 문제가 없지만, 현재 구현 내용 streamable-http 로 실행한다면 포트에 access 할 수 있는 누구라도 query_database를 포함한 모든 도구를 호출할 수 있습니다.

  • 8회 반복 상한은 하드 스톱보다는 문제로 인한 중저이며, 4번이 이상의 도구 왕복이 필요한 요청의 경우 실제 답가 아닌 오히려 "8회 후 중지" 메시지가 리턴됩니다.

  • CLI 호줄 전반에 대화 메모리가 없습니다. python -m toolserver.client.agent "..." 로 호출할 때마다 이전 문맥 없이 새 대화를 시작합니다.

  • 스트리밍을 하지 않습니다. 각 반복은 블로킹 messages.create 호출 때문에느린 도구나 긴 세대 응답이 그 턴 전체를 블록시킵니다.

  • 테스트는 AnthRopic 클라이언트와 MCP Client를 전혀 모의(mock) 합니다(의도적으로, 테스트에서 실제 API를 사용하지 않음). 이는 후자 어느 SDK의 스키마가 통합되지 않아도 pytest 만으로는 잡히지 않는다는 뜻입니다. 위 라이브 데모 실행이 실제 API를 사용한 유일한 검증이며, CI가 아닌 수동입니다.

설치 및 실행

Python 3.12, ANTHROPIC_API_KEY가 있어야 하며(가능하면 search_documents/list_documents 사용 시) docmind 저장소가 있어 ingest 처리된 코퍼스가 필요합니다.

git clone https://github.com/roshano3o3/mcp-toolserver.git
cd mcp-toolserver
python -m venv .venv
source .venv/bin/activate        # Windows: .venv\Scripts\activate
pip install -e .
cp .env.example .env              # edit .env and set ANTHROPIC_API_KEY

기본적으로 .env.example 안의 DOCMIND_CHROMA_PATH는 이웃한 docmind 저장소의 data/chroma를 가리킵니다. 실제 doc의 무단 corpus가 있는 경로가 바른곳로 설정하거나 무시하면 됩니다 — query_database, calculate 그리고 list_documents 의 오류 경로가 각각 모두 docmind 없이 동작하기 때문입니다.

에이전트를 직접 실행합니다(자체적으로 MCP 서버를 서브프로세스로 스냅하게 되므로 서버 프로세스가 별도로 있을 필요가 없음):

python -m toolserver.client.agent "How many employees are in the Engineering department?"

MCP 서버를 standalone으로 실행하는 경우, 예를 들어 다른 MCP 클라이언트가 접속할 수 있게 하려면:

python -m toolserver.server                      # stdio (default)
python -m toolserver.server --transport streamable-http   # http://127.0.0.1:8765/mcp by default

테스트 실행 방법:

pytest
ruff check .

실행된 SDK로 확인됨 (메모리 기반 작성이 아님)

mcp==2.0.0는 이전 mcp.server.fastmcp.FastMCP API와 비교해 상당히 달라졌습니다. 이 버전에는 해당 모듈이 존재하지 않습니다. 다음 내용은 모두 설치된 패키지 소스를 직접 읽고, 실존하는 smoke 테스트(인프로세스 및 실제 stdio 서브프로세스)를 실행해 확인했으며 훈련 데이터 기억으로부터 적지 않았습니다.

  • Server: from mcp.server.mcpserver import MCPServerMCPServer("name"), @server.tool() 괄호 필요(없이는 함께 오류). server.run(transport="stdio" | "sse" | "streamable-http").

  • Client: from mcp.client import Client — 새클라이언트 통합 클라이언트, 대부분의 케이스에서 직접 ClientSession 사용를 대체. in-process Server/MCPServer 또는 URL 문자열 또는 Transport(예: stdio_client(StdioServerParameters(...)))를 받습니다.

  • Discovery: await client.list_tools()ListToolsResult, 각 도구는 name, description, input_schema 필드를 가짐 — 이는 도구 사용 형식에 맞는 필드 이름이 같으므로 클라이언트 쪽 변환은 거의 직결 매핑이며 스키마 변환기가 아닙니다.

  • Tool results: CallToolResult.content (MCP 콘텐트 블록 목록, 항시 채워짐)과 .structured_content (타입 부여 {"result": ...} dict, 도구 함수에 반환 유형 annotation이 있는 경우 채워짐 — 여기서 네 도구 모두 만족)을 가집니다.

F
license - not found
Not graded
quality - not tested
C
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Servers

  • A
    license
    A
    quality
    D
    maintenance
    Enables Claude Code to perform programmatic tool calling by executing Python scripts that interact with multiple MCP servers in a single round-trip. This reduces latency and token consumption by keeping intermediate tool results within the local Python runtime instead of the conversation context.
    1
    MIT
  • F
    license
    Not graded
    quality
    B
    maintenance
    Enables automatic discovery and reuse of tools from Claude Code execution traces. Provides MCP tools that are distilled from real work, allowing you to reuse previously written scripts without manual effort.
  • A
    license
    Not graded
    quality
    B
    maintenance
    Enables document ingestion and typed knowledge graph queries through Claude MCP tools, allowing agents to extract, store, and retrieve typed entities and relations from documents.
    2
    MIT

View all related MCP servers

Related MCP Connectors

  • Free OpenAI-compatible inference with signed provenance receipts and 3 focused MCP tools.

  • Hosted MCP with 91 agent tools: X, domains, SEO, Maps, Trends, Search, YouTube, TikTok, and more.

  • AI Reasoning Cache & Consensus Layer with 11 MCP tools via Streamable HTTP.

View all MCP Connectors

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/roshano3o3/mcp-toolserver'

If you have feedback or need assistance with the MCP directory API, please join our Discord server