MCP server: `structuredContent` should include actual tool output, not just pagination metadata
### Checklist
- [x] I'm using the latest version of the extension (Run `glab --version`)
- Extension version: 1.80.4 (f4b518e9)
- [x] Operating system and version: macOS Darwin 24.6.0 arm64
- [x] Gitlab.com or self-managed instance? self-managed instance
- [x] GitLab version (if self-managed): N/A (issue is with MCP server, not GitLab API)
- [x] I have performed `glab auth status` to check for authentication issues
- [x] Run the command in debug mode and attach any useful output (see logs below)
### Summary
When using `glab mcp serve` with MCP clients that prioritize `structuredContent` (like Claude Code), the actual tool output is not displayed. This is because glab's `structuredContent` only contains pagination metadata, not the actual command output.
MCP clients like Claude Code prioritize `structuredContent` over `content` for agent performance. Since glab only puts pagination info in `structuredContent`, users see pagination metadata instead of the actual data (e.g., MR list).
### Environment
- OS: Darwin 24.6.0 arm64
- SHELL: /bin/zsh
- TERM: xterm-256color (via tmux)
- GLAB: glab 1.80.4 (f4b518e9)
Other: Using Claude Code 2.0.67 as MCP client
### Steps to reproduce
1. Configure `glab mcp serve` as an MCP server in Claude Code (stdio transport)
2. Call any glab tool, e.g., `glab_mr_list`
3. Observe that only pagination metadata is displayed, not the actual MR list
### What is the current _bug_ behavior?
glab MCP server returns:
```json
{
"result": {
"content": [
{"type": "text", "text": "Showing 8 open merge requests...\n\n!1359\t..."}
],
"structuredContent": {
"pagination": {
"actual_end": 1006,
"actual_size": 1006,
"actual_start": 0,
"limit": 50000,
"offset": 0,
"total_size": 1006,
"truncated": false
}
}
}
}
```
Claude Code (and other MCP clients following the spec) prioritizes `structuredContent`, so users only see:
```json
{"pagination":{"actual_end":1006,"actual_size":1006,...}}
```
The actual MR list in `content` is never displayed.
### What is the expected _correct_ behavior?
According to the MCP specification and Claude Code's documented behavior (https://github.com/anthropics/claude-code/issues/9962), `structuredContent` should include the actual tool output:
**Option 1**: Include actual output in `structuredContent`
```json
{
"structuredContent": {
"output": "Showing 8 open merge requests...",
"items": [...],
"pagination": {...}
}
}
```
**Option 2**: Only return `content`, don't return `structuredContent` if it's just metadata
```json
{
"content": [
{"type": "text", "text": "Showing 8 open merge requests..."}
]
}
```
**Option 3**: Add a flag to control behavior
```bash
glab mcp serve --no-structured-content
```
### Relevant logs and/or screenshots
MCP server log captured via wrapper script showing the full response:
**Request:**
```json
{"method":"tools/call","params":{"name":"glab_mr_list","arguments":{}},"jsonrpc":"2.0","id":2}
```
**Response from glab:**
```json
{"jsonrpc":"2.0","id":2,"result":{"content":[{"type":"text","text":"Showing 8 open merge requests on synology/OrangeDrive. (Page 1)\n\n!1359\tsynology/OrangeDrive!1359\tfeat: support complex share paths in PathConvertHelper\t(master) ← (WP159)\n!1354\tsynology/OrangeDrive!1354\tfeat: refactor msstore\t(master) ← (appstore)\n..."}],"structuredContent":{"pagination":{"actual_end":1006,"actual_size":1006,"actual_start":0,"limit":50000,"offset":0,"total_size":1006,"truncated":false}}}}
```
**What Claude Code displays:**
```json
{"pagination":{"actual_end":1006,"actual_size":1006,"actual_start":0,"limit":50000,"offset":0,"total_size":1006,"truncated":false}}
```
### Possible fixes
**Code location:** [`internal/commands/mcp/serve/server.go:277-286`](https://gitlab.com/gitlab-org/cli/-/blob/main/internal/commands/mcp/serve/server.go#L277-286)
```go
return &mcp.CallToolResult{
Content: []mcp.Content{
mcp.TextContent{
Type: "text",
Text: processedOutput,
},
},
StructuredContent: map[string]any{
"pagination": metadata, // <-- Only pagination, missing actual output
},
}, nil
```
**Suggested fix:** Include the actual output in `StructuredContent`:
```go
StructuredContent: map[string]any{
"output": processedOutput, // Add actual output here
"pagination": metadata,
},
```
Or remove `StructuredContent` entirely if it's only used for pagination metadata.
References:
- MCP Specification: https://modelcontextprotocol.io/specification/2025-11-25/server/tools
- Claude Code issue explaining client behavior: https://github.com/anthropics/claude-code/issues/9962
issue