|
| 1 | +# CLAUDE.md |
| 2 | + |
| 3 | +This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. |
| 4 | + |
| 5 | +## Project Overview |
| 6 | + |
| 7 | +This is an MCP (Model Context Protocol) server that provides AI assistants with access to Bing Webmaster Tools API. It's a **hybrid npm/Python package** distributed via npm but implemented in Python, using a JavaScript wrapper (`run.js`) to spawn the Python process. |
| 8 | + |
| 9 | +**Key Architecture Pattern**: The server acts as a bridge between MCP clients (Claude, Cursor, etc.) and Bing's REST API, using FastMCP to expose 70+ Bing Webmaster Tools functions as MCP tools. |
| 10 | + |
| 11 | +## Development Commands |
| 12 | + |
| 13 | +### Setup & Installation |
| 14 | +```bash |
| 15 | +# Install dependencies (uses uv package manager) |
| 16 | +make install |
| 17 | +# OR |
| 18 | +uv sync |
| 19 | + |
| 20 | +# Install in editable mode for development |
| 21 | +uv pip install -e . |
| 22 | +``` |
| 23 | + |
| 24 | +### Code Quality |
| 25 | +```bash |
| 26 | +# Run type checking (mypy --strict) and linting (ruff) |
| 27 | +make lint |
| 28 | + |
| 29 | +# Format code with ruff |
| 30 | +make format |
| 31 | +``` |
| 32 | + |
| 33 | +### Testing |
| 34 | +```bash |
| 35 | +# Run all tests with pytest (requires BING_WEBMASTER_API_KEY) |
| 36 | +make test |
| 37 | + |
| 38 | +# Run tests directly with uv |
| 39 | +uv run pytest mcp_server_bwt --doctest-modules |
| 40 | +``` |
| 41 | + |
| 42 | +### Running the Server |
| 43 | + |
| 44 | +```bash |
| 45 | +# Start the server directly (for testing) |
| 46 | +make start |
| 47 | +# OR |
| 48 | +uv run mcp_server_bwt/main.py |
| 49 | +# OR |
| 50 | +python -m mcp_server_bwt |
| 51 | + |
| 52 | +# Run with MCP Inspector (for debugging MCP protocol) |
| 53 | +make mcp_inspector |
| 54 | +``` |
| 55 | + |
| 56 | +### Building & Distribution |
| 57 | +```bash |
| 58 | +# Build Python wheel |
| 59 | +make build |
| 60 | + |
| 61 | +# Build and test npm package |
| 62 | +npm run build |
| 63 | +npm run validate |
| 64 | + |
| 65 | +# View what will be published |
| 66 | +npm run view-package |
| 67 | +``` |
| 68 | + |
| 69 | +### Versioning |
| 70 | +```bash |
| 71 | +# Sync version between Python (version.py) and npm (package.json) |
| 72 | +npm run sync-version |
| 73 | + |
| 74 | +# Version is stored in: mcp_server_bwt/version.py |
| 75 | +``` |
| 76 | + |
| 77 | +## Architecture |
| 78 | + |
| 79 | +### Dual Entry Points |
| 80 | + |
| 81 | +**1. npm Distribution (`run.js`)**: |
| 82 | +- Cross-platform JavaScript wrapper that spawns Python process |
| 83 | +- Checks for virtual environment Python first, falls back to system Python |
| 84 | +- Handles process lifecycle and signal forwarding |
| 85 | +- This is what users execute: `npx @isiahw1/mcp-server-bing-webmaster` |
| 86 | + |
| 87 | +**2. Python Module (`mcp_server_bwt/`)**: |
| 88 | +- `main.py` (1585 lines): Core implementation with all MCP tools |
| 89 | +- `__main__.py`: Python module entry point |
| 90 | +- `version.py`: Single source of truth for version (synced to package.json) |
| 91 | + |
| 92 | +### Core Components |
| 93 | + |
| 94 | +**BingWebmasterAPI Class** (`main.py:35-121`): |
| 95 | +- Async HTTP client wrapper using `httpx` |
| 96 | +- Implements context manager pattern for resource management |
| 97 | +- `_make_request()`: Handles all API communication |
| 98 | +- `_ensure_type_field()`: Adds OData type metadata for MCP compatibility |
| 99 | +- Base URL: `https://ssl.bing.com/webmaster/api.svc/json` |
| 100 | + |
| 101 | +**MCP Tool Pattern** (`main.py:129-1575`): |
| 102 | +All tools follow this structure: |
| 103 | +```python |
| 104 | +@mcp.tool(name="tool_name", description="...") |
| 105 | +async def tool_name(param: Annotated[type, "description"]) -> ReturnType: |
| 106 | + async with api: |
| 107 | + result = await api._make_request("EndpointName", ...) |
| 108 | + return api._ensure_type_field(result, "TypeName") |
| 109 | +``` |
| 110 | + |
| 111 | +**Server Initialization** (`main.py:20-25, 1578-1585`): |
| 112 | +```python |
| 113 | +mcp = FastMCP("mcp-server-bing-webmaster", version="1.0.0") |
| 114 | +api = BingWebmasterAPI(API_KEY) |
| 115 | + |
| 116 | +def app() -> None: |
| 117 | + mcp.run(transport="stdio") # Uses stdio transport for MCP protocol |
| 118 | +``` |
| 119 | + |
| 120 | +### Tool Organization |
| 121 | + |
| 122 | +The 70+ tools are organized into 16 functional categories: |
| 123 | +- Site Management (4 tools) |
| 124 | +- Traffic Analysis (6 tools) |
| 125 | +- Crawling & Indexing (5 tools) |
| 126 | +- URL Management (6 tools) |
| 127 | +- Content Management (2 tools) |
| 128 | +- Sitemap & Feed Management (5 tools) |
| 129 | +- Keyword Analysis (6 tools) |
| 130 | +- Link Analysis (3 tools) |
| 131 | +- URL Blocking (3 tools) |
| 132 | +- Deep Link Management (3 tools) |
| 133 | +- Page Preview Management (3 tools) |
| 134 | +- URL Query Parameters (4 tools) |
| 135 | +- Geographic Settings (2 tools) |
| 136 | +- Site Roles & Access (3 tools) |
| 137 | +- Site Moves/Migration (2 tools) |
| 138 | +- Child URLs (2 tools) |
| 139 | + |
| 140 | +### Error Handling Pattern |
| 141 | + |
| 142 | +All tools follow consistent error handling: |
| 143 | +1. HTTP status code checking (raises on non-200) |
| 144 | +2. Timeout exception handling (30s default) |
| 145 | +3. Logging errors with context |
| 146 | +4. Re-raising exceptions for MCP client handling |
| 147 | + |
| 148 | +### API Response Pattern |
| 149 | + |
| 150 | +Bing API returns OData-formatted responses: |
| 151 | +- Response format: `{"d": {...actual data...}}` |
| 152 | +- `_make_request()` automatically unwraps `data["d"]` |
| 153 | +- `_ensure_type_field()` adds `__type` metadata for MCP compatibility |
| 154 | + |
| 155 | +## Environment Configuration |
| 156 | + |
| 157 | +**Required**: |
| 158 | +- `BING_WEBMASTER_API_KEY`: Bing Webmaster Tools API key (obtained from Bing Webmaster Tools → Settings → API Access) |
| 159 | + |
| 160 | +**Loading**: Environment variables are loaded at module level (`main.py:29`) and raise `ValueError` if missing. |
| 161 | + |
| 162 | +## Adding New Tools |
| 163 | + |
| 164 | +When adding new Bing Webmaster Tools endpoints: |
| 165 | + |
| 166 | +1. **Check Bing API Documentation**: Verify the endpoint, method, and parameters |
| 167 | +2. **Add tool definition** in `main.py` following the pattern: |
| 168 | + ```python |
| 169 | + @mcp.tool(name="tool_name", description="Clear description of what it does") |
| 170 | + async def tool_name( |
| 171 | + param1: Annotated[str, "Parameter description"], |
| 172 | + param2: Annotated[Optional[int], "Optional parameter"] = None, |
| 173 | + ) -> ReturnType: |
| 174 | + """Docstring with detailed explanation.""" |
| 175 | + async with api: |
| 176 | + result = await api._make_request( |
| 177 | + "BingEndpointName", |
| 178 | + method="GET", # or POST, PUT, DELETE |
| 179 | + json_data={"key": "value"} if method != "GET" else None, |
| 180 | + params={"param": value} if additional_params else None, |
| 181 | + ) |
| 182 | + return api._ensure_type_field(result, "ResponseTypeName") |
| 183 | + ``` |
| 184 | +3. **Update README.md**: Add tool to appropriate category in Available Tools section |
| 185 | +4. **Test**: Verify tool works with `make mcp_inspector` or actual MCP client |
| 186 | +5. **Type hints**: Use `Annotated[type, "description"]` for all parameters |
| 187 | + |
| 188 | +## Build System |
| 189 | + |
| 190 | +**Python Build** (`pyproject.toml`): |
| 191 | +- Build backend: hatchling |
| 192 | +- Version source: `mcp_server_bwt/version.py` |
| 193 | +- Entry point: `mcp-server-bing-webmaster = "mcp_server_bwt.main:app"` |
| 194 | +- Dependencies: mcp[cli], httpx, python-dotenv |
| 195 | + |
| 196 | +**npm Build** (`package.json`): |
| 197 | +- Main entry: `run.js` |
| 198 | +- Binary: Maps `mcp-server-bing-webmaster` to `run.js` |
| 199 | +- Scripts: build, validate, sync-version |
| 200 | +- Files: Only include necessary files (mcp_server_bwt/, scripts/, docs, configs) |
| 201 | + |
| 202 | +**Version Synchronization**: |
| 203 | +- Python version in `mcp_server_bwt/version.py` is source of truth |
| 204 | +- `scripts/sync-version.js` keeps `package.json` in sync |
| 205 | +- Run automatically via npm hooks (preversion, postversion) |
| 206 | + |
| 207 | +## Testing MCP Integration |
| 208 | + |
| 209 | +**MCP Inspector** (recommended for debugging): |
| 210 | +```bash |
| 211 | +make mcp_inspector |
| 212 | +# Opens browser interface to test all tools interactively |
| 213 | +``` |
| 214 | + |
| 215 | +**Claude Code** (development mode): |
| 216 | +```bash |
| 217 | +export BING_WEBMASTER_API_KEY="your_key" |
| 218 | +cd /path/to/mcp-server-bing-webmaster |
| 219 | +claude mcp add bing-webmaster-dev -- uv run python -m mcp_server_bwt |
| 220 | +claude |
| 221 | +``` |
| 222 | + |
| 223 | +**Claude Desktop** (development mode): |
| 224 | +Add to `claude_desktop_config.json`: |
| 225 | +```json |
| 226 | +{ |
| 227 | + "mcpServers": { |
| 228 | + "bing-webmaster-dev": { |
| 229 | + "command": "uv", |
| 230 | + "args": ["run", "python", "-m", "mcp_server_bwt"], |
| 231 | + "cwd": "/path/to/mcp-server-bing-webmaster", |
| 232 | + "env": { |
| 233 | + "BING_WEBMASTER_API_KEY": "your_key" |
| 234 | + } |
| 235 | + } |
| 236 | + } |
| 237 | +} |
| 238 | +``` |
| 239 | + |
| 240 | +## CI/CD Pipeline |
| 241 | + |
| 242 | +**GitHub Actions Workflows** (`.github/workflows/`): |
| 243 | +- `ci.yml`: Run tests on PRs and main branch |
| 244 | +- `publish.yml`: Publish to npm on release |
| 245 | +- `version-bump.yml`: Automatic version management |
| 246 | +- `security.yml`: Secret scanning with gitleaks |
| 247 | + |
| 248 | +**Pre-commit Hooks**: Security scanning configured in `.pre-commit-config.yaml` |
| 249 | + |
| 250 | +## Code Style |
| 251 | + |
| 252 | +**Python**: |
| 253 | +- Type hints required (mypy --strict) |
| 254 | +- Line length: 100 characters (ruff) |
| 255 | +- Target: Python 3.10+ |
| 256 | +- Format: ruff (replaces black) |
| 257 | +- Linting: ruff (replaces flake8) |
| 258 | + |
| 259 | +**Imports**: Organized as: |
| 260 | +1. Standard library |
| 261 | +2. Third-party (httpx, mcp) |
| 262 | +3. Local modules |
| 263 | + |
| 264 | +## Async Pattern |
| 265 | + |
| 266 | +All API operations are async: |
| 267 | +- Use `async with api:` context manager for all API calls |
| 268 | +- HTTP client lifecycle managed by context manager |
| 269 | +- FastMCP handles async tool execution automatically |
| 270 | +- Don't forget `await` for all async operations |
| 271 | + |
| 272 | +## Distribution Strategy |
| 273 | + |
| 274 | +**Why npm?**: Makes installation trivial for MCP clients: `npx @isiahw1/mcp-server-bing-webmaster` |
| 275 | +**Why Python?**: FastMCP framework, better async support, easier API integration |
| 276 | +**How it works**: npm installs package, `run.js` spawns Python, Python runs MCP server |
| 277 | + |
| 278 | +## Common Pitfalls |
| 279 | + |
| 280 | +1. **API Key Not Set**: Server raises ValueError immediately if `BING_WEBMASTER_API_KEY` missing |
| 281 | +2. **Context Manager**: Always use `async with api:` - don't call `_make_request()` without it |
| 282 | +3. **OData Response**: Remember Bing wraps responses in `{"d": {...}}` - `_make_request()` handles this |
| 283 | +4. **Type Annotations**: MCP requires `Annotated[type, "description"]` for proper tool parameter documentation |
| 284 | +5. **Version Sync**: When bumping version, edit `mcp_server_bwt/version.py` then run `npm run sync-version` |
| 285 | +6. **Transport**: MCP uses stdio transport - server communicates via stdin/stdout, not HTTP |
| 286 | + |
| 287 | +## Useful References |
| 288 | + |
| 289 | +- MCP Protocol: https://modelcontextprotocol.io/ |
| 290 | +- FastMCP Framework: https://github.com/jlowin/fastmcp |
| 291 | +- Bing Webmaster API: https://www.bing.com/webmasters/help/webmaster-api-using-the-bing-webmaster-api-8a9fd7f6 |
| 292 | +- Getting Started Guides: `docs/getting-started-*.md` |
0 commit comments