Initial implementation for passing toolsets

This commit is contained in:
Maarten van Diemen
2025-11-02 23:20:24 +01:00
parent 83bb5ca3e8
commit 932a853db4
6 changed files with 85 additions and 15 deletions
+28 -7
View File
@@ -24,7 +24,7 @@ jobs:
steps: steps:
- name: Test Local Action - name: Test Local Action
id: inference id: inference
uses: actions/ai-inference@v1 uses: actions/ai-inference@v2
with: with:
prompt: 'Hello!' prompt: 'Hello!'
@@ -42,7 +42,7 @@ supports both plain text files and structured `.prompt.yml` files:
steps: steps:
- name: Run AI Inference with Text File - name: Run AI Inference with Text File
id: inference id: inference
uses: actions/ai-inference@v1 uses: actions/ai-inference@v2
with: with:
prompt-file: './path/to/prompt.txt' prompt-file: './path/to/prompt.txt'
``` ```
@@ -56,7 +56,7 @@ support templating, custom models, and JSON schema responses:
steps: steps:
- name: Run AI Inference with Prompt YAML - name: Run AI Inference with Prompt YAML
id: inference id: inference
uses: actions/ai-inference@v1 uses: actions/ai-inference@v2
with: with:
prompt-file: './.github/prompts/sample.prompt.yml' prompt-file: './.github/prompts/sample.prompt.yml'
input: | input: |
@@ -132,7 +132,7 @@ of an inline system prompt:
steps: steps:
- name: Run AI Inference with System Prompt File - name: Run AI Inference with System Prompt File
id: inference id: inference
uses: actions/ai-inference@v1 uses: actions/ai-inference@v2
with: with:
prompt: 'Hello!' prompt: 'Hello!'
system-prompt-file: './path/to/system-prompt.txt' system-prompt-file: './path/to/system-prompt.txt'
@@ -146,7 +146,7 @@ This can be useful when model response exceeds actions output limit
steps: steps:
- name: Test Local Action - name: Test Local Action
id: inference id: inference
uses: actions/ai-inference@v1 uses: actions/ai-inference@v2
with: with:
prompt: 'Hello!' prompt: 'Hello!'
@@ -169,7 +169,7 @@ repository management, issue tracking, and pull request operations.
steps: steps:
- name: AI Inference with GitHub Tools - name: AI Inference with GitHub Tools
id: inference id: inference
uses: actions/ai-inference@v1.2 uses: actions/ai-inference@v2
with: with:
prompt: 'List my open pull requests and create a summary' prompt: 'List my open pull requests and create a summary'
enable-github-mcp: true enable-github-mcp: true
@@ -183,7 +183,7 @@ and the GitHub MCP server:
steps: steps:
- name: AI Inference with Separate MCP Token - name: AI Inference with Separate MCP Token
id: inference id: inference
uses: actions/ai-inference@v1.2 uses: actions/ai-inference@v2
with: with:
prompt: 'List my open pull requests and create a summary' prompt: 'List my open pull requests and create a summary'
enable-github-mcp: true enable-github-mcp: true
@@ -191,6 +191,26 @@ steps:
github-mcp-token: ${{ secrets.USER_PAT }} 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 When MCP is enabled, the AI model will have access to GitHub tools and can
perform actions like searching issues and PRs. perform actions like searching issues and PRs.
@@ -213,6 +233,7 @@ the action:
| `max-tokens` | The max number of tokens to generate | 200 | | `max-tokens` | The max number of tokens to generate | 200 |
| `enable-github-mcp` | Enable Model Context Protocol integration with GitHub tools | `false` | | `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-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 ## Outputs
+2 -2
View File
@@ -199,7 +199,7 @@ describe('main.ts', () => {
await run() await run()
expect(mockConnectToGitHubMCP).toHaveBeenCalledWith('fake-token') expect(mockConnectToGitHubMCP).toHaveBeenCalledWith('fake-token', '')
expect(mockMcpInference).toHaveBeenCalledWith( expect(mockMcpInference).toHaveBeenCalledWith(
expect.objectContaining({ expect.objectContaining({
messages: [ messages: [
@@ -226,7 +226,7 @@ describe('main.ts', () => {
await run() await run()
expect(mockConnectToGitHubMCP).toHaveBeenCalledWith('fake-token') expect(mockConnectToGitHubMCP).toHaveBeenCalledWith('fake-token', '')
expect(mockSimpleInference).toHaveBeenCalled() expect(mockSimpleInference).toHaveBeenCalled()
expect(mockMcpInference).not.toHaveBeenCalled() expect(mockMcpInference).not.toHaveBeenCalled()
expect(core.warning).toHaveBeenCalledWith('MCP connection failed, falling back to simple inference') expect(core.warning).toHaveBeenCalledWith('MCP connection failed, falling back to simple inference')
+34
View File
@@ -113,6 +113,40 @@ describe('mcp.ts', () => {
expect(result?.tools).toHaveLength(0) expect(result?.tools).toHaveLength(0)
expect(core.info).toHaveBeenCalledWith('Retrieved 0 tools from GitHub MCP server') 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', () => { describe('executeToolCall', () => {
+4
View File
@@ -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. 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 required: false
default: '' 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. # Define your outputs here.
outputs: outputs:
+2 -1
View File
@@ -62,6 +62,7 @@ export async function run(): Promise<void> {
// Get GitHub MCP token (use dedicated token if provided, otherwise fall back to main token) // Get GitHub MCP token (use dedicated token if provided, otherwise fall back to main token)
const githubMcpToken = core.getInput('github-mcp-token') || token const githubMcpToken = core.getInput('github-mcp-token') || token
const githubMcpToolsets = core.getInput('github-mcp-toolsets')
const endpoint = core.getInput('endpoint') const endpoint = core.getInput('endpoint')
@@ -81,7 +82,7 @@ export async function run(): Promise<void> {
let modelResponse: string | null = null let modelResponse: string | null = null
if (enableMcp) { if (enableMcp) {
const mcpClient = await connectToGitHubMCP(githubMcpToken) const mcpClient = await connectToGitHubMCP(githubMcpToken, githubMcpToolsets)
if (mcpClient) { if (mcpClient) {
modelResponse = await mcpInference(inferenceRequest, mcpClient) modelResponse = await mcpInference(inferenceRequest, mcpClient)
+15 -5
View File
@@ -35,17 +35,27 @@ export interface GitHubMCPClient {
/** /**
* Connect to the GitHub MCP server and retrieve available tools * Connect to the GitHub MCP server and retrieve available tools
*/ */
export async function connectToGitHubMCP(token: string): Promise<GitHubMCPClient | null> { export async function connectToGitHubMCP(token: string, toolsets?: string): Promise<GitHubMCPClient | null> {
const githubMcpUrl = 'https://api.githubcopilot.com/mcp/' const githubMcpUrl = 'https://api.githubcopilot.com/mcp/'
core.info('Connecting to GitHub MCP server...') core.info('Connecting to GitHub MCP server...')
const transport = new StreamableHTTPClientTransport(new URL(githubMcpUrl), { const headers: Record<string, string> = {
requestInit: {
headers: {
Authorization: `Bearer ${token}`, Authorization: `Bearer ${token}`,
'X-MCP-Readonly': 'true', '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,
}, },
}) })