Skip to content

Commit b8e222d

Browse files
feature: repo resource
1 parent 09366fa commit b8e222d

File tree

2 files changed

+88
-0
lines changed

2 files changed

+88
-0
lines changed

pkg/github/repository_resource.go

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
package github
2+
3+
import (
4+
"context"
5+
"encoding/base64"
6+
"fmt"
7+
"regexp"
8+
"strings"
9+
10+
"github.com/google/go-github/v69/github"
11+
"github.com/mark3labs/mcp-go/mcp"
12+
"github.com/mark3labs/mcp-go/server"
13+
)
14+
15+
// getRepositoryContent defines the resource template and handler for the Repository Content API.
16+
func getRepositoryContent(client *github.Client) (resourceTemplate mcp.ResourceTemplate, handler server.ResourceTemplateHandlerFunc) {
17+
return mcp.NewResourceTemplate(
18+
"repo://{owner}/{repo}/contents/{path*}", // Resource template
19+
"Repository Content", // Description
20+
), func(ctx context.Context, request mcp.ReadResourceRequest) ([]mcp.ResourceContents, error) {
21+
// Extract parameters from request.Params.URI
22+
uri := request.Params.URI
23+
re := regexp.MustCompile(`^repo://([^/]+)/([^/]+)/contents(.*)$`)
24+
matches := re.FindStringSubmatch(uri)
25+
26+
if len(matches) != 4 {
27+
return nil, fmt.Errorf("invalid URI format: %s", uri)
28+
}
29+
30+
owner := matches[1]
31+
repo := matches[2]
32+
path := strings.TrimPrefix(matches[3], "/") // Remove leading slash from path if present
33+
34+
// Use the GitHub client to fetch repository content
35+
fileContent, directoryContent, _, err := client.Repositories.GetContents(ctx, owner, repo, path, nil)
36+
if err != nil {
37+
return nil, err
38+
}
39+
40+
if directoryContent != nil {
41+
// Process the directory content and return it as resource contents
42+
var resources []mcp.ResourceContents
43+
for _, entry := range directoryContent {
44+
resources = append(resources, mcp.TextResourceContents{
45+
URI: entry.GetHTMLURL(),
46+
MIMEType: entry.GetType(),
47+
Text: entry.GetName(),
48+
})
49+
50+
}
51+
return resources, nil
52+
} else if fileContent != nil {
53+
// Process the file content and return it as a binary resource
54+
if fileContent.Content != nil {
55+
decodedContent, err := fileContent.GetContent()
56+
if err != nil {
57+
return nil, err
58+
}
59+
60+
// Check if the file is text-based
61+
if strings.HasPrefix(fileContent.GetType(), "file") {
62+
// Return as TextResourceContents
63+
return []mcp.ResourceContents{
64+
mcp.TextResourceContents{
65+
URI: request.Params.URI,
66+
MIMEType: fileContent.GetType(),
67+
Text: decodedContent,
68+
},
69+
}, nil
70+
}
71+
72+
// Otherwise, return as BlobResourceContents
73+
return []mcp.ResourceContents{
74+
mcp.BlobResourceContents{
75+
URI: request.Params.URI,
76+
MIMEType: fileContent.GetType(),
77+
Blob: base64.StdEncoding.EncodeToString([]byte(decodedContent)), // Encode content as Base64
78+
},
79+
}, nil
80+
}
81+
}
82+
83+
return nil, nil
84+
}
85+
}

pkg/github/server.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,9 @@ func NewServer(client *github.Client) *server.MCPServer {
2020
server.WithResourceCapabilities(true, true),
2121
server.WithLogging())
2222

23+
// Add GitHub Resources
24+
s.AddResourceTemplate(getRepositoryContent(client))
25+
2326
// Add GitHub tools - Issues
2427
s.AddTool(getIssue(client))
2528
s.AddTool(addIssueComment(client))

0 commit comments

Comments
 (0)