forked from github/github-mcp-server
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathrepository_resource.go
More file actions
122 lines (104 loc) · 4.22 KB
/
repository_resource.go
File metadata and controls
122 lines (104 loc) · 4.22 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
package github
import (
"context"
"encoding/base64"
"mime"
"path/filepath"
"strings"
"github.com/github/github-mcp-server/pkg/translations"
"github.com/google/go-github/v69/github"
"github.com/mark3labs/mcp-go/mcp"
"github.com/mark3labs/mcp-go/server"
)
// getRepositoryContent defines the resource template and handler for the Repository Content API.
func getRepositoryContent(client *github.Client, t translations.TranslationHelperFunc) (mainTemplate mcp.ResourceTemplate, reftemplate mcp.ResourceTemplate, shaTemplate mcp.ResourceTemplate, tagTemplate mcp.ResourceTemplate, prTemplate mcp.ResourceTemplate, handler server.ResourceTemplateHandlerFunc) {
return mcp.NewResourceTemplate(
"repo://{owner}/{repo}/contents{/path*}", // Resource template
t("RESOURCE_REPOSITORY_CONTENT_DESCRIPTION", "Repository Content"),
), mcp.NewResourceTemplate(
"repo://{owner}/{repo}/refs/heads/{branch}/contents{/path*}", // Resource template
t("RESOURCE_REPOSITORY_CONTENT_BRANCH_DESCRIPTION", "Repository Content for specific branch"),
), mcp.NewResourceTemplate(
"repo://{owner}/{repo}/sha/{sha}/contents{/path*}", // Resource template
t("RESOURCE_REPOSITORY_CONTENT_COMMIT_DESCRIPTION", "Repository Content for specific commit"),
), mcp.NewResourceTemplate(
"repo://{owner}/{repo}/refs/tags/{tag}/contents{/path*}", // Resource template
t("RESOURCE_REPOSITORY_CONTENT_TAG_DESCRIPTION", "Repository Content for specific tag"),
), mcp.NewResourceTemplate(
"repo://{owner}/{repo}/refs/pull/{pr_number}/head/contents{/path*}", // Resource template
t("RESOURCE_REPOSITORY_CONTENT_PR_DESCRIPTION", "Repository Content for specific pull request"),
), func(ctx context.Context, request mcp.ReadResourceRequest) ([]mcp.ResourceContents, error) {
// Extract parameters from request.Params.URI
owner := request.Params.Arguments["owner"].([]string)[0]
repo := request.Params.Arguments["repo"].([]string)[0]
// path should be a joined list of the path parts
path := strings.Join(request.Params.Arguments["path"].([]string), "/")
opts := &github.RepositoryContentGetOptions{}
sha, ok := request.Params.Arguments["sha"].([]string)
if ok {
opts.Ref = sha[0]
}
branch, ok := request.Params.Arguments["branch"].([]string)
if ok {
opts.Ref = "refs/heads/" + branch[0]
}
tag, ok := request.Params.Arguments["tag"].([]string)
if ok {
opts.Ref = "refs/tags/" + tag[0]
}
prNumber, ok := request.Params.Arguments["pr_number"].([]string)
if ok {
opts.Ref = "refs/pull/" + prNumber[0] + "/head"
}
// Use the GitHub client to fetch repository content
fileContent, directoryContent, _, err := client.Repositories.GetContents(ctx, owner, repo, path, opts)
if err != nil {
return nil, err
}
if directoryContent != nil {
// Process the directory content and return it as resource contents
var resources []mcp.ResourceContents
for _, entry := range directoryContent {
mimeType := "text/directory"
if entry.GetType() == "file" {
mimeType = mime.TypeByExtension(filepath.Ext(entry.GetName()))
}
resources = append(resources, mcp.TextResourceContents{
URI: entry.GetHTMLURL(),
MIMEType: mimeType,
Text: entry.GetName(),
})
}
return resources, nil
} else if fileContent != nil {
// Process the file content and return it as a binary resource
if fileContent.Content != nil {
decodedContent, err := fileContent.GetContent()
if err != nil {
return nil, err
}
mimeType := mime.TypeByExtension(filepath.Ext(fileContent.GetName()))
// Check if the file is text-based
if strings.HasPrefix(mimeType, "text") {
// Return as TextResourceContents
return []mcp.ResourceContents{
mcp.TextResourceContents{
URI: request.Params.URI,
MIMEType: mimeType,
Text: decodedContent,
},
}, nil
}
// Otherwise, return as BlobResourceContents
return []mcp.ResourceContents{
mcp.BlobResourceContents{
URI: request.Params.URI,
MIMEType: mimeType,
Blob: base64.StdEncoding.EncodeToString([]byte(decodedContent)), // Encode content as Base64
},
}, nil
}
}
return nil, nil
}
}