Skip to content

feat(serve): stdio 외 직접 Streamable HTTP MCP transport 추가 (+선택적 bearer)#11

Closed
epruseal wants to merge 3 commits into
upstream-baselinefrom
feat/serve-streamable-http
Closed

feat(serve): stdio 외 직접 Streamable HTTP MCP transport 추가 (+선택적 bearer)#11
epruseal wants to merge 3 commits into
upstream-baselinefrom
feat/serve-streamable-http

Conversation

@epruseal

Copy link
Copy Markdown
Owner

⚠️ 검토 전용 PR — 머지하지 않습니다. 실제 기여 대상은 upstream AlexAI-MCP/OpenCrab이며, 이 PR은 그곳에 올라갈 diff를 epruseal/localcrab 안에서 미리 검토하기 위한 것입니다. base는 upstream/main 스냅샷(upstream-baseline)이라, 여기 diff = upstream PR에 들어갈 내용과 정확히 동일합니다.

동기

opencrab serve는 현재 stdio MCP만 제공합니다. 원격/HTTP로 붙이려면 supergateway 같은 외부 stdio→HTTP 브리지가 필요했습니다. 이 PR은 serve가 직접 Streamable HTTP(2025-03-26) MCP transport를 제공하게 해서 외부 브리지를 불필요하게 만듭니다. stdio는 기본값으로 그대로 유지됩니다(하위호환).

변경

  • opencrab/mcp/server.py_handle_raw에서 handle_request(dict)를 추출해 stdio·HTTP가 JSON-RPC 디스패치를 단일 출처로 공유. initialize가 클라이언트의 protocolVersion을 에코(2024-11-05 stdio / 2025-03-26 HTTP 핸드셰이크 모두 수용).
  • opencrab/mcp/http_app.py (신규) — 공유 FastAPI mcp_router(POST /mcphandle_request 위임, GET 405, DELETE 200, notification→202, 배치 지원) + 경량 create_app. 선택적 Bearer 인증(HMAC compare): 토큰이 --auth-token/--auth-token-file 또는 OPENCRAB_MCP_TOKEN(_FILE)로 주어질 때만 활성, 미설정 시 무인증.
  • opencrab/cli.pyserve --transport [stdio|http] --host --port --auth-token --auth-token-file. http는 uvicorn 단일 워커(chroma PersistentClient 단일 프로세스 제약).
  • opencrab/config.pyMCP_HTTP_HOST(127.0.0.1) / MCP_HTTP_PORT(8765). 토큰은 config에 저장 안 함.
  • 문서(영어) — README HTTP transport 섹션, .env.example, Makefile serve-http.

stateless 설계: 각 POST가 독립 요청/응답(Mcp-Session-Id·서버 푸시 SSE 없음). 모든 툴이 요청-응답형이라 충분. 새 의존성 0(fastapi/uvicorn 이미 필수).

범위 밖 (의도적)

  • apps/api/main.py의 멀티테넌트·인증 인지 /mcp건드리지 않음(별도 표면).
  • 락/파일스토어 전용 로직 없음.

검증

  • 빌드: python -m build 성공, wheel/sdist에 http_app.py 포함, 클린 venv 설치 OK.
  • 회귀: pytest131 passed, 3 skipped (handle_request 추출이 stdio 동작 보존).
  • 기능(임시 데이터·비프로덕션 포트):
    • stdio tools/list 정상.
    • 무인증 HTTP: initialize(protocolVersion 에코)/tools-list/tools-call(content)/notification→202/GET→405/DELETE→200.
    • 인증 HTTP: 무토큰·오답→401, 정답→200, /healthz→200(면제). 파일·OPENCRAB_MCP_TOKEN env 양쪽 확인.

epruseal added 3 commits June 18, 2026 13:48
Extract MCPServer.handle_request(dict) from _handle_raw so the stdio loop and
an HTTP transport can share one JSON-RPC dispatch source. Echo the client's
requested protocolVersion in initialize (honours both 2024-11-05 stdio and
2025-03-26 Streamable HTTP handshakes).
…r auth

- New opencrab/mcp/http_app.py: shared FastAPI mcp_router (POST /mcp dispatch
  via MCPServer.handle_request, GET 405, DELETE 200) + lightweight create_app.
  Optional Bearer auth (HMAC compare); token from --auth-token/--auth-token-file
  or OPENCRAB_MCP_TOKEN(_FILE). Stateless, single worker.
- opencrab serve gains --transport [stdio|http], --host, --port, --auth-token,
  --auth-token-file. stdio stays the default. No new deps (fastapi/uvicorn
  are already required).
- config: MCP_HTTP_HOST (127.0.0.1) / MCP_HTTP_PORT (8765).
README HTTP-transport section, MCP_HTTP_HOST/PORT in .env.example, serve-http
Makefile target.
@epruseal

Copy link
Copy Markdown
Owner Author

검토용 PR. upstream PR(AlexAI-MCP#8)로 대체되어 닫습니다.

@epruseal epruseal closed this Jun 18, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant