Skip to content

Commit 9cc7192

Browse files
authored
feat(mcp): log tool call (hide sensitive HTTP headers) (#225)
Signed-off-by: Marc Nuri <marc@marcnuri.com>
1 parent be80db1 commit 9cc7192

File tree

2 files changed

+28
-4
lines changed

2 files changed

+28
-4
lines changed

pkg/mcp/mcp.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -190,7 +190,7 @@ func toolCallLoggingMiddleware(next server.ToolHandlerFunc) server.ToolHandlerFu
190190
klog.V(5).Infof("mcp tool call: %s(%v)", ctr.Params.Name, ctr.Params.Arguments)
191191
if ctr.Header != nil {
192192
buffer := bytes.NewBuffer(make([]byte, 0))
193-
if err := ctr.Header.Write(buffer); err == nil {
193+
if err := ctr.Header.WriteSubset(buffer, map[string]bool{"Authorization": true, "authorization": true}); err == nil {
194194
klog.V(7).Infof("mcp tool call headers: %s", buffer)
195195
}
196196
}

pkg/mcp/mcp_tools_test.go

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package mcp
22

33
import (
4+
"github.com/mark3labs/mcp-go/client/transport"
45
"github.com/mark3labs/mcp-go/mcp"
56
"k8s.io/utils/ptr"
67
"regexp"
@@ -140,16 +141,39 @@ func TestToolCallLogging(t *testing.T) {
140141
}
141142
})
142143
})
143-
testCaseWithContext(t, &mcpContext{logLevel: 7}, func(c *mcpContext) {
144+
before := func(c *mcpContext) {
145+
c.clientOptions = append(c.clientOptions, transport.WithHeaders(map[string]string{
146+
"Accept-Encoding": "gzip",
147+
"Authorization": "Bearer should-not-be-logged",
148+
"authorization": "Bearer should-not-be-logged",
149+
"a-loggable-header": "should-be-logged",
150+
}))
151+
}
152+
testCaseWithContext(t, &mcpContext{logLevel: 7, before: before}, func(c *mcpContext) {
144153
_, _ = c.callTool("configuration_view", map[string]interface{}{
145154
"minified": false,
146155
})
147156
t.Run("Logs tool call headers", func(t *testing.T) {
148-
expectedLog := "mcp tool call headers: Accept-Encoding: gzip"
157+
expectedLog := "mcp tool call headers: A-Loggable-Header: should-be-logged"
149158
if !strings.Contains(c.logBuffer.String(), expectedLog) {
150159
t.Errorf("Expected log to contain '%s', got: %s", expectedLog, c.logBuffer.String())
151160
}
152161
})
153-
162+
sensitiveHeaders := []string{
163+
"Authorization",
164+
// TODO: Add more sensitive headers as needed
165+
}
166+
t.Run("Does not log sensitive headers", func(t *testing.T) {
167+
for _, header := range sensitiveHeaders {
168+
if strings.Contains(c.logBuffer.String(), header) {
169+
t.Errorf("Log should not contain sensitive header '%s', got: %s", header, c.logBuffer.String())
170+
}
171+
}
172+
})
173+
t.Run("Does not log sensitive header values", func(t *testing.T) {
174+
if strings.Contains(c.logBuffer.String(), "should-not-be-logged") {
175+
t.Errorf("Log should not contain sensitive header value 'should-not-be-logged', got: %s", c.logBuffer.String())
176+
}
177+
})
154178
})
155179
}

0 commit comments

Comments
 (0)