Summary
The MCP server currently defines excellent input schemas for all tools (with constraints, enums, descriptions), but no output schemas are defined. Per the MCP specification, output schemas are optional but recommended for structured responses.
Adding output schemas would:
- Enable client-side validation of responses
- Provide type information for better LLM parsing
- Improve documentation and developer experience
- Allow returning
structuredContent alongside text fallback
Current State
All tools return unstructured JSON text via marshalResult():
func marshalResult(v any) (*mcp.CallToolResult, error) {
data, err := json.MarshalIndent(v, "", " ")
return mcp.NewToolResultText(string(data)), nil // Text only, no schema
}
Proposed Solution
1. Extract schemas from Minder's existing OpenAPI spec
Minder already generates a comprehensive Swagger specification at:
pkg/api/openapi/minder/v1/minder.swagger.json
This contains complete JSON Schema-compatible definitions for all response types:
"v1ListRepositoriesResponse": {
"type": "object",
"properties": {
"results": {
"type": "array",
"items": { "$ref": "#/definitions/v1Repository" }
},
"cursor": { "type": "string" }
},
"required": ["results"]
}
2. Create a schema extraction tool
Build a code generator that:
- Reads Minder's
minder.swagger.json
- Extracts the
definitions section
- Resolves
$ref references into standalone schemas
- Outputs individual JSON schema files
3. Embed schemas at build time
// internal/schemas/embed.go
//go:embed generated/*.json
var schemaFS embed.FS
func GetOutputSchema(responseName string) map[string]any {
// Load and return schema for tool registration
}
4. Add to tool registration
s.AddTool(mcp.NewTool("minder_list_repositories",
// ... existing options ...
mcp.WithOutputSchema(schemas.GetOutputSchema("v1ListRepositoriesResponse")),
), handler)
5. Update marshalResult for structured content
If mcp-go supports it:
func marshalResultStructured(v any) (*mcp.CallToolResult, error) {
data, _ := json.MarshalIndent(v, "", " ")
return &mcp.CallToolResult{
Content: []mcp.Content{mcp.NewTextContent(string(data))},
StructuredContent: v,
}, nil
}
Tasks
| Tool |
Response Schema |
minder_list_projects |
v1ListProjectsResponse |
minder_list_repositories |
v1ListRepositoriesResponse |
minder_get_repository |
v1GetRepositoryByIdResponse / v1GetRepositoryByNameResponse |
minder_list_profiles |
v1ListProfilesResponse |
minder_get_profile |
v1GetProfileByIdResponse / v1GetProfileByNameResponse |
minder_get_profile_status |
v1GetProfileStatusByIdResponse / v1GetProfileStatusByNameResponse |
minder_list_rule_types |
v1ListRuleTypesResponse |
minder_get_rule_type |
v1GetRuleTypeByIdResponse / v1GetRuleTypeByNameResponse |
minder_list_data_sources |
v1ListDataSourcesResponse |
minder_get_data_source |
v1GetDataSourceByIdResponse / v1GetDataSourceByNameResponse |
minder_list_providers |
v1ListProvidersResponse |
minder_get_provider |
v1GetProviderResponse |
minder_list_artifacts |
v1ListArtifactsResponse |
minder_get_artifact |
v1GetArtifactByIdResponse / v1GetArtifactByNameResponse |
minder_list_evaluation_history |
v1ListEvaluationHistoryResponse |
Alternative Approaches Considered
| Approach |
Pros |
Cons |
| Extract from Swagger ✅ |
Already exists, no new deps |
Minor $ref resolution needed |
| protoc-gen-jsonschema |
Direct proto→schema |
Extra buf plugin dependency |
| invopop/jsonschema on Go types |
Already in deps |
Uses Go struct tags, not proto annotations |
| Manual schema maintenance |
Full control |
High maintenance burden, drift risk |
References
Summary
The MCP server currently defines excellent input schemas for all tools (with constraints, enums, descriptions), but no output schemas are defined. Per the MCP specification, output schemas are optional but recommended for structured responses.
Adding output schemas would:
structuredContentalongside text fallbackCurrent State
All tools return unstructured JSON text via
marshalResult():Proposed Solution
1. Extract schemas from Minder's existing OpenAPI spec
Minder already generates a comprehensive Swagger specification at:
pkg/api/openapi/minder/v1/minder.swagger.jsonThis contains complete JSON Schema-compatible definitions for all response types:
2. Create a schema extraction tool
Build a code generator that:
minder.swagger.jsondefinitionssection$refreferences into standalone schemas3. Embed schemas at build time
4. Add to tool registration
5. Update marshalResult for structured content
If mcp-go supports it:
Tasks
WithOutputSchema()andStructuredContentcmd/gen-schemasor similar)task gen-schemastarget to Taskfileinternal/schemas/package with embed and registryminder_list_projectsv1ListProjectsResponseminder_list_repositoriesv1ListRepositoriesResponseminder_get_repositoryv1GetRepositoryByIdResponse/v1GetRepositoryByNameResponseminder_list_profilesv1ListProfilesResponseminder_get_profilev1GetProfileByIdResponse/v1GetProfileByNameResponseminder_get_profile_statusv1GetProfileStatusByIdResponse/v1GetProfileStatusByNameResponseminder_list_rule_typesv1ListRuleTypesResponseminder_get_rule_typev1GetRuleTypeByIdResponse/v1GetRuleTypeByNameResponseminder_list_data_sourcesv1ListDataSourcesResponseminder_get_data_sourcev1GetDataSourceByIdResponse/v1GetDataSourceByNameResponseminder_list_providersv1ListProvidersResponseminder_get_providerv1GetProviderResponseminder_list_artifactsv1ListArtifactsResponseminder_get_artifactv1GetArtifactByIdResponse/v1GetArtifactByNameResponseminder_list_evaluation_historyv1ListEvaluationHistoryResponseRegister()to add output schemas to all toolsmarshalResult()to return structured content if supportedAlternative Approaches Considered
References
pkg/api/openapi/minder/v1/minder.swagger.json