# Deploy Kylas CRM MCP to the MCP Marketplace (Registry)
This guide walks you through publishing your Kylas CRM MCP server to the **official MCP Registry** so it appears in the [MCP marketplace](https://modelcontextprotocol.io/registry/about) and users can discover and install it.
---
## Prerequisites
- **GitHub account** – used to authenticate with the MCP Registry (namespace `io.github.YOUR_USERNAME/...`).
- **PyPI account** – [create one at pypi.org](https://pypi.org/account/register/) (needed for the Python package path).
- (Optional) **Docker Hub** or **GitHub Container Registry** account if you also publish the Docker image.
---
## Step 1: Replace placeholders
In this repo, replace **`YOUR_GITHUB_USERNAME`** with your real GitHub username in:
1. **`server.json`** – in `name`, and in `repository.url`.
2. **`README.md`** – in the line:
`<!-- mcp-name: io.github.YOUR_GITHUB_USERNAME/kylas-crm -->`
The registry uses this to verify PyPI ownership, so it must match `name` in `server.json` exactly.
3. **`Dockerfile`** – in the `LABEL io.modelcontextprotocol.server.name=...` line (only if you publish via Docker).
Example: if your GitHub username is `johndoe`, use:
- `name`: `io.github.johndoe/kylas-crm`
- `repository.url`: `https://github.com/johndoe/MCP`
- README: `<!-- mcp-name: io.github.johndoe/kylas-crm -->`
- Docker: `LABEL io.modelcontextprotocol.server.name="io.github.johndoe/kylas-crm"`
---
## Step 2: Install the MCP Publisher CLI
The registry uses the **mcp-publisher** tool to authenticate and publish.
**macOS/Linux (Homebrew):**
```bash
brew install mcp-publisher
```
**macOS/Linux (direct download):**
```bash
curl -L "https://github.com/modelcontextprotocol/registry/releases/latest/download/mcp-publisher_$(uname -s|tr '[:upper:]' '[:lower:]')_$(uname -m|sed 's/x86_64/amd64/;s/aarch64/arm64/').tar.gz" | tar xz
sudo mv mcp-publisher /usr/local/bin/
```
**Verify:**
```bash
mcp-publisher --help
```
---
## Step 3: Publish the Python package to PyPI
The MCP Registry only stores **metadata**; the installable artifact is your package on PyPI (or Docker/OCI). You must publish the package first.
### 3.1 Install build tools
```bash
pip install build twine
```
### 3.2 Build the package
From the repo root (where `pyproject.toml` and `main.py` are):
```bash
python -m build
```
This creates `dist/kylas_crm_mcp-1.0.0.tar.gz` (and optionally a wheel).
### 3.3 Upload to PyPI
```bash
twine upload dist/*
```
Use your PyPI username and password (or token). For the first time you may need to create an API token under [PyPI Account Settings](https://pypi.org/manage/account/).
**Important:** The string **`mcp-name: io.github.YOUR_GITHUB_USERNAME/kylas-crm`** must appear in the **long description** of the package (i.e. in `README.md`), because PyPI uses the project description for verification. The comment in `README.md` satisfies this.
---
## Step 4: Authenticate with the MCP Registry
From the same repo directory:
```bash
mcp-publisher login github
```
Follow the browser flow and enter the code shown in the terminal. After success you should see something like: `✓ Successfully logged in`.
---
## Step 5: Publish to the MCP Registry
Ensure `server.json` is in the current directory and the version in it matches the version you published to PyPI (e.g. `1.0.0`). Then run:
```bash
mcp-publisher publish
```
You should see:
```
Publishing to https://registry.modelcontextprotocol.io...
✓ Successfully published
✓ Server io.github.YOUR_GITHUB_USERNAME/kylas-crm version 1.0.0
```
---
## Step 6: Verify
Search for your server:
```bash
curl "https://registry.modelcontextprotocol.io/v0.1/servers?search=io.github.YOUR_GITHUB_USERNAME/kylas-crm"
```
Replace `YOUR_GITHUB_USERNAME` with your GitHub username. Your server metadata should appear in the JSON response.
---
## Optional: Publish as Docker image (OCI)
If you want the server to be installable via Docker as well:
1. Set the **LABEL** in `Dockerfile` (already added):
```dockerfile
LABEL io.modelcontextprotocol.server.name="io.github.YOUR_GITHUB_USERNAME/kylas-crm"
```
Use your real GitHub username.
2. Build and push to Docker Hub or GHCR, e.g.:
```bash
docker build -t yourusername/kylas-crm-mcp:1.0.0 .
docker push yourusername/kylas-crm-mcp:1.0.0
```
3. Add a **second entry** in `server.json` under `packages` for the OCI image, for example:
```json
{
"registryType": "oci",
"identifier": "docker.io/yourusername/kylas-crm-mcp:1.0.0",
"transport": { "type": "stdio" }
}
```
Then run `mcp-publisher publish` again (bump version if the registry requires it).
---
## Updating a published server
1. Bump version in `pyproject.toml` and `server.json` (e.g. `1.0.1`).
2. Rebuild and re-upload to PyPI: `python -m build && twine upload dist/*`
3. Run `mcp-publisher publish` again.
The registry supports versioning; clients can see and use the new version.
---
## Troubleshooting
| Issue | What to do |
|--------|------------|
| **"Registry validation failed for package"** | Ensure `README.md` (PyPI long description) contains exactly `mcp-name: io.github.YOUR_USERNAME/kylas-crm` (same as `name` in `server.json`). |
| **"Invalid or expired Registry JWT token"** | Run `mcp-publisher login github` again. |
| **"You do not have permission to publish this server"** | With GitHub login, `name` in `server.json` must start with `io.github.YOUR_GITHUB_USERNAME/`. |
| **Package not found on PyPI** | Publish the package first (`twine upload dist/*`) and wait a minute, then run `mcp-publisher publish` again. |
---
## References
- [MCP Registry – Publish a server (quickstart)](https://modelcontextprotocol.io/registry/quickstart)
- [Package types (PyPI, npm, Docker, MCPB)](https://modelcontextprotocol.io/registry/package-types)
- [Registry authentication (GitHub, DNS)](https://modelcontextprotocol.io/registry/authentication)
- [GitHub Actions for automated publishing](https://modelcontextprotocol.io/registry/github-actions)