@websamurai/mcp-wp-remote 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +173 -0
- package/index.js +142 -0
- package/package.json +23 -0
package/README.md
ADDED
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
# @samuraiwp/mcp-wp-remote
|
|
2
|
+
|
|
3
|
+
A STDIO bridge for connecting to WordPress sites via the Model Context Protocol (MCP). This package enables communication between MCP clients and WordPress installations running the SamuraiWP plugin.
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
`mcp-wp-remote` acts as a bridge between MCP clients and WordPress REST API endpoints. It reads JSON-RPC requests from STDIN, forwards them to a WordPress site's MCP endpoint, and returns responses via STDOUT.
|
|
8
|
+
|
|
9
|
+
## Installation
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
npm install -g @samuraiwp/mcp-wp-remote
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
Or use directly with npx:
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
npx @samuraiwp/mcp-wp-remote <url> <api-key>
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## Requirements
|
|
22
|
+
|
|
23
|
+
- Node.js (ES modules support required)
|
|
24
|
+
- WordPress site with SamuraiWP plugin installed
|
|
25
|
+
- Valid API key from your WordPress installation
|
|
26
|
+
|
|
27
|
+
## Usage
|
|
28
|
+
|
|
29
|
+
### Command Line
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
mcp-wp-remote <url> <api-key>
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
**Parameters:**
|
|
36
|
+
- `<url>` - Your WordPress site URL (e.g., `https://example.com`)
|
|
37
|
+
- `<api-key>` - API key for authentication (Bearer token)
|
|
38
|
+
|
|
39
|
+
The endpoint path `/wp-json/samur-ai/v1/mcp` is automatically appended to the URL if not present.
|
|
40
|
+
|
|
41
|
+
### Example
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
mcp-wp-remote https://mysite.com my-secret-api-key
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
Or with the full endpoint:
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
mcp-wp-remote https://mysite.com/wp-json/samur-ai/v1/mcp my-secret-api-key
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
### As MCP Server Configuration
|
|
54
|
+
|
|
55
|
+
Add to your MCP client configuration (e.g., Claude Desktop):
|
|
56
|
+
|
|
57
|
+
```json
|
|
58
|
+
{
|
|
59
|
+
"mcpServers": {
|
|
60
|
+
"wordpress": {
|
|
61
|
+
"command": "mcp-wp-remote",
|
|
62
|
+
"args": ["https://yoursite.com", "your-api-key"]
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
## How It Works
|
|
69
|
+
|
|
70
|
+
1. Accepts JSON-RPC 2.0 formatted messages via STDIN
|
|
71
|
+
2. Authenticates with WordPress using Bearer token authorization
|
|
72
|
+
3. Forwards requests to the WordPress MCP endpoint
|
|
73
|
+
4. Returns responses via STDOUT in JSON-RPC 2.0 format
|
|
74
|
+
|
|
75
|
+
### Communication Flow
|
|
76
|
+
|
|
77
|
+
```
|
|
78
|
+
MCP Client → STDIN → mcp-wp-remote → WordPress REST API
|
|
79
|
+
← STDOUT ← ←
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
## JSON-RPC Protocol
|
|
83
|
+
|
|
84
|
+
The bridge expects and returns JSON-RPC 2.0 formatted messages:
|
|
85
|
+
|
|
86
|
+
**Request:**
|
|
87
|
+
```json
|
|
88
|
+
{
|
|
89
|
+
"jsonrpc": "2.0",
|
|
90
|
+
"method": "method_name",
|
|
91
|
+
"params": {},
|
|
92
|
+
"id": 1
|
|
93
|
+
}
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
**Response (Success):**
|
|
97
|
+
```json
|
|
98
|
+
{
|
|
99
|
+
"jsonrpc": "2.0",
|
|
100
|
+
"result": {},
|
|
101
|
+
"id": 1
|
|
102
|
+
}
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
**Response (Error):**
|
|
106
|
+
```json
|
|
107
|
+
{
|
|
108
|
+
"jsonrpc": "2.0",
|
|
109
|
+
"error": {
|
|
110
|
+
"code": -32000,
|
|
111
|
+
"message": "Error description"
|
|
112
|
+
},
|
|
113
|
+
"id": 1
|
|
114
|
+
}
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
## Error Handling
|
|
118
|
+
|
|
119
|
+
The bridge handles various error scenarios:
|
|
120
|
+
|
|
121
|
+
- **Invalid URL**: Exits with code 1 if URL is malformed
|
|
122
|
+
- **HTTP Errors**: Returns JSON-RPC error with HTTP status code
|
|
123
|
+
- **Network Errors**: Returns JSON-RPC error with code -32000
|
|
124
|
+
- **Invalid Arguments**: Shows usage message and exits
|
|
125
|
+
|
|
126
|
+
## Features
|
|
127
|
+
|
|
128
|
+
- Automatic endpoint path normalization
|
|
129
|
+
- Bearer token authentication
|
|
130
|
+
- Multi-line JSON input support
|
|
131
|
+
- Graceful shutdown handling (SIGINT, SIGTERM)
|
|
132
|
+
- JSON-RPC 2.0 compliant error responses
|
|
133
|
+
|
|
134
|
+
## WordPress Setup
|
|
135
|
+
|
|
136
|
+
1. Install the SamuraiWP plugin on your WordPress site
|
|
137
|
+
2. Generate an API key in the plugin settings
|
|
138
|
+
3. Ensure the REST API endpoint is accessible at `/wp-json/samur-ai/v1/mcp`
|
|
139
|
+
|
|
140
|
+
## Development
|
|
141
|
+
|
|
142
|
+
```bash
|
|
143
|
+
# Clone repository
|
|
144
|
+
git clone <repository-url>
|
|
145
|
+
|
|
146
|
+
# Install dependencies (if any)
|
|
147
|
+
npm install
|
|
148
|
+
|
|
149
|
+
# Run locally
|
|
150
|
+
node index.js https://example.com your-api-key
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
## License
|
|
154
|
+
|
|
155
|
+
MIT
|
|
156
|
+
|
|
157
|
+
## Keywords
|
|
158
|
+
|
|
159
|
+
- MCP (Model Context Protocol)
|
|
160
|
+
- WordPress
|
|
161
|
+
- JSON-RPC
|
|
162
|
+
- STDIO Bridge
|
|
163
|
+
- REST API
|
|
164
|
+
|
|
165
|
+
## Author
|
|
166
|
+
|
|
167
|
+
SamuraiWP Team
|
|
168
|
+
|
|
169
|
+
## Support
|
|
170
|
+
|
|
171
|
+
For issues and questions:
|
|
172
|
+
- WordPress Plugin: [SamuraiWP](https://samuraiwp.com)
|
|
173
|
+
- GitHub Issues: Report issues in the repository
|
package/index.js
ADDED
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import { createInterface } from 'readline';
|
|
4
|
+
|
|
5
|
+
// Parse command line arguments
|
|
6
|
+
const args = process.argv.slice( 2 );
|
|
7
|
+
|
|
8
|
+
if ( args.length < 2 ) {
|
|
9
|
+
console.error( 'Usage: mcp-wp-remote <url> <api-key>' );
|
|
10
|
+
process.exit( 1 );
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
let url = args[ 0 ];
|
|
14
|
+
const apiKey = args[ 1 ];
|
|
15
|
+
if( args[ 2 ] ) {
|
|
16
|
+
/// use the third argument as api key if provided to create a tunnel for remote access to dev/internal sites
|
|
17
|
+
remoteapi = args[ 2 ];
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
// Add the endpoint path if not present
|
|
21
|
+
const endpoint = '/wp-json/samur-ai/v1/mcp';
|
|
22
|
+
if ( ! url.endsWith( endpoint ) ) {
|
|
23
|
+
url = url.replace( /\/$/, '' ) + endpoint;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
// Validate URL
|
|
27
|
+
try {
|
|
28
|
+
new URL( url );
|
|
29
|
+
} catch ( error ) {
|
|
30
|
+
console.error( 'Invalid URL provided:', url );
|
|
31
|
+
process.exit( 1 );
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// Create readline interface for STDIO
|
|
35
|
+
const rl = createInterface( {
|
|
36
|
+
input: process.stdin,
|
|
37
|
+
output: process.stdout,
|
|
38
|
+
terminal: false
|
|
39
|
+
} );
|
|
40
|
+
|
|
41
|
+
// Buffer for accumulating input lines
|
|
42
|
+
let inputBuffer = '';
|
|
43
|
+
console.log( JSON.stringify( {
|
|
44
|
+
jsonrpc: "2.0",
|
|
45
|
+
method: "notifications/message",
|
|
46
|
+
params: {
|
|
47
|
+
level: "info",
|
|
48
|
+
logger: "stdio",
|
|
49
|
+
data: {
|
|
50
|
+
message: "Welcome to the SamuraiWP MCP Remote Client!",
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
} ) );
|
|
54
|
+
|
|
55
|
+
// Process each line from STDIN
|
|
56
|
+
rl.on( 'line', async ( line ) => {
|
|
57
|
+
inputBuffer += line;
|
|
58
|
+
|
|
59
|
+
// Try to parse as JSON
|
|
60
|
+
try {
|
|
61
|
+
const jsonInput = JSON.parse( inputBuffer );
|
|
62
|
+
inputBuffer = ''; // Reset buffer on successful parse
|
|
63
|
+
|
|
64
|
+
// Send JSON-RPC request to endpoint
|
|
65
|
+
try {
|
|
66
|
+
let body = {
|
|
67
|
+
jsonrpc: '2.0',
|
|
68
|
+
method: jsonInput.method,
|
|
69
|
+
params: jsonInput.params || {},
|
|
70
|
+
};
|
|
71
|
+
const response = await fetch( url, {
|
|
72
|
+
method: 'POST',
|
|
73
|
+
headers: {
|
|
74
|
+
'Content-Type': 'application/json',
|
|
75
|
+
'Authorization': `Bearer ${ apiKey }`
|
|
76
|
+
},
|
|
77
|
+
body: JSON.stringify( body )
|
|
78
|
+
} );
|
|
79
|
+
|
|
80
|
+
if ( ! response.ok ) {
|
|
81
|
+
const errorText = await response.text();
|
|
82
|
+
console.error( JSON.stringify( {
|
|
83
|
+
jsonrpc: '2.0',
|
|
84
|
+
error: {
|
|
85
|
+
code: response.status,
|
|
86
|
+
message: `HTTP ${ response.status }: ${ errorText }`
|
|
87
|
+
},
|
|
88
|
+
id: jsonInput.id
|
|
89
|
+
} ) );
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
const result = await response.json();
|
|
94
|
+
if( result && result.jsonrpc && result.result ) {
|
|
95
|
+
let out = {
|
|
96
|
+
jsonrpc: '2.0',
|
|
97
|
+
result: result.result,
|
|
98
|
+
id: jsonInput.id
|
|
99
|
+
}
|
|
100
|
+
console.log( JSON.stringify( out ) );
|
|
101
|
+
} else {
|
|
102
|
+
const errorText = await response.text();
|
|
103
|
+
console.error( JSON.stringify( {
|
|
104
|
+
jsonrpc: '2.0',
|
|
105
|
+
error: {
|
|
106
|
+
code: response.status,
|
|
107
|
+
message: `HTTP ${ response.status }: ${ errorText }`
|
|
108
|
+
},
|
|
109
|
+
id: jsonInput.id
|
|
110
|
+
} ) );
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
} catch ( fetchError ) {
|
|
115
|
+
console.error( JSON.stringify( {
|
|
116
|
+
jsonrpc: '2.0',
|
|
117
|
+
error: {
|
|
118
|
+
code: -32000,
|
|
119
|
+
message: `Network error: ${ fetchError.message }`
|
|
120
|
+
},
|
|
121
|
+
id: jsonInput.id
|
|
122
|
+
} ) );
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
} catch ( parseError ) {
|
|
126
|
+
// Not valid JSON yet, continue accumulating
|
|
127
|
+
// This allows for multi-line JSON input
|
|
128
|
+
}
|
|
129
|
+
} );
|
|
130
|
+
|
|
131
|
+
rl.on( 'close', () => {
|
|
132
|
+
process.exit( 0 );
|
|
133
|
+
} );
|
|
134
|
+
|
|
135
|
+
// Handle process termination
|
|
136
|
+
process.on( 'SIGINT', () => {
|
|
137
|
+
process.exit( 0 );
|
|
138
|
+
} );
|
|
139
|
+
|
|
140
|
+
process.on( 'SIGTERM', () => {
|
|
141
|
+
process.exit( 0 );
|
|
142
|
+
} );
|
package/package.json
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@websamurai/mcp-wp-remote",
|
|
3
|
+
"version": "1.0.1",
|
|
4
|
+
"description": "STDIO to WordPress JSON-RPC bridge for MCP protocol",
|
|
5
|
+
"main": "index.js",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"scripts": {
|
|
8
|
+
"start": "node index.js"
|
|
9
|
+
},
|
|
10
|
+
"bin": {
|
|
11
|
+
"mcp-wp-remote": "index.js"
|
|
12
|
+
},
|
|
13
|
+
"keywords": [
|
|
14
|
+
"mcp",
|
|
15
|
+
"wordpress",
|
|
16
|
+
"json-rpc",
|
|
17
|
+
"stdio"
|
|
18
|
+
],
|
|
19
|
+
"author": "Kiera Howe",
|
|
20
|
+
"license": "MIT",
|
|
21
|
+
"devDependencies": {},
|
|
22
|
+
"dependencies": {}
|
|
23
|
+
}
|