topos.mcp.formatting

Response formatters for the Topos MCP server.

Converts ClassificationResult and distance results into the Pydantic return models defined in schemas.py.

topos.mcp.formatting.lattice_to_str(value)[source]
topos.mcp.formatting.str_to_lattice(value)[source]
topos.mcp.formatting.build_preference_walk(prefs, current)[source]

Materialize a PreferenceWalk for the result schema.

topos.mcp.formatting.build_guidance(result)[source]

Priority-aware next-step hint for agents.

Phrased against the three free generators (SIMPLE, COMPOSABLE, SECURE).

topos.mcp.formatting.build_agent_contract(result, *, coupling_available, security_findings, acknowledged_risks, grade_capped, warnings=None)[source]

Return compact loop-control fields for MCP agents.

topos.mcp.formatting.mdg_unavailable_message(warnings)[source]

The ‘COMPOSABLE not scored’ note surfaced when no MDG is available.

topos.mcp.formatting.build_pillars(result, coupling_available, *, warnings=None)[source]

Build the lean per-pillar (simple, composable, secure) summary.

Each pillar carries only achieved + score. The full metric and interpretation detail is NOT duplicated here — it lives once in the parent’s flat raw_metrics / interpretation (see _PILLAR_METRIC_PREFIXES for the namespacing). warnings is unused now that the mdg.unavailable note is injected into the flat interpretation by to_evaluation_result; kept for call-site stability.

topos.mcp.formatting.to_evaluation_result(result, coupling_available, *, preferences=None, priority_source=PrioritySource.DEFAULT, warnings=None, security_findings=None, acknowledged_risks=None, adjusted_verdict=None, include_agent_contract=True, verbose=True)[source]

Convert a ClassificationResult into the Pydantic return model.

When verbose is False the structured channel omits the 16 raw-metric floats and trims interpretation to failing generators only (see _failing_interpretation). Measurement showed raw_metrics + interpretation make up ~55% of the default structured payload, and clients routinely inject structured_content into context, so gating both channels (not just the markdown) is what earns the keep here.

topos.mcp.formatting.to_tool_result(model, markdown)[source]

Return a dual-channel ToolResult: markdown for the LLM, JSON for code.

content is the compact markdown the LLM reads (FastMCP wraps the bare string in a TextContent); structured_content is the model’s JSON-mode dump for programmatic clients.

Empirically verified FastMCP behavior (see tests/mcp/test_evaluate.py and a probe over mcp.call_tool + to_mcp_tool().model_dump()):

  • When a tool is annotated -> ToolResult, FastMCP emits no outputSchema for it — this is intentional and shrinks the eager tool-definition surface (outputSchema is optional per the MCP spec). Tools wanting to keep an outputSchema can instead annotate -> Model while still returning this ToolResult (both channels are honored at runtime regardless of the annotation).

  • structured_content is still delivered on the wire.

  • content is the markdown text, not the model JSON.

topos.mcp.formatting.render_evaluation_md(e, title=None, *, verbose=True)[source]