This repository was archived by the owner on Feb 12, 2026. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmcp-github-wrapper.ps1
More file actions
109 lines (94 loc) · 4.64 KB
/
mcp-github-wrapper.ps1
File metadata and controls
109 lines (94 loc) · 4.64 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
Param([Parameter(ValueFromRemainingArguments=$true)] [string[]]$Args)
# GitHub MCP Server wrapper - Docker/Podman version
# Uses the official GitHub MCP server Docker image
# Env overrides: MCP_GITHUB_DOCKER_IMAGE
# Logging note: Diagnostics go to stderr intentionally to keep stdout JSON-only for MCP.
Set-StrictMode -Version Latest
$ErrorActionPreference = 'Stop'
# Obtain GitHub token (prefer env var, fallback to Windows Credential Manager)
if (-not $env:GITHUB_PERSONAL_ACCESS_TOKEN) {
try { Import-Module CredentialManager -ErrorAction Stop } catch { Write-Error 'Install CredentialManager: Install-Module CredentialManager -Scope CurrentUser'; exit 1 }
# Try both common targets: 'github-mcp' (wrapper default) and 'GitHub' (docs/older installs)
$cred = Get-StoredCredential -Target 'github-mcp'
if (-not $cred) { $cred = Get-StoredCredential -Target 'GitHub' }
if (-not $cred) { Write-Error "Credential 'github-mcp' or 'GitHub' not found and GITHUB_PERSONAL_ACCESS_TOKEN not set"; exit 1 }
$env:GITHUB_PERSONAL_ACCESS_TOKEN = $cred.Password
}
# Ensure stdio transport unless explicitly provided
if (-not ($Args -contains 'stdio' -or $Args -contains '--stdio' -or $Args -contains '--sse' -or ($Args | Where-Object { $_ -like '--transport=*' -or $_ -like '--http*' -or $_ -like '--sse*' -or $_ -eq '--port' -or $_ -eq '--host' }))) {
$Args = @('stdio') + $Args
}
# Defaults
$IMG = $env:MCP_GITHUB_DOCKER_IMAGE; if (-not $IMG) { $IMG = 'ghcr.io/github/github-mcp-server:latest' }
$REMOTE_URL = $env:GITHUB_MCP_REMOTE_URL; if (-not $REMOTE_URL) { $REMOTE_URL = 'https://api.githubcopilot.com/mcp/' }
function Invoke-Exec { param([string]$File,[string[]]$Arguments) & $File @Arguments; if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE } }
function Use-RemoteServer {
[Console]::Error.WriteLine("Falling back to remote GitHub MCP server: $REMOTE_URL")
# Check if npx is available for mcp-remote
try {
$null = Get-Command npx -ErrorAction Stop
} catch {
[Console]::Error.WriteLine("Error: npx not found. Cannot use mcp-remote for remote server connection.")
[Console]::Error.WriteLine("Please install Node.js/npm or start Docker/Podman to use GitHub MCP server.")
exit 1
}
# Use mcp-remote to bridge stdio to remote HTTP+SSE server with OAuth
[Console]::Error.WriteLine("Using mcp-remote to connect to remote GitHub MCP server...")
# Use mcp-remote to connect with proper headers for GitHub authentication
# The Authorization header will use the GitHub token
$mcpRemoteArgs = @(
'-y',
'mcp-remote@latest',
$REMOTE_URL,
'--header', "Authorization:Bearer $($env:GITHUB_PERSONAL_ACCESS_TOKEN)"
) + $Args
# Execute mcp-remote with all arguments
& npx @mcpRemoteArgs
exit $LASTEXITCODE
}
# Find container runtime (prefer Podman on Windows)
$runtime = if (Get-Command podman -ErrorAction SilentlyContinue) { 'podman' } elseif (Get-Command docker -ErrorAction SilentlyContinue) { 'docker' } else { $null }
if (-not $runtime) {
Write-Error 'Error: No container runtime found. Please install Docker or Podman.'
[Console]::Error.WriteLine('Attempting to use remote server fallback...')
Use-RemoteServer
}
# Check if container runtime daemon is running
try {
& $runtime info 2>&1 | Out-Null
if ($LASTEXITCODE -ne 0) {
Write-Error "Error: $runtime daemon is not running. Please start it first."
[Console]::Error.WriteLine('Attempting to use remote server fallback...')
Use-RemoteServer
}
} catch {
Write-Error "Error: Failed to check $runtime daemon status."
[Console]::Error.WriteLine('Attempting to use remote server fallback...')
Use-RemoteServer
}
# Ensure image present (auto-pull if missing)
try {
& $runtime image inspect $IMG 2>&1 | Out-Null
if ($LASTEXITCODE -ne 0) {
[Console]::Error.WriteLine("Pulling GitHub MCP Docker image: $IMG")
& $runtime pull $IMG
if ($LASTEXITCODE -ne 0) {
Write-Error "Failed to pull image: $IMG"
[Console]::Error.WriteLine('Attempting to use remote server fallback...')
Use-RemoteServer
}
[Console]::Error.WriteLine("Pulled GitHub MCP Docker image successfully: $IMG")
}
} catch {
[Console]::Error.WriteLine("Pulling GitHub MCP Docker image: $IMG")
& $runtime pull $IMG
if ($LASTEXITCODE -ne 0) {
Write-Error "Failed to pull image: $IMG"
[Console]::Error.WriteLine('Attempting to use remote server fallback...')
Use-RemoteServer
}
[Console]::Error.WriteLine("Pulled GitHub MCP Docker image successfully: $IMG")
}
[Console]::Error.WriteLine("Using GitHub MCP via container image: $IMG")
# Run the container
Invoke-Exec $runtime @('run','-i','--rm','-e',"GITHUB_PERSONAL_ACCESS_TOKEN=$($env:GITHUB_PERSONAL_ACCESS_TOKEN)",$IMG) + $Args