Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 48 additions & 0 deletions .github/workflows/sdk-python-ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
name: Python SDK CI

on:
push:
branches: [main]
paths:
- 'packages/sdk-python/**'
pull_request:
branches: [main]
paths:
- 'packages/sdk-python/**'

concurrency:
group: sdk-python-ci-${{ github.ref }}
cancel-in-progress: true

jobs:
check:
runs-on: ubuntu-latest
defaults:
run:
working-directory: packages/sdk-python
steps:
- name: Checkout
uses: actions/checkout@v4

- name: Setup Python
uses: actions/setup-python@v5
with:
python-version: '3.13'

- name: Install uv
uses: astral-sh/setup-uv@v4

- name: Install dependencies
run: uv sync --extra dev

- name: Lint
run: uv run ruff check src/ tests/

- name: Format check
run: uv run ruff format --check src/ tests/

- name: Type check
run: uv run ty check src/

- name: Run tests
run: uv run pytest -m "not integration"
57 changes: 57 additions & 0 deletions .github/workflows/sdk-python-publish.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
name: Publish Python SDK

on:
push:
tags:
- 'sdk-python-v*'

jobs:
verify:
runs-on: ubuntu-latest
defaults:
run:
working-directory: packages/sdk-python
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: '3.13'
- uses: astral-sh/setup-uv@v4
- run: uv sync --extra dev
- run: uv run ruff check src/ tests/
- run: uv run ruff format --check src/ tests/
- run: uv run ty check src/
- run: uv run pytest -m "not integration"

publish:
needs: verify
runs-on: ubuntu-latest
environment: pypi
permissions:
id-token: write
defaults:
run:
working-directory: packages/sdk-python
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: '3.13'
- uses: astral-sh/setup-uv@v4

- name: Verify tag matches package version
run: |
TAG_VERSION="${GITHUB_REF#refs/tags/sdk-python-v}"
PKG_VERSION=$(python -c "import tomllib; print(tomllib.load(open('pyproject.toml','rb'))['project']['version'])")
if [ "$TAG_VERSION" != "$PKG_VERSION" ]; then
echo "::error::Tag version ($TAG_VERSION) != pyproject.toml version ($PKG_VERSION)"
exit 1
fi

- name: Build
run: uv build

- name: Publish to PyPI
uses: pypa/gh-action-pypi-publish@release/v1
with:
packages-dir: packages/sdk-python/dist/
7 changes: 4 additions & 3 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,10 @@ apps/
scanner/ # Security scanner (Python, runs as K8s Jobs)
docs/ # Documentation site (Astro/Starlight)
packages/
cli/ # mpak CLI
schemas/ # Shared Zod schemas
sdk/ # TypeScript SDK
cli/ # mpak CLI
schemas/ # Shared Zod schemas
sdk-typescript/ # TypeScript SDK
sdk-python/ # Python SDK (OpenAPI-generated types)
```

## Verification
Expand Down
52 changes: 52 additions & 0 deletions PRODUCT.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
# mpak

mpak is the open-source MCPB (MCP Bundle) registry: a package manager and distribution platform for MCP servers. It lets developers package MCP servers as self-contained bundles, publish them to the registry, and install them with a single CLI command.

## Status

OSS. Core registry (API, web, CLI, scanner) is public. Trust framework is a separate public repo. No private components.

## Domains

| Domain | Purpose |
|--------|---------|
| `mpak.dev` | Bundle registry web UI (search, browse, install) |
| `registry.mpak.dev` | MCP server discovery API |

## Repos / Paths in hq

| Path | Description |
|------|-------------|
| `products/mpak/code/` | This repo: monorepo (API, web, CLI, scanner, SDK) |
| `products/mpak/trust/` | mpak Trust Framework (MTF) security standard |
| `products/mpak/awesome/` | awesome-mcpb: curated list of MCPB bundles |
| `deployments/mpak/` | Kubernetes deployment config |

## Monorepo Layout

```
apps/
api/ # REST API (Hono, Node)
web/ # Registry web UI (Next.js)
cli/ # mpak CLI (Node)
scanner/ # Bundle scanner/validator
packages/
sdk-typescript/ # JS/TS SDK
sdk-python/ # Python SDK (OpenAPI-generated types)
```

## Deployment

See `deployments/mpak/CLAUDE.md` for environment config, deploy commands, and secrets management.

Environments: `staging` (default), `production`.

## Trust Framework

The mpak Trust Framework (MTF) defines security and provenance standards for published bundles. It lives at `products/mpak/trust/` and is published at `mpaktrust.org`.

## Key Concepts

- **MCPB bundle**: A zip containing an MCP server + `manifest.json` + deps. Self-contained, no install step.
- **mpak install**: Downloads a bundle, verifies integrity, configures the MCP client.
- **Registry**: Hosts bundle metadata, download counts, trust scores.
9 changes: 9 additions & 0 deletions packages/sdk-python/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
.venv/
dist/
*.egg-info/
__pycache__/
*.pyc
.pytest_cache/
.ruff_cache/
htmlcov/
.coverage
132 changes: 132 additions & 0 deletions packages/sdk-python/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
# mpak Python SDK

[![CI](https://github.com/NimbleBrainInc/mpak/actions/workflows/sdk-python-ci.yml/badge.svg)](https://github.com/NimbleBrainInc/mpak/actions/workflows/sdk-python-ci.yml)
[![PyPI](https://img.shields.io/pypi/v/mpak)](https://pypi.org/project/mpak/)
[![Python](https://img.shields.io/pypi/pyversions/mpak)](https://pypi.org/project/mpak/)
[![License](https://img.shields.io/pypi/l/mpak)](https://github.com/NimbleBrainInc/mpak/blob/main/packages/sdk-python/LICENSE)
[![mpak.dev](https://mpak.dev/badge.svg)](https://mpak.dev)

Python SDK for the mpak registry - search, download, and resolve MCPB bundles and Agent Skills.

## Installation

```bash
pip install mpak
```

## Quick Start

```python
from mpak import MpakClient

# Create client
client = MpakClient()

# Resolve a bundle to download URL
download = client.get_bundle_download("@nimblebraininc/echo", version="latest")
print(f"Download URL: {download.url}")
print(f"SHA256: {download.sha256}")

# Download and extract a bundle
manifest = client.load_bundle("@nimblebraininc/echo", dest="/app/bundle")
print(f"Loaded: {manifest['name']} v{manifest['version']}")
```

## CLI Usage

The package provides a `mpak-loader` CLI that replaces the standalone `mcpb-loader.py` script:

```bash
# Load from mpak registry
mpak-loader @nimblebraininc/echo /dest/dir

# Load specific version
mpak-loader @nimblebraininc/echo@1.0.0 /dest/dir

# Load from direct URL with SHA256 verification
mpak-loader https://example.com/bundle.mcpb /dest/dir abc123...
```

## Development

### Setup

```bash
# Install with dev dependencies
uv pip install -e ".[dev]"

# Generate types from OpenAPI spec
python scripts/generate-types.py
```

### Testing

```bash
# Run tests
pytest

# Run with coverage
pytest --cov=mpak --cov-report=html

# Lint and format
ruff check .
ruff format .
```

### Verification

Run all checks before submitting changes:

```bash
uv run ruff check src/ tests/ # lint
uv run ruff format --check src/ tests/ # format
uv run ty check src/ # type check
uv run pytest -m "not integration" # unit tests
uv run pytest -m integration # integration tests (hits live registry)
```

CI runs lint, format, type check, and unit tests on every PR via [`sdk-python-ci.yml`](../../.github/workflows/sdk-python-ci.yml).

## Releasing

Releases are automated via GitHub Actions and [PyPI trusted publishing](https://docs.pypi.org/trusted-publishers/) (OIDC). No API tokens required.

**Version is defined in one place:** `pyproject.toml`. The runtime version (`mpak.__version__`) and User-Agent are derived automatically via `importlib.metadata`.

### Steps

1. **Bump version** in `pyproject.toml`:
```bash
# Edit pyproject.toml version field, or use hatch:
hatch version patch # 0.1.0 → 0.1.1
hatch version minor # 0.1.0 → 0.2.0
hatch version major # 0.1.0 → 1.0.0
```

2. **Commit and push:**
```bash
git commit -am "sdk-python: bump to X.Y.Z"
git push
```

3. **Tag and push** (this triggers the publish):
```bash
git tag sdk-python-vX.Y.Z
git push origin sdk-python-vX.Y.Z
```

CI will run the full verification suite, verify the tag matches `pyproject.toml`, build, and publish to PyPI. See [`sdk-python-publish.yml`](../../.github/workflows/sdk-python-publish.yml).

## Type Generation

The SDK types are generated from the mpak registry OpenAPI spec. To regenerate:

```bash
python scripts/generate-types.py
```

This fetches the latest spec from `https://registry.mpak.dev/docs/json` and generates Pydantic models in `src/mpak/generated/types.py`.

## License

Apache-2.0
Loading
Loading