secure-github-ops
# Secure GitHub Ops MCP Server
Created by Aaron Murillo
An MCP server that makes GitHub automation actually safe. Every write operation needs approval before it runs, so you never have to worry about runaway scripts creating 100 issues while you're grabbing coffee.
## What This Does
You know how most automation just... does stuff immediately? This flips that. When you (or an AI) try to create an issue, open a PR, or add a comment, it goes into a pending queue. Then someone with admin access reviews and approves it. Only then does it actually hit GitHub.
Two roles:
- Operators can request actions
- Admins can approve, deny, and see what's pending
Everything gets logged so you have a full audit trail.
## Getting Started
You'll need Node 18+ and a GitHub token.
```bash
cd secure-github-ops
npm install
cp .env.example .env
```
Open `.env` and fill in your stuff:
```bash
GITHUB_TOKEN=ghp_your_token_here
ADMIN_API_KEYS=some-secret-admin-key
OPERATOR_API_KEYS=some-secret-operator-key
```
Then run it:
```bash
npm run build
npm start
```
For dev mode with hot reload:
```bash
npm run dev
```
## Using with Claude Desktop
Add this to your Claude Desktop config:
```json
{
"mcpServers": {
"secure-github-ops": {
"command": "node",
"args": ["/path/to/secure-github-ops/dist/index.js"],
"env": {
"GITHUB_TOKEN": "ghp_your_token",
"ADMIN_API_KEYS": "your-admin-key",
"OPERATOR_API_KEYS": "your-operator-key"
}
}
}
}
```
## The Tools
For operators and admins:
- github.issues.create - request to create an issue
- github.pr.open - request to open a PR
- github.comment.add - request to add a comment
Admin only:
- admin.approve_action - approve and run a pending action
- admin.deny_action - reject a pending action
- admin.list_pending_actions - see what's waiting
## How It Works
Say an operator wants to create an issue:
```javascript
// Operator requests it
{
"tool": "github.issues.create",
"arguments": {
"_authToken": "operator-key",
"owner": "myorg",
"repo": "myrepo",
"title": "Fix the login bug"
}
}
// Returns a pending action with an ID
```
Nothing happened on GitHub yet. Now an admin checks what's pending:
```javascript
{
"tool": "admin.list_pending_actions",
"arguments": { "_authToken": "admin-key" }
}
// Shows the pending issue request
```
Admin approves it:
```javascript
{
"tool": "admin.approve_action",
"arguments": {
"_authToken": "admin-key",
"actionId": "the-uuid-from-before"
}
}
// NOW the issue gets created
```
## Config Options
GITHUB_TOKEN (required) - Your GitHub PAT with repo access
ADMIN_API_KEYS (required) - Comma-separated admin keys
OPERATOR_API_KEYS (optional) - Comma-separated operator keys
ALLOWED_REPOS (optional) - Lock it down to specific repos like owner/repo1,owner/repo2
LOG_LEVEL (optional) - debug, info, warn, error
## About the STDIO Transport
This uses STDIO, which means it talks through stdin/stdout. All the logs go to stderr so they don't mess with the protocol. If you're wondering why there's no console.log anywhere, that's why.
Want HTTP instead? That's on the roadmap. The core code stays the same, just swap the transport.
## Running Tests
```bash
npm test
```
26 tests covering auth, config, and the pending store.
## Docker
```bash
docker build -t secure-github-ops .
docker run -e GITHUB_TOKEN=... -e ADMIN_API_KEYS=... secure-github-ops
```
## What's Next
Eventually adding HTTP transport so you can host this as a service. Also thinking about persistent storage for the pending actions (right now they live in memory).
TDQS
Scored across 6 tools
Each tool has a distinct purpose: admin tools handle approval/denial/pending, while github tools target unique actions (comment, create issue, open PR). No overlap exists.
Tool names follow a domain.subdomain.action pattern, but admin tools use verb_noun (e.g., approve_action) while github tools use noun.verb (e.g., comment.add) and an abbreviation (pr.open). This minor inconsistency is manageable.
6 tools is well-scoped for a secure approval workflow with limited GitHub write operations. Each tool serves a necessary role without bloat.
The set covers creation and commenting but lacks update, delete, or merge operations for GitHub resources. Admin tools are complete for approval, but the overall surface feels incomplete for typical GitHub write needs.