Skip to content

Commit 25aeed1

Browse files
authored
Merge pull request #3 from engmsaleh/main
fix: correct FastMCP initialization to fix server startup crash
2 parents e72dd2c + 802baf8 commit 25aeed1

File tree

2 files changed

+294
-3
lines changed

2 files changed

+294
-3
lines changed

CLAUDE.md

Lines changed: 292 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,292 @@
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`

mcp_server_bwt/main.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,8 @@
1919

2020
# Initialize MCP server with capabilities
2121
mcp = FastMCP(
22-
"mcp-server-bing-webmaster",
23-
version="1.0.0",
24-
description="Direct access to Bing Webmaster Tools API with OData compatibility",
22+
name="mcp-server-bing-webmaster",
23+
instructions="Direct access to Bing Webmaster Tools API with OData compatibility",
2524
)
2625

2726
# API configuration

0 commit comments

Comments
 (0)