Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -606,6 +606,7 @@ The following sets of tools are available:
| <picture><source media="(prefers-color-scheme: dark)" srcset="pkg/octicons/icons/repo-dark.png"><source media="(prefers-color-scheme: light)" srcset="pkg/octicons/icons/repo-light.png"><img src="pkg/octicons/icons/repo-light.png" width="20" height="20" alt="repo"></picture> | `repos` | GitHub Repository related tools |
| <picture><source media="(prefers-color-scheme: dark)" srcset="pkg/octicons/icons/shield-lock-dark.png"><source media="(prefers-color-scheme: light)" srcset="pkg/octicons/icons/shield-lock-light.png"><img src="pkg/octicons/icons/shield-lock-light.png" width="20" height="20" alt="shield-lock"></picture> | `secret_protection` | Secret protection related tools, such as GitHub Secret Scanning |
| <picture><source media="(prefers-color-scheme: dark)" srcset="pkg/octicons/icons/shield-dark.png"><source media="(prefers-color-scheme: light)" srcset="pkg/octicons/icons/shield-light.png"><img src="pkg/octicons/icons/shield-light.png" width="20" height="20" alt="shield"></picture> | `security_advisories` | Security advisories related tools |
| <picture><source media="(prefers-color-scheme: dark)" srcset="pkg/octicons/icons/beaker-dark.png"><source media="(prefers-color-scheme: light)" srcset="pkg/octicons/icons/beaker-light.png"><img src="pkg/octicons/icons/beaker-light.png" width="20" height="20" alt="beaker"></picture> | `skills` | Agent Skills discovery via skill:// resources from arbitrary GitHub repositories (experimental, see agentskills.io) |
| <picture><source media="(prefers-color-scheme: dark)" srcset="pkg/octicons/icons/star-dark.png"><source media="(prefers-color-scheme: light)" srcset="pkg/octicons/icons/star-light.png"><img src="pkg/octicons/icons/star-light.png" width="20" height="20" alt="star"></picture> | `stargazers` | GitHub Stargazers related tools |
| <picture><source media="(prefers-color-scheme: dark)" srcset="pkg/octicons/icons/people-dark.png"><source media="(prefers-color-scheme: light)" srcset="pkg/octicons/icons/people-light.png"><img src="pkg/octicons/icons/people-light.png" width="20" height="20" alt="people"></picture> | `users` | GitHub User related tools |
<!-- END AUTOMATED TOOLSETS -->
Expand Down Expand Up @@ -1503,6 +1504,17 @@ The following sets of tools are available:

<details>

<summary><picture><source media="(prefers-color-scheme: dark)" srcset="pkg/octicons/icons/beaker-dark.png"><source media="(prefers-color-scheme: light)" srcset="pkg/octicons/icons/beaker-light.png"><img src="pkg/octicons/icons/beaker-light.png" width="20" height="20" alt="beaker"></picture> Skills</summary>

- **list_repo_skills** - List Agent Skills in a repository
- **Required OAuth Scopes**: `repo`
- `owner`: Repository owner (username or organization name). (string, required)
- `repo`: Repository name. (string, required)

</details>

<details>

<summary><picture><source media="(prefers-color-scheme: dark)" srcset="pkg/octicons/icons/star-dark.png"><source media="(prefers-color-scheme: light)" srcset="pkg/octicons/icons/star-light.png"><img src="pkg/octicons/icons/star-light.png" width="20" height="20" alt="star"></picture> Stargazers</summary>

- **list_starred_repositories** - List starred repositories
Expand Down
1 change: 1 addition & 0 deletions docs/remote-server.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ Below is a table of available toolsets for the remote GitHub MCP Server. Each to
| <picture><source media="(prefers-color-scheme: dark)" srcset="../pkg/octicons/icons/repo-dark.png"><source media="(prefers-color-scheme: light)" srcset="../pkg/octicons/icons/repo-light.png"><img src="../pkg/octicons/icons/repo-light.png" width="20" height="20" alt="repo"></picture><br>`repos` | GitHub Repository related tools | https://api.githubcopilot.com/mcp/x/repos | [Install](https://insiders.vscode.dev/redirect/mcp/install?name=gh-repos&config=%7B%22type%22%3A%20%22http%22%2C%22url%22%3A%20%22https%3A%2F%2Fapi.githubcopilot.com%2Fmcp%2Fx%2Frepos%22%7D) | [read-only](https://api.githubcopilot.com/mcp/x/repos/readonly) | [Install read-only](https://insiders.vscode.dev/redirect/mcp/install?name=gh-repos&config=%7B%22type%22%3A%20%22http%22%2C%22url%22%3A%20%22https%3A%2F%2Fapi.githubcopilot.com%2Fmcp%2Fx%2Frepos%2Freadonly%22%7D) |
| <picture><source media="(prefers-color-scheme: dark)" srcset="../pkg/octicons/icons/shield-lock-dark.png"><source media="(prefers-color-scheme: light)" srcset="../pkg/octicons/icons/shield-lock-light.png"><img src="../pkg/octicons/icons/shield-lock-light.png" width="20" height="20" alt="shield-lock"></picture><br>`secret_protection` | Secret protection related tools, such as GitHub Secret Scanning | https://api.githubcopilot.com/mcp/x/secret_protection | [Install](https://insiders.vscode.dev/redirect/mcp/install?name=gh-secret_protection&config=%7B%22type%22%3A%20%22http%22%2C%22url%22%3A%20%22https%3A%2F%2Fapi.githubcopilot.com%2Fmcp%2Fx%2Fsecret_protection%22%7D) | [read-only](https://api.githubcopilot.com/mcp/x/secret_protection/readonly) | [Install read-only](https://insiders.vscode.dev/redirect/mcp/install?name=gh-secret_protection&config=%7B%22type%22%3A%20%22http%22%2C%22url%22%3A%20%22https%3A%2F%2Fapi.githubcopilot.com%2Fmcp%2Fx%2Fsecret_protection%2Freadonly%22%7D) |
| <picture><source media="(prefers-color-scheme: dark)" srcset="../pkg/octicons/icons/shield-dark.png"><source media="(prefers-color-scheme: light)" srcset="../pkg/octicons/icons/shield-light.png"><img src="../pkg/octicons/icons/shield-light.png" width="20" height="20" alt="shield"></picture><br>`security_advisories` | Security advisories related tools | https://api.githubcopilot.com/mcp/x/security_advisories | [Install](https://insiders.vscode.dev/redirect/mcp/install?name=gh-security_advisories&config=%7B%22type%22%3A%20%22http%22%2C%22url%22%3A%20%22https%3A%2F%2Fapi.githubcopilot.com%2Fmcp%2Fx%2Fsecurity_advisories%22%7D) | [read-only](https://api.githubcopilot.com/mcp/x/security_advisories/readonly) | [Install read-only](https://insiders.vscode.dev/redirect/mcp/install?name=gh-security_advisories&config=%7B%22type%22%3A%20%22http%22%2C%22url%22%3A%20%22https%3A%2F%2Fapi.githubcopilot.com%2Fmcp%2Fx%2Fsecurity_advisories%2Freadonly%22%7D) |
| <picture><source media="(prefers-color-scheme: dark)" srcset="../pkg/octicons/icons/beaker-dark.png"><source media="(prefers-color-scheme: light)" srcset="../pkg/octicons/icons/beaker-light.png"><img src="../pkg/octicons/icons/beaker-light.png" width="20" height="20" alt="beaker"></picture><br>`skills` | Agent Skills discovery via skill:// resources from arbitrary GitHub repositories (experimental, see agentskills.io) | https://api.githubcopilot.com/mcp/x/skills | [Install](https://insiders.vscode.dev/redirect/mcp/install?name=gh-skills&config=%7B%22type%22%3A%20%22http%22%2C%22url%22%3A%20%22https%3A%2F%2Fapi.githubcopilot.com%2Fmcp%2Fx%2Fskills%22%7D) | [read-only](https://api.githubcopilot.com/mcp/x/skills/readonly) | [Install read-only](https://insiders.vscode.dev/redirect/mcp/install?name=gh-skills&config=%7B%22type%22%3A%20%22http%22%2C%22url%22%3A%20%22https%3A%2F%2Fapi.githubcopilot.com%2Fmcp%2Fx%2Fskills%2Freadonly%22%7D) |
| <picture><source media="(prefers-color-scheme: dark)" srcset="../pkg/octicons/icons/star-dark.png"><source media="(prefers-color-scheme: light)" srcset="../pkg/octicons/icons/star-light.png"><img src="../pkg/octicons/icons/star-light.png" width="20" height="20" alt="star"></picture><br>`stargazers` | GitHub Stargazers related tools | https://api.githubcopilot.com/mcp/x/stargazers | [Install](https://insiders.vscode.dev/redirect/mcp/install?name=gh-stargazers&config=%7B%22type%22%3A%20%22http%22%2C%22url%22%3A%20%22https%3A%2F%2Fapi.githubcopilot.com%2Fmcp%2Fx%2Fstargazers%22%7D) | [read-only](https://api.githubcopilot.com/mcp/x/stargazers/readonly) | [Install read-only](https://insiders.vscode.dev/redirect/mcp/install?name=gh-stargazers&config=%7B%22type%22%3A%20%22http%22%2C%22url%22%3A%20%22https%3A%2F%2Fapi.githubcopilot.com%2Fmcp%2Fx%2Fstargazers%2Freadonly%22%7D) |
| <picture><source media="(prefers-color-scheme: dark)" srcset="../pkg/octicons/icons/people-dark.png"><source media="(prefers-color-scheme: light)" srcset="../pkg/octicons/icons/people-light.png"><img src="../pkg/octicons/icons/people-light.png" width="20" height="20" alt="people"></picture><br>`users` | GitHub User related tools | https://api.githubcopilot.com/mcp/x/users | [Install](https://insiders.vscode.dev/redirect/mcp/install?name=gh-users&config=%7B%22type%22%3A%20%22http%22%2C%22url%22%3A%20%22https%3A%2F%2Fapi.githubcopilot.com%2Fmcp%2Fx%2Fusers%22%7D) | [read-only](https://api.githubcopilot.com/mcp/x/users/readonly) | [Install read-only](https://insiders.vscode.dev/redirect/mcp/install?name=gh-users&config=%7B%22type%22%3A%20%22http%22%2C%22url%22%3A%20%22https%3A%2F%2Fapi.githubcopilot.com%2Fmcp%2Fx%2Fusers%2Freadonly%22%7D) |
<!-- END AUTOMATED TOOLSETS -->
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ require (
github.com/stretchr/testify v1.12.0
github.com/yosida95/uritemplate/v3 v3.0.2
golang.org/x/oauth2 v0.36.0
gopkg.in/yaml.v3 v3.0.1
)

require (
Expand All @@ -44,5 +45,4 @@ require (
golang.org/x/text v0.37.0 // indirect
golang.org/x/time v0.15.0 // indirect
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)
26 changes: 26 additions & 0 deletions pkg/github/__toolsnaps__/list_repo_skills.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
{
"annotations": {
"idempotentHint": false,
"readOnlyHint": true,
"title": "List Agent Skills in a repository"
},
"description": "List Agent Skills (SKILL.md files) defined in a GitHub repository. Returns each discovered skill's name plus a `skill://` URI you can pass directly to `resources/read` to fetch its SKILL.md. Recognizes the agentskills.io directory conventions: skills/*/SKILL.md, skills/{namespace}/*/SKILL.md, plugins/*/skills/*/SKILL.md, and root-level */SKILL.md. Use this when you need to discover what skills a repository exposes before reading any of them.",
"inputSchema": {
"properties": {
"owner": {
"description": "Repository owner (username or organization name).",
"type": "string"
},
"repo": {
"description": "Repository name.",
"type": "string"
}
},
"required": [
"owner",
"repo"
],
"type": "object"
},
"name": "list_repo_skills"
}
4 changes: 4 additions & 0 deletions pkg/github/resources.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,9 @@ func AllResources(t translations.TranslationHelperFunc) []inventory.ServerResour
GetRepositoryResourceCommitContent(t),
GetRepositoryResourceTagContent(t),
GetRepositoryResourcePrContent(t),

// Skill resources (SEP-2640): per-file template for any skill in any
// GitHub repo. Gated on the `skills` toolset.
GetSkillResourceFile(t),
}
}
30 changes: 30 additions & 0 deletions pkg/github/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"encoding/json"
"fmt"
"log/slog"
"slices"
"strings"
"time"

Expand All @@ -13,6 +14,7 @@ import (
"github.com/github/github-mcp-server/pkg/octicons"
"github.com/github/github-mcp-server/pkg/translations"
"github.com/github/github-mcp-server/pkg/utils"
"github.com/github/github-mcp-server/skills"
"github.com/modelcontextprotocol/go-sdk/mcp"
)

Expand Down Expand Up @@ -108,6 +110,22 @@ func NewMCPServer(ctx context.Context, cfg *MCPServerConfig, deps ToolDependenci
o(serverOpts)
}

// Declare the io.modelcontextprotocol/skills extension (SEP-2640) for the
// bundled Agent Skills. Must happen before NewServer since capabilities
// are captured at construction.
skillsPublisher := &skills.Publisher{Registry: skills.Bundled()}
skillsPublisher.DeclareCapability(serverOpts)

// When the `skills` toolset is enabled, skills/get and
// resources/directory/read additionally answer for repo-hosted skills —
// the SEP's unenumerable-catalog case, reachable by URI only.
if slices.ContainsFunc(inv.EnabledToolsets(), func(ts inventory.ToolsetMetadata) bool {
return ts.ID == ToolsetMetadataSkills.ID
}) {
skillsPublisher.DynamicGet = RepoSkillEntry
skillsPublisher.DynamicDirectoryRead = RepoSkillDirectory
}

ghServer := NewServer(cfg.Version, cfg.Translator("SERVER_NAME", "github-mcp-server"), cfg.Translator("SERVER_TITLE", "GitHub MCP Server"), serverOpts)

// Add middlewares. Order matters - for example, the error context middleware should be applied last so that it runs FIRST (closest to the handler) to ensure all errors are captured,
Expand All @@ -123,6 +141,15 @@ func NewMCPServer(ctx context.Context, cfg *MCPServerConfig, deps ToolDependenci
// Register GitHub tools/resources/prompts from the inventory.
inv.RegisterAll(ctx, ghServer, deps, cfg.ToolHandlerMiddleware...)

// Register the bundled Agent Skills: each skill file as a skill://
// resource, plus the extension's skills/list, skills/get, and
// resources/directory/read methods. Lives here — not in the stdio
// bootstrap — so the HTTP transport, which builds an mcp.Server per
// request through this same constructor, serves them too.
if err := skillsPublisher.Install(ghServer); err != nil {
return nil, fmt.Errorf("failed to install bundled skills: %w", err)
}

// Register MCP App UI resources whenever the embedded UI assets are
// available. The resources are static HTML and are only referenced by
// tools when the remote_mcp_ui_apps feature flag is enabled for the
Expand Down Expand Up @@ -199,6 +226,9 @@ func CompletionsHandler(getClient GetClientFn) func(ctx context.Context, req *mc
if strings.HasPrefix(req.Params.Ref.URI, "repo://") {
return RepositoryResourceCompletionHandler(getClient)(ctx, req)
}
if strings.HasPrefix(req.Params.Ref.URI, "skill://") {
return SkillResourceCompletionHandler(getClient)(ctx, req)
}
return nil, fmt.Errorf("unsupported resource URI: %s", req.Params.Ref.URI)
case "ref/prompt":
return nil, nil
Expand Down
Loading