diff --git a/README.md b/README.md index d57c33e..a2999e9 100644 --- a/README.md +++ b/README.md @@ -24,7 +24,7 @@ jobs: steps: - name: Test Local Action id: inference - uses: actions/ai-inference@v1 + uses: actions/ai-inference@v2 with: prompt: 'Hello!' @@ -42,7 +42,7 @@ supports both plain text files and structured `.prompt.yml` files: steps: - name: Run AI Inference with Text File id: inference - uses: actions/ai-inference@v1 + uses: actions/ai-inference@v2 with: prompt-file: './path/to/prompt.txt' ``` @@ -56,7 +56,7 @@ support templating, custom models, and JSON schema responses: steps: - name: Run AI Inference with Prompt YAML id: inference - uses: actions/ai-inference@v1 + uses: actions/ai-inference@v2 with: prompt-file: './.github/prompts/sample.prompt.yml' input: | @@ -132,7 +132,7 @@ of an inline system prompt: steps: - name: Run AI Inference with System Prompt File id: inference - uses: actions/ai-inference@v1 + uses: actions/ai-inference@v2 with: prompt: 'Hello!' system-prompt-file: './path/to/system-prompt.txt' @@ -146,7 +146,7 @@ This can be useful when model response exceeds actions output limit steps: - name: Test Local Action id: inference - uses: actions/ai-inference@v1 + uses: actions/ai-inference@v2 with: prompt: 'Hello!' @@ -169,7 +169,7 @@ repository management, issue tracking, and pull request operations. steps: - name: AI Inference with GitHub Tools id: inference - uses: actions/ai-inference@v1.2 + uses: actions/ai-inference@v2 with: prompt: 'List my open pull requests and create a summary' enable-github-mcp: true @@ -183,7 +183,7 @@ and the GitHub MCP server: steps: - name: AI Inference with Separate MCP Token id: inference - uses: actions/ai-inference@v1.2 + uses: actions/ai-inference@v2 with: prompt: 'List my open pull requests and create a summary' enable-github-mcp: true @@ -191,6 +191,26 @@ steps: github-mcp-token: ${{ secrets.USER_PAT }} ``` +#### Configuring GitHub MCP Toolsets + +By default, the GitHub MCP server provides a standard set of tools (`context`, `repos`, `issues`, `pull_requests`, `users`). You can customize which toolsets are available by specifying the `github-mcp-toolsets` parameter: + +```yaml +steps: + - name: AI Inference with Custom Toolsets + id: inference + uses: actions/ai-inference@v2 + with: + prompt: 'Analyze recent workflow runs and check security alerts' + enable-github-mcp: true + token: ${{ secrets.USER_PAT }} + github-mcp-toolsets: 'repos,issues,pull_requests,actions,code_security' +``` + +**Available toolsets:** +See: https://github.com/github/github-mcp-server/blob/main/README.md#tool-configuration + + When MCP is enabled, the AI model will have access to GitHub tools and can perform actions like searching issues and PRs. @@ -213,6 +233,7 @@ the action: | `max-tokens` | The max number of tokens to generate | 200 | | `enable-github-mcp` | Enable Model Context Protocol integration with GitHub tools | `false` | | `github-mcp-token` | Token to use for GitHub MCP server (defaults to the main token if not specified). This must be a PAT for MCP to work | `""` | +| `github-mcp-toolsets` | Comma-separated list of toolsets to enable for GitHub MCP (e.g., `repos,issues,pull_requests,actions`). Use `all` for all toolsets or `default` for the default set | `""` | ## Outputs diff --git a/__tests__/main.test.ts b/__tests__/main.test.ts index 48e70f9..69fc283 100644 --- a/__tests__/main.test.ts +++ b/__tests__/main.test.ts @@ -199,7 +199,7 @@ describe('main.ts', () => { await run() - expect(mockConnectToGitHubMCP).toHaveBeenCalledWith('fake-token') + expect(mockConnectToGitHubMCP).toHaveBeenCalledWith('fake-token', '') expect(mockMcpInference).toHaveBeenCalledWith( expect.objectContaining({ messages: [ @@ -226,7 +226,7 @@ describe('main.ts', () => { await run() - expect(mockConnectToGitHubMCP).toHaveBeenCalledWith('fake-token') + expect(mockConnectToGitHubMCP).toHaveBeenCalledWith('fake-token', '') expect(mockSimpleInference).toHaveBeenCalled() expect(mockMcpInference).not.toHaveBeenCalled() expect(core.warning).toHaveBeenCalledWith('MCP connection failed, falling back to simple inference') diff --git a/__tests__/mcp.test.ts b/__tests__/mcp.test.ts index 42ce59b..f8a37bf 100644 --- a/__tests__/mcp.test.ts +++ b/__tests__/mcp.test.ts @@ -113,6 +113,40 @@ describe('mcp.ts', () => { expect(result?.tools).toHaveLength(0) expect(core.info).toHaveBeenCalledWith('Retrieved 0 tools from GitHub MCP server') }) + + it('uses default toolsets when toolsets parameter is not provided', async () => { + const token = 'test-token' + + mockConnect.mockResolvedValue(undefined) + mockListTools.mockResolvedValue({tools: []}) + + await connectToGitHubMCP(token) + + expect(core.info).toHaveBeenCalledWith('Using default GitHub MCP toolsets') + }) + + it('uses custom toolsets when toolsets parameter is provided', async () => { + const token = 'test-token' + const toolsets = 'repos,issues,pull_requests,actions' + + mockConnect.mockResolvedValue(undefined) + mockListTools.mockResolvedValue({tools: []}) + + await connectToGitHubMCP(token, toolsets) + + expect(core.info).toHaveBeenCalledWith('Using GitHub MCP toolsets: repos,issues,pull_requests,actions') + }) + + it('ignores empty toolsets parameter', async () => { + const token = 'test-token' + + mockConnect.mockResolvedValue(undefined) + mockListTools.mockResolvedValue({tools: []}) + + await connectToGitHubMCP(token, ' ') + + expect(core.info).toHaveBeenCalledWith('Using default GitHub MCP toolsets') + }) }) describe('executeToolCall', () => { diff --git a/action.yml b/action.yml index 0f397a3..92ed0ef 100644 --- a/action.yml +++ b/action.yml @@ -58,6 +58,10 @@ inputs: description: The token to use for GitHub MCP server (defaults to the main token if not specified). This must be a PAT for MCP to work. required: false default: '' + github-mcp-toolsets: + description: 'Comma-separated list of toolsets to enable for GitHub MCP (e.g., "repos,issues,pull_requests,actions"). Use "all" for all toolsets, "default" for default set. If not specified, uses default toolsets (context,repos,issues,pull_requests,users).' + required: false + default: '' # Define your outputs here. outputs: diff --git a/src/main.ts b/src/main.ts index 2b5afb7..7d33487 100644 --- a/src/main.ts +++ b/src/main.ts @@ -62,6 +62,7 @@ export async function run(): Promise { // Get GitHub MCP token (use dedicated token if provided, otherwise fall back to main token) const githubMcpToken = core.getInput('github-mcp-token') || token + const githubMcpToolsets = core.getInput('github-mcp-toolsets') const endpoint = core.getInput('endpoint') @@ -81,7 +82,7 @@ export async function run(): Promise { let modelResponse: string | null = null if (enableMcp) { - const mcpClient = await connectToGitHubMCP(githubMcpToken) + const mcpClient = await connectToGitHubMCP(githubMcpToken, githubMcpToolsets) if (mcpClient) { modelResponse = await mcpInference(inferenceRequest, mcpClient) diff --git a/src/mcp.ts b/src/mcp.ts index 8e8e03e..616c8fd 100644 --- a/src/mcp.ts +++ b/src/mcp.ts @@ -35,17 +35,27 @@ export interface GitHubMCPClient { /** * Connect to the GitHub MCP server and retrieve available tools */ -export async function connectToGitHubMCP(token: string): Promise { +export async function connectToGitHubMCP(token: string, toolsets?: string): Promise { const githubMcpUrl = 'https://api.githubcopilot.com/mcp/' core.info('Connecting to GitHub MCP server...') + const headers: Record = { + Authorization: `Bearer ${token}`, + 'X-MCP-Readonly': 'true', + } + + // Add toolsets header if specified + if (toolsets && toolsets.trim() !== '') { + headers['X-MCP-Toolsets'] = toolsets + core.info(`Using GitHub MCP toolsets: ${toolsets}`) + } else { + core.info('Using default GitHub MCP toolsets') + } + const transport = new StreamableHTTPClientTransport(new URL(githubMcpUrl), { requestInit: { - headers: { - Authorization: `Bearer ${token}`, - 'X-MCP-Readonly': 'true', - }, + headers, }, })