Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit0a19bf4

Browse files
authored
Migrate Repository Resources to the Go SDK (#1457)
* Migrate repo resources to Go SDK* Enable resources for repos* Properly handle encoding and closing of the buffer* Remove outdated comment* Switch to StdEncoding, as it was originally* fix casing for linter* Update licenses
1 parent1b769a5 commit0a19bf4

File tree

15 files changed

+250
-615
lines changed

15 files changed

+250
-615
lines changed

‎go.mod‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ require (
5353
github.com/spf13/castv1.10.0// indirect
5454
github.com/spf13/pflagv1.0.10
5555
github.com/subosito/gotenvv1.6.0// indirect
56-
github.com/yosida95/uritemplate/v3v3.0.2// indirect
56+
github.com/yosida95/uritemplate/v3v3.0.2
5757
golang.org/x/oauth2v0.30.0// indirect
5858
golang.org/x/sysv0.31.0// indirect
5959
golang.org/x/textv0.28.0// indirect

‎pkg/github/repository_resource.go‎

Lines changed: 101 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package github
22

33
import (
4+
"bytes"
45
"context"
56
"encoding/base64"
67
"errors"
@@ -15,107 +16,120 @@ import (
1516
"github.com/github/github-mcp-server/pkg/raw"
1617
"github.com/github/github-mcp-server/pkg/translations"
1718
"github.com/google/go-github/v79/github"
18-
"github.com/mark3labs/mcp-go/mcp"
19-
"github.com/mark3labs/mcp-go/server"
19+
"github.com/modelcontextprotocol/go-sdk/mcp"
20+
"github.com/yosida95/uritemplate/v3"
21+
)
22+
23+
var (
24+
repositoryResourceContentURITemplate=uritemplate.MustNew("repo://{owner}/{repo}/contents{/path*}")
25+
repositoryResourceBranchContentURITemplate=uritemplate.MustNew("repo://{owner}/{repo}/refs/heads/{branch}/contents{/path*}")
26+
repositoryResourceCommitContentURITemplate=uritemplate.MustNew("repo://{owner}/{repo}/sha/{sha}/contents{/path*}")
27+
repositoryResourceTagContentURITemplate=uritemplate.MustNew("repo://{owner}/{repo}/refs/tags/{tag}/contents{/path*}")
28+
repositoryResourcePrContentURITemplate=uritemplate.MustNew("repo://{owner}/{repo}/refs/pull/{prNumber}/head/contents{/path*}")
2029
)
2130

2231
// GetRepositoryResourceContent defines the resource template and handler for getting repository content.
23-
funcGetRepositoryResourceContent(getClientGetClientFn,getRawClient raw.GetRawClientFn,t translations.TranslationHelperFunc) (mcp.ResourceTemplate, server.ResourceTemplateHandlerFunc) {
24-
returnmcp.NewResourceTemplate(
25-
"repo://{owner}/{repo}/contents{/path*}",// Resource template
26-
t("RESOURCE_REPOSITORY_CONTENT_DESCRIPTION","Repository Content"),
27-
),
28-
RepositoryResourceContentsHandler(getClient,getRawClient)
32+
funcGetRepositoryResourceContent(getClientGetClientFn,getRawClient raw.GetRawClientFn,t translations.TranslationHelperFunc) (mcp.ResourceTemplate, mcp.ResourceHandler) {
33+
return mcp.ResourceTemplate{
34+
Name:"repository_content",
35+
URITemplate:repositoryResourceContentURITemplate.Raw(),// Resource template
36+
Description:t("RESOURCE_REPOSITORY_CONTENT_DESCRIPTION","Repository Content"),
37+
},
38+
RepositoryResourceContentsHandler(getClient,getRawClient,repositoryResourceContentURITemplate)
2939
}
3040

3141
// GetRepositoryResourceBranchContent defines the resource template and handler for getting repository content for a branch.
32-
funcGetRepositoryResourceBranchContent(getClientGetClientFn,getRawClient raw.GetRawClientFn,t translations.TranslationHelperFunc) (mcp.ResourceTemplate, server.ResourceTemplateHandlerFunc) {
33-
returnmcp.NewResourceTemplate(
34-
"repo://{owner}/{repo}/refs/heads/{branch}/contents{/path*}",// Resource template
35-
t("RESOURCE_REPOSITORY_CONTENT_BRANCH_DESCRIPTION","Repository Content for specific branch"),
36-
),
37-
RepositoryResourceContentsHandler(getClient,getRawClient)
42+
funcGetRepositoryResourceBranchContent(getClientGetClientFn,getRawClient raw.GetRawClientFn,t translations.TranslationHelperFunc) (mcp.ResourceTemplate, mcp.ResourceHandler) {
43+
return mcp.ResourceTemplate{
44+
Name:"repository_content_branch",
45+
URITemplate:repositoryResourceBranchContentURITemplate.Raw(),// Resource template
46+
Description:t("RESOURCE_REPOSITORY_CONTENT_BRANCH_DESCRIPTION","Repository Content for specific branch"),
47+
},
48+
RepositoryResourceContentsHandler(getClient,getRawClient,repositoryResourceBranchContentURITemplate)
3849
}
3950

4051
// GetRepositoryResourceCommitContent defines the resource template and handler for getting repository content for a commit.
41-
funcGetRepositoryResourceCommitContent(getClientGetClientFn,getRawClient raw.GetRawClientFn,t translations.TranslationHelperFunc) (mcp.ResourceTemplate, server.ResourceTemplateHandlerFunc) {
42-
returnmcp.NewResourceTemplate(
43-
"repo://{owner}/{repo}/sha/{sha}/contents{/path*}",// Resource template
44-
t("RESOURCE_REPOSITORY_CONTENT_COMMIT_DESCRIPTION","Repository Content for specific commit"),
45-
),
46-
RepositoryResourceContentsHandler(getClient,getRawClient)
52+
funcGetRepositoryResourceCommitContent(getClientGetClientFn,getRawClient raw.GetRawClientFn,t translations.TranslationHelperFunc) (mcp.ResourceTemplate, mcp.ResourceHandler) {
53+
return mcp.ResourceTemplate{
54+
Name:"repository_content_commit",
55+
URITemplate:repositoryResourceCommitContentURITemplate.Raw(),// Resource template
56+
Description:t("RESOURCE_REPOSITORY_CONTENT_COMMIT_DESCRIPTION","Repository Content for specific commit"),
57+
},
58+
RepositoryResourceContentsHandler(getClient,getRawClient,repositoryResourceCommitContentURITemplate)
4759
}
4860

4961
// GetRepositoryResourceTagContent defines the resource template and handler for getting repository content for a tag.
50-
funcGetRepositoryResourceTagContent(getClientGetClientFn,getRawClient raw.GetRawClientFn,t translations.TranslationHelperFunc) (mcp.ResourceTemplate, server.ResourceTemplateHandlerFunc) {
51-
returnmcp.NewResourceTemplate(
52-
"repo://{owner}/{repo}/refs/tags/{tag}/contents{/path*}",// Resource template
53-
t("RESOURCE_REPOSITORY_CONTENT_TAG_DESCRIPTION","Repository Content for specific tag"),
54-
),
55-
RepositoryResourceContentsHandler(getClient,getRawClient)
62+
funcGetRepositoryResourceTagContent(getClientGetClientFn,getRawClient raw.GetRawClientFn,t translations.TranslationHelperFunc) (mcp.ResourceTemplate, mcp.ResourceHandler) {
63+
return mcp.ResourceTemplate{
64+
Name:"repository_content_tag",
65+
URITemplate:repositoryResourceTagContentURITemplate.Raw(),// Resource template
66+
Description:t("RESOURCE_REPOSITORY_CONTENT_TAG_DESCRIPTION","Repository Content for specific tag"),
67+
},
68+
RepositoryResourceContentsHandler(getClient,getRawClient,repositoryResourceTagContentURITemplate)
5669
}
5770

5871
// GetRepositoryResourcePrContent defines the resource template and handler for getting repository content for a pull request.
59-
funcGetRepositoryResourcePrContent(getClientGetClientFn,getRawClient raw.GetRawClientFn,t translations.TranslationHelperFunc) (mcp.ResourceTemplate, server.ResourceTemplateHandlerFunc) {
60-
returnmcp.NewResourceTemplate(
61-
"repo://{owner}/{repo}/refs/pull/{prNumber}/head/contents{/path*}",// Resource template
62-
t("RESOURCE_REPOSITORY_CONTENT_PR_DESCRIPTION","Repository Content for specific pull request"),
63-
),
64-
RepositoryResourceContentsHandler(getClient,getRawClient)
72+
funcGetRepositoryResourcePrContent(getClientGetClientFn,getRawClient raw.GetRawClientFn,t translations.TranslationHelperFunc) (mcp.ResourceTemplate, mcp.ResourceHandler) {
73+
return mcp.ResourceTemplate{
74+
Name:"repository_content_pr",
75+
URITemplate:repositoryResourcePrContentURITemplate.Raw(),// Resource template
76+
Description:t("RESOURCE_REPOSITORY_CONTENT_PR_DESCRIPTION","Repository Content for specific pull request"),
77+
},
78+
RepositoryResourceContentsHandler(getClient,getRawClient,repositoryResourcePrContentURITemplate)
6579
}
6680

6781
// RepositoryResourceContentsHandler returns a handler function for repository content requests.
68-
funcRepositoryResourceContentsHandler(getClientGetClientFn,getRawClient raw.GetRawClientFn)func(ctx context.Context,request mcp.ReadResourceRequest) ([]mcp.ResourceContents,error) {
69-
returnfunc(ctx context.Context,request mcp.ReadResourceRequest) ([]mcp.ResourceContents,error) {
70-
// the matcher will give []string with one element
71-
// https://github.com/mark3labs/mcp-go/pull/54
72-
o,ok:=request.Params.Arguments["owner"].([]string)
73-
if!ok||len(o)==0 {
82+
funcRepositoryResourceContentsHandler(getClientGetClientFn,getRawClient raw.GetRawClientFn,resourceURITemplate*uritemplate.Template) mcp.ResourceHandler {
83+
returnfunc(ctx context.Context,request*mcp.ReadResourceRequest) (*mcp.ReadResourceResult,error) {
84+
// Match the URI to extract parameters
85+
uriValues:=resourceURITemplate.Match(request.Params.URI)
86+
ifuriValues==nil {
87+
returnnil,fmt.Errorf("failed to match URI: %s",request.Params.URI)
88+
}
89+
90+
// Extract required vars
91+
owner:=uriValues.Get("owner").String()
92+
repo:=uriValues.Get("repo").String()
93+
94+
ifowner=="" {
7495
returnnil,errors.New("owner is required")
7596
}
76-
owner:=o[0]
7797

78-
r,ok:=request.Params.Arguments["repo"].([]string)
79-
if!ok||len(r)==0 {
98+
ifrepo=="" {
8099
returnnil,errors.New("repo is required")
81100
}
82-
repo:=r[0]
83101

84-
// path should be a joined list of the path parts
85-
path:=""
86-
p,ok:=request.Params.Arguments["path"].([]string)
87-
ifok {
88-
path=strings.Join(p,"/")
89-
}
102+
path:=uriValues.Get("path").String()
90103

91104
opts:=&github.RepositoryContentGetOptions{}
92105
rawOpts:=&raw.ContentOpts{}
93106

94-
sha,ok:=request.Params.Arguments["sha"].([]string)
95-
ifok&&len(sha)>0 {
96-
opts.Ref=sha[0]
97-
rawOpts.SHA=sha[0]
107+
sha:=uriValues.Get("sha").String()
108+
ifsha!="" {
109+
opts.Ref=sha
110+
rawOpts.SHA=sha
98111
}
99112

100-
branch,ok:=request.Params.Arguments["branch"].([]string)
101-
ifok&&len(branch)>0 {
102-
opts.Ref="refs/heads/"+branch[0]
103-
rawOpts.Ref="refs/heads/"+branch[0]
113+
branch:=uriValues.Get("branch").String()
114+
ifbranch!="" {
115+
opts.Ref="refs/heads/"+branch
116+
rawOpts.Ref="refs/heads/"+branch
104117
}
105118

106-
tag,ok:=request.Params.Arguments["tag"].([]string)
107-
ifok&&len(tag)>0 {
108-
opts.Ref="refs/tags/"+tag[0]
109-
rawOpts.Ref="refs/tags/"+tag[0]
119+
tag:=uriValues.Get("tag").String()
120+
iftag!="" {
121+
opts.Ref="refs/tags/"+tag
122+
rawOpts.Ref="refs/tags/"+tag
110123
}
111-
prNumber,ok:=request.Params.Arguments["prNumber"].([]string)
112-
ifok&&len(prNumber)>0 {
124+
125+
prNumber:=uriValues.Get("prNumber").String()
126+
ifprNumber!="" {
113127
// fetch the PR from the API to get the latest commit and use SHA
114128
githubClient,err:=getClient(ctx)
115129
iferr!=nil {
116130
returnnil,fmt.Errorf("failed to get GitHub client: %w",err)
117131
}
118-
prNum,err:=strconv.Atoi(prNumber[0])
132+
prNum,err:=strconv.Atoi(prNumber)
119133
iferr!=nil {
120134
returnnil,fmt.Errorf("invalid pull request number: %w",err)
121135
}
@@ -161,19 +175,33 @@ func RepositoryResourceContentsHandler(getClient GetClientFn, getRawClient raw.G
161175

162176
switch {
163177
casestrings.HasPrefix(mimeType,"text"),strings.HasPrefix(mimeType,"application"):
164-
return []mcp.ResourceContents{
165-
mcp.TextResourceContents{
166-
URI:request.Params.URI,
167-
MIMEType:mimeType,
168-
Text:string(content),
178+
return&mcp.ReadResourceResult{
179+
Contents: []*mcp.ResourceContents{
180+
{
181+
URI:request.Params.URI,
182+
MIMEType:mimeType,
183+
Text:string(content),
184+
},
169185
},
170186
},nil
171187
default:
172-
return []mcp.ResourceContents{
173-
mcp.BlobResourceContents{
174-
URI:request.Params.URI,
175-
MIMEType:mimeType,
176-
Blob:base64.StdEncoding.EncodeToString(content),
188+
varbuf bytes.Buffer
189+
base64Encoder:=base64.NewEncoder(base64.StdEncoding,&buf)
190+
_,err:=base64Encoder.Write(content)
191+
iferr!=nil {
192+
returnnil,fmt.Errorf("failed to base64 encode content: %w",err)
193+
}
194+
iferr:=base64Encoder.Close();err!=nil {
195+
returnnil,fmt.Errorf("failed to close base64 encoder: %w",err)
196+
}
197+
198+
return&mcp.ReadResourceResult{
199+
Contents: []*mcp.ResourceContents{
200+
{
201+
URI:request.Params.URI,
202+
MIMEType:mimeType,
203+
Blob:buf.Bytes(),
204+
},
177205
},
178206
},nil
179207
}

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp