# Publishing Guide

Guide for publishing the CAST.AI MCP Server to PyPI and npm.

## Prerequisites

1. **PyPI account**: https://pypi.org/account/register/
2. **npm account**: https://www.npmjs.com/signup
3. **uv installed**: `curl -LsSf https://astral.sh/uv/install.sh | sh`
4. **Node.js installed**: https://nodejs.org/

## Version Management

**IMPORTANT**: Keep versions in sync between:
- `pyproject.toml`: `version = "0.1.0"`
- `package.json`: `"version": "0.1.0"`

Use the sync script:
```bash
./scripts/sync-version.sh 0.2.0
```

## Publishing Process

### Step 1: Prepare Release

```bash
# Ensure clean working directory
git status

# Update version in both files
./scripts/sync-version.sh 0.2.4

# Run tests
uv run python verify.py

# Commit version bump
git add pyproject.toml package.json
git commit -m "Bump version to 0.2.0"
```

### Step 2: Publish to PyPI

```bash
# Clean previous builds
rm -rf dist/

# Build Python package
uv build

# Check dist/ contains both .tar.gz and .whl
ls -lh dist/

# Publish to PyPI
uv publish

# Or with token
uv publish --token $PYPI_TOKEN
```

**Verify PyPI installation:**
```bash
# Wait 2-3 minutes for indexing
uvx castai-mcp-server@0.2.0
```

### Step 3: Publish to npm

```bash
# Test what will be published
npm pack
tar -tzf castai-mcp-server-0.2.0.tgz

# Should contain: package.json, bin/, README.md, LICENSE
# Should NOT contain: src/, *.py files

# Login to npm (one-time)
npm login

# Publish to npm
npm publish
```

**Verify npm installation:**
```bash
npx castai-mcp-server@0.2.0
```

### Step 4: Create GitHub Release

```bash
# Tag and push
git tag v0.2.0
git push origin main --tags

# Create release on GitHub:
# - Go to Releases > Draft a new release
# - Choose tag v0.2.0
# - Title: "v0.2.0"
# - Add changelog
# - Attach dist/ files
# - Publish
```

## Testing Before Publishing

### Test Python Package Locally

```bash
# Install in development mode
uv pip install -e .

# Test entry point
export CASTAI_API_KEY="test-key"
castai-mcp-server

# Should start the MCP server
```

### Test npm Wrapper Locally

```bash
# Test wrapper directly
node bin/castai-mcp-server.js

# Test with npm pack
npm pack
npm install -g castai-mcp-server-0.1.0.tgz
castai-mcp-server
```

### Test with Claude Desktop

Add to `claude_desktop_config.json`:

```json
{
  "mcpServers": {
    "castai-dev": {
      "command": "node",
      "args": [
        "/Users/narunaskapocius/repos/github/castai-mcp-external/bin/castai-mcp-server.js"
      ],
      "env": {
        "CASTAI_API_KEY": "your-api-key"
      }
    }
  }
}
```

## Testing After Publishing

### Test PyPI Package

```bash
# Fresh environment
uvx castai-mcp-server@0.2.0

# With MCP Inspector
npx @modelcontextprotocol/inspector uvx castai-mcp-server@0.2.0
```

### Test npm Package

```bash
# Direct npx (no installation)
npx -y castai-mcp-server@0.2.0

# With MCP Inspector
npx @modelcontextprotocol/inspector npx castai-mcp-server@0.2.0
```

### Test in Claude Desktop

Update config to use published package:

```json
{
  "mcpServers": {
    "castai": {
      "command": "npx",
      "args": ["-y", "castai-mcp-server@0.2.0"],
      "env": {
        "CASTAI_API_KEY": "your-api-key"
      }
    }
  }
}
```

Restart Claude Desktop and test queries.

## Rollback

### If PyPI publish fails
```bash
# Cannot delete published versions from PyPI
# Must publish a new patch version (0.2.1)
```

### If npm publish fails
```bash
# Unpublish within 72 hours
npm unpublish castai-mcp-server@0.2.0

# Or deprecate
npm deprecate castai-mcp-server@0.2.0 "Use 0.2.1 instead"
```

## Troubleshooting

### PyPI: "File already exists"
- Version is already published to PyPI
- Bump to new version
- Cannot republish same version

### npm: "Version already published"
- Version is already published to npm
- Bump to new version
- Or unpublish within 72 hours

### uvx: "Package not found"
- Wait 5-10 minutes for PyPI to index
- Check package exists: https://pypi.org/project/castai-mcp-server/
- Try with explicit version: `uvx castai-mcp-server==0.2.0`

### npx wrapper fails
- Check wrapper is executable: `chmod +x bin/castai-mcp-server.js`
- Test locally: `node bin/castai-mcp-server.js`
- Verify .npmignore isn't excluding bin/

## Version History

Keep track of published versions:

- `0.1.0` - Initial release
- `0.2.0` - [Future version]

## Useful Commands

```bash
# Check PyPI versions
pip index versions castai-mcp-server

# Check npm versions
npm view castai-mcp-server versions

# Download published package (PyPI)
pip download --no-deps castai-mcp-server==0.1.0

# Download published package (npm)
npm pack castai-mcp-server@0.1.0
```