Skip to content

Commit 0e6f1b2

Browse files
committed
Further instructions and remove debugging printfs
Signed-off-by: Ed Snible <snible@us.ibm.com>
1 parent 9857d30 commit 0e6f1b2

2 files changed

Lines changed: 52 additions & 14 deletions

File tree

mcp/github_tool/README.md

Lines changed: 41 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -126,10 +126,10 @@ oc -n team1 get configmap environments -o yaml > /tmp/environments.yaml
126126
```YAML
127127
data:
128128
UPSTREAM_MCP: https://api.githubcopilot.com/mcp/
129-
REQUIRED_SCOPE=profile
129+
REQUIRED_SCOPE: profile
130130
INIT_AUTH_HEADER: Bearer ${GITHUB_TOKEN}
131-
UPSTREAM_HEADER_TO_USE_IF_IN_AUDIENCE=Bearer $GITHUB_TOKEN
132-
UPSTREAM_HEADER_TO_USE_IF_NOT_IN_AUDIENCE=Bearer rutabaga
131+
UPSTREAM_HEADER_TO_USE_IF_IN_AUDIENCE: Bearer $GITHUB_TOKEN
132+
UPSTREAM_HEADER_TO_USE_IF_NOT_IN_AUDIENCE: Bearer rutabaga
133133
```
134134
135135
After adding the new env vars, apply to Kagenti using `kubectl apply -n team1 -f /tmp/environments.yaml`.
@@ -141,3 +141,41 @@ Now that the environment variables are available, start an instance of the tool
141141
- Set the Target Port to 9090
142142
- Specify Subfolder `mcp/github_tool`
143143
- Click "Build & Deploy New Tool" to deploy.
144+
145+
Once the tool is deployed, if you wish to test it from outside Kagenti you'll need to create an HTTPRoute for it.
146+
147+
```bash
148+
cat <<EOF | > /tmp/expose-github-tool.yaml
149+
apiVersion: gateway.networking.k8s.io/v1
150+
kind: HTTPRoute
151+
metadata:
152+
labels:
153+
mcp-server: "true"
154+
name: github-route-ext
155+
namespace: team1
156+
spec:
157+
hostnames:
158+
- github-tool.127-0-0-1.sslip.io
159+
parentRefs:
160+
- group: gateway.networking.k8s.io
161+
kind: Gateway
162+
name: mcp-gateway
163+
namespace: gateway-system
164+
rules:
165+
- backendRefs:
166+
- group: ""
167+
kind: Service
168+
name: github-tool
169+
port: 8000
170+
weight: 1
171+
matches:
172+
- path:
173+
type: PathPrefix
174+
value: /
175+
EOF
176+
oc --context kind-agent-platform apply -f /tmp/expose-github-tool.yaml
177+
```
178+
179+
At this point, you can do the MCP curls above if you define `MCP=http://github-tool.127-0-0-1.sslip.io:8888/mcp`
180+
181+

mcp/github_tool/gtlib/upstream.go

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -134,10 +134,10 @@ func MakeUpstream(mcpServerURL, initAuthHeader string) (*client.Client, context.
134134
defer cancel()
135135
return nil, nil, fmt.Errorf("initialization failed %w", err)
136136
}
137-
fmt.Printf("@@@ ecs initResult=%v\n", initResult)
137+
fmt.Printf("initResult=%v\n", initResult)
138138

139139
clientTransport := httpClient.GetTransport()
140-
fmt.Printf("@@@ ecs transport is %v, a %T\n", clientTransport, clientTransport)
140+
fmt.Printf("transport is %v, a %T\n", clientTransport, clientTransport)
141141
streamableHttpTransport, ok := clientTransport.(*transport.StreamableHTTP)
142142
if ok {
143143
streamableHttpTransport.SetNotificationHandler(func(notification mcp.JSONRPCNotification) {
@@ -185,9 +185,9 @@ func toolToServerTool(m *mcpAuthImpl, newTool mcp.Tool) server.ServerTool {
185185
return server.ServerTool{
186186
Tool: newTool,
187187
Handler: func(ctx context.Context, request mcp.CallToolRequest) (*mcp.CallToolResult, error) {
188-
fmt.Printf("@@@ ecs in Handler, request.Header is %#v, a %T\n", request.Header, request.Header)
188+
fmt.Printf("In Handler, request.Header is %#v, a %T\n", request.Header, request.Header)
189189
for k, v := range request.Header {
190-
fmt.Printf("@@@ ecs Found header %s: %v\n", k, v)
190+
fmt.Printf("Found header %s: %v\n", k, v)
191191
}
192192
result, err := m.CallTool(ctx,
193193
downstreamSessionID(request.Header.Get("Mcp-Session-Id")),
@@ -420,10 +420,10 @@ func getAuthorizationHeaderFromBearer(auth string) string {
420420
// return os.Getenv(fmt.Sprintf("GITHUB_TOKEN_for_%s", decodedToken["preferred_username"]))
421421

422422
if scopeMatches {
423-
fmt.Printf("@@@ ecs the REQUIRED_SCOPE %q in scopes %v\n", requiredScope, scopes)
423+
fmt.Printf("The REQUIRED_SCOPE %q in scopes %v\n", requiredScope, scopes)
424424
return os.Getenv("UPSTREAM_HEADER_TO_USE_IF_IN_AUDIENCE")
425425
} else {
426-
fmt.Printf("@@@ ecs the REQUIRED_SCOPE %q NOT IN scopes %v\n", requiredScope, scopes)
426+
fmt.Printf("The REQUIRED_SCOPE %q NOT IN scopes %v\n", requiredScope, scopes)
427427
return os.Getenv("UPSTREAM_HEADER_TO_USE_IF_NOT_IN_AUDIENCE")
428428
}
429429

@@ -437,14 +437,14 @@ func getAuthorizationHeaderFromBearer(auth string) string {
437437
438438
// Validate the signing method and return the secret key
439439
if hmacToken, ok := token.Method.(*jwt.SigningMethodHMAC); ok {
440-
fmt.Printf("@@@ ecs got HMAC token %#v\n", hmacToken)
440+
fmt.Printf("Got HMAC token %#v\n", hmacToken)
441441
secretKey := "a-string-secret-at-least-256-bits-long" // TODO
442442
return secretKey, nil
443443
}
444444
445445
// FYI Keycloak bearer tokens are signed with jwt.SigningMethodRSA, not SigningMethodHMAC
446446
if rsaToken, ok := token.Method.(*jwt.SigningMethodRSA); ok {
447-
fmt.Printf("@@@ ecs got RSA token %#v\n", rsaToken)
447+
fmt.Printf("Got RSA token %#v\n", rsaToken)
448448
449449
// A fast way to validate is to follow the steps of
450450
// https://stackoverflow.com/questions/77838958/go-validate-access-token-keycloak
@@ -462,10 +462,10 @@ func getAuthorizationHeaderFromBearer(auth string) string {
462462
return nil, fmt.Errorf("unexpected signing method: %v", token.Header["alg"])
463463
})
464464
if err != nil {
465-
fmt.Printf("@@@ ecs could not parse JWT, failed with %v\n", err)
465+
fmt.Printf("Could not parse JWT, failed with %v\n", err)
466466
} else {
467-
fmt.Printf("@@@ ecs parsed into parsedToken %#v, a %T\n", parsedToken, parsedToken)
468-
fmt.Printf("@@@ ecs claims is %#v\n", claims)
467+
fmt.Printf("Parsed into parsedToken %#v, a %T\n", parsedToken, parsedToken)
468+
fmt.Printf("Claims is %#v\n", claims)
469469
}
470470
471471
return "" // fail

0 commit comments

Comments
 (0)