도구를 별도 프로세스의 MCP 서버로 떼어 내면, 도구 목록을 묻고 도구를 실행하는 일이 모두 표준 입출력(stdio)을 오가는 JSON-RPC 메시지가 됩니다.
서버를 만들고(mcp_server.py), 모델 없이 클라이언트로 확인하고(mcp_verify.py), LangGraph Agent 에 붙이는(mcp_agent.py) 과정을 시퀀스로 따라갑니다.
JSON-RPC 메시지는 모양만 보인 (예시) 이고, 도구 목록과 호출 결과는 mcp_verify.py 와 같은 방식으로 서버를 실제로 띄워 얻은 값입니다.
mcp_verify.py 는 모델과 Agent 없이 ①~⑦과 ⑫~⑭만 씁니다. mcp_agent.py 에서는 도구 목록을 받을 때(⑥ 앞)와 도구를 부를 때(⑫ 앞)마다 ①③④⑤가 새로 일어납니다. 호출마다 새 세션을 열기 때문입니다.mcp_verify.py | mcp_agent.py | mcp_agent_external.py | |
|---|---|---|---|
| 클라이언트 | stdio_client + ClientSession | MultiServerMCPClient (서버 1개) | MultiServerMCPClient (서버 2개) |
| 세션 | 한 번 열어 끝까지 사용 | 목록 조회와 도구 호출마다 새로 엶 | 같음. 서버마다 따로 |
| 서버 프로세스 | 1개가 끝까지 떠 있음 | 호출마다 떴다가 내려감 | 같음 |
| 모델 | 없음 | claude-sonnet-4-6 | claude-haiku-4-5 |
| 결과를 받는 모양 | CallToolResult.content[0].text | ToolMessage (content 는 text 블록 리스트) | |
print() 를 쓰면 그 글자가 JSON-RPC 메시지 사이에 끼어듭니다. FastMCP 의 시작 배너와 로그는 표준 에러로 나가므로 통로를 막지 않습니다. 디버깅 값도 표준 에러나 파일로 보냅니다..invoke() 하면 NotImplementedError: StructuredTool does not support sync invocation. 이 납니다. 그래서 mcp_agent.py 는 async def main 과 agent.astream 을 씁니다.get_tools() 로 만든 도구는 부를 때마다 세션을 새로 열고, stdio 에서는 곧 서버 프로세스를 새로 띄운다는 뜻입니다. 서버의 전역 변수에 값을 남겨 다음 호출에서 쓰는 설계는 동작하지 않고, 호출마다 프로세스 기동 비용이 듭니다.Args: 는 인자 설명이 되지 않습니다. 설치된 FastMCP 2.13.0 이 만든 inputSchema 에는 인자별 description 이 없고, Args: 줄은 도구 설명 글 안에 남습니다. tool_error.py 의 @tool 과 같은 모습입니다.return 하므로 결과의 isError 는 false 입니다. 실패인지는 모델이 글을 읽고 판단합니다. 그래서 안내문에 다음 행동(등록된 이름 목록)을 담아 두는 것이 중요합니다.day4_practice/make_data.py더미 데이터 3종(employees 5건, assets 8건, projects 4건)을 JSON 으로 씁니다.day4_practice/mcp_server.py도구 4개를 노출하는 FastMCP 서버 sds-company-data. 클라이언트가 자식 프로세스로 띄웁니다.day4_practice/mcp_verify.py모델 없이 ClientSession 으로 initialize, list_tools, call_tool 을 확인합니다.day4_practice/mcp_agent.pyMultiServerMCPClient 로 받은 도구 4개와 calculator 를 합쳐 Agent 를 돌립니다. Bedrock 을 호출합니다.day4_practice/mcp_agent_external.py우리 서버와 공개 MCP 서버(time)를 한 Agent 에 붙입니다. Bedrock 을 호출합니다.day4_practice/apt_trade_mcp.py국토교통부 아파트 매매 실거래가 API 를 감싼 서버 apt-trade. 키는 .env 의 DATA_GO_KR_API_KEY 에서 읽습니다.