Commit bd075b0
authored
Deduplicate raw MCP text envelope construction with shared helper (#4352)
Raw MCP text-content envelopes
(`{"content":[{"type":"text","text":"..."}]}`) were being
hand-constructed in multiple production paths, creating drift risk if
the envelope shape changes. This PR centralizes that shape behind one
helper and updates existing call sites to use it.
- **Shared MCP response helper**
- Added `mcp.BuildMCPTextResponse(text string) map[string]interface{}`
in `internal/mcp/tool_result.go`.
- Establishes a single source of truth for raw text envelope shape used
by guard-facing/raw-map flows.
- **Call site consolidation**
- Replaced inline envelope maps in:
- `internal/server/unified.go` (`callCollaboratorPermission`)
- `internal/proxy/proxy.go` (`restBackendCaller`)
- `internal/server/system_tools.go` (`sysInit`)
- `internal/server/system_tools.go` (`listServers`)
- **Targeted unit coverage**
- Added `TestBuildMCPTextResponse` in `internal/mcp/tool_result_test.go`
to validate envelope structure and text passthrough.
```go
func BuildMCPTextResponse(text string) map[string]interface{} {
return map[string]interface{}{
"content": []map[string]interface{}{
{"type": "text", "text": text},
},
}
}
```
> [!WARNING]
>
> <details>
> <summary>Firewall rules blocked me from connecting to one or more
addresses (expand for details)</summary>
>
> #### I tried to connect to the following addresses, but was blocked by
firewall rules:
>
> - `example.com`
> - Triggering command: `/tmp/go-build3674478355/b509/launcher.test
/tmp/go-build3674478355/b509/launcher.test
-test.testlogfile=/tmp/go-build3674478355/b509/testlog.txt
-test.paniconexit0 -test.timeout=10m0s -test.v=true
rotocol/go-sdk@v1.5.0/internal/json/json.go -I x_amd64/vet --gdwarf-5
--64 ut-4038412272.c x_amd64/vet -I g_.a -fPIC x_amd64/vet -pthread
go-sdk/oauthex -fmessage-length-bool x_amd64/vet` (dns block)
> - Triggering command: `/tmp/go-build2111533505/b513/launcher.test
/tmp/go-build2111533505/b513/launcher.test
-test.testlogfile=/tmp/go-build2111533505/b513/testlog.txt
-test.paniconexit0 -test.timeout=10m0s` (dns block)
> - `invalid-host-that-does-not-exist-12345.com`
> - Triggering command: `/tmp/go-build3674478355/b491/config.test
/tmp/go-build3674478355/b491/config.test
-test.testlogfile=/tmp/go-build3674478355/b491/testlog.txt
-test.paniconexit0 -test.timeout=10m0s -test.v=true
/internal/httpcommon/ascii.go /internal/httpcommon/headermap.go
x_amd64/vet --gdwarf-5 ternal/engine/in-atomic -o x_amd64/vet 2897��
g_.a -I x_amd64/vet --gdwarf-5` (dns block)
> - Triggering command: `/tmp/go-build2111533505/b495/config.test
/tmp/go-build2111533505/b495/config.test
-test.testlogfile=/tmp/go-build2111533505/b495/testlog.txt
-test.paniconexit0 -test.timeout=10m0s 2897�� g_.a -goversion
64/pkg/tool/linux_amd64/vet -c=4 -nolocalimports -importcfg
64/pkg/tool/linux_amd64/vet -uns�� q62FCnbEi 64/pkg/tool/linu-I
64/pkg/tool/linux_amd64/vet g_.a amVETxCjQ ache/go/1.25.9/x--noprofile
64/pkg/tool/linux_amd64/vet` (dns block)
> - `nonexistent.local`
> - Triggering command: `/tmp/go-build3674478355/b509/launcher.test
/tmp/go-build3674478355/b509/launcher.test
-test.testlogfile=/tmp/go-build3674478355/b509/testlog.txt
-test.paniconexit0 -test.timeout=10m0s -test.v=true
rotocol/go-sdk@v1.5.0/internal/json/json.go -I x_amd64/vet --gdwarf-5
--64 ut-4038412272.c x_amd64/vet -I g_.a -fPIC x_amd64/vet -pthread
go-sdk/oauthex -fmessage-length-bool x_amd64/vet` (dns block)
> - Triggering command: `/tmp/go-build2111533505/b513/launcher.test
/tmp/go-build2111533505/b513/launcher.test
-test.testlogfile=/tmp/go-build2111533505/b513/testlog.txt
-test.paniconexit0 -test.timeout=10m0s` (dns block)
> - `slow.example.com`
> - Triggering command: `/tmp/go-build3674478355/b509/launcher.test
/tmp/go-build3674478355/b509/launcher.test
-test.testlogfile=/tmp/go-build3674478355/b509/testlog.txt
-test.paniconexit0 -test.timeout=10m0s -test.v=true
rotocol/go-sdk@v1.5.0/internal/json/json.go -I x_amd64/vet --gdwarf-5
--64 ut-4038412272.c x_amd64/vet -I g_.a -fPIC x_amd64/vet -pthread
go-sdk/oauthex -fmessage-length-bool x_amd64/vet` (dns block)
> - Triggering command: `/tmp/go-build2111533505/b513/launcher.test
/tmp/go-build2111533505/b513/launcher.test
-test.testlogfile=/tmp/go-build2111533505/b513/testlog.txt
-test.paniconexit0 -test.timeout=10m0s` (dns block)
> - `this-host-does-not-exist-12345.com`
> - Triggering command: `/tmp/go-build3674478355/b518/mcp.test
/tmp/go-build3674478355/b518/mcp.test
-test.testlogfile=/tmp/go-build3674478355/b518/testlog.txt
-test.paniconexit0 -test.timeout=10m0s -test.v=true
olang.org/grpc@v1.80.0/internal/transport/bdp_estimator.go
olang.org/grpc@v1.80.0/internal/transport/client_stream.go x_amd64/vet
--gdwarf-5 g/grpc/metadata -o x_amd64/vet .cfg�� 2897549/b447/_pkg_.a
-trimpath x_amd64/vet -p contextprotocol//usr/bin/runc -lang=go1.25
x_amd64/vet` (dns block)
> - Triggering command: `/tmp/go-build3099190320/b253/mcp.test
/tmp/go-build3099190320/b253/mcp.test
-test.testlogfile=/tmp/go-build3099190320/b253/testlog.txt
-test.paniconexit0 -test.timeout=10m0s` (dns block)
>
> If you need me to access, download, or install something from one of
these locations, you can either:
>
> - Configure [Actions setup
steps](https://gh.io/copilot/actions-setup-steps) to set up my
environment, which run before the firewall is enabled
> - Add the appropriate URLs or hosts to the custom allowlist in this
repository's [Copilot coding agent
settings](https://github.com/github/gh-aw-mcpg/settings/copilot/coding_agent)
(admins only)
>
> </details>5 files changed
Lines changed: 30 additions & 28 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
156 | 156 | | |
157 | 157 | | |
158 | 158 | | |
| 159 | + | |
| 160 | + | |
| 161 | + | |
| 162 | + | |
| 163 | + | |
| 164 | + | |
| 165 | + | |
| 166 | + | |
| 167 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
415 | 415 | | |
416 | 416 | | |
417 | 417 | | |
| 418 | + | |
| 419 | + | |
| 420 | + | |
| 421 | + | |
| 422 | + | |
| 423 | + | |
| 424 | + | |
| 425 | + | |
| 426 | + | |
| 427 | + | |
| 428 | + | |
| 429 | + | |
| 430 | + | |
| 431 | + | |
| 432 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
20 | 20 | | |
21 | 21 | | |
22 | 22 | | |
| 23 | + | |
23 | 24 | | |
24 | 25 | | |
25 | 26 | | |
| |||
331 | 332 | | |
332 | 333 | | |
333 | 334 | | |
334 | | - | |
335 | | - | |
336 | | - | |
337 | | - | |
338 | | - | |
339 | | - | |
| 335 | + | |
340 | 336 | | |
341 | 337 | | |
342 | 338 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
5 | 5 | | |
6 | 6 | | |
7 | 7 | | |
| 8 | + | |
8 | 9 | | |
9 | 10 | | |
10 | 11 | | |
| |||
89 | 90 | | |
90 | 91 | | |
91 | 92 | | |
92 | | - | |
93 | | - | |
94 | | - | |
95 | | - | |
96 | | - | |
97 | | - | |
98 | | - | |
99 | | - | |
| 93 | + | |
100 | 94 | | |
101 | 95 | | |
102 | 96 | | |
| |||
105 | 99 | | |
106 | 100 | | |
107 | 101 | | |
108 | | - | |
109 | | - | |
110 | | - | |
111 | | - | |
112 | | - | |
113 | | - | |
114 | | - | |
115 | | - | |
| 102 | + | |
116 | 103 | | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
346 | 346 | | |
347 | 347 | | |
348 | 348 | | |
349 | | - | |
350 | | - | |
351 | | - | |
352 | | - | |
353 | | - | |
354 | | - | |
| 349 | + | |
355 | 350 | | |
356 | 351 | | |
357 | 352 | | |
| |||
0 commit comments