37 lines
1.4 KiB
Go
37 lines
1.4 KiB
Go
package github
|
|
|
|
import (
|
|
"os"
|
|
"testing"
|
|
|
|
"github.com/github/github-mcp-server/pkg/toolvalidation"
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
// TestAllToolRegistrationsExplicitlySetReadOnlyHint statically scans every
|
|
// non-test Go source file in this package and asserts that every mcp.Tool
|
|
// composite literal explicitly sets Annotations.ReadOnlyHint.
|
|
//
|
|
// The AST scan itself lives in pkg/toolvalidation so downstream packages
|
|
// (e.g. github/github-mcp-server-remote) can apply the same guardrail to
|
|
// their own tool registrations without duplicating the parser logic.
|
|
//
|
|
// This complements TestAllToolsHaveRequiredMetadata, which can only check
|
|
// that Annotations is non-nil at runtime: Go cannot distinguish an unset
|
|
// bool field from one explicitly set to false. Source-level validation
|
|
// closes that gap and prevents future tool registrations from silently
|
|
// defaulting ReadOnlyHint to false (which has caused downstream agents to
|
|
// prompt for human approval on read-intent tools).
|
|
//
|
|
// Related issue: github/github-mcp-server#2483
|
|
func TestAllToolRegistrationsExplicitlySetReadOnlyHint(t *testing.T) {
|
|
pkgDir, err := os.Getwd()
|
|
require.NoError(t, err, "must be able to resolve package directory")
|
|
|
|
violations, err := toolvalidation.ScanReadOnlyHint(pkgDir)
|
|
require.NoError(t, err)
|
|
if len(violations) > 0 {
|
|
t.Fatal(toolvalidation.FormatReadOnlyHintViolations(violations))
|
|
}
|
|
}
|