Skip to content

MCP — GitHub Server

Enforce Scopebound policies on agents using the GitHub MCP server.

Install

pip install scopebound

Role template

from scopebound import ScopeboundSDK
from scopebound.adapters.mcp_github import GitHubMCPAdapter

sb = ScopeboundSDK(base_url="https://your-partner.api.scopebound.ai", api_key="sb-...")

role = GitHubMCPAdapter.role_template(
    name="github-agent",
    allowed_repos=["scopebound-ai/scopebound", "scopebound-ai/scopebound-python"],
    allowed_branches=["main", "release/*"],   # branches agent may read/push to
    block_push_to_main=True,                  # enforces no direct push to main
    approval_required=["merge_pr"]            # HITL on merge
)
sb.create_role(**role)

Integration

from scopebound.adapters.mcp_github import GitHubMCPAdapter

adapter = GitHubMCPAdapter(sb, role_id="github-agent")

@server.pre_call
def enforce(tool_name: str, arguments: dict) -> None:
    adapter.enforce(tool_name, arguments)

Enforced tools

Tool Default policy Notes
read_file Allow Repo must be in allowed_repos
create_issue Allow Repo must be in allowed_repos
push_commit Allow Branch must not be main unless block_push_to_main=False
create_pr Allow Repo must be in allowed_repos
merge_pr Approval required Always requires HITL by default

Deny codes

Code Trigger
SCOPE_VIOLATION Tool not in role's allowed_tools
PARAMETER_VIOLATION Repo not in allowed_repos, or direct push to main blocked
MCP_SERVER_UNAUTHORIZED Agent's JWT does not include github in allowed_mcp_servers
MCP_TOOL_NOT_FOUND Tool name not in GitHub MCP server's declared manifest
MCP_ARGUMENT_SCHEMA_VIOLATION Required argument missing from call

Example: block direct push to main

# Role created with block_push_to_main=True
try:
    adapter.enforce("push_commit", {"repo": "scopebound-ai/scopebound", "branch": "main", "message": "fix"})
except ScopeboundDenyError as e:
    print(e.deny_code)   # PARAMETER_VIOLATION
    print(e.reason)      # "direct push to main is not permitted"

HITL approval on merge

from scopebound import ScopeboundPendingError

try:
    adapter.enforce("merge_pr", {"repo": "scopebound-ai/scopebound", "pr_number": 42})
except ScopeboundPendingError as e:
    status = sb.get_approval(e.approval_id)
    # Poll until approved or expired

Direct endpoint

curl -X POST https://your-partner.api.scopebound.ai/v1/mcp/enforce \
  -H "X-Scopebound-API-Key: sb-your-key" \
  -H "Content-Type: application/json" \
  -d '{
    "jwt": "your-session-jwt",
    "tool_name": "push_commit",
    "arguments": {"repo": "scopebound-ai/scopebound", "branch": "feature/new-rule"},
    "mcp_server": "github",
    "mcp_tool_schema": {"required": ["repo", "branch"]}
  }'