#
tokens: 1376/50000 4/4 files
lines: on (toggle) GitHub
raw markdown copy reset
# Directory Structure

```
├── .gitignore
├── README.md
└── wp-server-python
    ├── requirements.txt
    └── wp.py
```

# Files

--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------

```
 1 | build/
 2 | 
 3 | # Node-generated files
 4 | node_modules/
 5 | 
 6 | # Python-generated files
 7 | __pycache__/
 8 | *.py[oc]
 9 | dist/
10 | wheels/
11 | *.egg-info
12 | 
13 | # Virtual environments
14 | .venv
15 | 
```

--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------

```markdown
 1 | # Very much a work in progress that has not progressed
 2 | 
 3 | You should go to https://github.com/Automattic/wordpress-mcp for a fully functional WordPress MCP implementation.
 4 | 
 5 | To try it you currently need a WordPress instance locally on `http://localhost:8888/`.
 6 | 
 7 | It is currently a python app, I used `uv` locally,so you will need to:
 8 | 
 9 | `uv venv`
10 | `source .venv/bin/activate`
11 | `uv pip install -r requirements.txt`
12 | 
13 | You can then run the server with `uv run wp.py` to see if you get any errors, but you don't need to run from terminal as Claude will start its own instance.
14 | 
15 | You also need to add the following to your `claude_desktop_config.json`:
16 | 
17 | ```
18 | {
19 |   "mcpServers": {
20 |     "wordpress": {
21 |       "command": "uv",
22 |       "args": [
23 |         "--directory",
24 |         "/FULL/PATH/TO/wp-server-python",
25 |         "run",
26 |         "wp.py"
27 |       ]
28 |     }
29 |   }
30 | }
31 | ```
32 | 
```

--------------------------------------------------------------------------------
/wp-server-python/requirements.txt:
--------------------------------------------------------------------------------

```
1 | httpx>=0.25.0
2 | fastmcp>=0.1.0 
```

--------------------------------------------------------------------------------
/wp-server-python/wp.py:
--------------------------------------------------------------------------------

```python
 1 | from typing import Any
 2 | import httpx
 3 | from mcp.server.fastmcp import FastMCP
 4 | 
 5 | # Initialize FastMCP server
 6 | mcp = FastMCP("wordpress")
 7 | 
 8 | # Constants
 9 | WP_API_BASE = "http://localhost:8888/wp-json/wp/v2"
10 | USER_AGENT = "wp-mcp/1.0"
11 | 
12 | async def make_wp_request(url: str) -> dict[str, Any] | None:
13 |     """Make a request to the WordPress API with proper error handling."""
14 |     headers = {
15 |         "User-Agent": USER_AGENT,
16 |         "Accept": "application/json"
17 |     }
18 |     async with httpx.AsyncClient() as client:
19 |         try:
20 |             response = await client.get(url, headers=headers, timeout=30.0)
21 |             response.raise_for_status()
22 |             return response.json()
23 |         except Exception as e:
24 |             return {"error": str(e)}
25 | 
26 | def format_post(post: dict) -> str:
27 |     """Format a WordPress post into a readable string."""
28 |     return f"""
29 | Title: {post.get('title', {}).get('rendered', 'Untitled')}
30 | Status: {post.get('status', 'unknown')}
31 | Date: {post.get('date', 'unknown')}
32 | Link: {post.get('link', 'unknown')}
33 | Excerpt: {post.get('excerpt', {}).get('rendered', 'No excerpt available').strip()}
34 | """
35 | 
36 | def format_page(page: dict) -> str:
37 |     """Format a WordPress page into a readable string."""
38 |     return f"""
39 | Title: {page.get('title', {}).get('rendered', 'Untitled')}
40 | Status: {page.get('status', 'unknown')}
41 | Date: {page.get('date', 'unknown')}
42 | Link: {page.get('link', 'unknown')}
43 | Parent: {page.get('parent', 0)}
44 | Menu Order: {page.get('menu_order', 0)}
45 | """
46 | 
47 | @mcp.tool()
48 | async def wp_list_posts() -> str:
49 |     """Get a list of public posts from WordPress.
50 |     
51 |     Returns a formatted string containing post information.
52 |     """
53 |     url = f"{WP_API_BASE}/posts"
54 |     data = await make_wp_request(url)
55 | 
56 |     if not data:
57 |         return "Unable to fetch posts."
58 |     
59 |     if isinstance(data, dict) and "error" in data:
60 |         return f"Error fetching posts: {data['error']}"
61 | 
62 |     if not data:
63 |         return "No posts found."
64 | 
65 |     posts = [format_post(post) for post in data]
66 |     return "\n---\n".join(posts)
67 | 
68 | @mcp.tool()
69 | async def wp_list_pages() -> str:
70 |     """Get a list of pages from WordPress.
71 |     
72 |     Returns a formatted string containing page information.
73 |     """
74 |     url = f"{WP_API_BASE}/pages"
75 |     data = await make_wp_request(url)
76 | 
77 |     if not data:
78 |         return "Unable to fetch pages."
79 |     
80 |     if isinstance(data, dict) and "error" in data:
81 |         return f"Error fetching pages: {data['error']}"
82 | 
83 |     if not data:
84 |         return "No pages found."
85 | 
86 |     pages = [format_page(page) for page in data]
87 |     return "\n---\n".join(pages)
88 | 
89 | if __name__ == "__main__":
90 |     # Initialize and run the server
91 |     mcp.run(transport='stdio') 
```