Skip to content

feat: structured output support (MCP 2025-06-18 spec) - #16

Merged
Sbussiso merged 1 commit into
masterfrom
feat/structured-output
Jul 16, 2026
Merged

feat: structured output support (MCP 2025-06-18 spec)#16
Sbussiso merged 1 commit into
masterfrom
feat/structured-output

Conversation

@Sbussiso

Copy link
Copy Markdown
Contributor

Summary

Enable smolagents structured_output=True support so the agent sees tool output schemas upfront, reducing wasted steps and silencing the FutureWarning.

Tools now return Pydantic model instances (not json.dumps strings) when response_format="json", so FastMCP emits outputSchema and structuredContent per the MCP 2025-06-18 spec.

Changes

  • New Pydantic output models for all 14 tools across 3 modules:
    • Thingiverse: SearchResult, SearchResultItem, ModelDetails, ModelFile, DownloadResult, DownloadedFile, SkippedFile
    • Cura: SliceResult, SliceSettings, SliceStats
    • OctoPrint: StatusResult, ServerInfo, ConnectionInfo, TemperatureReading, FileListResult, FileEntry, JobResult, ConnectResult, UploadResult, StartPrintResult, ControlJobResult, TemperatureResult, HomeResult, MoveResult, DryRunPreview
  • Refactored tools to return model instances on the JSON path; markdown path unchanged (still returns str)
  • Dry-run paths (confirm=false) on actuation tools now return a DryRunPreview model on the JSON path — the tool always returns the declared type regardless of the confirm flag
  • Return type annotations updated from -> str to -> str | <ResultModel> (or -> str | DryRunPreview | <ResultModel> for actuation tools)
  • Tests updated to assert Pydantic instances on the JSON path and str on the markdown path. New tests verify all 14 tools emit outputSchema and that model schemas match.
  • Version bump 0.1.1 → 0.2.0

Backward Compatibility

  • The response_format="markdown" path (the default) is unchanged — still returns a human-readable str.
  • Error strings ("Error: ...") are still returned as str on all paths.
  • The JSON payload shape is identical to before — only the type of the returned Python object changed (model instance instead of JSON string). On the MCP wire, structuredContent carries the same fields.

Reference

Consumer

PrintPal/main.py will pass structured_output=True to MCPClient after this lands.

Test Plan

  • uv run pytest -q — 83 passed
  • uvx ruff check src tests — all checks passed
  • uvx ruff format --check src tests — 10 files already formatted
  • uv build && uvx twine check dist/* — both PASSED
  • End-to-end verification: all 14 tools emit outputSchema

Tools now return Pydantic model instances (not json.dumps strings) when
response_format=json, so FastMCP emits outputSchema and structuredContent.
This enables smolagents structured_output=True — the agent sees tool output
schemas up front, reducing wasted steps and silencing the FutureWarning.

New output models:
- Thingiverse: SearchResult, SearchResultItem, ModelDetails, ModelFile,
  DownloadResult, DownloadedFile, SkippedFile
- Cura: SliceResult, SliceSettings, SliceStats
- OctoPrint: StatusResult, ServerInfo, ConnectionInfo, TemperatureReading,
  FileListResult, FileEntry, JobResult, ConnectResult, UploadResult,
  StartPrintResult, ControlJobResult, TemperatureResult, HomeResult,
  MoveResult, DryRunPreview

Dry-run paths (confirm=false) on actuation tools now return a DryRunPreview
model on the JSON path instead of a descriptive string — the tool always
returns the declared type.

Backward compatibility:
- Markdown path (default) unchanged — still returns str
- Error strings still return str
- JSON payload shape identical — only the Python object type changed

Tests updated to assert Pydantic instances on JSON path and str on markdown.
New tests verify all 14 tools emit outputSchema and model schemas match.

Bumps version 0.1.1 -> 0.2.0.
@Sbussiso
Sbussiso merged commit a871c33 into master Jul 16, 2026
6 checks passed
@Sbussiso
Sbussiso deleted the feat/structured-output branch July 16, 2026 23:06
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