Skip to content
Open
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
51 changes: 51 additions & 0 deletions .github/workflows/release-mcp.yml
Original file line number Diff line number Diff line change
Expand Up @@ -65,3 +65,54 @@ jobs:
with:
packages-dir: dist/
attestations: true

build-mcpb:
name: Build MCPB bundle
needs: build
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- uses: actions/checkout@v6

# ``scripts/build_mcpb.py`` is stdlib-only and shells out to the ``mcpb``
# CLI — no project deps are needed for this job. Use setup-python
# instead of setup-uv so we don't pull in a project venv resolution we
# don't use.
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: "3.14"

- name: Install Node.js (for mcpb CLI)
uses: actions/setup-node@v5
with:
node-version: "20"

- name: Install mcpb CLI
run: npm install -g @anthropic-ai/mcpb

- name: Build .mcpb bundle
id: build
run: |
artifact=$(python scripts/build_mcpb.py | tail -n 1)
echo "artifact=${artifact}" >> "$GITHUB_OUTPUT"
ls -la "${artifact}"

- name: Upload .mcpb artifact
uses: actions/upload-artifact@v7
with:
name: mcpb
path: ${{ steps.build.outputs.artifact }}

- name: Attach .mcpb to GitHub release
# The release workflow triggers on ``mcp-v*`` tags; semantic-release
# creates the GitHub release in an earlier job. Upload the .mcpb as
# an additional asset on the release matching the tag that
# triggered this run.
if: startsWith(github.ref, 'refs/tags/mcp-v')
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
tag="${GITHUB_REF#refs/tags/}"
gh release upload "$tag" "${{ steps.build.outputs.artifact }}" --clobber
22 changes: 18 additions & 4 deletions frontapp_mcp_server/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,21 @@ FRONTAPP_BASE_URL=https://api2.frontapp.com # optional override

### 4. Use with Claude Desktop (stdio)

Add to `~/Library/Application Support/Claude/claude_desktop_config.json`:
**Recommended: install the `.mcpb` bundle** — Claude Desktop has built-in support for
[MCP Bundles](https://github.com/anthropics/mcpb), which install local MCP servers in
one click and prompt for the API key via UI (no JSON editing).

1. Download `frontapp-mcp-server-<version>.mcpb` from the
[latest GitHub release](https://github.com/dougborg/frontapp-openapi-client/releases?q=mcp-v).
1. Drag the `.mcpb` file into Claude Desktop, or open it from the Finder.
1. Confirm install in the dialog. Claude Desktop prompts for your Frontapp API key
(stored securely; never written to a config file by hand).

The bundle ships the server source plus a manifest that declares the runtime
requirements; UV handles dep resolution on first launch.

**Manual `uvx` install (fallback)** — if you'd rather edit
`~/Library/Application Support/Claude/claude_desktop_config.json` directly:

```json
{
Expand All @@ -78,11 +92,11 @@ Add to `~/Library/Application Support/Claude/claude_desktop_config.json`:
}
```

Restart Claude Desktop and the Frontapp tools will appear.
Either path: restart Claude Desktop and the Frontapp tools will appear.

> **Running off a local checkout (dev mode)?** The package isn't on PyPI yet (issue
> #10), and `uvx` resolves from PyPI. To dogfood from a local clone, see
> [MCP_CLAUDE_DESKTOP_DEV.md](MCP_CLAUDE_DESKTOP_DEV.md) — it covers the
> #10), and both the `.mcpb` bundle and `uvx` resolve from PyPI. To dogfood from a local
> clone, see [MCP_CLAUDE_DESKTOP_DEV.md](MCP_CLAUDE_DESKTOP_DEV.md) — it covers the
> `uv run --directory <repo>` config + `.env` setup.

### 5. Use with Claude.ai (streamable-http)
Expand Down
18 changes: 18 additions & 0 deletions frontapp_mcp_server/mcpb/.mcpbignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Files excluded from the .mcpb archive when ``mcpb pack`` runs against the
# build/mcpb/ staging directory. The CLI already excludes a default set
# (.git, node_modules, .DS_Store, .vscode, etc.); this list adds project-
# specific noise.
__pycache__/
*.pyc
*.pyo
.pytest_cache/
.ruff_cache/
.mypy_cache/
.coverage
.coverage.*
htmlcov/
.venv/
*.egg-info/
build/
dist/
tests/
54 changes: 54 additions & 0 deletions frontapp_mcp_server/mcpb/manifest.template.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
{
"manifest_version": "0.4",
"name": "frontapp-mcp-server",
"display_name": "Frontapp",
"version": "__VERSION__",
"description": "MCP server for the Front shared-inbox API — search conversations, read messages, and draft replies from Claude Desktop.",
"long_description": "Exposes Front's Core API (conversations, messages, comments, drafts) as MCP tools. Includes cursor-paginated list/search, full message and comment read tools, two-step confirmation on every mutation, and a drafts-first outbound flow (agents draft, humans send from Front's UI). Transport layer handles retries, 429 rate limits, and cursor pagination.",
"author": {
"name": "Doug Borg",
"email": "dougborg@dougborg.org",
"url": "https://github.com/dougborg"
},
"repository": {
"type": "git",
"url": "https://github.com/dougborg/frontapp-openapi-client.git"
},
"homepage": "https://github.com/dougborg/frontapp-openapi-client",
"documentation": "https://dougborg.github.io/frontapp-openapi-client/",
"support": "https://github.com/dougborg/frontapp-openapi-client/issues",
"license": "MIT",
"keywords": ["frontapp", "front", "conversations", "mcp", "claude", "shared-inbox"],
"server": {
"type": "uv",
"entry_point": "src/frontapp_mcp/__main__.py",
"mcp_config": {
"command": "uv",
"args": [
"run",
"--directory",
"${__dirname}",
"frontapp-mcp-server"
],
"env": {
"FRONTAPP_API_KEY": "${user_config.api_key}"
}
}
},
"compatibility": {
"claude_desktop": ">=0.10.0",
"platforms": ["darwin", "linux", "win32"],
"runtimes": {
"python": ">=3.12,<4.0"
}
},
"user_config": {
"api_key": {
"type": "string",
"title": "Frontapp API Key",
"description": "Front API token. Create one at Front → Settings → Developers → API tokens.",
"required": true,
"sensitive": true
}
}
}
34 changes: 34 additions & 0 deletions frontapp_mcp_server/mcpb/pyproject.template.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# Bundle pyproject.toml for the .mcpb artifact — do NOT edit this directly to
# add deps. The build script (scripts/build_mcpb.py) substitutes ``__VERSION__``
# from the package's own pyproject.toml at pack time. Production runtime deps
# are mirrored from ``frontapp_mcp_server/pyproject.toml`` and must stay in
# sync; the build script verifies this and fails loudly on drift.
#
# This file deliberately omits the ``[tool.uv.sources]`` workspace ref — the
# bundle resolves ``frontapp-openapi-client`` from PyPI, since the workspace
# doesn't exist on the user's machine.
[project]
name = "frontapp-mcp-server"
version = "__VERSION__"
description = "MCP server for the Frontapp API"
requires-python = ">=3.12"
dependencies = [
"fastmcp>=2.13.0",
"frontapp-openapi-client>=0.1.0",
"prefab-ui>=0.19,<0.20",
"pydantic>=2.12.0",
"python-dotenv>=1.0.0",
"structlog>=25.5.0",
"aiosqlite>=0.20.0",
"platformdirs>=4.0.0",
]

[project.scripts]
frontapp-mcp-server = "frontapp_mcp.server:main"

[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"

[tool.hatch.build.targets.wheel]
packages = ["src/frontapp_mcp"]
2 changes: 1 addition & 1 deletion frontapp_mcp_server/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ classifiers = [
]
dependencies = [
"fastmcp>=2.13.0",
"frontapp-openapi-client>=0.51.0",
"frontapp-openapi-client>=0.1.0",
"prefab-ui>=0.19,<0.20",
"pydantic>=2.12.0",
"python-dotenv>=1.0.0",
Expand Down
9 changes: 9 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -469,6 +469,15 @@ regenerate-all = ["vendor-spec", "regenerate-client", "facts"]
validate-openapi = "openapi-spec-validator docs/frontapp-openapi.yaml"
validate-openapi-redocly = "npx @redocly/cli lint docs/frontapp-openapi.yaml"

# -----------------------------------------------------------------------------
# MCP Bundle (.mcpb) Build
# -----------------------------------------------------------------------------
# Produces ``dist/frontapp-mcp-server-<version>.mcpb`` for one-click install
# in Claude Desktop. Requires the ``mcpb`` CLI on PATH:
# npm install -g @anthropic-ai/mcpb
# CI installs it on demand; locally, install once with the command above.
build-mcpb = "python scripts/build_mcpb.py"

# -----------------------------------------------------------------------------
# Documentation Tasks
# -----------------------------------------------------------------------------
Expand Down
Loading
Loading