Codeberg MCP Server
A Model Context Protocol (MCP) server that provides Claude Code with comprehensive access to Codeberg repositories and features through the codeberg-cli tool.
Features
- Repository Management: List, create, clone repositories
- Issue Management: Create, update, comment on issues
- Pull Request Operations: Create, review, merge pull requests
- Authentication: Check auth status and user information
- Full CLI Integration: Leverages existing
codeberg-cliauthentication
Prerequisites
Required Software
- Python 3.12+
- codeberg-cli - Install from codeberg.org/Aviac/codeberg-cli
- Task runner (optional) - Install from taskfile.dev
Codeberg Authentication & Permissions
Before using this MCP server, you need to authenticate with Codeberg and ensure proper permissions.
Step 1: Install codeberg-cli
# Download and install codeberg-cli from Debian/Ubuntu package repository
# Add the repository
echo 'deb https://codeberg.org/api/packages/timstoop/debian bookworm main' | sudo tee /etc/apt/sources.list.d/codeberg-cli.list
sudo apt-get update --allow-insecure-repositories
sudo apt-get install -y --allow-unauthenticated codeberg-cli
# Or download binary directly (replace with latest version)
wget https://codeberg.org/Aviac/codeberg-cli/releases/latest/download/berg-linux-amd64
chmod +x berg-linux-amd64
sudo mv berg-linux-amd64 /usr/local/bin/berg
Step 2: Create a Codeberg Access Token
- Go to codeberg.org and log in
- Navigate to Settings → Applications → Generate New Token
- Create a token with the following scopes:
Required Permissions:
repo- Full repository access (read, write, admin)user- User profile informationread:user- Read user profile datawrite:repo_hook- Repository webhook management (if needed)
Optional Permissions (for enhanced functionality):
read:org- Read organization datawrite:org- Write organization data (if managing org repos)
Step 3: Authenticate with codeberg-cli
# Method 1: Interactive authentication
berg auth login
# Method 2: Token-based authentication
export BERG_TOKEN="your_token_here"
berg auth status
Verify authentication works:
berg user view
berg repo list
Installation
Development Setup
# Clone the repository
git clone <repository-url>
cd codeberg-mcp
# Create virtual environment and install dependencies
task venv
task install-dev
# Set up pre-commit hooks
task setup-precommit
# Run tests to verify setup
task test
Production Installation
# Install directly from source
pip install .
# Or install in development mode
pip install -e .
Container Deployment
# Pull published container
docker pull codeberg.org/timstoop/codeberg-mcp:main
# Run with authentication
docker run -e BERG_TOKEN="your_token" codeberg.org/timstoop/codeberg-mcp:main
# Or build locally
docker build -t codeberg-mcp .
docker run -e BERG_TOKEN="your_token" codeberg-mcp
Note: The published Docker container at codeberg.org/timstoop/codeberg-mcp includes a modified version of codeberg-cli with all pending patches already applied, ensuring the latest fixes and features are available without waiting for upstream releases.
Configuration
Environment Variables
BERG_BASE_URL- Codeberg instance URL (default:https://codeberg.org)BERG_TOKEN- Authentication token (recommended method)LOG_LEVEL- Logging level (default:INFO)
Example Configuration
export BERG_BASE_URL="https://codeberg.org"
export BERG_TOKEN="your_personal_access_token"
export LOG_LEVEL="INFO"
Usage
Running the MCP Server
# Using task runner
task serve
# Using Python directly
python -m app.run
# Using installed package
codeberg-mcp
Claude Code Integration
Add to your Claude Code MCP configuration:
{
"mcpServers": {
"codeberg": {
"command": "codeberg-mcp",
"env": {
"BERG_TOKEN": "your_token_here"
}
}
}
}
Available MCP Tools
Repository Management
list_repositories
List repositories accessible to the authenticated user.
Parameters:
owner(optional): Filter repositories by owner
Example:
{
"name": "list_repositories",
"arguments": {
"owner": "username"
}
}
get_repository
Get detailed information about a specific repository.
Parameters:
repository(required): Repository in "owner/repo" format
Example:
{
"name": "get_repository",
"arguments": {
"repository": "owner/repo-name"
}
}
create_repository
Create a new repository.
Parameters:
name(required): Repository namedescription(optional): Repository descriptionprivate(optional): Whether repository should be private (default: false)
Example:
{
"name": "create_repository",
"arguments": {
"name": "my-new-repo",
"description": "A test repository",
"private": false
}
}
clone_repository
Clone a repository to a local path.
Parameters:
repository(required): Repository in "owner/repo" formatpath(required): Local path to clone to
Example:
{
"name": "clone_repository",
"arguments": {
"repository": "owner/repo-name",
"path": "/path/to/local/directory"
}
}
Issue Management
list_issues
List repository issues with optional filtering.
Parameters:
repository(required): Repository in "owner/repo" formatstate(optional): Filter by state - "open", "closed", or "all"
Example:
{
"name": "list_issues",
"arguments": {
"repository": "owner/repo-name",
"state": "open"
}
}
get_issue
Get detailed information about a specific issue.
Parameters:
repository(required): Repository in "owner/repo" formatissue_number(required): Issue number
Example:
{
"name": "get_issue",
"arguments": {
"repository": "owner/repo-name",
"issue_number": 42
}
}
create_issue
Create a new issue.
Parameters:
repository(required): Repository in "owner/repo" formattitle(required): Issue titlebody(optional): Issue description
Example:
{
"name": "create_issue",
"arguments": {
"repository": "owner/repo-name",
"title": "Bug: Application crashes on startup",
"body": "Detailed description of the bug..."
}
}
update_issue
Update an existing issue.
Parameters:
repository(required): Repository in "owner/repo" formatissue_number(required): Issue numbertitle(optional): New titlebody(optional): New bodystate(optional): New state - "open" or "closed"
Example:
{
"name": "update_issue",
"arguments": {
"repository": "owner/repo-name",
"issue_number": 42,
"state": "closed"
}
}
add_issue_comment
Add a comment to an issue.
Parameters:
repository(required): Repository in "owner/repo" formatissue_number(required): Issue numberbody(required): Comment body
Example:
{
"name": "add_issue_comment",
"arguments": {
"repository": "owner/repo-name",
"issue_number": 42,
"body": "This issue has been fixed in commit abc123"
}
}
get_issue_comments
Get comments on an issue.
Parameters:
repository(required): Repository in "owner/repo" formatissue_number(required): Issue number
Example:
{
"name": "get_issue_comments",
"arguments": {
"repository": "owner/repo-name",
"issue_number": 42
}
}
Pull Request Management
list_pull_requests
List repository pull requests with optional filtering.
Parameters:
repository(required): Repository in "owner/repo" formatstate(optional): Filter by state - "open", "closed", "merged", or "all"
Example:
{
"name": "list_pull_requests",
"arguments": {
"repository": "owner/repo-name",
"state": "open"
}
}
get_pull_request
Get detailed information about a specific pull request.
Parameters:
repository(required): Repository in "owner/repo" formatpr_number(required): Pull request number
Example:
{
"name": "get_pull_request",
"arguments": {
"repository": "owner/repo-name",
"pr_number": 15
}
}
create_pull_request
Create a new pull request.
Parameters:
repository(required): Repository in "owner/repo" formattitle(required): Pull request titlehead(required): Head branchbase(required): Base branchbody(optional): Pull request description
Example:
{
"name": "create_pull_request",
"arguments": {
"repository": "owner/repo-name",
"title": "Add new feature",
"head": "feature-branch",
"base": "main",
"body": "This PR adds a new feature that..."
}
}
review_pull_request
Review a pull request.
Parameters:
repository(required): Repository in "owner/repo" formatpr_number(required): Pull request numberevent(required): Review event - "APPROVE", "REQUEST_CHANGES", or "COMMENT"body(optional): Review body (required for REQUEST_CHANGES and COMMENT)
Example:
{
"name": "review_pull_request",
"arguments": {
"repository": "owner/repo-name",
"pr_number": 15,
"event": "APPROVE",
"body": "Looks good to me!"
}
}
merge_pull_request
Merge a pull request.
Parameters:
repository(required): Repository in "owner/repo" formatpr_number(required): Pull request numbermerge_method(optional): Merge method - "merge", "squash", or "rebase" (default: "merge")commit_title(optional): Custom commit titlecommit_message(optional): Custom commit message
Example:
{
"name": "merge_pull_request",
"arguments": {
"repository": "owner/repo-name",
"pr_number": 15,
"merge_method": "squash",
"commit_title": "Add new feature (#15)"
}
}
get_pull_request_comments
Get comments on a pull request.
Parameters:
repository(required): Repository in "owner/repo" formatpr_number(required): Pull request number
Example:
{
"name": "get_pull_request_comments",
"arguments": {
"repository": "owner/repo-name",
"pr_number": 15
}
}
get_pull_request_reviews
Get reviews on a pull request.
Parameters:
repository(required): Repository in "owner/repo" formatpr_number(required): Pull request number
Example:
{
"name": "get_pull_request_reviews",
"arguments": {
"repository": "owner/repo-name",
"pr_number": 15
}
}
Authentication & User Management
get_auth_status
Check authentication status.
Parameters: None
Example:
{
"name": "get_auth_status",
"arguments": {}
}
get_user_info
Get user information.
Parameters:
username(optional): Username to get info for (defaults to current user)
Example:
{
"name": "get_user_info",
"arguments": {
"username": "specific-user"
}
}
Error Handling
The MCP server provides comprehensive error handling:
- Authentication Errors: Clear messages for token/auth issues
- Permission Errors: Detailed information about missing permissions
- Validation Errors: Input validation with helpful error messages
- CLI Errors: Formatted error messages from codeberg-cli
- Network Errors: Timeout and connection error handling
Security Considerations
- Token Security: Never hardcode tokens in configuration
- Environment Variables: Use environment variables for sensitive data
- Minimal Permissions: Use least-privilege principle for token scopes
- Token Rotation: Regularly rotate access tokens
Development
Running Tests
# Run all tests
task test
# Run with coverage
task test-cov
# Run quality checks
task lint
Code Quality
# Format code
task format
# Run type checking
task mypy
# Run security scan
task bandit
Pre-commit Hooks
# Install hooks
task setup-precommit
# Run hooks manually
pre-commit run --all-files
Local Test Environment
The project includes a local Forgejo test environment for integration testing:
# Start local test environment (Forgejo with PKI-based HTTPS)
cd test-environment
docker compose up -d
# Configure for local testing
export BERG_BASE_URL="https://localhost"
export BERG_TOKEN="your_test_token"
# Stop environment
docker compose down
The test environment runs on port 443 with self-signed certificates for realistic HTTPS testing.
Troubleshooting
Common Issues
-
Authentication Failed
# Check authentication berg auth status # Re-authenticate berg auth login -
Permission Denied
- Verify token has required scopes
- Check repository access permissions
- Ensure token hasn't expired
-
CLI Not Found
# Verify codeberg-cli installation which berg berg --version -
Network Issues
- Check internet connectivity
- Verify BERG_BASE_URL is correct
- Check firewall/proxy settings
Debug Mode
Enable debug logging:
export LOG_LEVEL="DEBUG"
codeberg-mcp
Contributing
- Fork the repository
- Create a feature branch
- Write tests first (TDD approach)
- Implement features
- Ensure all quality checks pass
- Submit a pull request
License
MIT License - see LICENSE file for details.
This project is a wrapper around existing tools and is designed for maximum compatibility and ease of use.
Support
- Issues: Report bugs and feature requests on the repository issue tracker
- Documentation: Check the project documentation for detailed information
- Community: Join the Codeberg community for support and discussions