# shared-client-python Implementation Summary

## Phase 2 Complete ✅

Successfully created a reusable PyPI package that extracts shared client utilities from reddit-mcp and ports missing features from yt-mcp.

## Package Structure

```
shared-client-python/
├── src/fivemghost_shared_client/
│   ├── __init__.py                # v0.1.0, exports main APIs
│   ├── token_manager.py           # Parameterized TokenManager (env_token_name)
│   ├── oauth_flow.py              # Parameterized OAuth flow (client_name, timeout_seconds)
│   ├── shared_auth.py             # Shared auth.json read/write (ported from yt-mcp)
│   ├── launcher.py                # Parameterized launcher generation
│   ├── config_helpers.py          # Path constants & helpers
│   ├── _classify_failure.py       # Registration failure classification (ported from yt-mcp)
│   ├── registration/
│   │   ├── __init__.py            # Public exports
│   │   ├── cli_registry.py        # Orchestrates all CLI registrations
│   │   ├── codex_internal.py      # Codex-internal TOML writing (regex-based, ported from yt-mcp)
│   │   ├── openclaw.py            # OpenClaw dual-path: CLI → JSON fallback (ported from yt-mcp)
│   │   └── skills.py              # Skill installation (ported from yt-mcp)
│   └── token_manager.py           
├── pyproject.toml                 # Build config, httpx>=0.25 dependency
├── tests/
│   └── test_imports.py            # Import verification tests
└── README.md                       # Package documentation
```

## Parameterization Completed

All hardcoded project names have been converted to parameters:

| Module | Hardcoded → Parameter |
|--------|----------------------|
| `TokenManager` | `REDDIT_MCP_TOKEN` → `env_token_name` |
| `oauth_flow.run_oauth_flow()` | `"reddit-mcp-cli"` → `client_name` |
| `launcher.build_launcher_source()` | `"5mghost-rover"`, `"reddit-mcp"` → `package_name`, `executable_name` |
| `launcher.write_uvx_launcher()` | config_dir → `config_dir` parameter |
| CLI registry | `"reddit-mcp"` → `server_name`, `launcher_path` → `launcher_path` |

## Key Features Extracted

### From reddit-mcp:
- ✅ `TokenManager` — JWT/PAT token management with server verification + caching
- ✅ `run_oauth_flow()` — OAuth2 PKCE implementation with DCR registration
- ✅ `launcher.py` — uvx launcher generation
- ✅ CLI registration orchestration for: claude-internal, claude, codex, gemini-internal, gemini, opencode

### From yt-mcp (Ported):
- ✅ `shared_auth.py` — Shared auth.json read/write with atomic writes
- ✅ `codex_internal.py` — Codex-internal TOML writing via regex upsert
- ✅ `openclaw.py` — OpenClaw dual-path: tries mcporter CLI, falls back to JSON write
- ✅ `skills.py` — Skill installation to CLI skill directories
- ✅ `_classify_failure.py` — Registration failure classification

## Registration Support

All supported CLIs are registered in `cli_registry.py`:

| CLI | Registration Method |
|-----|-------------------|
| `claude-internal` | `{bin} mcp add -s user {name} -- python3 {launcher} serve` |
| `claude` | `{bin} mcp add -s user {name} -- python3 {launcher} serve` |
| `codex` | `{bin} mcp add {name} -- python3 {launcher} serve` |
| `codex-internal` | Direct TOML write (regex-based upsert) |
| `gemini-internal` | `{bin} mcp add -s user {name} python3 {launcher} serve` (no `--`) |
| `gemini` | `{bin} mcp add -s user {name} python3 {launcher} serve` (no `--`) |
| `opencode` | `{bin} mcp add {name} -- python3 {launcher} serve` |
| `openclaw` | Try `mcporter config add` CLI, fallback to JSON write |

## Skill Installation Targets

Supports installation to all CLI skill directories:
- `~/.claude-internal/skills/{skill-name}/`
- `~/.claude/skills/{skill-name}/`
- `~/.codex-internal/skills/{skill-name}/`
- `~/.codex/skills/{skill-name}/`
- `~/.gemini-internal/skills/{skill-name}/`
- `~/.gemini/skills/{skill-name}/`
- `~/.openclaw/skills/{skill-name}/` (optional)

## Testing

All imports verified ✅

```bash
# Install
pip install -e /Users/yimingwang/ai_workspace/services/mcp_projects/shared-client-python

# Test
python3 -c "from fivemghost_shared_client import TokenManager, run_oauth_flow; print('✅ OK')"

# Run full test suite
cd /Users/yimingwang/ai_workspace/services/mcp_projects/shared-client-python && python3 tests/test_imports.py
```

## Next Steps (Phase 3)

This shared package is now ready to be:
1. Published to PyPI as `5mghost-shared-client==0.1.0`
2. Integrated into reddit-mcp and yt-mcp as a dependency
3. Used to refactor both packages to eliminate code duplication

Example usage in a project:

```python
from pathlib import Path
from fivemghost_shared_client import TokenManager, run_oauth_flow
from fivemghost_shared_client.registration import register_all, install_skills
from fivemghost_shared_client.launcher import write_uvx_launcher

# Token management
tm = TokenManager(
    auth_json_path=Path.home() / ".my-mcp" / "auth.json",
    env_token_name="MY_MCP_TOKEN",
)
token = await tm.get_valid_token()

# OAuth login
tokens = await run_oauth_flow(
    auth_url="https://auth.example.com",
    client_name="my-mcp-cli",
)

# Register with all CLIs
register_all(
    server_name="my-mcp",
    runtime="python3",
    launcher_path=launcher_path,
)

# Install skills
install_skills(
    skill_name="use-my-mcp",
    source_dir=Path("./skills/use-my-mcp"),
)
```

## Single External Dependency

- `httpx>=0.25` — Used for async HTTP requests in token refresh and OAuth

No unnecessary dependencies added (no TOML/YAML libs for codex-internal, using stdlib regex instead).

## Python Requirements

- `requires-python = ">=3.10"` — Matches reddit-mcp requirement, enables TypedDict and modern syntax
