Skip to content

feat: add structured output schemas to read-only tools#2382

Draft
SamMorrowDrums wants to merge 8 commits intomainfrom
sammorrowdrums/structured-output-schemas
Draft

feat: add structured output schemas to read-only tools#2382
SamMorrowDrums wants to merge 8 commits intomainfrom
sammorrowdrums/structured-output-schemas

Conversation

@SamMorrowDrums
Copy link
Copy Markdown
Collaborator

Summary

Adds structured output (OutputSchema + StructuredContent) to read-only tools by leveraging the go-sdk's mcp.AddTool[In, Out]() generic registration path.

How it works

  1. TypedRegisterFunc — A new closure field on ServerTool that captures Go type parameters (In, Out) and calls mcp.AddTool[In, Out]() instead of the untyped s.AddTool(). Set automatically in NewServerToolWithContextHandler and NewServerTool.

  2. RegisterFunc preference — When TypedRegisterFunc is set, RegisterFunc uses it. This enables the SDK to auto-generate OutputSchema from the Out type and populate StructuredContent on tool results.

  3. Backwards compatibility — Tools still return MarshalledTextResult(...) for Content (text). The SDK adds StructuredContent alongside without overwriting existing content.

Tools with structured output

Tool Out Type
get_me MinimalUser
list_issues MinimalIssuesResponse
list_pull_requests ListPullRequestsResult
search_issues IssueSearchResult
search_pull_requests PullRequestSearchResult
search_code CodeSearchResult

Tools unchanged (Out=any, no structured output)

  • issue_read — multi-method tool (get, get_comments, get_sub_issues, get_labels) returning different shapes
  • pull_request_read — multi-method tool (8 methods) returning different shapes

Changes

  • pkg/inventory/server_tool.go — Added TypedRegisterFunc field, updated RegisterFunc to prefer it, set it in NewServerToolWithContextHandler and NewServerTool
  • pkg/github/minimal_types.go — Added wrapper output structs (ListPullRequestsResult, CodeSearchResult, IssueSearchResult, PullRequestSearchResult) and convertToCodeSearchResult
  • pkg/github/context_tools.goget_me returns MinimalUser as typed output
  • pkg/github/issues.golist_issues returns MinimalIssuesResponse, search_issues returns IssueSearchResult
  • pkg/github/pullrequests.golist_pull_requests returns ListPullRequestsResult, search_pull_requests returns PullRequestSearchResult
  • pkg/github/search.gosearch_code returns CodeSearchResult
  • pkg/github/search_utils.gosearchHandler now also returns *github.IssuesSearchResult for callers to convert
  • pkg/github/tools_validation_test.go — Tests verifying TypedRegisterFunc is set on all tools and structured output tools register without panics
  • pkg/github/pullrequests_test.go — Updated test to match new wrapped output format

SamMorrowDrums and others added 8 commits April 23, 2026 22:34
Replace the server instructions system with MCP skill resources that
follow the skill:// URI convention for discovery by MCP clients.

Each skill resource covers a domain of tools and provides YAML
frontmatter (name, description, allowed-tools) plus markdown guidance.

All tools remain available by default (all tools mode). Skills provide
contextual guidance that clients can discover via resources/list.

16 skills covering all toolsets: context, repos, issues, pull-requests,
code-security, actions, discussions, projects, notifications, gists,
users-orgs, security-advisories, labels, git, stargazers, copilot.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Update all 16 skill definitions to use explicit backtick-formatted
tool names with '## Available Tools' sections instead of bold markdown
references. This makes tool names more reliably parseable by models
that consume the SKILL.md content via load_skill.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…kills

Replace 16 toolset-oriented skills (repos, issues, pull-requests, etc.)
with 27 workflow-oriented skills that map to real user intents:

PR workflows: create-pr, review-pr, self-review-pr, address-pr-feedback, merge-pr
Issue workflows: triage-issues, create-issue, manage-sub-issues
CI/CD: debug-ci, trigger-workflow
Security: security-audit, fix-dependabot, research-vulnerability
Code exploration: explore-repo, search-code, trace-history
Projects: manage-project
Notifications: handle-notifications
Releases: prepare-release
Repository management: manage-repo, manage-labels
Collaboration: contribute-oss, browse-discussions, delegate-to-copilot
Discovery: discover-github, share-snippet, get-context

Each skill focuses on a specific workflow with non-obvious guidance,
anti-patterns, and identity-aware instructions (e.g., reviewing someone
else's PR vs self-reviewing your own). Tools overlap across skills
based on workflow needs rather than API domain.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Update all 27 skill descriptions to include both what the skill does
AND when to use it, following the agent skills specification guidance
that descriptions are the primary triggering mechanism. Descriptions
now explicitly list user intents that should activate each skill.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Skills now only include tools that are actually registered with the
MCP server, based on the active toolset configuration. Skills with
no available tools are skipped entirely. This prevents skills from
referencing non-existent tools (e.g., gist tools when the gists
toolset isn't enabled).

RegisterSkillResources now accepts a map of available tool names
built from the inventory at startup time.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
When skills handle progressive disclosure, the server should expose
all tools via tools/list regardless of toolset configuration. The
client decides tool visibility through skill allowedTools, not the
server.

This replaces the previous filtering approach — now inv.AllTools()
registers every tool with the MCP server, and skills reference the
full tool surface.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
All toolsets are now enabled by default (Default: true). This ensures
every tool is registered out of the box, which is required for skills
to work — skills handle progressive tool discovery, so the server
should expose the full surface. Users can still restrict with
--toolsets if needed.

Reverts the inv.AllTools() registration workaround from server.go
since the normal RegisterAll path now picks up everything.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Add TypedRegisterFunc to ServerTool that uses mcp.AddTool[In, Out]()
for typed tool registration. The SDK auto-generates OutputSchema from
the Go Out type and populates StructuredContent on tool results,
while preserving existing TextContent for backwards compatibility.

Tools updated with typed structured output:
- get_me (MinimalUser)
- list_issues (MinimalIssuesResponse)
- list_pull_requests (ListPullRequestsResult)
- search_issues (IssueSearchResult)
- search_pull_requests (PullRequestSearchResult)
- search_code (CodeSearchResult)

Tools like issue_read and pull_request_read keep Out=any since they
are multi-method tools returning different shapes per method.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@SamMorrowDrums SamMorrowDrums force-pushed the sammorrowdrums/structured-output-schemas branch from 6f83796 to c94b89a Compare April 24, 2026 18:08
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