Skip to content

feat(mcp): embed deep-link URLs in tool responses (parallel to katana #442) #59

@dougborg

Description

@dougborg

Motivation

The Katana MCP server (sibling repo `katana-openapi-client`) just shipped #442 / PR #448: every `get_` / `create_` / list-row response now carries a `katana_url` field that deep-links to the entity in Katana's web app.

The same DX gap exists here. Today, an agent that has just fetched a StatusPro order has no way to surface a clickable link in its summary without composing the URL itself — and URL conventions are easy to get wrong silently. The user clicks, gets a 404, and assumes StatusPro is down. The fix on the Katana side eliminated this class of error.

Scope

Mirror the Katana implementation:

  1. New helper `statuspro_mcp/web_urls.py` (parallel to `katana_mcp/web_urls.py`) — single source of truth for URL construction. Reads a `STATUSPRO_WEB_BASE_URL` env var with a sensible default, parallel to whatever the existing API base-URL convention is.
  2. `statuspro_url` field on response models — add to every `get_` / `create_` / list-row Pydantic class that exposes an entity ID. Populate via the existing `_*_to_response()` helpers.
  3. Server `instructions` block — document the URL patterns (so agents that only have an ID from another tool can construct one without an extra round-trip).
  4. Help resource sync — if the MCP server has a `statuspro://help` resource, add a "Linking to StatusPro" section.
  5. Markdown emission for create-tool paths — write-only tools that use `make_simple_result` (markdown only, no JSON mode) need to include the URL in the markdown text. `structuredContent` is for UI binding per MCP Apps SEP-1865 and isn't in LLM context. (Caught in Katana review — same fix needed here.)

Reference

Full implementation, including the helper API, env-var override, response wiring across 14 response classes, test hermeticity (`monkeypatch.delenv`), and the markdown-emission fix for create tools: dougborg/katana-openapi-client#448.

The Katana `web_urls.py` is ~60 lines; the per-response wiring is one-liners. Total scope is small but touches every foundation tool.

Verification

  • Unit tests on the helper (entity → URL, `id=None` → `None`, env-var override, trailing-slash).
  • Live click-through of one URL per entity type to confirm the path conventions match StatusPro's actual routes — same gap as katana#TBD (live-UI verification ticket).

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions