Skip to content

v0.5.1 — MCP tool 출력 강타입화 (PATCH)

Latest

Choose a tag to compare

@DanMeon DanMeon released this 07 May 07:09
· 20 commits to main since this release
0fd49fc

PATCH release. v0.5.0 GA 한 rhwp-mcp 의 7 도구 중 약타입 (dict[str, Any] / list[dict[str, Any]]) 으로 반환하던 3 도구 (get_ir / iter_blocks / chunks) 의 출력 시그니처를 Pydantic V2 모델 (HwpDocument / list[Block] / list[ChunkRecord]) 로 강타입화. fastmcp v3 의 자동 outputSchema 가 약타입 (additionalProperties: true 만) → 강타입 (필드별 type / Discriminator + Tag 11 변형 / required 명시) 으로 강화 — LLM 의 응답 해석 / 후속 도구 호출 정확도 향상. wire format byte-equal — 외부 클라이언트 (Claude Desktop / Cline 등) 의 LLM 프롬프트 / 후처리 코드 영향 0. 코어 wheel 의존성 / extras / schema ("1.1") 변경 없음.

Added

  • rhwp.mcp.tools.ChunkRecord BaseModel 신규 — page_content: str + metadata: dict[str, Any]. model_config = ConfigDict(extra="forbid", frozen=True). RAG 청크의 직렬화 표면 — LangChain Documentpage_content / metadata 평탄화. mode × block kind 동적 metadata 키 집합은 rhwp.integrations.langchain.HwpLoader 가 SSOT — 분기 모델 (ChunkRecord_Single 등) 거부 결정으로 metadata 자유 dict 유지 (schema 비대 + forward-compat 깨짐 회피).

Changed

  • rhwp.mcp.tools.get_ir(path) 반환 타입 — dict[str, Any]HwpDocument. fastmcp 가 자동으로 model_dump(mode="json") 직렬화 → result.structured_content 가 v0.5.0 dict 출력과 byte-equal. result.data 는 typed BaseModel 인스턴스 (v0.5.1 신규 표면) — discriminated union block 들의 강타입 access 가능.
  • rhwp.mcp.tools.iter_blocks(path, ...) 반환 타입 — list[dict[str, Any]]list[Block]. callable Discriminator + Tag 11 변형 (paragraph / table / picture / formula / footnote / endnote / list_item / caption / toc / field / unknown) 그대로 노출 — outputSchema 의 oneOf 11 변형이 LLM 에 정확한 kind 별 필드 구조 노출.
  • rhwp.mcp.tools.chunks(path, ...) 반환 타입 — list[dict[str, Any]]list[ChunkRecord]. dict 평탄화 코드 제거 — fastmcp 자동 직렬화에 위임.
  • README MCP 도구 표 출력 컬럼 갱신 + v0.5.1 마이그 노트 한 단락 추가 — result.data 의 dict 인덱싱 → typed attribute access 마이그 (단 iter_blocks list element 는 fastmcp v3 의 oneOf deserialization 한계로 dict 폴백 — v0.5.0 access 패턴 그대로 동작).

Fixed

  • python/rhwp/ir/nodes.pyUnknownBlock.kind 의 JSON Schema 에 not.enum: sorted(_KNOWN_KINDS) constraint 추가 (Field(json_schema_extra=callable) 표준 hook). fastmcp v3 + jsonschema 의 strict oneOf validation 이 ParagraphBlock 과 UnknownBlock 양쪽 valid 인스턴스 (예: 빈 ParagraphBlock) 에서 RuntimeError: Invalid structured content 로 fail 하던 client side wire format 호환 깨짐 해결. callable Discriminator (_block_discriminator) 의 런타임 동작은 SSOT 그대로 — schema export 만 strict 화. packaged python/rhwp/ir/schema/hwp_ir_v1.json 자동 재생성. v0.2.0 Frozen IR 의 forward-compat 라우팅 (미지 kind → UnknownBlock) 보존 — tests/test_ir_schema_export.py::test_unknown_kind_routing_pydantic_matches_schema 가 회귀 가드.

Build

  • external/rhwp submodule pin 변경 없음 — v0.5.0 동일 (62a458a, v0.7.10). 본 PATCH 는 pure Python schema 강화, 상류 변경 0.
  • 신규 의존성 / extras 변경 없음. CI test-without-extras job 의 expected skip count 5 그대로 (tests/test_mcp_server.py 의 file-level pytest.importorskip("fastmcp") 보존).

Notes

  • spec / ADR / 구현 로그: docs/roadmap/v0.5.1/mcp-typed-output.md (Frozen, 10 인수조건, 8 결정) / docs/design/v0.5.1/mcp-typed-output-research.md (Frozen, 5 결정 매트릭스) / docs/implementation/v0.5.1/migration.md (Frozen).
  • v0.5.1 작업 중 표면화된 fastmcp v3 의 두 한계는 spec body 에 정확히 반영: (1) result.structured_content 의 wrap 분기 (BaseModel = inline / list[T] = {"result": ...} envelope), (2) callable Discriminator + Tag 유니온의 oneOf schema 가 dynamic 모델 reconstruct 안 됨 (list element dict 폴백). server side 의 typed 출력은 AC-2 / AC-3 가, wire format byte-equal 은 AC-5 가 cover.