Skip to main content
Glama
README.md
# Ubuntu MCP Servers

MCP servers for querying and submitting Ubuntu data via [ubq](https://github.com/canonical/ubq). Each server exposes a focused set of tools and resources for a single data domain — bugs, packages, versions, or merge requests.

## Requirements

- Python >= 3.13
- [uv](https://docs.astral.sh/uv/) (recommended) or pip

## Installation

```shell
git clone https://github.com/lvoytek/ubuntu-mcp.git && cd ubuntu-mcp
uv sync
```

This installs the five entry-point commands:

| Command | Server |
|---|---|
| `ubuntu-mcp-bugs` | Bug data |
| `ubuntu-mcp-packages` | Package data |
| `ubuntu-mcp-versions` | Package version data |
| `ubuntu-mcp-merge-requests` | Merge request data |
| `ubuntu-mcp-all` | All of the above at once |

## Running a server

All servers share the same CLI flags:

```shell
ubuntu-mcp-bugs                                           # streamable-http on 0.0.0.0:8000 (default)
ubuntu-mcp-bugs --transport streamable-http --host 127.0.0.1 --port 9000
ubuntu-mcp-bugs --transport stdio                         # for MCP clients that spawn the process
```

Replace `ubuntu-mcp-bugs` with any of the commands above.

### Running all servers

Use `ubuntu-mcp-all` to start every server at once on sequential ports:

```shell
ubuntu-mcp-all                              # bugs=8000, packages=8001, versions=8002, merge-requests=8003
ubuntu-mcp-all --host 127.0.0.1 --port 9000 # bugs=9000, packages=9001, versions=9002, merge-requests=9003
```

### Connecting an MCP client

For an HTTP server, add the URL to your client config:

```json
{
  "mcp": {
    "ubuntu-mcp-bugs": {
      "type": "remote",
      "url": "http://127.0.0.1:8000/mcp"
    },
    "ubuntu-mcp-packages": {
      "type": "remote",
      "url": "http://127.0.0.1:8001/mcp"
    },
    "ubuntu-mcp-versions": {
      "type": "remote",
      "url": "http://127.0.0.1:8002/mcp"
    },
    "ubuntu-mcp-merge-requests": {
      "type": "remote",
      "url": "http://127.0.0.1:8003/mcp"
    }
  }
}
```

For stdio, point the client at the entry-point command directly.

## Authentication

Most tools require an authenticated session before they can query data. Call `login_provider` first.

### Launchpad

Launchpad supports three authentication modes:

| Mode | When |
|---|---|
| **Anonymous** | No credentials provided — read-only public access. Best for CI or headless environments. |
| **Credential file** | `credential_file` path points to a file containing a Launchpad OAuth token. |
| **Inline token** | `token` (and optionally `username`) passed directly. |

A default credential file path is also checked automatically: `~/.config/ubq/launchpad-credentials`. If this file exists and no other credentials are provided, its contents are used as the token.

#### Anonymous (no credentials)

```json
{
  "tool": "login_provider",
  "arguments": { "provider_name": "launchpad" }
}
```

#### Credential file

```json
{
  "tool": "login_provider",
  "arguments": {
    "provider_name": "launchpad",
    "credential_file": "/path/to/launchpad-token"
  }
}
```

#### Inline token

```json
{
  "tool": "login_provider",
  "arguments": {
    "provider_name": "launchpad",
    "token": "oauth-token-value"
  }
}
```

### GitHub

GitHub requires a personal access token passed via `token`:

```json
{
  "tool": "login_provider",
  "arguments": {
    "provider_name": "github",
    "token": "ghp_xxxxxxxxxxxx"
  }
}
```

### Snapcraft

Snapcraft requires a token passed via `token`:

```json
{
  "tool": "login_provider",
  "arguments": {
    "provider_name": "snapcraft",
    "token": "snap-token-value"
  }
}
```

## Servers and tools

### Bugs — `ubuntu-mcp-bugs`

| Tool | Description |
|---|---|
| `login_provider` | Authenticate with a bug data provider |
| `list_bug_providers` | List available bug data provider names |
| `get_bug` | Fetch a bug by ID |
| `search_bugs` | Search bugs by criteria |
| `submit_bug` | Submit a new bug |

**Resources:**

- `ubq://bugs/providers` — available bug data providers
- `ubq://bugs/sessions` — active bug data provider sessions

#### `get_bug`

```
bug_id: str          — the bug ID
provider_name: str   — e.g. "launchpad" or "github"
metadata_only: bool  — set True to skip comments and tasks
```

#### `search_bugs`

```
provider_name: str          — e.g. "launchpad" or "github"
title: str | None           — filter by title substring
tags: list[str] | None      — filter by tags
status: str | None          — e.g. "New", "Fix Released"
importance: str | None      — e.g. "Medium", "High"
owner: str | None           — username of the bug owner
assignee: str | None        — username of the assignee
milestone: str | None       — milestone name
created_since: str | None   — ISO 8601 date (e.g. "2025-01-01")
created_before: str | None  — ISO 8601 date
modified_since: str | None  — ISO 8601 date
```

#### `submit_bug`

```
title: str                  — bug title (required)
provider_name: str          — e.g. "launchpad" or "github"
package_names: list[str]    — affected package names
description: str | None     — bug description
importance: str | None      — e.g. "Medium"
status: str | None          — e.g. "New"
tags: list[str] | None      — tags to apply
assignee: str | None        — username to assign
private: bool               — mark the bug private (default False)
milestone: str | None       — target milestone
```

---

### Packages — `ubuntu-mcp-packages`

| Tool | Description |
|---|---|
| `login_provider` | Authenticate with a package data provider |
| `list_package_providers` | List available package data provider names |
| `get_package` | Fetch a package by name |

**Resources:**

- `ubq://packages/providers` — available package data providers
- `ubq://packages/sessions` — active package data provider sessions

#### `get_package`

```
package_name: str    — the source package name
provider_name: str   — e.g. "launchpad" or "snapcraft"
```

---

### Versions — `ubuntu-mcp-versions`

| Tool | Description |
|---|---|
| `login_provider` | Authenticate with a version data provider |
| `list_version_providers` | List available version data provider names |
| `get_version` | Fetch the version of a package in an Ubuntu series |

**Resources:**

- `ubq://versions/providers` — available version data providers
- `ubq://versions/sessions` — active version data provider sessions

#### `get_version`

```
package_name: str    — the source package name
series: str          — Ubuntu codename (e.g. "noble", "jammy")
provider_name: str   — e.g. "launchpad" or "snapcraft"
pocket: str | None   — "Release", "Security", "Updates", "Proposed", or None for default
```

---

### Merge Requests — `ubuntu-mcp-merge-requests`

| Tool | Description |
|---|---|
| `login_provider` | Authenticate with a merge request provider |
| `list_merge_request_providers` | List available merge request provider names |
| `get_merge_request` | Fetch a merge request by ID |
| `get_merge_requests_from_user` | Fetch merge requests assigned to a user |

**Resources:**

- `ubq://merge-requests/providers` — available merge request providers
- `ubq://merge-requests/sessions` — active merge request provider sessions

#### `get_merge_request`

```
merge_request_id: str  — the merge request ID
provider_name: str     — e.g. "launchpad" or "github"
```

#### `get_merge_requests_from_user`

```
user_id: str         — username
provider_name: str    — e.g. "launchpad" or "github"
```

## Available providers

| Provider | Domains |
|---|---|
| `launchpad` | Bugs, packages, versions, merge requests |
| `github` | Bugs, merge requests |
| `snapcraft` | Packages, versions |

## Development

```shell
uv sync                    # install all dependencies
uv run ruff check .         # lint
uv run pytest tests/ -v    # run tests
```

## License

GPL-3.0

TDQS

A3.6/5.0

Scored across 5 tools

Disambiguation5/5

Each tool targets a distinct operation: listing providers, authentication, searching, fetching by ID, and submitting. No overlaps or ambiguity.

Naming Consistency5/5

All tool names follow a consistent verb_noun pattern with underscore separation (e.g., get_bug, list_bug_providers, login_provider, search_bugs, submit_bug).

Tool Count5/5

Five tools cover the essential bug tracking workflow without being excessive or insufficient for a focused server.

Completeness4/5

Basic operations (list, auth, search, get, create) are present, but update and delete/close operations are missing, leaving minor gaps in full lifecycle management.

Maintenance

ActivityInactive
ResponsivenessNo issues