PluginProbe
xSpeed Cache: AI-Powered Performance Hub with MCP, Caching & CDN / 1.3.7
xSpeed Cache: AI-Powered Performance Hub with MCP, Caching & CDN v1.3.7
1.3.7 1.3.6 1.3.5 1.3.4 1.3.3 1.3.2 1.3.1 1.3.0 1.2.4 trunk 1.0.0 1.0.1 1.0.2 1.0.3 1.0.4 1.0.5 1.0.6 1.0.7 1.0.8 1.0.9 1.1.0 1.1.1 1.1.2 1.1.3 1.1.4 All 33 releases
← All changes | includes/modules/Mcp/Mcp_Server.php +22 -2 1.3.5 → 1.3.7 View file →
@@ -67,8 +67,14 @@
67 67 }
68 68 Mcp_Rate_Limiter::clear();
69 69
70 70 $raw = $request->get_body();
71 + // Second line behind McpModule::cap_request_body(), which is the one
72 + // that runs before WordPress decodes. Kept because the pretty
73 + // front-door path reaches here without WP_REST_Server::dispatch().
74 + if ( strlen( $raw ) > Mcp_Tools::MAX_TOOL_BODY_BYTES ) {
75 + return self::error_response( null, self::INVALID_REQUEST, 'Request body is too large.', 413 );
76 + }
71 77 $msg = json_decode( $raw, true );
72 78
73 79 if ( null === $msg && JSON_ERROR_NONE !== json_last_error() ) {
74 80 return self::error_response( null, self::PARSE_ERROR, 'Parse error: body is not valid JSON.', 400 );
@@ -127,10 +133,11 @@
127 133 'capabilities' => array(
128 134 'tools' => array( 'listChanged' => false ),
129 135 ),
130 136 'serverInfo' => array(
131 - 'name' => 'xspeed',
132 - 'version' => defined( 'XSPEED_VERSION' ) ? XSPEED_VERSION : '1.0.0',
137 + 'name' => 'xspeed',
138 + 'version' => defined( 'XSPEED_VERSION' ) ? XSPEED_VERSION : '1.0.0',
139 + 'xspeedAuth' => self::$auth_kind,
133 140 ),
134 141 )
135 142 );
136 143
@@ -216,9 +223,20 @@
216 223 *
217 224 * @param \WP_REST_Request $request Incoming request.
218 225 * @return bool
219 226 */
227 + /**
228 + * Which credential authorized this request: 'site' (the pairing token)
229 + * or 'oauth'. Reported in `initialize` so xSpeed Hub stores only the
230 + * pairing token when a site syncs it. An OAuth token can be read-only
231 + * and expires within the hour; storing one would break the Hub.
232 + *
233 + * @var string
234 + */
235 + private static $auth_kind = '';
236 +
220 237 private static function authorize( \WP_REST_Request $request ): bool {
238 + self::$auth_kind = '';
221 239 $presented = self::extract_token( $request );
222 240 if ( '' === $presented ) {
223 241 return false;
224 242 }
@@ -231,8 +249,9 @@
231 249 $stored = Mcp_Pairing::site_token();
232 250 if ( '' !== $stored && hash_equals( $stored, $presented ) ) {
233 251 Mcp_Tools::set_read_only_override( null );
234 252 Mcp_Tools::set_configure_override( null );
253 + self::$auth_kind = 'site';
235 254 return true;
236 255 }
237 256
238 257 // Path 2: an OAuth 2.1 access token minted by Mcp_OAuth. Its own
@@ -242,8 +261,9 @@
242 261 $grant = Mcp_OAuth::validate_token( $presented );
243 262 if ( null !== $grant ) {
244 263 Mcp_Tools::set_read_only_override( Mcp_OAuth::scope_is_read_only( $grant['scope'] ) );
245 264 Mcp_Tools::set_configure_override( Mcp_OAuth::scope_allows_configure( $grant['scope'] ) );
265 + self::$auth_kind = 'oauth';
246 266 return true;
247 267 }
248 268
249 269 return false;