Skip to content

Update make release to accept bump type as positional argument#34

Merged
pelikhan merged 2 commits intomainfrom
copilot/update-make-release-command
Jan 6, 2026
Merged

Update make release to accept bump type as positional argument#34
pelikhan merged 2 commits intomainfrom
copilot/update-make-release-command

Conversation

Copy link
Contributor

Copilot AI commented Jan 6, 2026

Changed make release syntax from make release BUMP=patch to make release patch and corrected the workflow URL.

Changes

  • Makefile syntax: Uses $(filter-out $@,$(MAKECMDGOALS)) to capture bump type as positional argument instead of Makefile variable
  • Catch-all pattern: Added %: @: rule to prevent make from treating the argument as a separate target
  • Workflow URL: Updated from release.md to release.lock.yml
  • Help text: Updated to reflect new usage pattern

Usage

# Old syntax (no longer works)
make release BUMP=patch

# New syntax
make release patch
make release minor
make release major

Error handling remains unchanged - validates bump type and prompts for confirmation before creating tags.

Original prompt

Update make release:


💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.

…x workflow URL

Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Copilot AI changed the title [WIP] Update make release command syntax for version bumps Update make release to accept bump type as positional argument Jan 6, 2026
Copilot AI requested a review from pelikhan January 6, 2026 23:04
@pelikhan pelikhan marked this pull request as ready for review January 6, 2026 23:07
@pelikhan pelikhan merged commit a49ecd2 into main Jan 6, 2026
@pelikhan pelikhan deleted the copilot/update-make-release-command branch January 6, 2026 23:07
lpcox pushed a commit that referenced this pull request Jan 8, 2026
* Initial plan

* Update make release to accept bump type as positional argument and fix workflow URL

Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
pelikhan added a commit that referenced this pull request Feb 4, 2026
OAuth discovery requests to `/.well-known/oauth-authorization-server`
hang instead of returning 404, causing Codex rmcp client to timeout
after 15s per server. Gateway only registers handler at
`/mcp/.well-known/oauth-authorization-server`.

## Changes

- **Route registration**: Add handler at
`/.well-known/oauth-authorization-server` in both unified
(`transport.go`) and routed (`routed.go`) modes
- **Handler reuse**: Both paths now use existing
`handleOAuthDiscovery()` that returns 404
- **Test coverage**: Added test cases for root-level and MCP-prefixed
paths (GET/POST methods)

## Implementation

```go
// OAuth discovery endpoints - return 404 since we don't use OAuth
// Standard path for OAuth discovery (per RFC 8414)
mux.Handle("/.well-known/oauth-authorization-server", withResponseLogging(handleOAuthDiscovery()))
// MCP-prefixed path for backward compatibility
mux.Handle("/mcp/.well-known/oauth-authorization-server", withResponseLogging(handleOAuthDiscovery()))
```

Result: OAuth discovery now fails fast with immediate 404 instead of
timing out.

> [!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-build3835057396/b270/launcher.test
/tmp/go-build3835057396/b270/launcher.test
-test.testlogfile=/tmp/go-build3835057396/b270/testlog.txt
-test.paniconexit0 -test.timeout=10m0s -test.v=true g_.a dler at
/.well-known/oauth-authorization-server for both unified and routed
modes
- Prevents req--norc x_amd64/vet` (dns block)
> - `invalid-host-that-does-not-exist-12345.com`
> - Triggering command: `/tmp/go-build3835057396/b258/config.test
/tmp/go-build3835057396/b258/config.test
-test.testlogfile=/tmp/go-build3835057396/b258/testlog.txt
-test.paniconexit0 -test.timeout=10m0s -test.v=true
ache/go/1.25.6/x64/src/runtime/cgo` (dns block)
> - `nonexistent.local`
> - Triggering command: `/tmp/go-build3835057396/b270/launcher.test
/tmp/go-build3835057396/b270/launcher.test
-test.testlogfile=/tmp/go-build3835057396/b270/testlog.txt
-test.paniconexit0 -test.timeout=10m0s -test.v=true g_.a dler at
/.well-known/oauth-authorization-server for both unified and routed
modes
- Prevents req--norc x_amd64/vet` (dns block)
> - `slow.example.com`
> - Triggering command: `/tmp/go-build3835057396/b270/launcher.test
/tmp/go-build3835057396/b270/launcher.test
-test.testlogfile=/tmp/go-build3835057396/b270/testlog.txt
-test.paniconexit0 -test.timeout=10m0s -test.v=true g_.a dler at
/.well-known/oauth-authorization-server for both unified and routed
modes
- Prevents req--norc x_amd64/vet` (dns block)
> - `this-host-does-not-exist-12345.com`
> - Triggering command: `/tmp/go-build3835057396/b279/mcp.test
/tmp/go-build3835057396/b279/mcp.test
-test.testlogfile=/tmp/go-build3835057396/b279/testlog.txt
-test.paniconexit0 -test.timeout=10m0s -test.v=true g_.a
64/src/crypto/internal/boring/bbig/big.go
df11d1ebad5122b89293a9cf3b8353f09e1d0c3b3841ebf6471/log.json -g&#34;
&#34;-lresolv&#34; ernal/sys -I 64/pkg/tool/linux_amd64/vet` (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>

<!-- START COPILOT ORIGINAL PROMPT -->



<details>

<summary>Original prompt</summary>

> 
> ----
> 
> *This section details on the original issue you should resolve*
> 
> <issue_title>OAuth discovery requests hang instead of returning
404</issue_title>
> <issue_description>## Summary
> 
> OAuth discovery requests to `/.well-known/oauth-authorization-server`
hang indefinitely instead of returning a quick 404 response. This causes
Codex MCP connections to timeout after 15 seconds per server.
> 
> ## Problem
> 
> The Codex rmcp client (Rust MCP client) attempts OAuth discovery at
the **standard path**:
> ```
> GET http://host.docker.internal/.well-known/oauth-authorization-server
> ```
> 
> But the MCP Gateway registers the OAuth handler at:
> ```
> /mcp/.well-known/oauth-authorization-server
> ```
> 
> Since there's no handler at `/.well-known/...`, the request has no
matching route and hangs instead of returning 404.
> 
> ## Evidence
> 
> ### Smoke-codex workflow run:
https://github.com/github/gh-aw/actions/runs/21688558782
> 
> **Error pattern:**
> ```
> DEBUG session_init: codex_rmcp_client::auth_status: OAuth discovery
requests failed for
> http://host.docker.internal:80/mcp/playwright: error sending request
for url
> (http://host.docker.internal/.well-known/oauth-authorization-server)
> 
> Caused by:
>     operation timed out
> ```
> 
> **Result:**
> - OAuth discovery times out (15 seconds per server)
> - 4 of 6 MCP servers fail to connect
> - Only tavily and safeoutputs succeed (race condition - they complete
before timeout exhausts resources)
> 
> **Firewall logs confirm traffic reaches gateway:**
> ```
> ▼ 11 requests | 11 allowed | 0 blocked | 1 unique domain
> | Domain              | Allowed | Denied |
> |---------------------|---------|--------|
> | host.docker.internal | 11      | 0      |
> ```
> 
> ### Comparison with working run
> 
> In run 21653900083 (before chroot mode), using IP address 172.30.0.1,
OAuth discovery was NOT attempted and all 6 MCP servers connected
successfully:
> ```
> ready: ["safeoutputs", "safeinputs", "github", "playwright", "tavily",
"serena"]
> ```
> 
> ## Current Route Registration
> 
> From `internal/server/transport.go`:
> 
> | Route | Handler |
> |-------|---------|
> | `/mcp/.well-known/oauth-authorization-server` | OAuth handler
(returns 404) |
> | `/mcp/` and `/mcp` | StreamableHTTPHandler |
> | `/health` | Health check |
> | `/close` | Graceful shutdown |
> | `/.well-known/*` | **NO HANDLER** ← causes hang |
> 
> ## Proposed Fix
> 
> Add a handler for OAuth discovery at the standard path (without
`/mcp/` prefix):
> 
> ```go
> // In internal/server/transport.go, add alongside existing routes:
> mux.HandleFunc("/.well-known/oauth-authorization-server", func(w
http.ResponseWriter, r *http.Request) {
>     http.NotFound(w, r)
> })
> ```
> 
> This ensures OAuth discovery requests get an immediate 404 response
instead of hanging.
> 
> ## Impact
> 
> This fix would:
> 1. Make OAuth discovery fail fast (instant 404 instead of 15s timeout)
> 2. Allow all 6 MCP servers to connect successfully in Codex workflows
> 3. Fix smoke-codex CI failures
> 
> ## Related
> 
> - gh-aw PR github/gh-aw-mcpg#13792: Removed hardcoded IP from Codex
config (firewall fix - separate issue)</issue_description>
> 
> ## Comments on the Issue (you are @copilot in this section)
> 
> <comments>
> </comments>
> 


</details>



<!-- START COPILOT CODING AGENT SUFFIX -->

- Fixes #672

<!-- START COPILOT CODING AGENT TIPS -->
---

✨ Let Copilot coding agent [set things up for
you](https://github.com/github/gh-aw-mcpg/issues/new?title=✨+Set+up+Copilot+instructions&body=Configure%20instructions%20for%20this%20repository%20as%20documented%20in%20%5BBest%20practices%20for%20Copilot%20coding%20agent%20in%20your%20repository%5D%28https://gh.io/copilot-coding-agent-tips%29%2E%0A%0A%3COnboard%20this%20repo%3E&assignees=copilot)
— coding agent works faster and does higher quality work when set up for
your repo.
lpcox added a commit that referenced this pull request Feb 5, 2026
Duplicate code analysis identified ~54 lines of duplication across 2
patterns in the DIFC and config validation modules.

## Changes

### DIFC Label Constructors
Extracted common label-with-tags creation pattern into
`newLabelWithTags()` helper:

```go
// Before: Duplicated logic in both constructors
func NewSecrecyLabelWithTags(tags []Tag) *SecrecyLabel {
    label := NewSecrecyLabel()
    label.Label.AddAll(tags)
    return label
}

func NewIntegrityLabelWithTags(tags []Tag) *IntegrityLabel {
    label := NewIntegrityLabel()
    label.Label.AddAll(tags)
    return label
}

// After: Single helper, constructors simplified
func newLabelWithTags(tags []Tag) *Label {
    label := NewLabel()
    label.AddAll(tags)
    return label
}

func NewSecrecyLabelWithTags(tags []Tag) *SecrecyLabel {
    return &SecrecyLabel{Label: newLabelWithTags(tags)}
}

func NewIntegrityLabelWithTags(tags []Tag) *IntegrityLabel {
    return &IntegrityLabel{Label: newLabelWithTags(tags)}
}
```

Eliminates ~8 lines of duplication in `internal/difc/labels.go`.

### Docker Inspect Wrappers
Analysis confirmed `checkPortMapping()`, `checkStdinInteractive()`, and
`checkLogDirMounted()` already share the `runDockerInspect()` helper.
Each function has distinct domain logic and return types. No further
abstraction warranted.

> [!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-build4007704820/b274/launcher.test
/tmp/go-build4007704820/b274/launcher.test
-test.testlogfile=/tmp/go-build4007704820/b274/testlog.txt
-test.paniconexit0 -test.timeout=10m0s -test.v=true
ache/go/1.25.6/x64/src/runtime/cgo .cfg 64/pkg/tool/linux_amd64/vet -p
vendor/golang.or-unsafeptr=false -lang=go1.25
64/pkg/tool/linux_amd64/vet -I 8340911/b183/ -I rgo/bin/as -g&#34;
&#34;-lresolv&#34; --64 -o 8340911/b183/` (dns block)
> - `invalid-host-that-does-not-exist-12345.com`
> - Triggering command: `/tmp/go-build3364410036/b001/config.test
/tmp/go-build3364410036/b001/config.test
-test.testlogfile=/tmp/go-build3364410036/b001/testlog.txt
-test.paniconexit0 -test.timeout=10m0s -test.v=true go
ps140/fips140.go-imultiarch 64/pkg/tool/linux86_64-linux-gnu` (dns
block)
> - `nonexistent.local`
> - Triggering command: `/tmp/go-build4007704820/b274/launcher.test
/tmp/go-build4007704820/b274/launcher.test
-test.testlogfile=/tmp/go-build4007704820/b274/testlog.txt
-test.paniconexit0 -test.timeout=10m0s -test.v=true
ache/go/1.25.6/x64/src/runtime/cgo .cfg 64/pkg/tool/linux_amd64/vet -p
vendor/golang.or-unsafeptr=false -lang=go1.25
64/pkg/tool/linux_amd64/vet -I 8340911/b183/ -I rgo/bin/as -g&#34;
&#34;-lresolv&#34; --64 -o 8340911/b183/` (dns block)
> - `slow.example.com`
> - Triggering command: `/tmp/go-build4007704820/b274/launcher.test
/tmp/go-build4007704820/b274/launcher.test
-test.testlogfile=/tmp/go-build4007704820/b274/testlog.txt
-test.paniconexit0 -test.timeout=10m0s -test.v=true
ache/go/1.25.6/x64/src/runtime/cgo .cfg 64/pkg/tool/linux_amd64/vet -p
vendor/golang.or-unsafeptr=false -lang=go1.25
64/pkg/tool/linux_amd64/vet -I 8340911/b183/ -I rgo/bin/as -g&#34;
&#34;-lresolv&#34; --64 -o 8340911/b183/` (dns block)
> - `this-host-does-not-exist-12345.com`
> - Triggering command: `/tmp/go-build4007704820/b283/mcp.test
/tmp/go-build4007704820/b283/mcp.test
-test.testlogfile=/tmp/go-build4007704820/b283/testlog.txt
-test.paniconexit0 -test.timeout=10m0s -test.v=true 64/src/net red-by:
lpcox &lt;15877973&#43;lpcox@users.noreply.github.com&gt;
ache/go/1.25.6/x64/pkg/tool/linux_amd64/vet -p
crypto/internal/-unsafeptr=false -lang=go1.25 01.o` (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>

<!-- START COPILOT ORIGINAL PROMPT -->



<details>

<summary>Original prompt</summary>

> 
> ----
> 
> *This section details on the original issue you should resolve*
> 
> <issue_title>[duplicate-code] Duplicate Code Analysis Report -
f550849</issue_title>
> <issue_description>*Analysis of commit
f550849*
> 
> ## Summary
> 
> This analysis identified **2 significant duplication patterns** across
the Go codebase, affecting the DIFC (Decentralized Information Flow
Control) module and configuration validation code. A total of
approximately **54 lines** of meaningful duplicated code were detected.
> 
> ## Detected Patterns
> 
> This analysis found 2 significant duplication patterns requiring
refactoring:
> 
> 1. **DIFC Label Constructor Duplication** - Severity: Medium - See
sub-issue #aw_xyz789ghi012
> 2. **Docker Inspect Wrapper Functions** - Severity: Medium - See
sub-issue #aw_mno345pqr678
> 
> ## Overall Impact
> 
> - **Total Duplicated Lines**: ~54 lines across 2 patterns
> - **Affected Files**: 2 files (`internal/difc/labels.go`,
`internal/difc/agent.go`, `internal/config/validation_env.go`)
> - **Maintainability Risk**: Medium - Duplication increases risk of
inconsistent updates
> - **Refactoring Priority**: Medium - Both patterns are in active
development areas
> 
> ## Next Steps
> 
> 1. Review individual pattern sub-issues for detailed analysis
> 2. Prioritize refactoring based on severity and impact
> 3. Create implementation plan for highest priority patterns
> 4. Consider using Go generics or helper functions to reduce
duplication
> 
> ## Analysis Metadata
> 
> - **Analyzed Files**: 60 Go files (excluding tests, workflows, and
agent configs)
> - **Detection Method**: Semantic code analysis using grep and manual
code review
> - **Commit**: f550849
> - **Analysis Date**: 2026-02-05T03:03:56Z
> - **Triggered by**: `@lpcox`
> 
> 
> 
> 
> > AI generated by [Duplicate Code
Detector](https://github.com/github/gh-aw-mcpg/actions/runs/21697098717)
> > - [x] expires <!-- gh-aw-expires: 2026-02-12T03:07:40.520Z --> on
Feb 12, 2026, 3:07 AM UTC
> 
> <!-- gh-aw-agentic-workflow: Duplicate Code Detector, engine: copilot,
run: https://github.com/github/gh-aw-mcpg/actions/runs/21697098717 -->
> 
> <!-- gh-aw-workflow-id: duplicate-code-detector
--></issue_description>
> 
> ## Comments on the Issue (you are @copilot in this section)
> 
> <comments>
> </comments>
> 


</details>


> **Custom agent used: agentic-workflows**
> GitHub Agentic Workflows (gh-aw) - Create, debug, and upgrade
AI-powered workflows with intelligent prompt routing



<!-- START COPILOT CODING AGENT SUFFIX -->

- Fixes #678

<!-- START COPILOT CODING AGENT TIPS -->
---

💬 We'd love your input! Share your thoughts on Copilot coding agent in
our [2 minute survey](https://gh.io/copilot-coding-agent-survey).
lpcox added a commit that referenced this pull request Feb 8, 2026
#844)

Nightly stress test detected configuration errors in two MCP servers:
filesystem expected directories as CLI arguments but received
environment variables, and playwright had redundant host list entries.

## Changes

**filesystem server**
- Changed from `env.ALLOWED_PATHS` to `entrypointArgs: ["/workspace"]`
- Server requires directory paths as positional arguments after
container name

**playwright server**  
- Simplified allowed-hosts/origins from
`localhost;localhost:*;127.0.0.1;127.0.0.1:*` to
`localhost:*;127.0.0.1:*`
- Removed redundant non-wildcard entries

## Configuration structure

Gateway converts workflow YAML to Docker commands following this
pattern:
```bash
docker run [args...] <container> [entrypointArgs...]
```

- `args`: Docker runtime flags (e.g., `--init`, `--network host`) -
before container
- `entrypointArgs`: Application arguments - after container

## Testing

Added `TestLoadFromStdin_FilesystemServerConfig` and
`TestLoadFromStdin_PlaywrightServerConfig` to validate argument
placement and prevent similar configuration errors.

> [!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-build1254119737/b275/launcher.test
/tmp/go-build1254119737/b275/launcher.test
-test.testlogfile=/tmp/go-build1254119737/b275/testlog.txt
-test.paniconexit0 -test.timeout=10m0s -test.v=true
/opt/hostedtoolcache/go/1.25.6/x64/src/runtime/cgo 6765506/b184/
ache/Python/3.12.12/x64/bin/as --gdwarf-5 --64 -o as 6765�� d -n 10 -I
docker-buildx --gdwarf-5 --64 -o docker-buildx` (dns block)
> - `invalid-host-that-does-not-exist-12345.com`
> - Triggering command: `/tmp/go-build3908585129/b001/config.test
/tmp/go-build3908585129/b001/config.test
-test.testlogfile=/tmp/go-build3908585129/b001/testlog.txt
-test.paniconexit0 -test.timeout=10m0s -test.v=true go1.25.6 -c=4
-nolocalimports -importcfg /tmp/go-build2196765506/b210/importcfg -pack
/opt/hostedtoolcache/go/1.25.6/x64/src/net/http/httptest/httptest.go
conf�� go k/gh-aw-mcpg/gh-aw-mcpg/tools.go--gdwarf2
ache/Python/3.12.12/x64/bin/bash--64
k/gh-aw-mcpg/gh-/opt/hostedtoolcache/go/1.25.6/x64/pkg/tool/linux_amd64/compile
k/gh-aw-mcpg/gh--o k/gh-aw-mcpg/gh-/tmp/go-build2196765506/b125/_pkg_.a
.o` (dns block)
> - `nonexistent.local`
> - Triggering command: `/tmp/go-build1254119737/b275/launcher.test
/tmp/go-build1254119737/b275/launcher.test
-test.testlogfile=/tmp/go-build1254119737/b275/testlog.txt
-test.paniconexit0 -test.timeout=10m0s -test.v=true
/opt/hostedtoolcache/go/1.25.6/x64/src/runtime/cgo 6765506/b184/
ache/Python/3.12.12/x64/bin/as --gdwarf-5 --64 -o as 6765�� d -n 10 -I
docker-buildx --gdwarf-5 --64 -o docker-buildx` (dns block)
> - `slow.example.com`
> - Triggering command: `/tmp/go-build1254119737/b275/launcher.test
/tmp/go-build1254119737/b275/launcher.test
-test.testlogfile=/tmp/go-build1254119737/b275/testlog.txt
-test.paniconexit0 -test.timeout=10m0s -test.v=true
/opt/hostedtoolcache/go/1.25.6/x64/src/runtime/cgo 6765506/b184/
ache/Python/3.12.12/x64/bin/as --gdwarf-5 --64 -o as 6765�� d -n 10 -I
docker-buildx --gdwarf-5 --64 -o docker-buildx` (dns block)
> - `this-host-does-not-exist-12345.com`
> - Triggering command: `/tmp/go-build1254119737/b284/mcp.test
/tmp/go-build1254119737/b284/mcp.test
-test.testlogfile=/tmp/go-build1254119737/b284/testlog.txt
-test.paniconexit0 -test.timeout=10m0s -test.v=true
/tmp/go-build2196765506/b218/_pkg_.a 6765506/b184/ p/bin/as -p
github.com/githu-unsafeptr=false -lang=go1.25 as 6765�� d -n 10
--debug-prefix-map ache/go/1.25.6/x64/pkg/tool/linux_amd64/vet -I
/opt/hostedtoolcmod -I ache/go/1.25.6/x64/pkg/tool/linuf() { test
&#34;$1&#34; = get &amp;&amp; echo &#34;******&#34;; }; f sto-w` (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>

<!-- START COPILOT ORIGINAL PROMPT -->



<details>

<summary>Original prompt</summary>


----

*This section details on the original issue you should resolve*

<issue_title>[mcp-stress-test] Server Configuration Failures Detected -
filesystem & playwright</issue_title>
<issue_description>The nightly stress test detected 2 servers with
configuration errors (not authentication issues).

## Test Summary

- **Test Session:** stress-test-20260208-034257
- **Test Date:** 2026-02-08T03:42:57Z
- **Total Configuration Failures:** 2

## Failed Servers

### 1. filesystem - Command Arguments Error

**Container:** mcp/filesystem

**Issue Type:** Configuration Error

**Error:**
``````
Usage: mcp-server-filesystem (allowed-directory) [additional-directories...]
``````

**Analysis:**
The filesystem server expects allowed directories as positional
command-line arguments, but the configuration is passing them as
environment variables (`ALLOWED_PATHS`). The docker command structure
needs to be updated.

**Current Configuration Issue:**
The server is launched with environment variable but expects positional
args.

**Suggested Fix:**
Update configuration to pass directories as positional arguments:

``````json
{
  "filesystem": {
    "type": "stdio",
    "container": "mcp/filesystem",
    "args": ["/workspace", "/additional/path"]
  }
}
``````

Or update the docker args to include the directory paths:
```````json
{
  "filesystem": {
    "type": "stdio",
    "command": "docker",
    "args": ["run", "--rm", "-i", "-v", "/tmp/mcp-test-fs:/workspace:rw", "mcp/filesystem", "/workspace"]
  }
}
``````

**Suggested Investigation:**
- [ ] Review filesystem server documentation for correct argument format
- [ ] Update gateway configuration to pass directories correctly
- [ ] Test with simple single directory first
- [ ] Consider if server should be updated to support env vars

---

### 2. playwright - Duplicate Flag Error

**Container:** mcr.microsoft.com/playwright/mcp

**Issue Type:** Configuration Error

**Error:**
``````
error: unknown option '--init'
``````

**Analysis:**
The docker command includes the `--init` flag twice - once as a docker
option (correct) and once passed to the playwright binary (incorrect).
The playwright binary doesn't recognize the `--init` flag and fails.

**Current Configuration Issue:**
``````
docker run --rm -i --init --network host mcr.microsoft.com/playwright/mcp --output-dir ... --init --network host
```````

Notice `--init` and `--network host` appear twice.

**Suggested Fix:**
Remove the duplicate flags from the playwright server arguments:

``````json
{
  "playwright": {
    "type": "stdio",
    "command": "docker",
    "args": [
      "run", "--rm", "-i",
      "--init",
      "--network", "host",
      "-v", "/tmp/gh-aw/mcp-logs:/tmp/gh-aw/mcp-logs:rw",
      "mcr.microsoft.com/playwright/mcp",
      "--output-dir", "/tmp/gh-aw/mcp-logs/playwright",
      "--allowed-hosts", "localhost,localhost:*,127.0.0.1,127.0.0.1:*",
      "--allowed-origins", "localhost;localhost:*;127.0.0.1;127.0.0.1:*"
    ]
  }
}
``````

**Suggested Investigation:**
- [ ] Review playwright MCP server documentation
- [ ] Remove duplicate `--init` and `--network host` from args array
- [ ] Verify correct flag order for playwright binary
- [ ] Test with corrected configuration

---

## Gateway Logs

From the gateway logs, both issues are clearly configuration-related,
not authentication or protocol issues:

**filesystem:**
- Server expects CLI args but receives env vars
- Quick fix: restructure docker command args

**playwright:**
- Duplicate flags passed to both docker and playwright binary
- Quick fix: remove duplicate flags from args array

## Test Configuration Used

The test used the following configuration:
- Startup Timeout: 60s
- Tool Timeout: 30s
- Test Method: Sequential server testing
- Gateway: Successfully handled all requests

## Impact

These configuration issues prevent 2 MCP servers from launching:
1. **filesystem** - Would provide file system access if configured
correctly
2. **playwright** - Would provide browser automation if configured
correctly

Both are fixable with configuration changes and don't require code
modifications.

## Next Steps

1. **Priority: High** - Fix filesystem configuration
   - Update docker args to pass directories as positional arguments
   - Test with `/workspace` mount
   
2. **Priority: High** - Fix playwright configuration
   - Remove duplicate `--init` and `--network host` flags
   - Verify flag order matches playwright binary expectations

3. Re-run stress test to verify fixes
4. Update documentation with correct configuration examples

---
*Generated by Nightly MCP Stress Test*  
*Test Session: stress-test-20260208-034257*

**Full Test Results:** See workflow run artifacts at
`/tmp/mcp-stress-results/`




> AI generated by [Nightly MCP Server Stress
Test](https://github.com/github/gh-aw-mcpg/actions/runs/21791681391)

<!-- gh-aw-agentic-workflow: Nightly MCP Server Stress Test, engine:
copilot, run:
https://github.com/github/gh-aw-mcpg/actions/runs/2179168139...

</details>


> **Custom agent used: agentic-workflows**
> GitHub Agentic Workflows (gh-aw) - Create, debug, and upgrade
AI-powered workflows with intelligent prompt routing



<!-- START COPILOT CODING AGENT SUFFIX -->

- Fixes #843

<!-- START COPILOT CODING AGENT TIPS -->
---

✨ Let Copilot coding agent [set things up for
you](https://github.com/github/gh-aw-mcpg/issues/new?title=✨+Set+up+Copilot+instructions&body=Configure%20instructions%20for%20this%20repository%20as%20documented%20in%20%5BBest%20practices%20for%20Copilot%20coding%20agent%20in%20your%20repository%5D%28https://gh.io/copilot-coding-agent-tips%29%2E%0A%0A%3COnboard%20this%20repo%3E&assignees=copilot)
— coding agent works faster and does higher quality work when set up for
your repo.
lpcox added a commit that referenced this pull request Feb 11, 2026
The Language Support Tester workflow documentation hardcoded
`/workspace/` paths, preventing the agent from locating test samples at
runtime. GitHub Actions workspace paths vary by environment (e.g.,
`/home/runner/work/{repo}/{repo}`).

## Changes

- **Updated path references in
`.github/agentics/language-support-tester.md`**:
  - Changed hardcoded `/workspace/` paths to `{workspace}` placeholder
- Added instructions to use workspace path from `github-context` section
  - Applied to JavaScript/TypeScript test samples path
  - Applied to Python test samples path
  - Updated "Important Notes" section references

The agent now receives the actual runtime workspace path via
`__GH_AW_GITHUB_WORKSPACE__` in the github-context and can correctly
construct paths to test samples:

```markdown
- Use the test samples at `{workspace}/test/serena-mcp-tests/samples/js_project/` (use the workspace path from github-context)
```

## Notes

Test sample files already exist in the repository with expected content
(`Calculator` class, `add` method, `format_number` function,
`package.json`). No code changes required.

> [!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-build380999041/b279/launcher.test
/tmp/go-build380999041/b279/launcher.test
-test.testlogfile=/tmp/go-build380999041/b279/testlog.txt
-test.paniconexit0 -test.timeout=10m0s -test.v=true 64/src/runtime/cgo
HEAD ache/go/1.25.6/x64/pkg/tool/linu-o it base64
/usr/bin/dirname/tmp/go-build380999041/b263/_pkg_.a 8.o comm�� /go-build
Fix workflow docgithub.com/github/gh-aw-mcpg/internal/config
x_amd64/vet` (dns block)
> - `invalid-host-that-does-not-exist-12345.com`
> - Triggering command: `/tmp/go-build380999041/b264/config.test
/tmp/go-build380999041/b264/config.test
-test.testlogfile=/tmp/go-build380999041/b264/testlog.txt
-test.paniconexit0 -test.timeout=10m0s -test.v=true 64/src/runtime/c-c=4
kdf/cast.go ache/go/1.25.6/x-importcfg cal/bin/git base64 /usr/sbin/git
6.o -c 64/src/runtime/cgo tf &#34;%s%s&#34;, sep, $0; sep=RS }
x_amd64/compile --abbrev-ref HEAD /usr/bin/base64 x_amd64/compile` (dns
block)
> - `nonexistent.local`
> - Triggering command: `/tmp/go-build380999041/b279/launcher.test
/tmp/go-build380999041/b279/launcher.test
-test.testlogfile=/tmp/go-build380999041/b279/testlog.txt
-test.paniconexit0 -test.timeout=10m0s -test.v=true 64/src/runtime/cgo
HEAD ache/go/1.25.6/x64/pkg/tool/linu-o it base64
/usr/bin/dirname/tmp/go-build380999041/b263/_pkg_.a 8.o comm�� /go-build
Fix workflow docgithub.com/github/gh-aw-mcpg/internal/config
x_amd64/vet` (dns block)
> - `slow.example.com`
> - Triggering command: `/tmp/go-build380999041/b279/launcher.test
/tmp/go-build380999041/b279/launcher.test
-test.testlogfile=/tmp/go-build380999041/b279/testlog.txt
-test.paniconexit0 -test.timeout=10m0s -test.v=true 64/src/runtime/cgo
HEAD ache/go/1.25.6/x64/pkg/tool/linu-o it base64
/usr/bin/dirname/tmp/go-build380999041/b263/_pkg_.a 8.o comm�� /go-build
Fix workflow docgithub.com/github/gh-aw-mcpg/internal/config
x_amd64/vet` (dns block)
> - `this-host-does-not-exist-12345.com`
> - Triggering command: `/tmp/go-build380999041/b288/mcp.test
/tmp/go-build380999041/b288/mcp.test
-test.testlogfile=/tmp/go-build380999041/b288/testlog.txt
-test.paniconexit0 -test.timeout=10m0s -test.v=true 737903/b083/_pkg_.a
JWKP/08bK8wSDgKwIadp3JWKP x_amd64/vet cal/bin/git /unix /x64=/_/GOROOT
x_amd64/vet o_.o�� ache/go/1.25.6/x-errorsas
ache/go/1.25.6/x-ifaceassert x_amd64/vet 737903/b083/symabash HEAD
ndor/bin/git x_amd64/vet` (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>

<!-- START COPILOT ORIGINAL PROMPT -->



<details>

<summary>Original prompt</summary>

> 
> ----
> 
> *This section details on the original issue you should resolve*
> 
> <issue_title>[language-support] Missing test samples for
TypeScript/JavaScript and Python language support testing</issue_title>
> <issue_description>## Summary
> 
> The Language Support Tester workflow references test sample
directories that do not exist in the repository, preventing proper
testing of TypeScript/JavaScript and Python language support with the
Serena MCP server.
> 
> ## Missing Directories
> 
> The following test sample directories referenced in
`.github/agentics/language-support-tester.md` are missing:
> 
> - `/workspace/test/serena-mcp-tests/samples/js_project/`
> - `/workspace/test/serena-mcp-tests/samples/python_project/`
> 
> ## Impact
> 
> - **Go language support**: ✅ Successfully tested with existing Go
files
> - **TypeScript/JavaScript support**: ❌ Cannot test - no test samples
exist
> - **Python support**: ❌ Cannot test - no test samples exist
> 
> ## Test Results
> 
> ### Go Language Support (✅ Working)
> 
> Successfully tested Go language support using the main repository
code:
> - `get_symbols_overview` on `main.go` returned functions: `main`,
`buildVersionString`, and constant `shortHashLength`
> - `find_symbol` successfully found the `main` function with correct
location and signature
> - `find_symbol` successfully found the `Version` variable in
`version.go` with complete info including documentation
> 
> ### TypeScript/JavaScript Support (⚠️ Unable to Test)
> 
> The referenced test directory
`/workspace/test/serena-mcp-tests/samples/js_project/` does not exist.
The repository contains no JavaScript or TypeScript files for testing.
> 
> ### Python Support (⚠️ Unable to Test)
> 
> The referenced test directory
`/workspace/test/serena-mcp-tests/samples/python_project/` does not
exist. The repository contains no Python files for testing.
> 
> ## Reproduction Steps
> 
> 1. Run the Language Support Tester workflow
> 2. Agent attempts to locate test samples at the documented paths
> 3. Paths do not exist in the repository
> 
> ## Recommended Solution
> 
> Create the missing test sample directories with appropriate test
files:
> 
> 1. Create `/workspace/test/serena-mcp-tests/samples/js_project/` with:
>    - `index.js` or `index.ts` with sample functions/classes
>    - `package.json` with project metadata
> 
> 2. Create `/workspace/test/serena-mcp-tests/samples/python_project/`
with:
>    - `calculator.py` with a `Calculator` class and `add` method
>    - `utils.py` with utility functions like `format_number`
> 
> Alternatively, update the testing workflow documentation to reference
existing test files or clarify that only Go language support needs
testing.
> 
> ## Additional Context
> 
> - Serena MCP server version: `ghcr.io/github/serena-mcp-server:latest`
> - Workflow: `.github/workflows/language-support-tester.lock.yml`
> - Task specification: `.github/agentics/language-support-tester.md`
> - Active project: `gh-aw-mcpg` (Go language configured)
> 
> 
> 
> 
> > AI generated by [Language Support
Tester](https://github.com/github/gh-aw-mcpg/actions/runs/21861851918)
> > - [x] expires <!-- gh-aw-expires: 2026-02-17T10:55:01.059Z --> on
Feb 17, 2026, 10:55 AM UTC
> 
> <!-- gh-aw-agentic-workflow: Language Support Tester, engine: copilot,
run: https://github.com/github/gh-aw-mcpg/actions/runs/21861851918 -->
> 
> <!-- gh-aw-workflow-id: language-support-tester
--></issue_description>
> 
> ## Comments on the Issue (you are @claude[agent] in this section)
> 
> <comments>
> </comments>
> 


</details>



<!-- START COPILOT CODING AGENT SUFFIX -->

- Fixes #875
lpcox added a commit that referenced this pull request Feb 11, 2026
…ag validation, and lifecycle hooks (#882)

Implements Priority 1 and 2 recommendations from Go Fan report for
github.com/spf13/cobra v1.10.2. Leverages new Cobra features for cleaner
CLI code and better reliability.

## Context-based graceful shutdown

Replace manual signal handling with `signal.NotifyContext` for proper
cancellation propagation:

```go
// Before: manual signal channel
ctx, cancel := context.WithCancel(context.Background())
sigChan := make(chan os.Signal, 1)
signal.Notify(sigChan, os.Interrupt, syscall.SIGTERM)

// After: v1.10.0 pattern
ctx, cancel := signal.NotifyContext(cmd.Context(), os.Interrupt, syscall.SIGTERM)
```

- HTTP server shutdown with 5s timeout via `httpServer.Shutdown(ctx)`
- Context cancellation propagates through unified server

## Declarative flag validation

Replace manual preRun validation with Cobra's built-in validation
groups:

```go
// Flag validation groups
cmd.MarkFlagsMutuallyExclusive("routed", "unified")
cmd.MarkFlagsOneRequired("config", "config-stdin")
```

- Removes 5 lines of manual validation logic from `preRun`
- Produces consistent error messages: `"at least one of the flags in the
group [config config-stdin] is required"`
- Updates integration test to expect new error format

## Lifecycle hooks

- Add `PersistentPostRun` hook for logger cleanup
- Moves defer calls from `run()` to `postRun()` for cleaner separation
- Logger initialization in run, cleanup in postRun

## Enhanced completions

Add ActiveHelp hints for better shell completion UX:

```go
cmd.ValidArgsFunction = func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
    return cobra.AppendActiveHelp(nil,
        "Tip: Use --config <file> for file-based config or --config-stdin for piped JSON config"),
        cobra.ShellCompDirectiveNoFileComp
}
```

## Version template

Custom formatting: `MCPG Gateway {{.Version}}` instead of default
output.

## Tests

- Context cancellation behavior
- Flag validation group registration
- Version template and postRun hook presence

> [!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-build884163099/b275/launcher.test
/tmp/go-build884163099/b275/launcher.test
-test.testlogfile=/tmp/go-build884163099/b275/testlog.txt
-test.paniconexit0 -test.timeout=10m0s -test.v=true go 95WK6prK2
x_amd64/vet` (dns block)
> - `invalid-host-that-does-not-exist-12345.com`
> - Triggering command: `/tmp/go-build884163099/b260/config.test
/tmp/go-build884163099/b260/config.test
-test.testlogfile=/tmp/go-build884163099/b260/testlog.txt
-test.paniconexit0 -test.timeout=10m0s -test.v=true g_.a HEAD 64/bin/as
TOKEN&#34;; }; f sto/tmp/go-build3472542465/b223/cmd.test go cal/bin/git
512block_amd64.o-test.timeout=10m0s 64/s�� 64/src/runtime/cgo xpwaXSmNs
ache/go/1.25.6/x64/pkg/tool/linu--64 --abbrev-ref 2542465/b013/
.12/x64/bin/git 05.o` (dns block)
> - `nonexistent.local`
> - Triggering command: `/tmp/go-build884163099/b275/launcher.test
/tmp/go-build884163099/b275/launcher.test
-test.testlogfile=/tmp/go-build884163099/b275/testlog.txt
-test.paniconexit0 -test.timeout=10m0s -test.v=true go 95WK6prK2
x_amd64/vet` (dns block)
> - `slow.example.com`
> - Triggering command: `/tmp/go-build884163099/b275/launcher.test
/tmp/go-build884163099/b275/launcher.test
-test.testlogfile=/tmp/go-build884163099/b275/testlog.txt
-test.paniconexit0 -test.timeout=10m0s -test.v=true go 95WK6prK2
x_amd64/vet` (dns block)
> - `this-host-does-not-exist-12345.com`
> - Triggering command: `/tmp/go-build884163099/b284/mcp.test
/tmp/go-build884163099/b284/mcp.test
-test.testlogfile=/tmp/go-build884163099/b284/testlog.txt
-test.paniconexit0 -test.timeout=10m0s -test.v=true g_.a HEAD
x_amd64/vet --abbrev-ref /bidi git x_amd64/vet 64/s��
64/src/runtime/cgo1.25.6 V8YDPttZl inux.go esnew.go ocknew.go nix_cgo.go
nix_cgo_res.go` (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>

<!-- START COPILOT ORIGINAL PROMPT -->



<details>

<summary>Original prompt</summary>


----

*This section details on the original issue you should resolve*

<issue_title>[go-fan] Go Module Review:
github.com/spf13/cobra</issue_title>
<issue_description># 🐹 Go Fan Report: Cobra CLI Framework

## Module Overview

**Cobra** (github.com/spf13/cobra) is the industry-standard CLI
framework for Go, powering tools like kubectl, hugo, and GitHub CLI. It
provides a powerful structure for building modern command-line
applications with commands, subcommands, flags, and shell completions.

**Current Version**: v1.10.2 ✅ (Latest: v1.10.2, Dec 3, 2025)  
**Repository**: https://github.com/spf13/cobra  
**Popularity**: 40k+ stars

## Current Usage in gh-aw-mcpg

**Well-Implemented** ✅

The project uses Cobra appropriately across 7 files in `internal/cmd/`:

### Files & Structure
- **root.go** - Root command definition and CLI entry point
- **completion.go** - Shell completion commands (bash, zsh, fish,
powershell)
- **flags*.go** (5 files) - Well-organized flag definitions by domain:
  - `flags_core.go` - Core configuration flags
  - `flags_logging.go` - Logging flags
  - `flags_difc.go` - DIFC feature flags (properly uses `MarkHidden()`)
  - `flags_launch.go` - Launch configuration
  - `flags.go` - Registration helpers

### Key Patterns Observed
✅ Clean command structure without unnecessary nesting  
✅ Flags well-organized by functional area  
✅ Proper use of `MarkHidden()` for experimental features  
✅ Comprehensive shell completion support  
✅ Version command integration

## Research Findings

### Recent Cobra Updates (v1.10.x)

#### v1.10.2 (Dec 2025) - Current Version
- **Dependency Cleanup**: Migrated from deprecated `gopkg.in/yaml.v3` to
`go.yaml.in/yaml/v3`
  - Significantly cleaner dependency chain
  - No action required (transparent upgrade)
- Performance improvements (vars → consts)
- Enhanced documentation for repeated flags

#### v1.10.0 (Sep 2025)
- **Context Support**: Commands can now receive and use context for
cancellation/timeout
- **Customizable ShellCompDirective**: Per-command completion behavior
- Improved map flag completions

#### v1.9.0 (Feb 2025)
- **Linker Deadcode Elimination**: Smaller binaries by removing unused
code
- **CompletionFunc Type**: Cleaner completion code
- **CompletionWithDesc Helper**: Easier completions with descriptions
- **ActiveHelp**: Context-sensitive help during tab completion

### Best Practices from Cobra Maintainers

1. **Error Handling**: Use `RunE` instead of `Run` to return errors
properly
2. **Flag Validation**: Use built-in flag groups instead of manual
validation
3. **Context Usage**: Pass context to commands for cancellation and
timeouts
4. **Completions**: Implement dynamic completions for better UX
5. **Lifecycle Hooks**: Use Pre/Post Run hooks for setup and teardown

## Improvement Opportunities

### 🏃 Quick Wins (High Impact, Low Effort)

#### 1. Add Context Support (v1.10.0 feature)
**Priority**: HIGH | **Effort**: LOW

**Current**: No evidence of context usage for graceful shutdown  
**Opportunity**: Enable proper cancellation and timeout handling

``````go
// In root.go
ctx, cancel := signal.NotifyContext(context.Background(), os.Interrupt, syscall.SIGTERM)
defer cancel()
rootCmd.SetContext(ctx)

// In command RunE
func(cmd *cobra.Command, args []string) error {
    ctx := cmd.Context() // Get context with cancellation support
    // Use ctx for HTTP requests, goroutines, etc.
    return server.Run(ctx)
}
``````

**Benefits**:
- ✅ Proper graceful shutdown on SIGINT/SIGTERM
- ✅ Timeout handling for long-running operations
- ✅ Request tracing and cancellation propagation
- ✅ Better testability with context-based timeouts

#### 2. Use Flag Validation Groups
**Priority**: HIGH | **Effort**: LOW

**Current**: Manual flag validation in code  
**Opportunity**: Declarative validation with better error messages

``````go
// Mutually exclusive flags
cmd.MarkFlagsMutuallyExclusive("config", "stdin-config")

// Flags required together
cmd.MarkFlagsRequiredTogether("log-dir", "enable-file-logging")

// At least one required
cmd.MarkFlagsOneRequired("config", "stdin-config")
``````

**Benefits**:
- ✅ Cleaner code (remove manual validation logic)
- ✅ Consistent, user-friendly error messages
- ✅ Self-documenting flag relationships
- ✅ Less maintenance burden

#### 3. Enhanced Dynamic Completions
**Priority**: MEDIUM | **Effort**: MEDIUM

**Current**: Static shell completions  
**Opportunity**: Dynamic completions for config files, server IDs

``````go
// Config file completion
cmd.RegisterFlagCompletionFunc("config", func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
    configs, _ := filepath.Glob("*.toml")
    suggestions := []string{}
    for _, c := range configs {
        suggestions = append(suggestions, c+"\tTOML configuration file")
    }
    return suggestions, cobra.ShellCompDirectiveDefault
})

// Server ID completion (from loaded config)
cmd.RegisterFlagCompletionFunc("server-id", func(cmd *co...

</details>



<!-- START COPILOT CODING AGENT SUFFIX -->

- Fixes #874
lpcox added a commit that referenced this pull request Feb 11, 2026
…tories (#889)

Nightly documentation reconciliation identified critical discrepancies
between documented and actual default values, plus incomplete internal
directory listings.

## Changes

### Critical: Payload Size Threshold Default
Updated README.md (3 locations) to reflect actual implementation default
of **10240 bytes (10KB)** instead of incorrectly documented 1024 bytes:
- CLI flag description (line 206)
- Flags usage table (line 281)  
- Environment variables table (line 319)

Implementation sources:
- `internal/cmd/flags_logging.go:14` - `defaultPayloadSizeThreshold =
10240`
- `internal/config/config_payload.go:11` - `DefaultPayloadSizeThreshold
= 10240`

### Minor: Complete Internal Directory Listings
Added missing internal packages to project structure documentation:

**CONTRIBUTING.md**: Added 9 missing directories (auth, difc, envutil,
middleware, sys, testutil, version, tty, timeutil) to both tree diagram
and Key Directories section

**AGENTS.md**: Added 7 missing directories (difc, envutil, middleware,
sys, testutil, tty, version) to project structure list

All 16 internal directories now documented in alphabetical order:
`auth`, `cmd`, `config`, `difc`, `envutil`, `guard`, `launcher`,
`logger`, `mcp`, `middleware`, `server`, `sys`, `testutil`, `timeutil`,
`tty`, `version`

> [!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-build2370360416/b279/launcher.test
/tmp/go-build2370360416/b279/launcher.test
-test.testlogfile=/tmp/go-build2370360416/b279/testlog.txt
-test.paniconexit0 -test.timeout=10m0s -test.v=true 64/src/runtime/cgo
git ache/go/1.25.6/x64/pkg/tool/linu-o --global r it 08.o -d go git
x_amd64/vet
e/REDACTED/work/gh/opt/hostedtoolcache/go/1.25.6/x64/pkg/tool/linux_amd64/vet
64/src/runtime/c-unsafeptr=false 64/bin/git x_amd64/vet` (dns block)
> - `invalid-host-that-does-not-exist-12345.com`
> - Triggering command: `/tmp/go-build2370360416/b264/config.test
/tmp/go-build2370360416/b264/config.test
-test.testlogfile=/tmp/go-build2370360416/b264/testlog.txt
-test.paniconexit0 -test.timeout=10m0s -test.v=true 64/src/runtime/cgo
HEAD ache/go/1.25.6/x64/pkg/tool/linu-fmessage-length=0 get --global
rgo/bin/git 06.o -d 1.2.0/auth/auth.go git x_amd64/compile get --global
.12/x64/which x_amd64/compile` (dns block)
> - `nonexistent.local`
> - Triggering command: `/tmp/go-build2370360416/b279/launcher.test
/tmp/go-build2370360416/b279/launcher.test
-test.testlogfile=/tmp/go-build2370360416/b279/testlog.txt
-test.paniconexit0 -test.timeout=10m0s -test.v=true 64/src/runtime/cgo
git ache/go/1.25.6/x64/pkg/tool/linu-o --global r it 08.o -d go git
x_amd64/vet
e/REDACTED/work/gh/opt/hostedtoolcache/go/1.25.6/x64/pkg/tool/linux_amd64/vet
64/src/runtime/c-unsafeptr=false 64/bin/git x_amd64/vet` (dns block)
> - `slow.example.com`
> - Triggering command: `/tmp/go-build2370360416/b279/launcher.test
/tmp/go-build2370360416/b279/launcher.test
-test.testlogfile=/tmp/go-build2370360416/b279/testlog.txt
-test.paniconexit0 -test.timeout=10m0s -test.v=true 64/src/runtime/cgo
git ache/go/1.25.6/x64/pkg/tool/linu-o --global r it 08.o -d go git
x_amd64/vet
e/REDACTED/work/gh/opt/hostedtoolcache/go/1.25.6/x64/pkg/tool/linux_amd64/vet
64/src/runtime/c-unsafeptr=false 64/bin/git x_amd64/vet` (dns block)
> - `this-host-does-not-exist-12345.com`
> - Triggering command: `/tmp/go-build2370360416/b288/mcp.test
/tmp/go-build2370360416/b288/mcp.test
-test.testlogfile=/tmp/go-build2370360416/b288/testlog.txt
-test.paniconexit0 -test.timeout=10m0s -test.v=true g_.a
64/src/internal/bisect/bisect.go--64 86_64/as --global abis p/bin/git
ache/go/1.25.6/x/tmp/go-build2370360416/b059/vet.cfg -d ; then \
$GOPATH/bin/golangci-lint run --timeout=5m || echo &#34;��� Warning:
golangci-lint failed
/opt/hostedtoolcache/go/1.25.6/x64/pkg/tool/linux_amd64/link -wdcAJ1yv
x_amd64/vet rt-size &#39;1280,
7/opt/hostedtoolcache/go/1.25.6/x64/pkg/tool/linux_amd64/vet` (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>

<!-- START COPILOT ORIGINAL PROMPT -->



<details>

<summary>Original prompt</summary>


----

*This section details on the original issue you should resolve*

<issue_title>📚 Documentation Reconciliation Report - February 11,
2026</issue_title>
<issue_description>## Summary

Found **1 critical** and **2 minor** discrepancies between documentation
and implementation during nightly reconciliation check.

- Workflow Run:
[§21890623217](https://github.com/github/gh-aw-mcpg/actions/runs/21890623217)
- Date: February 11, 2026
- Branch: main

## Critical Issues 🔴

Issues that would cause user confusion or broken workflows if followed:

### 1. Payload Size Threshold Default Value Mismatch

**Location:** README.md, lines 206, 281, 319

**Problem:** Documentation states the default payload size threshold is
`1024` bytes (1KB), but the actual implementation uses `10240` bytes
(10KB).

**Actual Behavior:**
- Code: `internal/cmd/flags_logging.go:14` defines
`defaultPayloadSizeThreshold = 10240`
- Code: `internal/config/config_payload.go:11` defines
`DefaultPayloadSizeThreshold = 10240`
- Tests: `internal/cmd/flags_logging_test.go` confirms default is 10240
bytes

**Impact:** Users expecting the documented 1KB threshold will actually
get a 10KB threshold, which could result in:
- More payloads being stored inline than expected (up to 10KB instead of
1KB)
- Less disk I/O than anticipated
- Different memory usage patterns
- Confusion when testing payload storage behavior

**Suggested Fix:** Update README.md to reflect the actual default:

```markdown
# Line 206
- CLI flag: `--payload-size-threshold (bytes)` (default: 10240)

# Line 281
--payload-size-threshold int   Size threshold (in bytes) for storing payloads to disk. Payloads larger than this are stored, smaller ones returned inline (default 10240)

# Line 319
| `MCP_GATEWAY_PAYLOAD_SIZE_THRESHOLD` | Size threshold in bytes for payload storage (sets default for `--payload-size-threshold` flag) | `10240` |
```

**Code Reference:**
- `internal/cmd/flags_logging.go:14`
- `internal/config/config_payload.go:11`
- `internal/cmd/flags_logging_test.go:46`

## Minor Issues 🔵

Small inconsistencies or missing details:

### 1. Internal Directory Structure Incomplete in CONTRIBUTING.md

**Location:** CONTRIBUTING.md, lines 206-233 (Project Structure section)

**Problem:** Documentation lists only 7 internal directories, but 16
actually exist.

**Missing Directories:**
- `internal/difc/` - Data Information Flow Control
- `internal/envutil/` - Environment variable utilities
- `internal/middleware/` - HTTP middleware (jq schema processing)
- `internal/sys/` - System utilities
- `internal/testutil/` - Test utilities and helpers
- `internal/tty/` - Terminal detection utilities
- `internal/version/` - Version management

**Impact:** Developers may be unaware of these internal packages when
working on the codebase, potentially duplicating functionality or
missing useful utilities.

**Suggested Fix:** Update the Project Structure section to include all
internal directories with brief descriptions.

**Code Reference:** Directory listing shows all 16 directories exist and
contain working code.

### 2. Internal Directory Structure Incomplete in AGENTS.md

**Location:** AGENTS.md, lines 12-20 (Project Structure section)

**Problem:** Similar to CONTRIBUTING.md, lists only 9 internal
directories instead of 16.

**Missing Directories:** Same as above (difc, envutil, middleware, sys,
testutil, tty, version)

**Impact:** AI agents working with the codebase may not be aware of all
available internal packages.

**Suggested Fix:** Update the Project Structure section to include all
internal directories.

**Code Reference:** Same directory listing as above.

## Documentation Completeness

### Accurate Sections ✅

The following sections were verified and found to be accurate:

- **Go Version Requirement** - Correctly documented as 1.25.0 (matches
`go.mod`)
- **Make Targets** - All 11 documented targets exist and work correctly:
  - `make build`, `test`, `test-unit`, `test-integration`, `test-all`
  - `make lint`, `coverage`, `install`, `agent-finished`
  - `make format`, `clean`
- **Configuration Fields** - All documented fields match code struct
definitions in `internal/config/`
- **Environment Variables** - Correctly documented and extensively used
(140+ references in code)
- **External Links**:
  - MCP Gateway spec link is valid (returns HTTP 200)
  - GitHub token URL is valid (redirects properly)
- **Feature Documentation**:
  - HTTP transport correctly marked as "fully supported"
- Container field requirement for stdio servers matches validation code
- Command field restriction for JSON stdin format accurately documented
  - Sequential launch flag exists and works as documented
- **CLI Flags** - All documented flags exist and match actual
implementation
- **Docker Configuration Examples** - Format and field names match
actual usage
- **Configuration Validation** - Documented behavior matches
`internal/config/validation*.go`

## Tested Commands

All commands from CONTRIBUTING....

</details>



<!-- START COPILOT CODING AGENT SUFFIX -->

- Fixes #886
lpcox added a commit that referenced this pull request Feb 14, 2026
The Serena MCP container was missing the Python language server,
preventing Python code analysis despite having the Python runtime
installed. Only Go language support was functional.

## Changes

- **Dockerfile**: Added `python-lsp-server[all]` installation between
Serena and TypeScript language server setup

The container already had:
- Go support via `gopls`
- TypeScript/JavaScript support via `typescript-language-server`
- Startup script correctly configuring all three languages in
`.serena/project.yml`

Only the Python language server package was missing. The `[all]` extra
includes optional dependencies for full LSP functionality.

> [!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-build1194592432/b279/launcher.test
/tmp/go-build1194592432/b279/launcher.test
-test.testlogfile=/tmp/go-build1194592432/b279/testlog.txt
-test.paniconexit0 -test.timeout=10m0s -test.v=true
ternal/fips140/bigmod/nat_amd64.--gdwarf-5 HEAD x_amd64/compile
/tmp/apt-dpkg-in/opt/hostedtoolcache/go/1.25.7/x64/pkg/tool/linux_amd64/vet
tar amd64/compile x_amd64/compile add go -v x_amd64/vet -f 4971347/b009/
es x_amd64/vet` (dns block)
> - `invalid-host-that-does-not-exist-12345.com`
> - Triggering command: `/tmp/go-build1194592432/b264/config.test
/tmp/go-build1194592432/b264/config.test
-test.testlogfile=/tmp/go-build1194592432/b264/testlog.txt
-test.paniconexit0 -test.timeout=10m0s -test.v=true 64/src/runtime/cgo
zclWGwGwi ache/go/1.25.7/x64/pkg/tool/linu-o .util;
print(imp/opt/hostedtoolcache/go/1.25.7/x64/pkg/tool/linux_amd64/vet
r/runc-log.json /usr/sbin/tar 06.o ortc�� 64/src/runtime/cgo go
x_amd64/compile -f - /usr/sbin/dpkg-d-unreachable=false x_amd64/compile`
(dns block)
> - `nonexistent.local`
> - Triggering command: `/tmp/go-build1194592432/b279/launcher.test
/tmp/go-build1194592432/b279/launcher.test
-test.testlogfile=/tmp/go-build1194592432/b279/testlog.txt
-test.paniconexit0 -test.timeout=10m0s -test.v=true
ternal/fips140/bigmod/nat_amd64.--gdwarf-5 HEAD x_amd64/compile
/tmp/apt-dpkg-in/opt/hostedtoolcache/go/1.25.7/x64/pkg/tool/linux_amd64/vet
tar amd64/compile x_amd64/compile add go -v x_amd64/vet -f 4971347/b009/
es x_amd64/vet` (dns block)
> - `slow.example.com`
> - Triggering command: `/tmp/go-build1194592432/b279/launcher.test
/tmp/go-build1194592432/b279/launcher.test
-test.testlogfile=/tmp/go-build1194592432/b279/testlog.txt
-test.paniconexit0 -test.timeout=10m0s -test.v=true
ternal/fips140/bigmod/nat_amd64.--gdwarf-5 HEAD x_amd64/compile
/tmp/apt-dpkg-in/opt/hostedtoolcache/go/1.25.7/x64/pkg/tool/linux_amd64/vet
tar amd64/compile x_amd64/compile add go -v x_amd64/vet -f 4971347/b009/
es x_amd64/vet` (dns block)
> - `this-host-does-not-exist-12345.com`
> - Triggering command: `/tmp/go-build1194592432/b288/mcp.test
/tmp/go-build1194592432/b288/mcp.test
-test.testlogfile=/tmp/go-build1194592432/b288/testlog.txt
-test.paniconexit0 -test.timeout=10m0s -test.v=true 64/src/runtime/cgo
64/src/maps/iter.go ache/go/1.25.7/x64/pkg/tool/linu-o r/runc-log.json
abis /systemd-sysctl 08.o main�� ; then \
$GOPATH/bin/golangci-lint run --timeout=5m || echo &#34;��� Warning:
golangci-lint failed
/opt/hostedtoolcache/go/1.25.7/x64/pkg/tool/linux_amd64/vet --auto
x_amd64/vet --detach 4971347/b004/ d-dispatcher/off-unreachable=false
x_amd64/vet` (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>

<!-- START COPILOT ORIGINAL PROMPT -->



<details>

<summary>Original prompt</summary>

> 
> ----
> 
> *This section details on the original issue you should resolve*
> 
> <issue_title>[language-support] TypeScript/JavaScript and Python
language support not available in Serena MCP container</issue_title>
> <issue_description>## Summary
> 
> Testing of language support for Go, TypeScript/JavaScript, and Python
revealed that only **Go language support is working correctly**.
TypeScript/JavaScript and Python language servers are not available or
configured in the Serena MCP container.
> 
> ## Test Results
> 
> ### ✅ Go Language Support - PASSED
> 
> All Go language operations work correctly:
> - **Symbol overview**: Successfully retrieved functions and constants
from `main.go`
> - **Symbol finding**: Located `main` and `buildVersionString`
functions with detailed info
> - **Pattern search**: Found function declarations using regex patterns
> - **Reference finding**: Discovered all references to
`buildVersionString` across multiple files
> - **Code body retrieval**: Successfully retrieved complete function
implementations
> 
> ### ❌ TypeScript/JavaScript Language Support - FAILED
> 
> **Issue**: Cannot activate TypeScript/JavaScript projects
> - The Serena configuration (`.serena/project.yml`) only includes `go`
in the `languages:` list
> - Attempts to activate a JavaScript project failed with
`ProjectNotFoundError`
> - `tsserver` binary exists at `/usr/local/bin/tsserver` but no
TypeScript language server wrapper found
> - Configuration file is owned by root and cannot be modified due to
container security restrictions
> 
> ### ❌ Python Language Support - FAILED
> 
> **Issue**: Cannot activate Python projects
> - The Serena configuration (`.serena/project.yml`) only includes `go`
in the `languages:` list
> - Attempts to activate a Python project failed with
`ProjectNotFoundError`
> - No Python language servers found in the container (checked for
`pyls`, `pylsp`, `jedi-language-server`)
> - Configuration file permissions prevent adding Python to supported
languages
> 
> ## Root Cause
> 
> The Serena MCP container is configured with only Go language support.
The `.serena/project.yml` file contains:
> 
> ``````yaml
> languages:
> - go
> ``````
> 
> According to the project configuration documentation, supported
languages include:
> - `typescript` (also handles JavaScript files)
> - `python` (or `python_jedi` as alternative)
> 
> However, these are not enabled in the current configuration, and the
configuration file cannot be modified at runtime due to permission
restrictions.
> 
> ## Impact
> 
> - **Go projects**: ✅ Fully functional
> - **TypeScript/JavaScript projects**: ❌ Cannot be analyzed
> - **Python projects**: ❌ Cannot be analyzed
> - **Multi-language repositories**: Limited to Go code only
> 
> ## Reproduction Steps
> 
> 1. Start Serena MCP server with current configuration
> 2. Activate main Go project: `serena-activate_project` → **Success**
> 3. Try to activate TypeScript/JavaScript project:
`serena-activate_project` with JS path → **Fails with
ProjectNotFoundError**
> 4. Try to activate Python project: `serena-activate_project` with
Python path → **Fails with ProjectNotFoundError**
> 5. Check configuration: `cat .serena/project.yml` shows only `go` in
languages list
> 
> ## Recommendations
> 
> 1. **Update Serena container configuration** to include TypeScript and
Python language servers
> 2. **Modify `.serena/project.yml`** to include:
>    ``````yaml
>    languages:
>    - go
>    - typescript
>    - python
>    ``````
> 3. **Install required language servers** in the container:
>    - TypeScript: `typescript-language-server` or equivalent
>    - Python: `python-lsp-server` (pylsp) or `jedi-language-server`
> 4. **Test sample projects** at `test/serena-mcp-tests/samples/` once
language servers are available
> 
> ## Environment Details
> 
> - Repository: github/gh-aw-mcpg
> - Sparse checkout: 33% of files (Go code is present, test samples may
not be available)
> - Serena version: 0.1.4
> - Container: ghcr.io/github/serena-mcp-server:latest
> - Test date: 2026-02-12
> 
> 
> 
> 
> > AI generated by [Language Support
Tester](https://github.com/github/gh-aw-mcpg/actions/runs/21943451066)
> > - [x] expires <!-- gh-aw-expires: 2026-02-19T10:53:23.898Z --> on
Feb 19, 2026, 10:53 AM UTC
> 
> <!-- gh-aw-agentic-workflow: Language Support Tester, engine: copilot,
run: https://github.com/github/gh-aw-mcpg/actions/runs/21943451066 -->
> 
> <!-- gh-aw-workflow-id: language-support-tester
--></issue_description>
> 
> ## Comments on the Issue (you are @claude[agent] in this section)
> 
> <comments>
> </comments>
> 


</details>



<!-- START COPILOT CODING AGENT SUFFIX -->

- Fixes #913
lpcox added a commit that referenced this pull request Feb 16, 2026
…n() helper (#978)

Six MCP method wrappers (`listTools`, `callTool`, `listResources`,
`readResource`, `listPrompts`, `getPrompt`) contained identical 3-line
session nil checks, creating maintenance burden and risk of inconsistent
error messages.

## Changes

- **Extract validation helper**: Created `requireSession()` method to
centralize session nil checking
- **Update all callers**: Replaced inline checks across 6 methods with
helper call
- **Add test coverage**: Unit test validates helper behavior for nil
sessions

## Before/After

```go
// Before: Duplicated in 6 methods
func (c *Connection) listTools() (*Response, error) {
	if c.session == nil {
		return nil, fmt.Errorf("SDK session not available for plain JSON-RPC transport")
	}
	// ...
}

// After: Single source of truth
func (c *Connection) requireSession() error {
	if c.session == nil {
		return fmt.Errorf("SDK session not available for plain JSON-RPC transport")
	}
	return nil
}

func (c *Connection) listTools() (*Response, error) {
	if err := c.requireSession(); err != nil {
		return nil, err
	}
	// ...
}
```

Reduces code by ~12 lines and ensures consistent error messaging across
all SDK method wrappers.

> [!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-build1651638344/b275/launcher.test
/tmp/go-build1651638344/b275/launcher.test
-test.testlogfile=/tmp/go-build1651638344/b275/testlog.txt
-test.paniconexit0 -test.timeout=10m0s -test.v=true -c=4 -nolocalimports
-importcfg /tmp/go-build1651638344/b235/importcfg -pack
/home/REDACTED/go/pkg/mod/github.com/spf13/pflag@v1.0.9/bool.go
/home/REDACTED/go/pkg/mod/github.com/spf13/pflag@v1.0.9/bool_func.go
rev-�� go 8AG1CVhJp /home/REDACTED/wor-o wright&#34;
--viewpo/opt/hostedtoolcache/go/1.25.7/x64/pkg/tool/linux_amd64/compile
5519/field .12/x64/git git` (dns block)
> - Triggering command: `/tmp/go-build4267259821/b275/launcher.test
/tmp/go-build4267259821/b275/launcher.test
-test.testlogfile=/tmp/go-build4267259821/b275/testlog.txt
-test.paniconexit0 -test.timeout=10m0s -test.v=true 1638344/b190/_pkg_.a
ache/go/1.25.7/x64/src/crypto/in-nolocalimports 1638344/b190=&gt; -p
l/ascii -lang=go1.25 /opt/hostedtoolcache/go/1.25.7/x64/pkg/tool/linu-I
go_.�� 64/src/net Wvey/P0HIK0znqdopQQs2Wvey x_amd64/compile -I ions =0
x_amd64/compile` (dns block)
> - Triggering command: `/tmp/go-build4134285178/b275/launcher.test
/tmp/go-build4134285178/b275/launcher.test
-test.testlogfile=/tmp/go-build4134285178/b275/testlog.txt
-test.paniconexit0 -test.timeout=10m0s -test.v=true se
1638344/b069/vet.cfg .cfg --gdwarf-5 --64 -o
ache/go/1.25.7/x64/pkg/tool/linux_amd64/vet` (dns block)
> - `invalid-host-that-does-not-exist-12345.com`
> - Triggering command: `/tmp/go-build1651638344/b260/config.test
/tmp/go-build1651638344/b260/config.test
-test.testlogfile=/tmp/go-build1651638344/b260/testlog.txt
-test.paniconexit0 -test.timeout=10m0s -test.v=true go
ternal/fips140/a--64 64/pkg/tool/linu-o nner/.nvm credential.helpe-I
/home/REDACTED/wor/opt/hostedtoolcache/go/1.25.7/x64/src/net
64/pkg/tool/linu-I rev-�� go HEAD x_amd64/vet list` (dns block)
> - `nonexistent.local`
> - Triggering command: `/tmp/go-build1651638344/b275/launcher.test
/tmp/go-build1651638344/b275/launcher.test
-test.testlogfile=/tmp/go-build1651638344/b275/testlog.txt
-test.paniconexit0 -test.timeout=10m0s -test.v=true -c=4 -nolocalimports
-importcfg /tmp/go-build1651638344/b235/importcfg -pack
/home/REDACTED/go/pkg/mod/github.com/spf13/pflag@v1.0.9/bool.go
/home/REDACTED/go/pkg/mod/github.com/spf13/pflag@v1.0.9/bool_func.go
rev-�� go 8AG1CVhJp /home/REDACTED/wor-o wright&#34;
--viewpo/opt/hostedtoolcache/go/1.25.7/x64/pkg/tool/linux_amd64/compile
5519/field .12/x64/git git` (dns block)
> - Triggering command: `/tmp/go-build4267259821/b275/launcher.test
/tmp/go-build4267259821/b275/launcher.test
-test.testlogfile=/tmp/go-build4267259821/b275/testlog.txt
-test.paniconexit0 -test.timeout=10m0s -test.v=true 1638344/b190/_pkg_.a
ache/go/1.25.7/x64/src/crypto/in-nolocalimports 1638344/b190=&gt; -p
l/ascii -lang=go1.25 /opt/hostedtoolcache/go/1.25.7/x64/pkg/tool/linu-I
go_.�� 64/src/net Wvey/P0HIK0znqdopQQs2Wvey x_amd64/compile -I ions =0
x_amd64/compile` (dns block)
> - Triggering command: `/tmp/go-build4134285178/b275/launcher.test
/tmp/go-build4134285178/b275/launcher.test
-test.testlogfile=/tmp/go-build4134285178/b275/testlog.txt
-test.paniconexit0 -test.timeout=10m0s -test.v=true se
1638344/b069/vet.cfg .cfg --gdwarf-5 --64 -o
ache/go/1.25.7/x64/pkg/tool/linux_amd64/vet` (dns block)
> - `slow.example.com`
> - Triggering command: `/tmp/go-build1651638344/b275/launcher.test
/tmp/go-build1651638344/b275/launcher.test
-test.testlogfile=/tmp/go-build1651638344/b275/testlog.txt
-test.paniconexit0 -test.timeout=10m0s -test.v=true -c=4 -nolocalimports
-importcfg /tmp/go-build1651638344/b235/importcfg -pack
/home/REDACTED/go/pkg/mod/github.com/spf13/pflag@v1.0.9/bool.go
/home/REDACTED/go/pkg/mod/github.com/spf13/pflag@v1.0.9/bool_func.go
rev-�� go 8AG1CVhJp /home/REDACTED/wor-o wright&#34;
--viewpo/opt/hostedtoolcache/go/1.25.7/x64/pkg/tool/linux_amd64/compile
5519/field .12/x64/git git` (dns block)
> - Triggering command: `/tmp/go-build4267259821/b275/launcher.test
/tmp/go-build4267259821/b275/launcher.test
-test.testlogfile=/tmp/go-build4267259821/b275/testlog.txt
-test.paniconexit0 -test.timeout=10m0s -test.v=true 1638344/b190/_pkg_.a
ache/go/1.25.7/x64/src/crypto/in-nolocalimports 1638344/b190=&gt; -p
l/ascii -lang=go1.25 /opt/hostedtoolcache/go/1.25.7/x64/pkg/tool/linu-I
go_.�� 64/src/net Wvey/P0HIK0znqdopQQs2Wvey x_amd64/compile -I ions =0
x_amd64/compile` (dns block)
> - Triggering command: `/tmp/go-build4134285178/b275/launcher.test
/tmp/go-build4134285178/b275/launcher.test
-test.testlogfile=/tmp/go-build4134285178/b275/testlog.txt
-test.paniconexit0 -test.timeout=10m0s -test.v=true se
1638344/b069/vet.cfg .cfg --gdwarf-5 --64 -o
ache/go/1.25.7/x64/pkg/tool/linux_amd64/vet` (dns block)
> - `this-host-does-not-exist-12345.com`
> - Triggering command: `/tmp/go-build1651638344/b284/mcp.test
/tmp/go-build1651638344/b284/mcp.test
-test.testlogfile=/tmp/go-build1651638344/b284/testlog.txt
-test.paniconexit0 -test.timeout=10m0s -test.v=true in.so /lto-wrapper
/usr/bin/base64
WebFetch,WebSear/opt/hostedtoolcache/go/1.25.7/x64/pkg/tool/linux_amd64/vet
a20 rgo/bin/git base64 ortc�� 64/src/runtime/c-errorsas 3-Nd5vpBC
ache/go/1.25.7/x-nilfunc --oneline -n /usr/bin/base64 04.o` (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>

<!-- START COPILOT ORIGINAL PROMPT -->



<details>

<summary>Original prompt</summary>


----

*This section details on the original issue you should resolve*

<issue_title>[duplicate-code] Duplicate Code Pattern: MCP Session Nil
Validation Checks</issue_title>
<issue_description># 🔍 Duplicate Code Pattern: MCP Session Validation
Checks

*Part of duplicate code analysis: #970*

## Summary

The `internal/mcp/connection.go` file contains **6 identical session nil
checks** across different MCP method wrappers. Each method performs the
exact same validation before executing its SDK call.

## Duplication Details

### Pattern: Repeated Session Nil Validation
- **Severity**: Medium
- **Occurrences**: 6 instances
- **Locations**:
  - `internal/mcp/connection.go`:
    - Line 821-823: `listTools()`
    - Line 833-835: `callTool()`
    - Line 867-869: `listResources()`
    - Line 879-881: `readResource()`
    - Line 901-903: `listPrompts()`
    - Line 913-915: `getPrompt()`

### Code Sample:
``````go
func (c *Connection) listTools() (*Response, error) {
	if c.session == nil {
		return nil, fmt.Errorf("SDK session not available for plain JSON-RPC transport")
	}
	result, err := c.session.ListTools(c.ctx, &sdk.ListToolsParams{})
	if err != nil {
		return nil, err
	}
	return marshalToResponse(result)
}

func (c *Connection) listResources() (*Response, error) {
	if c.session == nil {
		return nil, fmt.Errorf("SDK session not available for plain JSON-RPC transport")
	}
	result, err := c.session.ListResources(c.ctx, &sdk.ListResourcesParams{})
	if err != nil {
		return nil, err
	}
	return marshalToResponse(result)
}
// ... 4 more methods with identical session nil check
``````

## Impact Analysis

- **Maintainability**: **Medium Impact** - Error message changes require
updating 6 locations
- **Bug Risk**: **Medium** - Risk of inconsistent error messages if
updates are missed
- **Code Bloat**: ~18 lines of duplicate validation code (6 checks × 3
lines each)
- **Consistency**: Error messages could diverge over time if not
carefully maintained

## Refactoring Recommendations

### 1. **Extract Session Validation Helper** (Recommended)
Create a helper method to centralize the session validation:

``````go
// In connection.go
func (c *Connection) requireSession() error {
	if c.session == nil {
		return fmt.Errorf("SDK session not available for plain JSON-RPC transport")
	}
	return nil
}

// Updated methods use the helper:
func (c *Connection) listTools() (*Response, error) {
	if err := c.requireSession(); err != nil {
		return nil, err
	}
	result, err := c.session.ListTools(c.ctx, &sdk.ListToolsParams{})
	if err != nil {
		return nil, err
	}
	return marshalToResponse(result)
}

func (c *Connection) listResources() (*Response, error) {
	if err := c.requireSession(); err != nil {
		return nil, err
	}
	result, err := c.session.ListResources(c.ctx, &sdk.ListResourcesParams{})
	if err != nil {
		return nil, err
	}
	return marshalToResponse(result)
}
// ... other methods follow same pattern
``````

- **Location**: `internal/mcp/connection.go` (add `requireSession`
helper method)
- **Estimated Effort**: 1 hour
- **Benefits**:
  - Single point of truth for session validation
  - Consistent error messages across all methods
  - Easier to enhance validation logic (e.g., add logging, metrics)
  - Reduces code by ~12 lines

### 2. **Alternative: Method Decorator Pattern** (More Complex)
For a more sophisticated approach, consider a decorator that wraps SDK
calls:

``````go
type sdkCall func() (interface{}, error)

func (c *Connection) withSession(call sdkCall) (*Response, error) {
	if c.session == nil {
		return nil, fmt.Errorf("SDK session not available for plain JSON-RPC transport")
	}
	result, err := call()
	if err != nil {
		return nil, err
	}
	return marshalToResponse(result)
}

// Usage:
func (c *Connection) listTools() (*Response, error) {
	return c.withSession(func() (interface{}, error) {
		return c.session.ListTools(c.ctx, &sdk.ListToolsParams{})
	})
}
``````

- **Estimated Effort**: 2-3 hours
- **Benefits**: More DRY, but adds complexity with closures

## Implementation Checklist

- [ ] Review duplication findings
- [ ] Create `requireSession()` helper method in Connection struct
- [ ] Update `listTools()` to use helper
- [ ] Update `callTool()` to use helper
- [ ] Update `listResources()` to use helper
- [ ] Update `readResource()` to use helper
- [ ] Update `listPrompts()` to use helper
- [ ] Update `getPrompt()` to use helper
- [ ] Run `make test-all` to verify no functionality broken
- [ ] Run `make lint` to ensure code quality

## Parent Issue

See parent analysis report: #970
Related to #970




> AI generated by [Duplicate Code
Detector](https://github.com/github/gh-aw-mcpg/actions/runs/22058864442)
> - [x] expires <!-- gh-aw-expires: 2026-02-23T10:32:38.091Z --> on Feb
23, 2026, 10:32 AM UTC

<!-- gh-aw-agentic-workflow: Duplicate Code Detector, engine: copilot,
run: https://github.com/github/gh-aw-mcpg/actions/runs/22058864442 -->

<!-- gh-aw-workflow-id: ...

</details>



<!-- START COPILOT CODING AGENT SUFFIX -->

- Fixes #972
lpcox added a commit that referenced this pull request Feb 16, 2026
The Go Fan report identified BurntSushi/toml as a critical dependency
and recommended verifying TOML 1.1 support, error reporting
improvements, and validation patterns. Analysis reveals the
implementation already follows all best practices—no functional changes
needed.

## Changes

**Enhanced inline documentation** (`internal/config/config_core.go`):
- Package-level overview of TOML 1.1 features (multi-line arrays,
duplicate key detection)
- Documented streaming decoder pattern and memory efficiency rationale
- Explained warning-based validation design decision (backward
compatibility vs strict errors)
- Clarified column-level error reporting (v1.5.0+ Position.Line +
Position.Col)

**Comprehensive review document** (`docs/TOML_MODULE_REVIEW.md`):
- Implementation analysis: TOML 1.1 specification support verified
- Multi-layer validation architecture documented (parse → schema →
field-level → variable expansion)
- Test coverage audit: 31+ tests including duplicate key detection,
streaming large files, unknown field warnings
- Best practices: MetaData.Undecoded() for typo detection, dual
type-check for ParseError compatibility

## Implementation Status

All Go Fan recommendations already implemented:
- ✅ TOML 1.1 compatibility (v1.6.0 default)
- ✅ Column-level error reporting with Position.Line and Position.Col
- ✅ Unknown field detection via MetaData.Undecoded() with warnings
- ✅ Streaming decoder for memory efficiency
- ✅ Comprehensive test coverage

## Example

Current error reporting with line and column numbers:

```go
if perr, ok := err.(*toml.ParseError); ok {
    return nil, fmt.Errorf("failed to parse TOML at line %d, column %d: %s",
        perr.Position.Line, perr.Position.Col, perr.Message)
}
```

TOML 1.1 multi-line arrays in use:

```toml
[servers.github]
args = [
    "run", "--rm", "-i",
    "--name", "awmg-github-mcp"
]
```

> [!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-build247104886/b279/launcher.test
/tmp/go-build247104886/b279/launcher.test
-test.testlogfile=/tmp/go-build247104886/b279/testlog.txt
-test.paniconexit0 -test.timeout=10m0s -test.v=true 64/src/runtime/cgo
HEAD 86_64/as toml k/gh-aw-mcpg/gh--unsafeptr=false
ache/Python/3.12-unreachable=false .o rev-�� go ac/hmac.go
x_amd64/compile toml 64975/b009/ /opt/hostedtoolc-unreachable=false
x_amd64/compile` (dns block)
> - `invalid-host-that-does-not-exist-12345.com`
> - Triggering command: `/tmp/go-build247104886/b264/config.test
/tmp/go-build247104886/b264/config.test
-test.testlogfile=/tmp/go-build247104886/b264/testlog.txt
-test.paniconexit0 -test.timeout=10m0s -test.v=true 64/src/runtime/cgo
64/src/unicode/casetables.go
ache/go/1.25.7/x64/pkg/tool/linux86_64-linux-gnu toml is rgo/bin/grep .o
rev-�� 64/src/runtime/cgo go x_amd64/compile toml
k/gh-aw-mcpg/gh--unsafeptr=false p/bin/grep x_amd64/compile` (dns block)
> - `nonexistent.local`
> - Triggering command: `/tmp/go-build247104886/b279/launcher.test
/tmp/go-build247104886/b279/launcher.test
-test.testlogfile=/tmp/go-build247104886/b279/testlog.txt
-test.paniconexit0 -test.timeout=10m0s -test.v=true 64/src/runtime/cgo
HEAD 86_64/as toml k/gh-aw-mcpg/gh--unsafeptr=false
ache/Python/3.12-unreachable=false .o rev-�� go ac/hmac.go
x_amd64/compile toml 64975/b009/ /opt/hostedtoolc-unreachable=false
x_amd64/compile` (dns block)
> - `slow.example.com`
> - Triggering command: `/tmp/go-build247104886/b279/launcher.test
/tmp/go-build247104886/b279/launcher.test
-test.testlogfile=/tmp/go-build247104886/b279/testlog.txt
-test.paniconexit0 -test.timeout=10m0s -test.v=true 64/src/runtime/cgo
HEAD 86_64/as toml k/gh-aw-mcpg/gh--unsafeptr=false
ache/Python/3.12-unreachable=false .o rev-�� go ac/hmac.go
x_amd64/compile toml 64975/b009/ /opt/hostedtoolc-unreachable=false
x_amd64/compile` (dns block)
> - `this-host-does-not-exist-12345.com`
> - Triggering command: `/tmp/go-build247104886/b288/mcp.test
/tmp/go-build247104886/b288/mcp.test
-test.testlogfile=/tmp/go-build247104886/b288/testlog.txt
-test.paniconexit0 -test.timeout=10m0s -test.v=true 64/src/runtime/cgo
ternal/fips140/nistec/fiat/cast.--64 64/pkg/tool/linux_amd64/asm toml
k/gh-aw-mcpg/gh--unsafeptr=false k/_temp/ghcca-no-unreachable=false
64/pkg/tool/linu/tmp/go-build247104886/b068/vet.cfg -w ; then \
$GOPATH/bin/golangci-lint run --timeout=5m || echo &#34;��� Warning:
golangci-lint failed
/opt/hostedtoolcache/go/1.25.7/x64/pkg/tool/linux_amd64/vet security
x_amd64/vet OUTPUT 64975/b004/ 168.63.129.16 x_amd64/vet` (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>

<!-- START COPILOT ORIGINAL PROMPT -->



<details>

<summary>Original prompt</summary>


----

*This section details on the original issue you should resolve*

<issue_title>[go-fan] Go Module Review: BurntSushi/toml - TOML
Configuration Parser</issue_title>
<issue_description># 🐹 Go Fan Report: github.com/BurntSushi/toml

## Module Overview

**BurntSushi/toml** is the de-facto standard TOML parser for Go,
providing robust parsing and encoding of TOML configuration files with
full reflection support. It's the most popular and well-maintained TOML
library in the Go ecosystem, used by thousands of projects including the
MCP Gateway for parsing `config.toml` files.

- **Version**: v1.6.0 (latest, December 18, 2025)
- **Repository**: https://github.com/BurntSushi/toml
- **Stars**: 4,898 ⭐
- **License**: MIT
- **Maintainer**: Martin Tournoij (`@arp242`)
- **Last Update**: February 16, 2026 (updated just hours ago! 🔥)

## Current Usage in gh-aw-mcpg

**Note**: Analysis based on configuration files and documented patterns,
as the source code is not available in the sparse checkout.

### Configuration Files
- `config.toml` - Main gateway configuration
- `config.example.toml` - Comprehensive example (154 lines)
- `config.example-payload-threshold.toml` - Payload configuration

### Key Configuration Elements

The gateway uses TOML for:

1. **Gateway Settings** - Port, API key, timeouts, payload directory
2. **MCP Server Definitions** - Docker container configurations with:
   - Command and arguments arrays
   - Environment variable mappings
   - Tool filtering lists
3. **Modern TOML 1.1 Syntax** - Multi-line inline arrays, nested tables

### Example Configuration Pattern
``````toml
[gateway]
port = 3000
startup_timeout = 60
tool_timeout = 120

[servers.github]
command = "docker"
args = [
    "run", "--rm", "-i",
    "--name", "awmg-github-mcp",
    "-e", "GITHUB_PERSONAL_ACCESS_TOKEN"
]

[servers.github.env]
GITHUB_PERSONAL_ACCESS_TOKEN = ""
``````

## Research Findings

### 🔥 Recent Updates (Just Released Hours Ago!)

The repository was updated **today** (February 16, 2026) at 04:57 UTC,
making it an excellent time to review!

### Latest Version: v1.6.0 (December 18, 2025)

🎉 **Major Update**: **TOML 1.1 is now the default!**

**Key Changes**:
1. ✨ **TOML 1.1 Default** - Newlines in inline tables now allowed (huge
usability improvement!)
2. 🐛 **Fixed Duplicate Array Detection** - Now correctly detects
duplicate array keys as errors
3. 🔧 **Float Encoding** - Large floats round-trip correctly with
exponent syntax (e.g., `5e+22`)

**This is perfect timing!** The gateway's configs already use TOML 1.1
syntax with multi-line arrays, which is exactly what v1.6.0 enables by
default.

### Previous Versions

**v1.5.0 (March 18, 2025)**:
- Added `Position.Col` for **column-level error reporting** (line AND
column!)
- Allow custom string types as map keys
- Enhanced `ParseError.Message` to always be set
- Multiple encoding bug fixes

**v1.4.0 (May 23, 2024)**:
- **Added `toml.Marshal()`** - Convenient marshaling function
- Requires Go 1.18+
- Improved error position wrapping for custom types

### Best Practices from Module Documentation

1. **Detailed Error Handling**:
   ``````go
   var config Config
   meta, err := toml.DecodeFile("config.toml", &config)
   if err != nil {
       // ParseError includes line/column info
       log.Fatalf("Config error: %v", err)
   }
   ``````

2. **Strict Decoding** (Catch Typos):
   ``````go
   dec := toml.NewDecoder(file)
   dec.DisallowUnknownFields() // Errors on "prot" instead of "port"
   if err := dec.Decode(&config); err != nil {
       return fmt.Errorf("invalid config: %w", err)
   }
   ``````

3. **Metadata for Validation**:
   ``````go
   meta, _ := toml.Decode(data, &config)
   if !meta.IsDefined("required_field") {
       return errors.New("missing required field")
   }
   // Check for unrecognized keys
   if undecoded := meta.Undecoded(); len(undecoded) > 0 {
       log.Warnf("Unknown config keys: %v", undecoded)
   }
   ``````

4. **Marshal for Output**:
   ``````go
   data, err := toml.Marshal(config)
   if err != nil {
       return err
   }
   ``````

## Improvement Opportunities

**Important Note**: These recommendations are based on the module's
capabilities and common patterns. Implementation requires accessing the
full repository source code (currently unavailable due to sparse
checkout).

### 🏃 Quick Wins

#### 1. Verify TOML 1.1 Compatibility ✅
**Impact**: Low (already working) | **Effort**: Very Low

The gateway configs use TOML 1.1 syntax (multi-line arrays), which is
perfect since v1.6.0 makes it the default.

**Action**: 
- Verify no `BURNTSUSHI_TOML_110` environment variable workarounds in
code
- Confirm clean usage of TOML 1.1 features

**Benefit**: Ensure idiomatic usage of the latest TOML spec

#### 2. Leverage Enhanced Error Reporting (v1.5.0 Feature)
**Impact**: Medium | **Effort**: Low

v1.5.0 added `Position.Col` for column-level errors.

**Action**:
- Update error messages to show both line AND column: `"error at line
%d, column %d"`
- Th...

</details>



<!-- START COPILOT CODING AGENT SUFFIX -->

- Fixes #969
lpcox added a commit that referenced this pull request Feb 19, 2026
The jq middleware payload preview size (500 characters) was hardcoded in
multiple locations, making it difficult to adjust consistently.

## Changes

- **Added `PayloadPreviewSize` constant** in
`internal/middleware/jqschema.go`
  - Replaces hardcoded `500` in preview truncation logic
  - Replaces hardcoded `500` in logging statements
  - Updates function documentation

- **Updated references** in documentation (`README.md`, `AGENTS.md`) and
tests to reference the constant

## Example

Before:
```go
truncated := len(payloadStr) > 500
if truncated {
    preview = payloadStr[:500] + "..."
}
```

After:
```go
truncated := len(payloadStr) > PayloadPreviewSize
if truncated {
    preview = payloadStr[:PayloadPreviewSize] + "..."
}
```

The constant provides a single point of configuration for payload
preview behavior across the middleware package.

> [!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-build3360590955/b279/launcher.test
/tmp/go-build3360590955/b279/launcher.test
-test.testlogfile=/tmp/go-build3360590955/b279/testlog.txt
-test.paniconexit0 -test.timeout=10m0s -test.v=true 4047529/b162/_pkg_.a
64/src/runtime/cgo x_amd64/vet` (dns block)
> - `invalid-host-that-does-not-exist-12345.com`
> - Triggering command: `/tmp/go-build3360590955/b264/config.test
/tmp/go-build3360590955/b264/config.test
-test.testlogfile=/tmp/go-build3360590955/b264/testlog.txt
-test.paniconexit0 -test.timeout=10m0s -test.v=true 64/src/runtime/cgo
3E2y/lfIxJsLvVk-kDynw3E2y .12/x64/bin/as` (dns block)
> - `nonexistent.local`
> - Triggering command: `/tmp/go-build3360590955/b279/launcher.test
/tmp/go-build3360590955/b279/launcher.test
-test.testlogfile=/tmp/go-build3360590955/b279/testlog.txt
-test.paniconexit0 -test.timeout=10m0s -test.v=true 4047529/b162/_pkg_.a
64/src/runtime/cgo x_amd64/vet` (dns block)
> - `slow.example.com`
> - Triggering command: `/tmp/go-build3360590955/b279/launcher.test
/tmp/go-build3360590955/b279/launcher.test
-test.testlogfile=/tmp/go-build3360590955/b279/testlog.txt
-test.paniconexit0 -test.timeout=10m0s -test.v=true 4047529/b162/_pkg_.a
64/src/runtime/cgo x_amd64/vet` (dns block)
> - `this-host-does-not-exist-12345.com`
> - Triggering command: `/tmp/go-build3360590955/b288/mcp.test
/tmp/go-build3360590955/b288/mcp.test
-test.testlogfile=/tmp/go-build3360590955/b288/testlog.txt
-test.paniconexit0 -test.timeout=10m0s -test.v=true se
4047529/b025/vet.cfg rgo/bin/as -p internal/msan -lang=go1.25
/opt/hostedtoolcache/go/1.25.7/x-trimpath go_.��
lcache/go/1.25.7/x64=/_/GOROOT Rd x_amd64/vet -p hash/maphash
-lang=go1.25 x_amd64/vet` (dns block)
> - Triggering command: `/tmp/go-build1404549538/b001/mcp.test
/tmp/go-build1404549538/b001/mcp.test
-test.testlogfile=/tmp/go-build1404549538/b001/testlog.txt
-test.paniconexit0 -test.timeout=10m0s -tes��
io.containerd.runtime.v2.task/moby/63201cdb6593143a21722511515a1/run/containerd/io.containerd.rugofmt
-test.timeout=10m0s k/gh-aw-mcpg/gh-aw-mcpg/awmg se
4047529/b025/vet--norc ffbfb0094a8a3294--noprofile
k/gh-aw-mcpg/gh-aw-mcpg/awmg -tes�� -test.paniconexit0 y
by/71af78b18fce5832ab10e180bbc3a77cfee5908e386c9517dcf943eeea458c34/log.json
ntime.v2.task/mo/opt/hostedtoolcache/go/1.25.7/x64/pkg/tool/linux_amd64/vet
Rd t&#34;,
              &#34;REQUESTS_CA_B-c iginal` (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>

<!-- START COPILOT CODING AGENT TIPS -->
---

💡 You can make Copilot smarter by setting up custom instructions,
customizing its development environment and configuring Model Context
Protocol (MCP) servers. Learn more [Copilot coding agent
tips](https://gh.io/copilot-coding-agent-tips) in the docs.
lpcox added a commit that referenced this pull request Feb 19, 2026
The Language Support Tester workflow failed because it referenced the
registry image `ghcr.io/github/gh-aw-mcpg` without building it locally
first, causing Docker daemon connectivity issues and missing Serena MCP
tools.

## Changes

Added local container build steps following the `smoke-copilot.md`
pattern:

- **Docker Buildx setup** - Added `docker/setup-buildx-action@v3` step
- **Local MCP Gateway build** - Builds `local-awmg:v0.1.4` with embedded
`awmg` binary
- **Container reference** - Updated `sandbox.mcp.container` from
`ghcr.io/github/gh-aw-mcpg` to `local-awmg`

```yaml
steps:
  - name: Set up Docker Buildx
    uses: docker/setup-buildx-action@v3
  - name: Build local MCP Gateway container
    run: |
      VERSION="dev-$(git rev-parse --short HEAD)"
      docker build -t local-awmg:v0.1.4 --build-arg VERSION=${VERSION} .

sandbox:
  mcp:
    container: "local-awmg"  # Changed from registry reference
```

This ensures the MCP Gateway is available without external registry
dependencies, enabling Serena tools (`activate_project`, `find_symbols`,
etc.) for Go, TypeScript/JavaScript, and Python language testing.

> [!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:
>
> -
`https://api.github.com/repos/docker/setup-buildx-action/git/ref/tags/v3`
> - Triggering command: `/usr/bin/gh gh api
/repos/docker/setup-buildx-action/git/ref/tags/v3 --jq .object.sha`
(http block)
> - `https://api.github.com/repos/github/gh-aw/git/ref/tags/v0.46.1`
> - Triggering command: `/usr/bin/gh gh api
/repos/github/gh-aw/git/ref/tags/v0.46.1 --jq .object.sha` (http block)
> - `https://api.github.com/user`
> - Triggering command: `/usr/bin/gh gh api user --jq .login
-main/dist/indexuser.name` (http 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>

<!-- START COPILOT ORIGINAL PROMPT -->



<details>

<summary>Original prompt</summary>

> 
> ----
> 
> *This section details on the original issue you should resolve*
> 
> <issue_title>[language-support] Serena MCP server tools unavailable —
language support tests could not run</issue_title>
> <issue_description>## Summary
> 
> The Language Support Tester workflow (run #34, run ID
22164360544) could not complete language support testing for **Go**,
**TypeScript/JavaScript**, and **Python** because the Serena MCP server
tools were not available in the sandbox environment.
> 
> ## Failure Details
> 
> ### Root Cause
> 
> The Docker daemon is not accessible from within the sandbox container:
> 
> ```
> Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is
the docker daemon running?
> ```
> 
> Because Docker is unavailable, the Serena MCP server container
(`ghcr.io/github/serena-mcp-server:latest`) cannot be started. As a
result, none of the language server tools (`activate_project`,
`find_symbols`, `get_definition`, etc.) were present in the agent's
available tool list.
> 
> ### Diagnostic evidence
> 
> - `/tmp/gh-aw/mcp-logs/` — empty (no MCP server logs, no `tools.json`)
> - `/tmp/gh-aw/mcp-config/` — contains only `jq-error.log`, no MCP
configuration JSON files
> - `docker images` / `docker ps` — command fails: daemon not reachable
> - `awmg` binary — not found in `PATH`
> - Serena tools (`activate_project`, `find_symbols`, etc.) — absent
from agent function-call interface
> 
> ### Languages affected
> 
> | Language | Status |
> |---|---|
> | Go | ❌ Not tested — Serena unavailable |
> | TypeScript/JavaScript | ❌ Not tested — Serena unavailable |
> | Python | ❌ Not tested — Serena unavailable |
> 
> ## Steps to Reproduce
> 
> 1. Trigger the **Language Support Tester** workflow
> 2. Observe that no Serena MCP tools appear in the agent's available
tools
> 3. `docker ps` inside the sandbox returns a daemon connection error
> 
> ## Expected Behavior
> 
> - Serena MCP server starts successfully
> - `activate_project`, `find_symbols`, `get_definition` tools are
available
> - Language support is verified for Go, TypeScript/JavaScript, and
Python
> 
> ## Suggested Investigation
> 
> - Verify that the sandbox container has access to the Docker daemon
(Docker-in-Docker or DooD)
> - Confirm the workflow's `tools: serena:` configuration is correctly
translating into MCP server setup
> - Check whether the pre-pull step (`docker pull
ghcr.io/github/serena-mcp-server:latest`) is succeeding before the agent
starts
> 
> 
> 
> 
> > Generated by [Language Support
Tester](https://github.com/github/gh-aw-mcpg/actions/runs/22164360544)
> > - [x] expires <!-- gh-aw-expires: 2026-02-26T01:14:02.300Z --> on
Feb 26, 2026, 1:14 AM UTC
> 
> <!-- gh-aw-agentic-workflow: Language Support Tester, engine: copilot,
run: https://github.com/github/gh-aw-mcpg/actions/runs/22164360544 -->
> 
> <!-- gh-aw-workflow-id: language-support-tester
--></issue_description>
> 
> ## Comments on the Issue (you are @copilot in this section)
> 
> <comments>
> </comments>
> 


</details>



<!-- START COPILOT CODING AGENT SUFFIX -->

- Fixes #1088

<!-- START COPILOT CODING AGENT TIPS -->
---

🔒 GitHub Advanced Security automatically protects Copilot coding agent
pull requests. You can protect all pull requests by enabling Advanced
Security for your repositories. [Learn more about Advanced
Security.](https://gh.io/cca-advanced-security)
lpcox added a commit that referenced this pull request Feb 23, 2026
…ddleware chaining code (#1311)

## Summary

Consolidates duplicate middleware chaining pattern (`WithSDKLogging` →
`rejectIfShutdown` → `applyAuthIfConfigured`) that was replicated
verbatim between `CreateHTTPServerForMCP` (transport.go) and
`CreateHTTPServerForRoutedMode` (routed.go).

## Changes

- **Added `wrapWithMiddleware` helper** in `http_helpers.go` that
encapsulates the standard middleware stack with documented spec
references (5.1.3 for shutdown, 7.1 for auth)
- **Updated both server factories** to use the helper, reducing 9 lines
of duplicate code per location to a single function call
- **Added comprehensive tests** covering auth scenarios, shutdown
behavior, middleware ordering verification, and log tag variations

## Example

Before:
```go
// Duplicated in both transport.go and routed.go
loggedHandler := WithSDKLogging(handler, "unified")
shutdownHandler := rejectIfShutdown(unifiedServer, loggedHandler, "server:transport")
finalHandler := applyAuthIfConfigured(apiKey, shutdownHandler.ServeHTTP)
```

After:
```go
// Single call, consistent across both modes
finalHandler := wrapWithMiddleware(handler, "unified", unifiedServer, apiKey)
```

## Impact

Adding new middleware layers (rate limiting, tracing, etc.) now requires
changes in one location instead of two, with spec references and
ordering documented centrally.

> [!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-build1187723181/b275/launcher.test
/tmp/go-build1187723181/b275/launcher.test
-test.testlogfile=/tmp/go-build1187723181/b275/testlog.txt
-test.paniconexit0 -test.timeout=10m0s -test.v=true go HEAD ndor/bin/as
--global r = get &amp;&amp; echo &#34;--abbrev-ref ortcfg rev-��
64/src/runtime/c-c=4 64/src/os/dir_un-nolocalimports x_amd64/vet get
--global
ache/Python/3.12/home/REDACTED/go/pkg/mod/github.com/google/jsonschema-go@v0.4.2/jsonschema/annotations.go
x_amd64/vet` (dns block)
> - `invalid-host-that-does-not-exist-12345.com`
> - Triggering command: `/tmp/go-build1187723181/b260/config.test
/tmp/go-build1187723181/b260/config.test
-test.testlogfile=/tmp/go-build1187723181/b260/testlog.txt
-test.paniconexit0 -test.timeout=10m0s -test.v=true ortcfg s.go
64/pkg/tool/linu-o --global go x86-64.so.2 64/pkg/tool/linu-buildtags
ortc�� 1554416/b013/_pk-errorsas 64/src/crypto/in-ifaceassert
64/pkg/tool/linu-nilfunc unset --global 86_64/uname
64/pkg/tool/linu-tests` (dns block)
> - `nonexistent.local`
> - Triggering command: `/tmp/go-build1187723181/b275/launcher.test
/tmp/go-build1187723181/b275/launcher.test
-test.testlogfile=/tmp/go-build1187723181/b275/testlog.txt
-test.paniconexit0 -test.timeout=10m0s -test.v=true go HEAD ndor/bin/as
--global r = get &amp;&amp; echo &#34;--abbrev-ref ortcfg rev-��
64/src/runtime/c-c=4 64/src/os/dir_un-nolocalimports x_amd64/vet get
--global
ache/Python/3.12/home/REDACTED/go/pkg/mod/github.com/google/jsonschema-go@v0.4.2/jsonschema/annotations.go
x_amd64/vet` (dns block)
> - `slow.example.com`
> - Triggering command: `/tmp/go-build1187723181/b275/launcher.test
/tmp/go-build1187723181/b275/launcher.test
-test.testlogfile=/tmp/go-build1187723181/b275/testlog.txt
-test.paniconexit0 -test.timeout=10m0s -test.v=true go HEAD ndor/bin/as
--global r = get &amp;&amp; echo &#34;--abbrev-ref ortcfg rev-��
64/src/runtime/c-c=4 64/src/os/dir_un-nolocalimports x_amd64/vet get
--global
ache/Python/3.12/home/REDACTED/go/pkg/mod/github.com/google/jsonschema-go@v0.4.2/jsonschema/annotations.go
x_amd64/vet` (dns block)
> - `this-host-does-not-exist-12345.com`
> - Triggering command: `/tmp/go-build1187723181/b284/mcp.test
/tmp/go-build1187723181/b284/mcp.test
-test.testlogfile=/tmp/go-build1187723181/b284/testlog.txt
-test.paniconexit0 -test.timeout=10m0s -test.v=true go
64/src/internal/-ifaceassert 64/pkg/tool/linu-nilfunc --global
user.email ache/Python/3.12--abbrev-ref 64/pkg/tool/linuHEAD abis��
toml@v1.6.0/decode.go toml@v1.6.0/deprecated.go u/13/cc1 -tree /cgroup
k/_temp/ghcca-node/node/bin/node/opt/hostedtoolcache/go/1.25.6/x64/src/net
u/13/cc1` (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>

<!-- START COPILOT ORIGINAL PROMPT -->



<details>

<summary>Original prompt</summary>

> 
> ----
> 
> *This section details on the original issue you should resolve*
> 
> <issue_title>[duplicate-code] Duplicate Code Pattern: Middleware
Chaining and HTTP Server Construction</issue_title>
> <issue_description>*Part of duplicate code analysis:
#1283*
> 
> ## Summary
> 
> The three-step middleware wrapping chain (`WithSDKLogging` →
`rejectIfShutdown` → `applyAuthIfConfigured`) and the final
`http.Server` construction are duplicated verbatim between
`CreateHTTPServerForMCP` (transport.go) and
`CreateHTTPServerForRoutedMode` (routed.go), along with identical
comments.
> 
> ## Duplication Details
> 
> ### Pattern: Middleware chain + http.Server construction
> - **Severity**: Low
> - **Occurrences**: 2 (one per HTTP server factory function)
> - **Locations**:
>   - `internal/server/transport.go` (lines 118–135)
> - `internal/server/routed.go` (lines 140–162, inside per-backend loop)
> 
> **`transport.go`**:
> ````go
> // Wrap SDK handler with detailed logging for JSON-RPC translation
debugging
> loggedHandler := WithSDKLogging(streamableHandler, "unified")
> 
> // Apply shutdown check middleware (spec 5.1.3)
> // This must come before auth to ensure shutdown takes precedence
> shutdownHandler := rejectIfShutdown(unifiedServer, loggedHandler,
"server:transport")
> 
> // Apply auth middleware if API key is configured (spec 7.1)
> finalHandler := applyAuthIfConfigured(apiKey,
shutdownHandler.ServeHTTP)
> 
> mux.Handle("/mcp/", finalHandler)
> mux.Handle("/mcp", finalHandler)
> 
> return &http.Server{Addr: addr, Handler: mux}
> ````
> 
> **`routed.go`** (inside per-backend loop, then after):
> ````go
> loggedHandler := WithSDKLogging(routeHandler, "routed:"+backendID)
> shutdownHandler := rejectIfShutdown(unifiedServer, loggedHandler,
"server:routed")
> finalHandler := applyAuthIfConfigured(apiKey,
shutdownHandler.ServeHTTP)
> 
> mux.Handle(route+"/", finalHandler)
> mux.Handle(route, finalHandler)
> 
> // ... (outside loop)
> return &http.Server{Addr: addr, Handler: mux}
> ````
> 
> ## Impact Analysis
> 
> - **Maintainability**: Adding a new middleware layer (e.g., rate
limiting, tracing) requires changes in both files. The spec references
in comments (5.1.3, 7.1) would also need to be kept in sync.
> - **Bug Risk**: Low, since the middleware order is mechanically
enforced, but adding middleware only in one place is a realistic
mistake.
> - **Code Bloat**: Minor (~6 lines duplicated).
> 
> ## Refactoring Recommendations
> 
> 1. **Extract a `wrapWithMiddleware` helper** in `transport.go` or
`http_helpers.go`:
>    ````go
> // wrapWithMiddleware applies the standard middleware stack to an SDK
handler.
> // Order: SDK logging → shutdown check (spec 5.1.3) → auth (spec 7.1)
> func wrapWithMiddleware(handler http.Handler, logTag string,
unifiedServer *UnifiedServer, apiKey string) http.HandlerFunc {
>        loggedHandler := WithSDKLogging(handler, logTag)
> shutdownHandler := rejectIfShutdown(unifiedServer, loggedHandler,
"server:"+logTag)
>        return applyAuthIfConfigured(apiKey, shutdownHandler.ServeHTTP)
>    }
>    ````
> 
> 2. **Optionally extract `buildHTTPServer`**:
>    ````go
> func buildHTTPServer(addr string, mux *http.ServeMux) *http.Server {
>        return &http.Server{Addr: addr, Handler: mux}
>    }
>    ````
> 
> 3. **Estimated effort**: ~20 minutes  
> 4. **Benefits**: Middleware order documented and enforced in one
place; easier to add new middleware globally
> 
> ## Implementation Checklist
> 
> - [ ] Review duplication findings
> - [ ] Extract `wrapWithMiddleware` helper
> - [ ] Update `transport.go` and `routed.go` to use the helper
> - [ ] Verify middleware order is preserved
> - [ ] Verify no functionality broken
> 
> ## Parent Issue
> 
> See parent analysis report: #1283
> Related to #1283
> 
> 
> 
> 
> > Generated by [Duplicate Code
Detector](https://github.com/github/gh-aw-mcpg/actions/runs/22269224479)
> > - [x] expires <!-- gh-aw-expires: 2026-03-01T03:02:48.820Z --> on
Mar 1, 2026, 3:02 AM UTC
> 
> <!-- gh-aw-agentic-workflow: Duplicate Code Detector, engine: copilot,
run: https://github.com/github/gh-aw-mcpg/actions/runs/22269224479 -->
> 
> <!-- gh-aw-workflow-id: duplicate-code-detector
--></issue_description>
> 
> ## Comments on the Issue (you are @claude[agent] in this section)
> 
> <comments>
> </comments>
> 


</details>



<!-- START COPILOT CODING AGENT SUFFIX -->

- Fixes #1284
lpcox added a commit that referenced this pull request Feb 23, 2026
The language-support-tester workflow was failing at runtime because
Serena MCP tools (`serena-get_symbols_overview`, `serena-find_symbol`)
were unavailable, blocking Go, TypeScript, and Python language support
tests.

## Root Cause

The `.lock.yml` file was compiled with gh-aw v0.48.3 and out of sync
with its source. The workflow needed recompilation to pick up:

- MCP gateway upgrade (v0.1.4 → v0.1.5)
- Compiler improvements (v0.48.3 → v0.49.2)
- Updated prompt handling

## Changes

- Recompiled `.github/workflows/language-support-tester.lock.yml` using
`gh aw compile`
- Updated compiler metadata and dependency versions

## Configuration Verification

The source `.md` file was already correct:
- Serena tool specification: `serena: ["go", "typescript", "python"]`
(array format) ✓
- Container config: `ghcr.io/github/serena-mcp-server:latest` ✓
- Entrypoint: `start-mcp-server --context codex --project
${GITHUB_WORKSPACE}` ✓
- Test samples present for all three languages ✓

Serena tools should now be available when the workflow runs.

> [!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-build546163221/b275/launcher.test
/tmp/go-build546163221/b275/launcher.test
-test.testlogfile=/tmp/go-build546163221/b275/testlog.txt
-test.paniconexit0 -test.timeout=10m0s -test.v=true go1.25.6 -c=4
-nolocalimports -importcfg /tmp/go-build546163221/b160/importcfg -pack
/opt/hostedtoolcache/go/1.25.6/x64/src/crypto/x509/cert_pool.go rev-��
go HEAD /usr/bin/base64 it base64
ache/Python/3.12/tmp/go-build546163221/b182/_pkg_.a 64/pkg/include` (dns
block)
> - `https://api.github.com/repos/actions/setup-go/git/ref/tags/v6`
> - Triggering command: `/usr/bin/gh gh api
/repos/actions/setup-go/git/ref/tags/v6 --jq .object.sha
/home/REDACTED/.cargo/bin/git base64 tnet/tools/git /usr/bin/base64 git
/usr/local/.ghcup/bin/git base64 -d t git ndor/bin/git 0,
length(NVM_DIbase64 HEAD bin/git git` (http block)
> -
`https://api.github.com/repos/docker/setup-buildx-action/git/ref/tags/v3`
> - Triggering command: `/usr/bin/gh gh api
/repos/docker/setup-buildx-action/git/ref/tags/v3 --jq .object.sha`
(http block)
> - Triggering command: `/usr/bin/gh gh api
/repos/docker/setup-buildx-action/git/ref/tags/v3 --jq .object.sha
/home/REDACTED/.lo/home/REDACTED/.nvm/Dockerfile base64 cal/bin/git
/usr/bin/base64 with v0.49.2).
-20 /usr/bin/sed base64 -d .12/x64/git sed
/home/REDACTED/.lo/home/REDACTED/.nvm/nvm-exec s/^session\.savebase64
ons/[^/]*)?/[^/]-d /) exit(2);
    /home/REDACTED/.nvm/rename_test.sh git` (http block)
> - `https://api.github.com/repos/github/gh-aw/git/ref/tags/v0.49.2`
> - Triggering command: `/usr/bin/gh gh api
/repos/github/gh-aw/git/ref/tags/v0.49.2 --jq .object.sha ndor/bin/git
git /usr/bin/base64 --abbrev-ref HEAD /usr/bin/base64 base64 -d
/usr/bin/awk base64 /usr/bin/base64 /g awk /usr/bin/which t }
  }
  { printf &#34;%s%s&#34;, sep, HEAD` (http block)
> - Triggering command: `/usr/bin/gh gh api
/repos/github/gh-aw/git/ref/tags/v0.49.2 --jq .object.sha
/usr/local/.ghcup/bin/git base64 it /usr/bin/base64 git ndor/bin/git
base64 -d nfig/composer/vendor/bin/git git /snap/bin/git --abbrev-ref
HEAD ache/uv/0.10.4/x86_64/git git` (http block)
> - `invalid-host-that-does-not-exist-12345.com`
> - Triggering command: `/tmp/go-build546163221/b260/config.test
/tmp/go-build546163221/b260/config.test
-test.testlogfile=/tmp/go-build546163221/b260/testlog.txt
-test.paniconexit0 -test.timeout=10m0s -test.v=true go
ternal/fips140/a--gdwarf2 64/pkg/tool/linu--64 ^/home/REDACTED/.nas git
/usr/bin/base64 64/pkg/tool/linu-I rev-�� go lang.org/x/text/--64
64/pkg/tool/linu-o
nfig/composer/ve/opt/hostedtoolcache/go/1.25.6/x64/pkg/tool/linux_amd64/vet
base64 bin/git 64/pkg/tool/linu/tmp/go-build546163221/b193/vet.cfg` (dns
block)
> - `nonexistent.local`
> - Triggering command: `/tmp/go-build546163221/b275/launcher.test
/tmp/go-build546163221/b275/launcher.test
-test.testlogfile=/tmp/go-build546163221/b275/testlog.txt
-test.paniconexit0 -test.timeout=10m0s -test.v=true go1.25.6 -c=4
-nolocalimports -importcfg /tmp/go-build546163221/b160/importcfg -pack
/opt/hostedtoolcache/go/1.25.6/x64/src/crypto/x509/cert_pool.go rev-��
go HEAD /usr/bin/base64 it base64
ache/Python/3.12/tmp/go-build546163221/b182/_pkg_.a 64/pkg/include` (dns
block)
> - `slow.example.com`
> - Triggering command: `/tmp/go-build546163221/b275/launcher.test
/tmp/go-build546163221/b275/launcher.test
-test.testlogfile=/tmp/go-build546163221/b275/testlog.txt
-test.paniconexit0 -test.timeout=10m0s -test.v=true go1.25.6 -c=4
-nolocalimports -importcfg /tmp/go-build546163221/b160/importcfg -pack
/opt/hostedtoolcache/go/1.25.6/x64/src/crypto/x509/cert_pool.go rev-��
go HEAD /usr/bin/base64 it base64
ache/Python/3.12/tmp/go-build546163221/b182/_pkg_.a 64/pkg/include` (dns
block)
> - `this-host-does-not-exist-12345.com`
> - Triggering command: `/tmp/go-build546163221/b284/mcp.test
/tmp/go-build546163221/b284/mcp.test
-test.testlogfile=/tmp/go-build546163221/b284/testlog.txt
-test.paniconexit0 -test.timeout=10m0s -test.v=true _.a HEAD
64/pkg/tool/linux_amd64/compile de/node/bin/git tail /) exit(2);
-unreachable=false 64/pkg/tool/linu/tmp/go-build546163221/b120/vet.cfg
/hom�� go Usv7CWTeK x_amd64/vet bin/git base64 /usr/bin/head
x_amd64/vet` (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>

<!-- START COPILOT ORIGINAL PROMPT -->



<details>

<summary>Original prompt</summary>

> 
> ----
> 
> *This section details on the original issue you should resolve*
> 
> <issue_title>[language-support] Serena MCP tools unavailable —
language support testing blocked (Go, TypeScript/JavaScript,
Python)</issue_title>
> <issue_description>## Summary
> 
> The automated language support tester ran and attempted to test Go,
TypeScript/JavaScript, and Python language support using the Serena MCP
server. All three tests failed because the required Serena MCP tools are
not available in the agent's tool inventory.
> 
> ## Failed Tests
> 
> | Language | Tool Attempted | Result |
> |----------|---------------|--------|
> | Go | `serena-get_symbols_overview` (relative_path:
`internal/server`) | ❌ Tool not available |
> | Go | `serena-find_symbol` | ❌ Tool not available |
> | TypeScript/JavaScript | `serena-get_symbols_overview`
(relative_path:
`test/serena-mcp-tests/samples/js_project/calculator.js`) | ❌ Tool not
available |
> | TypeScript/JavaScript | `serena-find_symbol` | ❌ Tool not available
|
> | Python | `serena-get_symbols_overview` (relative_path:
`test/serena-mcp-tests/samples/python_project/calculator.py`) | ❌ Tool
not available |
> | Python | `serena-find_symbol` | ❌ Tool not available |
> 
> ## Error Details
> 
> When the agent attempted to call `serena-get_symbols_overview` and
`serena-find_symbol`, neither tool appeared in the available tool set.
The Serena MCP server does not appear to be running and connected as an
MCP server in this workflow environment.
> 
> ## Steps to Reproduce
> 
> 1. Trigger the `language-support-tester` workflow
> 2. Observe that `serena-get_symbols_overview` and `serena-find_symbol`
are not listed as available tools
> 3. All Serena-based language tests fail
> 
> ## Expected Behavior
> 
> The Serena MCP server should be running and its tools should be
available with the `serena-` prefix, as documented in
`.github/agentics/language-support-tester.md`.
> 
> ## Possible Causes
> 
> - The Serena MCP server is not configured or not started in this
workflow
> - The MCP gateway is not routing Serena tool calls correctly
> - The `serena` tool configuration in the workflow definition may be
missing or incorrect (should use array format: `serena: ["go",
"typescript", "python"]`)
> 
> ## References
> 
> - Workflow definition: `.github/workflows/language-support-tester.md`
> - Agent prompt: `.github/agentics/language-support-tester.md`
> 
> 
> 
> 
> > Generated by [Language Support
Tester](https://github.com/github/gh-aw-mcpg/actions/runs/22292141786)
> > - [x] expires <!-- gh-aw-expires: 2026-03-02T03:49:03.671Z --> on
Mar 2, 2026, 3:49 AM UTC
> 
> <!-- gh-aw-agentic-workflow: Language Support Tester, engine: copilot,
run: https://github.com/github/gh-aw-mcpg/actions/runs/22292141786 -->
> 
> <!-- gh-aw-workflow-id: language-support-tester
--></issue_description>
> 
> ## Comments on the Issue (you are @claude[agent] in this section)
> 
> <comments>
> </comments>
> 


</details>



<!-- START COPILOT CODING AGENT SUFFIX -->

- Fixes #1309
lpcox added a commit that referenced this pull request Mar 10, 2026
…cies exist (#1741)

The v0.1.12 auto-detection introduced a timing bug where guards were
downgraded to noop during registration, before DIFC auto-enablement ran.
This broke AllowOnly enforcement in smoke tests.

## Problem

Guard registration (line 180) happens before auto-detection (line 188).
When `requireGuardPolicyIfGuardEnabled` finds no resolved policy during
registration, it falls back to noop. By the time
`hasServerGuardPolicies(cfg)` triggers auto-enablement, the guard is
already noop.

## Solution

Modified `requireGuardPolicyIfGuardEnabled` to check
`serverCfg.GuardPolicies` before falling back:

```go
if policy == nil {
    // Keep non-noop guard if server has guard policies configured
    if serverCfg, ok := us.cfg.Servers[serverID]; ok && len(serverCfg.GuardPolicies) > 0 {
        return g, nil  // Guard will be initialized on first use
    }
    return guard.NewNoopGuard(), nil
}
```

This preserves the WASM guard discovered from `/guards/{serverID}/` when
guard policies exist, allowing proper initialization during
`ensureGuardInitialized`.

## Changes

- **internal/server/unified.go**: Added guard policy check before noop
fallback
- **internal/server/require_guard_policy_test.go**: Tests for fallback
behavior with/without policies
- **internal/server/guard_policy_parsing_test.go**: Tests for
`parseServerGuardPolicy` and `resolveGuardPolicy`
- **internal/server/has_server_guard_policies_test.go**: Tests for
policy detection logic

> [!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-build2269947796/b332/launcher.test
/tmp/go-build2269947796/b332/launcher.test
-test.testlogfile=/tmp/go-build2269947796/b332/testlog.txt
-test.paniconexit0 -test.timeout=10m0s -test.v=true --abbrev-ref HEAD
/usr/bin/base64 --abbrev-ref 877973&#43;lpcox@userev-parse
ache/Python/3.12--abbrev-ref base64 -d 64/pkg/tool/linu--abbrev-ref
base64 /usr/bin/dirname x_amd64/compile 64/pkg/tool/linu-d ndor/bin/git
t }
  }
  { printf &#34;%s%s&#34;, sep, HEAD` (dns block)
> - `invalid-host-that-does-not-exist-12345.com`
> - Triggering command: `/tmp/go-build2269947796/b314/config.test
/tmp/go-build2269947796/b314/config.test
-test.testlogfile=/tmp/go-build2269947796/b314/testlog.txt
-test.paniconexit0 -test.timeout=10m0s -test.v=true --abbrev-ref HEAD
/usr/bin/base64 m/CLAUDE.md m/CODE_OF_CONDUC-o
ache/go/1.25.7/x/tmp/go-build1778197618/b062/_pkg_.a base64 -d
m/LICENSE.md m/Makefile /home/REDACTED/go/-lang=go1.25 m/README.md
m/ROADMAP.md Policy_ServerGuaccs13v1iKv05Y3GP5cax/ccs13v1iKv05Y3GP5cax
git` (dns block)
> - `nonexistent.local`
> - Triggering command: `/tmp/go-build2269947796/b332/launcher.test
/tmp/go-build2269947796/b332/launcher.test
-test.testlogfile=/tmp/go-build2269947796/b332/testlog.txt
-test.paniconexit0 -test.timeout=10m0s -test.v=true --abbrev-ref HEAD
/usr/bin/base64 --abbrev-ref 877973&#43;lpcox@userev-parse
ache/Python/3.12--abbrev-ref base64 -d 64/pkg/tool/linu--abbrev-ref
base64 /usr/bin/dirname x_amd64/compile 64/pkg/tool/linu-d ndor/bin/git
t }
  }
  { printf &#34;%s%s&#34;, sep, HEAD` (dns block)
> - `slow.example.com`
> - Triggering command: `/tmp/go-build2269947796/b332/launcher.test
/tmp/go-build2269947796/b332/launcher.test
-test.testlogfile=/tmp/go-build2269947796/b332/testlog.txt
-test.paniconexit0 -test.timeout=10m0s -test.v=true --abbrev-ref HEAD
/usr/bin/base64 --abbrev-ref 877973&#43;lpcox@userev-parse
ache/Python/3.12--abbrev-ref base64 -d 64/pkg/tool/linu--abbrev-ref
base64 /usr/bin/dirname x_amd64/compile 64/pkg/tool/linu-d ndor/bin/git
t }
  }
  { printf &#34;%s%s&#34;, sep, HEAD` (dns block)
> - `this-host-does-not-exist-12345.com`
> - Triggering command: `/tmp/go-build2269947796/b341/mcp.test
/tmp/go-build2269947796/b341/mcp.test
-test.testlogfile=/tmp/go-build2269947796/b341/testlog.txt
-test.paniconexit0 -test.timeout=10m0s -test.v=true --abbrev-ref HEAD
ptables --abbrev-ref 877973&#43;lpcox@use-c tnet/tools/git base64` (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>
lpcox added a commit that referenced this pull request Mar 11, 2026
Addresses duplicate code analysis findings: ~60 lines of repeated
mutex-locking and logging patterns across logger and DIFC packages.

## Changes

**DIFC Tag Mutation (#1767)** - 21 lines reduced
- Extracted `modifyTag` helper to consolidate mutex-lock + dual-logging
pattern
- Refactored `AddSecrecyTag`, `AddIntegrityTag`, `DropIntegrityTag`

```go
// Before: duplicated 7-line pattern in each method
func (a *AgentLabels) AddSecrecyTag(tag Tag) {
    logAgent.Printf("Agent %s adding secrecy tag: %s", a.AgentID, tag)
    a.mu.Lock()
    defer a.mu.Unlock()
    a.Secrecy.Label.Add(tag)
    log.Printf("[DIFC] Agent %s gained secrecy tag: %s", a.AgentID, tag)
}

// After: unified helper
func (a *AgentLabels) AddSecrecyTag(tag Tag) {
    a.modifyTag("secrecy", "adding", "gained", tag, func() {
        a.Secrecy.Label.Add(tag)
    })
}
```

**Global Logger RWMutex Access (#1768)** - 40 lines reduced
- Created generic `withGlobalLogger` helper with `closableLogger`
constraint
- Refactored 8+ call sites across file_logger, markdown_logger,
jsonl_logger, server_file_logger, tools_logger, rpc_logger

```go
// Before: duplicated RWMutex pattern
globalLoggerMu.RLock()
defer globalLoggerMu.RUnlock()
if globalLogger != nil {
    globalLogger.DoSomething(args...)
}

// After: type-safe generic helper
withGlobalLogger(&globalLoggerMu, &globalLogger, func(logger *Logger) {
    logger.DoSomething(args...)
})
```

**Logger Initialization (#1766)** - No changes required
- Reviewed existing `initLogger` generic - already well-abstracted
- Documented pattern rationale in common.go

## Documentation
Added "Global Logger RWMutex Access Pattern" section to
`internal/logger/common.go` explaining the refactoring approach and
benefits.

> [!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-build2039083650/b332/launcher.test
/tmp/go-build2039083650/b332/launcher.test
-test.testlogfile=/tmp/go-build2039083650/b332/testlog.txt
-test.paniconexit0 -test.timeout=10m0s -test.v=true se stmain.go
ache/go/1.25.7/x64/pkg/tool/linux_amd64/link . --gdwarf2 --64
ache/go/1.25.7/x64/pkg/tool/linuHEAD -I 7410264/b320/difc.test -I
86_64/git --gdwarf-5 --64 -o
Rlvht1SmvPjlx/EgKV67uNxy1s5Sk4WJTJ/FFffmGA1P5hLrHEAD` (dns block)
> - Triggering command: `/tmp/go-build139309952/b332/launcher.test
/tmp/go-build139309952/b332/launcher.test
-test.testlogfile=/tmp/go-build139309952/b332/testlog.txt
-test.paniconexit0 -test.timeout=10m0s -test.v=true .cfg
/opt/hostedtoolc-goversion 64/pkg/tool/linux_amd64/vet -bool -buildtags
ache/go/1.25.7/x/tmp/go-build139309952/b319/_pkg_.a
64/pkg/tool/linu-trimpath rev-�� .cfg HEAD ache/go/1.25.7/x-lang=go1.25
--abbrev-ref HEAD tnet/tools/git tf &#34;%s%s&#34;, sep, -goversion`
(dns block)
> - Triggering command: `/tmp/go-build311971124/b336/launcher.test
/tmp/go-build311971124/b336/launcher.test
-test.testlogfile=/tmp/go-build311971124/b336/testlog.txt
-test.paniconexit0 -test.timeout=10m0s star��` (dns block)
> - `invalid-host-that-does-not-exist-12345.com`
> - Triggering command: `/tmp/go-build2039083650/b314/config.test
/tmp/go-build2039083650/b314/config.test
-test.testlogfile=/tmp/go-build2039083650/b314/testlog.txt
-test.paniconexit0 -test.timeout=10m0s -test.v=true 7410264/b253/_pkg_.a
/tmp/go-build1837410264/b068/vet.cfg
ache/go/1.25.7/x64/pkg/tool/linux_amd64/vet -dumpbase ntio/asm/base64
-dumpbase-ext ache/go/1.25.7/xHEAD eU_a��
/opt/hostedtoolcache/go/1.25.7/x64/src/net -I rgo/bin/git
7410264/b253/symbase64 --64 -o /opt/hostedtoolcache/go/1.25.7/xHEAD`
(dns block)
> - Triggering command: `/tmp/go-build139309952/b314/config.test
/tmp/go-build139309952/b314/config.test
-test.testlogfile=/tmp/go-build139309952/b314/testlog.txt
-test.paniconexit0 -test.timeout=10m0s -test.v=true ;
            s#^/home/REDACTED/.nvm/##;
            \#^[^v]# d;
            \#^versions$# d;
tr /opt/hostedtoolcache/go/1.25.7/xHEAD 64/pkg/tool/linux_amd64/vet
pkg/mod/github.cgit pkg/mod/github.crev-parse
ache/Python/3.12--abbrev-ref 64/pkg/tool/linuHEAD /usr�� .cfg
/opt/hostedtoolc-test.timeout=10m0s 64/pkg/tool/linux_amd64/vet
github.com/segmebase64 -trimpath .12/x64/git
64/pkg/tool/linux_amd64/vet` (dns block)
> - Triggering command: `/tmp/go-build311971124/b318/config.test
/tmp/go-build311971124/b318/config.test
-test.testlogfile=/tmp/go-build311971124/b318/testlog.txt
-test.paniconexit0 -test.timeout=10m0s .pro��
/opt/hostedtoolc--abbrev-ref /opt/hostedtoolcHEAD
d-dispatcher/off.d/chrony-onoffline /tmp/go-build186dirname git
64/pkg/tool/linux_amd64/compile d-dispatcher/off.d/chrony-onoffline
-nam�� moby -id /usr/bin/runc.original -address /run/containerd/-d
docker-buildx /usr/bin/runc.original` (dns block)
> - `nonexistent.local`
> - Triggering command: `/tmp/go-build2039083650/b332/launcher.test
/tmp/go-build2039083650/b332/launcher.test
-test.testlogfile=/tmp/go-build2039083650/b332/testlog.txt
-test.paniconexit0 -test.timeout=10m0s -test.v=true se stmain.go
ache/go/1.25.7/x64/pkg/tool/linux_amd64/link . --gdwarf2 --64
ache/go/1.25.7/x64/pkg/tool/linuHEAD -I 7410264/b320/difc.test -I
86_64/git --gdwarf-5 --64 -o
Rlvht1SmvPjlx/EgKV67uNxy1s5Sk4WJTJ/FFffmGA1P5hLrHEAD` (dns block)
> - Triggering command: `/tmp/go-build139309952/b332/launcher.test
/tmp/go-build139309952/b332/launcher.test
-test.testlogfile=/tmp/go-build139309952/b332/testlog.txt
-test.paniconexit0 -test.timeout=10m0s -test.v=true .cfg
/opt/hostedtoolc-goversion 64/pkg/tool/linux_amd64/vet -bool -buildtags
ache/go/1.25.7/x/tmp/go-build139309952/b319/_pkg_.a
64/pkg/tool/linu-trimpath rev-�� .cfg HEAD ache/go/1.25.7/x-lang=go1.25
--abbrev-ref HEAD tnet/tools/git tf &#34;%s%s&#34;, sep, -goversion`
(dns block)
> - Triggering command: `/tmp/go-build311971124/b336/launcher.test
/tmp/go-build311971124/b336/launcher.test
-test.testlogfile=/tmp/go-build311971124/b336/testlog.txt
-test.paniconexit0 -test.timeout=10m0s star��` (dns block)
> - `slow.example.com`
> - Triggering command: `/tmp/go-build2039083650/b332/launcher.test
/tmp/go-build2039083650/b332/launcher.test
-test.testlogfile=/tmp/go-build2039083650/b332/testlog.txt
-test.paniconexit0 -test.timeout=10m0s -test.v=true se stmain.go
ache/go/1.25.7/x64/pkg/tool/linux_amd64/link . --gdwarf2 --64
ache/go/1.25.7/x64/pkg/tool/linuHEAD -I 7410264/b320/difc.test -I
86_64/git --gdwarf-5 --64 -o
Rlvht1SmvPjlx/EgKV67uNxy1s5Sk4WJTJ/FFffmGA1P5hLrHEAD` (dns block)
> - Triggering command: `/tmp/go-build139309952/b332/launcher.test
/tmp/go-build139309952/b332/launcher.test
-test.testlogfile=/tmp/go-build139309952/b332/testlog.txt
-test.paniconexit0 -test.timeout=10m0s -test.v=true .cfg
/opt/hostedtoolc-goversion 64/pkg/tool/linux_amd64/vet -bool -buildtags
ache/go/1.25.7/x/tmp/go-build139309952/b319/_pkg_.a
64/pkg/tool/linu-trimpath rev-�� .cfg HEAD ache/go/1.25.7/x-lang=go1.25
--abbrev-ref HEAD tnet/tools/git tf &#34;%s%s&#34;, sep, -goversion`
(dns block)
> - Triggering command: `/tmp/go-build311971124/b336/launcher.test
/tmp/go-build311971124/b336/launcher.test
-test.testlogfile=/tmp/go-build311971124/b336/testlog.txt
-test.paniconexit0 -test.timeout=10m0s star��` (dns block)
> - `this-host-does-not-exist-12345.com`
> - Triggering command: `/tmp/go-build2039083650/b341/mcp.test
/tmp/go-build2039083650/b341/mcp.test
-test.testlogfile=/tmp/go-build2039083650/b341/testlog.txt
-test.paniconexit0 -test.timeout=10m0s -test.v=true
/opt/hostedtoolcache/go/1.25.7/x64/src/net -I iptables --gdwarf-5 --64
-o as -I /opt/hostedtoolcache/go/1.25.7/x64/src/net -I
7410264/b248/vet.cfg --gdwarf-5 --64 -o */bin.*$&#34;) { next }
  }
  { printf &#34;%s%s&#34;, sep, HEAD` (dns block)
> - Triggering command: `/tmp/go-build139309952/b341/mcp.test
/tmp/go-build139309952/b341/mcp.test
-test.testlogfile=/tmp/go-build139309952/b341/testlog.txt
-test.paniconexit0 -test.timeout=10m0s -test.v=true -importcfg
4E-sSYy/pwgIjRIG-w ache/go/1.25.7/x-buildmode=exe --abbrev-ref HEAD
nfig/composer/ve--version ache/go/1.25.7/x-extld=gcc` (dns block)
> - Triggering command: `/tmp/go-build311971124/b345/mcp.test
/tmp/go-build311971124/b345/mcp.test
-test.testlogfile=/tmp/go-build311971124/b345/testlog.txt
-test.paniconexit0 -test.timeout=10m0s /usr��
1dedc330cd146d1731f9c903fe295e422bb440808c4a20ae
/var/run/docker/runtime-runc/moby 86_64/git
/run/containerd//opt/hostedtoolcache/go/1.25.7/x64/pkg/tool/linux_amd64/vet
--log-format json 1a2fc60e6817294b-buildtags /usr�� --root
/var/run/docker/-ifaceassert by/7842e098fbefc-nilfunc
/run/containerd/bash 1a2fc60e6817294b/usr/bin/runc json
1a2fc60e6817294b-tests` (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>
lpcox added a commit that referenced this pull request Mar 11, 2026
## Summary

Eliminates ~71 lines of duplicate code across the DIFC package by
extracting two generic helpers. Addresses issue #1719 patterns 2 and 3
(pattern 1 was previously resolved).

## Changes

### CheckFlow Consolidation (`labels.go`)

**Problem**: `SecrecyLabel.CheckFlow` and `IntegrityLabel.CheckFlow`
contained 58 lines of nearly identical nil handling, locking, and tag
iteration logic with only semantic differences (subset vs superset
checks).

**Solution**: Extracted `checkFlowHelper` that parameterizes flow
semantics:

```go
// Generic helper with parameterized semantics
func checkFlowHelper(srcLabel *Label, targetLabel *Label, checkSubset bool, labelType string) (bool, []Tag)

// Thin wrappers (10 lines each)
func (l *SecrecyLabel) CheckFlow(target *SecrecyLabel) (bool, []Tag) {
    return checkFlowHelper(l.Label, target.Label, true, "Secrecy")  // subset check
}

func (l *IntegrityLabel) CheckFlow(target *IntegrityLabel) (bool, []Tag) {
    return checkFlowHelper(l.Label, target.Label, false, "Integrity")  // superset check
}
```

### EvaluationResult Initialization (`evaluator.go`)

**Problem**: Three evaluation functions repeated identical 5-line
initialization blocks.

**Solution**: Extracted `newEmptyEvaluationResult()` helper used by
`Evaluate`, `evaluateRead`, and `evaluateWrite`.

## Testing

- Added 12 comprehensive test cases for new helpers
- All existing tests pass (100+ in difc package)
- No behavior changes

> [!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-build817523219/b332/launcher.test
/tmp/go-build817523219/b332/launcher.test
-test.testlogfile=/tmp/go-build817523219/b332/testlog.txt
-test.paniconexit0 -test.timeout=10m0s -test.v=true
ache/go/1.25.7/x64/src/runtime/c-errorsas J4aB/2fPHF0HdMhn8ydxhJ4aB
64/pkg/tool/linux_amd64/vet -I /tmp/go-build151-n -I
64/pkg/tool/linux_amd64/vet go_.�� 8036719/b171=/tmp/go-build .cfg
64/pkg/tool/linux_amd64/vet -p ache/go/1.25.7/x-d -lang=go1.16
64/pkg/tool/linux_amd64/vet` (dns block)
> - Triggering command: `/tmp/go-build2582390263/b336/launcher.test
/tmp/go-build2582390263/b336/launcher.test
-test.testlogfile=/tmp/go-build2582390263/b336/testlog.txt
-test.paniconexit0 -test.timeout=10m0s [
�� --prefix=/net/ipv4/neigh/veth8c3e74e
--prefix=/net/ipv6/conf/veth8c3e74e ache/uv/0.10.9/x86_64/git --64
ache/go/1.25.7/x-d /snap/bin/git bash /usr�� --root
/var/run/docker/runtime-runc/moby 64/pkg/tool/linux_amd64/vet
/run/containerd/bash --log-format 619fd60bb04098d5--version
64/pkg/tool/linux_amd64/vet` (dns block)
> - `invalid-host-that-does-not-exist-12345.com`
> - Triggering command: `/tmp/go-build817523219/b314/config.test
/tmp/go-build817523219/b314/config.test
-test.testlogfile=/tmp/go-build817523219/b314/testlog.txt
-test.paniconexit0 -test.timeout=10m0s -test.v=true o QT x_amd64/vet -p
g/x/net/idna -lang=go1.25 x_amd64/vet go_.�� 64/src/net
ache/go/1.25.7/x64/src/runtime/c-nolocalimports
ache/go/1.25.7/x64/pkg/tool/linu-importcfg 8036719/b171/
crypto/internal/-d` (dns block)
> - Triggering command: `/tmp/go-build2582390263/b318/config.test
/tmp/go-build2582390263/b318/config.test
-test.testlogfile=/tmp/go-build2582390263/b318/testlog.txt
-test.paniconexit0 -test.timeout=10m0s e755�� moby -address x_amd64/vet
-publish-binary
/usr/bin/contain/home/REDACTED/work/_temp/ghcca-node/node -id
x_amd64/vet de/n��
/run/containerd/io.containerd.runtime.v2.task/moby/d20f582628202OUTPUT
delete /opt/containerd/bin/bash s-through=-lpthrbase64
ache/go/1.25.7/x-d ine bash` (dns block)
> - `nonexistent.local`
> - Triggering command: `/tmp/go-build817523219/b332/launcher.test
/tmp/go-build817523219/b332/launcher.test
-test.testlogfile=/tmp/go-build817523219/b332/testlog.txt
-test.paniconexit0 -test.timeout=10m0s -test.v=true
ache/go/1.25.7/x64/src/runtime/c-errorsas J4aB/2fPHF0HdMhn8ydxhJ4aB
64/pkg/tool/linux_amd64/vet -I /tmp/go-build151-n -I
64/pkg/tool/linux_amd64/vet go_.�� 8036719/b171=/tmp/go-build .cfg
64/pkg/tool/linux_amd64/vet -p ache/go/1.25.7/x-d -lang=go1.16
64/pkg/tool/linux_amd64/vet` (dns block)
> - Triggering command: `/tmp/go-build2582390263/b336/launcher.test
/tmp/go-build2582390263/b336/launcher.test
-test.testlogfile=/tmp/go-build2582390263/b336/testlog.txt
-test.paniconexit0 -test.timeout=10m0s [
�� --prefix=/net/ipv4/neigh/veth8c3e74e
--prefix=/net/ipv6/conf/veth8c3e74e ache/uv/0.10.9/x86_64/git --64
ache/go/1.25.7/x-d /snap/bin/git bash /usr�� --root
/var/run/docker/runtime-runc/moby 64/pkg/tool/linux_amd64/vet
/run/containerd/bash --log-format 619fd60bb04098d5--version
64/pkg/tool/linux_amd64/vet` (dns block)
> - `slow.example.com`
> - Triggering command: `/tmp/go-build817523219/b332/launcher.test
/tmp/go-build817523219/b332/launcher.test
-test.testlogfile=/tmp/go-build817523219/b332/testlog.txt
-test.paniconexit0 -test.timeout=10m0s -test.v=true
ache/go/1.25.7/x64/src/runtime/c-errorsas J4aB/2fPHF0HdMhn8ydxhJ4aB
64/pkg/tool/linux_amd64/vet -I /tmp/go-build151-n -I
64/pkg/tool/linux_amd64/vet go_.�� 8036719/b171=/tmp/go-build .cfg
64/pkg/tool/linux_amd64/vet -p ache/go/1.25.7/x-d -lang=go1.16
64/pkg/tool/linux_amd64/vet` (dns block)
> - Triggering command: `/tmp/go-build2582390263/b336/launcher.test
/tmp/go-build2582390263/b336/launcher.test
-test.testlogfile=/tmp/go-build2582390263/b336/testlog.txt
-test.paniconexit0 -test.timeout=10m0s [
�� --prefix=/net/ipv4/neigh/veth8c3e74e
--prefix=/net/ipv6/conf/veth8c3e74e ache/uv/0.10.9/x86_64/git --64
ache/go/1.25.7/x-d /snap/bin/git bash /usr�� --root
/var/run/docker/runtime-runc/moby 64/pkg/tool/linux_amd64/vet
/run/containerd/bash --log-format 619fd60bb04098d5--version
64/pkg/tool/linux_amd64/vet` (dns block)
> - `this-host-does-not-exist-12345.com`
> - Triggering command: `/tmp/go-build817523219/b341/mcp.test
/tmp/go-build817523219/b341/mcp.test
-test.testlogfile=/tmp/go-build817523219/b341/testlog.txt
-test.paniconexit0 -test.timeout=10m0s -test.v=true
p=/opt/hostedtoolcache/go/1.25.7/x64=/_/GOROOT .cfg
64/pkg/tool/linux_amd64/vet --gdwarf-5 --64 -o
64/pkg/tool/linux_amd64/vet 8036�� /server/auth.go /server/handlers.go
64/pkg/tool/linux_amd64/vet /tmp/go-build151/usr/bin/runc.original
-imultiarch x86_64-linux-gnu 64/pkg/tool/linux_amd64/vet` (dns block)
> - Triggering command: `/tmp/go-build2582390263/b345/mcp.test
/tmp/go-build2582390263/b345/mcp.test
-test.testlogfile=/tmp/go-build2582390263/b345/testlog.txt
-test.paniconexit0 -test.timeout=10m0s crea��
b1f0f2a3ed4d89922f26e357de08e619fd60bb04098d570e
/run/containerd/io.containerd.runtime.v2.task/moby/f41fcf883e64cbb1a392bb10395bbjson
64/pkg/tool/linux_amd64/vet /run/containerd//usr/bin/runc.original l ||
true &amp;&amp; eva--version /usr/bin/base64 64/pkg/tool/linux_amd64/vet
/usr�� .cfg /var/run/docker/runtime-runc/moby
64/pkg/tool/linux_amd64/vet /run/containerd/bash --log-format json with
other checks...&#34;; \
elif command -v golan` (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>
lpcox added a commit that referenced this pull request Mar 13, 2026
Addresses duplicate code analysis identifying ~50 lines of structural
duplication across two patterns in `internal/server/unified.go`.

## Changes

### Pattern 1: Backend Tool Call Execution (~40 lines eliminated)

Extracted `executeBackendToolCall` helper consolidating:
- Connection management via `launcher.GetOrLaunchForSession`
- `tools/call` request dispatch
- Backend error checking
- Result unmarshaling

**Before:**
```go
// guardBackendCaller.CallTool and callBackendTool Phase 3 each had:
conn, err := launcher.GetOrLaunchForSession(us.launcher, serverID, sessionID)
if err != nil { ... }
response, err := conn.SendRequestWithServerID(ctx, "tools/call", ...)
if err != nil { ... }
if response.Error != nil { ... }
var result interface{}
json.Unmarshal(response.Result, &result)
```

**After:**
```go
result, err := executeBackendToolCall(ctx, us.launcher, serverID, sessionID, toolName, args)
```

### Pattern 2: Sys Tool Delegation (~10 lines eliminated)

Extracted `callSysServer` helper consolidating:
- Tool name marshaling
- `sysServer.HandleRequest` delegation

**Before:**
```go
// sysInitHandler and sysListHandler each had:
params, _ := json.Marshal(map[string]interface{}{
    "name": toolName,
    "arguments": map[string]interface{}{},
})
result, err := us.sysServer.HandleRequest("tools/call", json.RawMessage(params))
```

**After:**
```go
result, err := us.callSysServer("sys_init")
```

## Impact

- Eliminates copy-paste error risk when modifying backend call or sys
server logic
- Follows existing helper patterns (`newErrorCallToolResult`,
`parseToolArguments`)
- No functional changes—pure refactoring

> [!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-build4242760615/b336/launcher.test
/tmp/go-build4242760615/b336/launcher.test
-test.testlogfile=/tmp/go-build4242760615/b336/testlog.txt
-test.paniconexit0 -test.timeout=10m0s -uns�� ache/go/1.25.7/x64/src/net
/tmp/go-build1249286257/b024/vet.cfg
ache/go/1.25.7/x64/pkg/tool/linux_amd64/vet unset position.go
.12/x64/bin/git ache/go/1.25.7/x64/pkg/tool/linuHEAD -W -I
/tmp/go-build1249286257/b165/
ache/go/1.25.7/x64/pkg/tool/linux_amd64/compile . --gdwarf2 --64
ache/go/1.25.7/x64/pkg/tool/linux_amd64/compile` (dns block)
> - Triggering command: `/tmp/go-build2320097585/b332/launcher.test
/tmp/go-build2320097585/b332/launcher.test
-test.testlogfile=/tmp/go-build2320097585/b332/testlog.txt
-test.paniconexit0 -test.timeout=10m0s -test.v=true 64/bin/git ortcfg
/usr/sbin/bash submodules | heanode 9286257/b132/vet-v ndor/bin/git bash
/usr�� runtime-runc/moby ortcfg csi/net-interface-handler
aw-mcpg/internal/opt/hostedtoolcache/go/1.25.7/x64/pkg/tool/linux_amd64/asm
aw-mcpg/internal-V=full` (dns block)
> - `invalid-host-that-does-not-exist-12345.com`
> - Triggering command: `/tmp/go-build4242760615/b318/config.test
/tmp/go-build4242760615/b318/config.test
-test.testlogfile=/tmp/go-build4242760615/b318/testlog.txt
-test.paniconexit0 -test.timeout=10m0s --de�� c.test --debug-prefix-map
64/bin/git -I /opt/hostedtoolc-unsafeptr=false ut-1969789729.c
VF78F_aidvBPXKXaKR/S4HB-3OSyH3DKHEAD` (dns block)
> - Triggering command: `/tmp/go-build2320097585/b314/config.test
/tmp/go-build2320097585/b314/config.test
-test.testlogfile=/tmp/go-build2320097585/b314/testlog.txt
-test.paniconexit0 -test.timeout=10m0s -test.v=true 17fb9960acf3cdef
-importcfg ine by/b2276789a3c14/usr/bin/chronyc -w -buildmode=exe ine
--ve�� 85e4fa5c5748c5dd -extld=gcc /opt/hostedtoolcache/go/1.25.7/xjson
aw-mcpg/internalbase64 9286257/b151/vet-d ns
/opt/hostedtoolcache/go/1.25.7/x64/pkg/tool/linu--listen` (dns block)
> - `nonexistent.local`
> - Triggering command: `/tmp/go-build4242760615/b336/launcher.test
/tmp/go-build4242760615/b336/launcher.test
-test.testlogfile=/tmp/go-build4242760615/b336/testlog.txt
-test.paniconexit0 -test.timeout=10m0s -uns�� ache/go/1.25.7/x64/src/net
/tmp/go-build1249286257/b024/vet.cfg
ache/go/1.25.7/x64/pkg/tool/linux_amd64/vet unset position.go
.12/x64/bin/git ache/go/1.25.7/x64/pkg/tool/linuHEAD -W -I
/tmp/go-build1249286257/b165/
ache/go/1.25.7/x64/pkg/tool/linux_amd64/compile . --gdwarf2 --64
ache/go/1.25.7/x64/pkg/tool/linux_amd64/compile` (dns block)
> - Triggering command: `/tmp/go-build2320097585/b332/launcher.test
/tmp/go-build2320097585/b332/launcher.test
-test.testlogfile=/tmp/go-build2320097585/b332/testlog.txt
-test.paniconexit0 -test.timeout=10m0s -test.v=true 64/bin/git ortcfg
/usr/sbin/bash submodules | heanode 9286257/b132/vet-v ndor/bin/git bash
/usr�� runtime-runc/moby ortcfg csi/net-interface-handler
aw-mcpg/internal/opt/hostedtoolcache/go/1.25.7/x64/pkg/tool/linux_amd64/asm
aw-mcpg/internal-V=full` (dns block)
> - `slow.example.com`
> - Triggering command: `/tmp/go-build4242760615/b336/launcher.test
/tmp/go-build4242760615/b336/launcher.test
-test.testlogfile=/tmp/go-build4242760615/b336/testlog.txt
-test.paniconexit0 -test.timeout=10m0s -uns�� ache/go/1.25.7/x64/src/net
/tmp/go-build1249286257/b024/vet.cfg
ache/go/1.25.7/x64/pkg/tool/linux_amd64/vet unset position.go
.12/x64/bin/git ache/go/1.25.7/x64/pkg/tool/linuHEAD -W -I
/tmp/go-build1249286257/b165/
ache/go/1.25.7/x64/pkg/tool/linux_amd64/compile . --gdwarf2 --64
ache/go/1.25.7/x64/pkg/tool/linux_amd64/compile` (dns block)
> - Triggering command: `/tmp/go-build2320097585/b332/launcher.test
/tmp/go-build2320097585/b332/launcher.test
-test.testlogfile=/tmp/go-build2320097585/b332/testlog.txt
-test.paniconexit0 -test.timeout=10m0s -test.v=true 64/bin/git ortcfg
/usr/sbin/bash submodules | heanode 9286257/b132/vet-v ndor/bin/git bash
/usr�� runtime-runc/moby ortcfg csi/net-interface-handler
aw-mcpg/internal/opt/hostedtoolcache/go/1.25.7/x64/pkg/tool/linux_amd64/asm
aw-mcpg/internal-V=full` (dns block)
> - `this-host-does-not-exist-12345.com`
> - Triggering command: `/tmp/go-build4242760615/b345/mcp.test
/tmp/go-build4242760615/b345/mcp.test
-test.testlogfile=/tmp/go-build4242760615/b345/testlog.txt
-test.paniconexit0 -test.timeout=10m0s -I ache/go/1.25.7/x64/src/net -I
if (a[i] &amp;&amp; a[i] !~ /^[0-9]&#43;$/) exit(2);
      if (a[i] &lt; b[i]) exit(3);
else if (a[i] &gt; b[i]) exit(0) --gdwarf-5 --64 -o
ache/go/1.25.7/x64/pkg/tool/linuHEAD -o
/tmp/go-build1249286257/b210/_pkg_.a -trimpath
ache/go/1.25.7/x64/pkg/tool/linux_amd64/vet -p
github.com/githu/tmp/go-build3632611954/b228/vet.cfg -lang=go1.25
ache/go/1.25.7/x64/pkg/tool/linux_amd64/vet` (dns block)
> - Triggering command: `/tmp/go-build2320097585/b341/mcp.test
/tmp/go-build2320097585/b341/mcp.test
-test.testlogfile=/tmp/go-build2320097585/b341/testlog.txt
-test.paniconexit0 -test.timeout=10m0s -test.v=true
/home/REDACTED/work/gh-aw-mcpg/gh-aw-mcpg/internal/strutil/truncat6662819a7d6931901c1593745131476bbash
y CURL_CA_BUNDLE=/etc/ssl/certs/ca-certificates.crt&#34;,
&#34;REQUESTS_CA_BUNDLE=/etc/ssl/c--version
by/bd0209c110101/opt/hostedtoolcache/go/1.25.7/x64/pkg/tool/linux_amd64/link
aw-mcpg/internal-o
ache/go/1.25.7/x/tmp/go-build2320097585/b314/config.test docker insp��
551622d230bb31fc-s by/bd0209c110101-w rtificates.crt&#34;,-buildmode=exe
by/a501e7528e5b9bash e330148d0ce51d5e/usr/bin/runc` (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>
lpcox added a commit that referenced this pull request Mar 19, 2026
…edup logic (#2123)

The trim→skip-empty→deduplicate→optional-sort pattern was reimplemented
inline in three separate packages, with behavioral drift already present
(silent skip vs. error on duplicate, whitespace rejection in one but not
others).

## Changes

- **`internal/strutil/deduplicate.go`** — new `DeduplicateStrings(input
[]string, sorted bool) []string` canonical helper
- **`internal/strutil/deduplicate_test.go`** — table-driven tests
covering nil input, trim, dedup, sort, and order preservation
- **`internal/difc/sink_server_ids.go`** — replace 14-line inline loop
with `strutil.DeduplicateStrings(serverIDs, true)`; log when entries are
dropped
- **`internal/cmd/flags_difc.go`** — `parseDIFCSinkServerIDs`: keep the
embedded-whitespace error check (not handled by the helper), delegate
dedup to `strutil.DeduplicateStrings`
- **`internal/config/guard_policy.go`** — unchanged;
`normalizeAndValidateScopeArray` returns an error on duplicates rather
than silently dropping them, so it doesn't share the same contract

## Before / After

```go
// Before — ~15 lines repeated inline in SetSinkServerIDs
unique := make(map[string]struct{}, len(serverIDs))
normalized := make([]string, 0, len(serverIDs))
for _, serverID := range serverIDs {
    trimmed := strings.TrimSpace(serverID)
    if trimmed == "" { continue }
    if _, exists := unique[trimmed]; exists {
        duplicateIDs = append(duplicateIDs, trimmed)
        continue
    }
    unique[trimmed] = struct{}{}
    normalized = append(normalized, trimmed)
}
sort.Strings(normalized)

// After
normalized := strutil.DeduplicateStrings(serverIDs, true)
```

> [!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-build1731765213/b332/launcher.test
/tmp/go-build1731765213/b332/launcher.test
-test.testlogfile=/tmp/go-build1731765213/b332/testlog.txt
-test.paniconexit0 -test.timeout=10m0s conf�� 1.4.0/auth/auth.go
1.4.0/auth/client.go x_amd64/compile` (dns block)
> - Triggering command: `/tmp/go-build908205860/b328/launcher.test
/tmp/go-build908205860/b328/launcher.test
-test.testlogfile=/tmp/go-build908205860/b328/testlog.txt
-test.paniconexit0 -test.timeout=10m0s -test.v=true --version y
06bc07c272bb18e2 ntime.v2.task/mosystemd-run containerd.sock x_amd64/vet
ctl insp�� .go {{.Config.OpenSt--property=CPUQuota=5%
/usr/libexec/doc--property=MemoryHigh=170M 64/src/net
ache/go/1.25.8/xinfo x_amd64/vet 45045761271a86c7-collect-logs` (dns
block)
> - `invalid-host-that-does-not-exist-12345.com`
> - Triggering command: `/tmp/go-build1731765213/b317/config.test
/tmp/go-build1731765213/b317/config.test
-test.testlogfile=/tmp/go-build1731765213/b317/testlog.txt
-test.paniconexit0 -test.timeout=10m0s conf�� .go` (dns block)
> - Triggering command: `/tmp/go-build908205860/b313/config.test
/tmp/go-build908205860/b313/config.test
-test.testlogfile=/tmp/go-build908205860/b313/testlog.txt
-test.paniconexit0 -test.timeout=10m0s -test.v=true 9c9123b84b4d4e8c
-tests ash b8a4de3a75e76448grep fe9 x_amd64/compile fe9/init.pid --ve��
c48959766ef0f63f b8a4de3a75e764483c627dce6b038343b5b6efe353b9d178502
&#34;CURL_CA_BUNDLE=/--systemd-cgroup b8a4de3a75e76448git` (dns block)
> - `nonexistent.local`
> - Triggering command: `/tmp/go-build1731765213/b332/launcher.test
/tmp/go-build1731765213/b332/launcher.test
-test.testlogfile=/tmp/go-build1731765213/b332/testlog.txt
-test.paniconexit0 -test.timeout=10m0s conf�� 1.4.0/auth/auth.go
1.4.0/auth/client.go x_amd64/compile` (dns block)
> - Triggering command: `/tmp/go-build908205860/b328/launcher.test
/tmp/go-build908205860/b328/launcher.test
-test.testlogfile=/tmp/go-build908205860/b328/testlog.txt
-test.paniconexit0 -test.timeout=10m0s -test.v=true --version y
06bc07c272bb18e2 ntime.v2.task/mosystemd-run containerd.sock x_amd64/vet
ctl insp�� .go {{.Config.OpenSt--property=CPUQuota=5%
/usr/libexec/doc--property=MemoryHigh=170M 64/src/net
ache/go/1.25.8/xinfo x_amd64/vet 45045761271a86c7-collect-logs` (dns
block)
> - `slow.example.com`
> - Triggering command: `/tmp/go-build1731765213/b332/launcher.test
/tmp/go-build1731765213/b332/launcher.test
-test.testlogfile=/tmp/go-build1731765213/b332/testlog.txt
-test.paniconexit0 -test.timeout=10m0s conf�� 1.4.0/auth/auth.go
1.4.0/auth/client.go x_amd64/compile` (dns block)
> - Triggering command: `/tmp/go-build908205860/b328/launcher.test
/tmp/go-build908205860/b328/launcher.test
-test.testlogfile=/tmp/go-build908205860/b328/testlog.txt
-test.paniconexit0 -test.timeout=10m0s -test.v=true --version y
06bc07c272bb18e2 ntime.v2.task/mosystemd-run containerd.sock x_amd64/vet
ctl insp�� .go {{.Config.OpenSt--property=CPUQuota=5%
/usr/libexec/doc--property=MemoryHigh=170M 64/src/net
ache/go/1.25.8/xinfo x_amd64/vet 45045761271a86c7-collect-logs` (dns
block)
> - `this-host-does-not-exist-12345.com`
> - Triggering command: `/tmp/go-build1731765213/b341/mcp.test
/tmp/go-build1731765213/b341/mcp.test
-test.testlogfile=/tmp/go-build1731765213/b341/testlog.txt
-test.paniconexit0 -test.timeout=10m0s
/tmp/go-build1731765213/b271/vet.cfg flib/difflib.go main x_amd64/cgo`
(dns block)
> - Triggering command: `/tmp/go-build908205860/b337/mcp.test
/tmp/go-build908205860/b337/mcp.test
-test.testlogfile=/tmp/go-build908205860/b337/testlog.txt
-test.paniconexit0 -test.timeout=10m0s -test.v=true y x_amd64/vet
by/027a141771b2cb8a4de3a75e764483c627dce6b038343b5b6efe353b9d178502/log.json
azero@v1.11.0/bugrep azero@v1.11.0/ca-qE x_amd64/vet 709/log.json 92b4��
by/027a141771b2cb8a4de3a75e764483c627dce6b038343b5b6efe353b9d178502
--bundle
by/027a141771b2cb8a4de3a75e764483c627dce6b038343b5b6efe353b9d178502/init.pid
6efe353b9d178502bash 77a1358e1f687d17/usr/bin/runc x_amd64/vet
table.d/chrony-onoffline` (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>

<!-- START COPILOT CODING AGENT TIPS -->
---

📍 Connect Copilot coding agent with [Jira](https://gh.io/cca-jira-docs),
[Azure Boards](https://gh.io/cca-azure-boards-docs) or
[Linear](https://gh.io/cca-linear-docs) to delegate work to Copilot in
one click without leaving your project management tool.
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.

2 participants