server.py•1.82 kB
import os
from fastapi import FastAPI
from pydantic import BaseModel
import requests
from dotenv import load_dotenv
# Load .env locally only (does nothing in Cloud Run)
load_dotenv()
GITHUB_TOKEN = os.getenv("GITHUB_TOKEN")
GITHUB_API_URL = "https://api.github.com"
HEADERS = {"Authorization": f"Bearer {GITHUB_TOKEN}"}
app = FastAPI(
title="GitHub MCP Server",
description="Exposes GitHub actions as tools via MCP-compatible OpenAPI endpoints.",
version="1.0.0",
)
class RepoInput(BaseModel):
owner: str
repo: str
class IssueInput(RepoInput):
title: str
body: str = ""
class PRInput(RepoInput):
pull_number: int
@app.get("/get_open_pull_requests")
def get_open_pull_requests(owner: str, repo: str):
url = f"{GITHUB_API_URL}/repos/{owner}/{repo}/pulls?state=open"
response = requests.get(url, headers=HEADERS)
return response.json()
@app.get("/list_open_issues")
def list_open_issues(owner: str, repo: str):
url = f"{GITHUB_API_URL}/repos/{owner}/{repo}/issues?state=open"
response = requests.get(url, headers=HEADERS)
return response.json()
@app.post("/create_issue")
def create_issue(input: IssueInput):
url = f"{GITHUB_API_URL}/repos/{input.owner}/{input.repo}/issues"
payload = {"title": input.title, "body": input.body}
response = requests.post(url, headers=HEADERS, json=payload)
return response.json()
@app.post("/merge_pull_request")
def merge_pull_request(input: PRInput):
url = f"{GITHUB_API_URL}/repos/{input.owner}/{input.repo}/pulls/{input.pull_number}/merge"
response = requests.put(url, headers=HEADERS)
return response.json()
# Required for Cloud Run: bind to 0.0.0.0 and $PORT
if __name__ == "__main__":
import uvicorn
uvicorn.run("server:app", host="0.0.0.0", port=int(os.getenv("PORT", 8080)))