get_param( 'mcp_token' ); if ( is_string( $token ) && '' !== $token ) { return sanitize_text_field( $token ); } } $token = filter_input( INPUT_GET, 'mcp_token', FILTER_UNSAFE_RAW ); $token = is_string( $token ) ? wp_unslash( $token ) : ''; return is_string( $token ) && '' !== $token ? sanitize_text_field( $token ) : null; } /** * Get normalized MCP token records from the plugin config. * * @return array> */ function rwpai_get_saved_mcp_tokens() { $config = function_exists( 'rwpai_get_plugin_config' ) ? rwpai_get_plugin_config() : array(); $mcp = isset( $config['mcp'] ) && is_array( $config['mcp'] ) ? $config['mcp'] : array(); if ( function_exists( 'rwpai_sanitize_mcp_tokens' ) ) { return rwpai_sanitize_mcp_tokens( $mcp ); } return array(); } /** * Resolve the WordPress user to impersonate for MCP requests. * * @return int */ function rwpai_get_mcp_auth_user_id() { if ( is_user_logged_in() && current_user_can( 'manage_options' ) ) { return get_current_user_id(); } $filtered_user_id = apply_filters( 'rwpai_mcp_auth_user_id', 0 ); if ( $filtered_user_id > 0 && get_user_by( 'id', (int) $filtered_user_id ) ) { return (int) $filtered_user_id; } $admin_ids = get_users( array( 'role' => 'administrator', 'number' => 1, 'orderby' => 'ID', 'order' => 'ASC', 'fields' => 'ids', ) ); if ( ! empty( $admin_ids ) ) { return (int) $admin_ids[0]; } return 0; } /** * Validate an opaque MCP bearer token. * * @param string $token Token value from the Authorization header. * @return bool */ function rwpai_is_valid_mcp_bearer_token( $token ) { if ( '' === $token ) { return false; } $current_time = time(); $token_records = rwpai_get_saved_mcp_tokens(); foreach ( $token_records as $token_record ) { $saved_token = isset( $token_record['token'] ) ? (string) $token_record['token'] : ''; if ( '' === $saved_token || ! hash_equals( $saved_token, $token ) ) { continue; } $expires_at = isset( $token_record['expires_at'] ) && null !== $token_record['expires_at'] ? intval( $token_record['expires_at'] ) : null; if ( null !== $expires_at && $expires_at < $current_time ) { return false; } return true; } return false; } /** * Authenticate a saved MCP bearer token and set the current user. * * @param string $token Token value from the Authorization header. * @return true|WP_Error|null */ function rwpai_authenticate_mcp_bearer_token( $token ) { if ( str_starts_with( $token, 'access_' ) || str_starts_with( $token, 'oauth_' ) ) { return null; } if ( ! rwpai_is_valid_mcp_bearer_token( $token ) ) { return new WP_Error( 'invalid_token', 'Token is invalid, expired, or has been revoked.', array( 'status' => 401 ) ); } $user_id = rwpai_get_mcp_auth_user_id(); if ( $user_id <= 0 ) { return new WP_Error( 'mcp_user_not_found', 'No administrator account is available for MCP authentication.', array( 'status' => 500 ) ); } wp_set_current_user( $user_id ); return true; } /** * Authenticate incoming REST requests to the MCP endpoints. * * @param mixed $result Existing authentication result. * @return mixed */ function rwpai_rest_authenticate_mcp_request( $result ) { if ( ! empty( $result ) ) { return $result; } if ( ! rwpai_is_mcp_request_uri() ) { return $result; } $authorization = filter_input( INPUT_SERVER, 'HTTP_AUTHORIZATION', FILTER_UNSAFE_RAW ); $authorization = is_string( $authorization ) ? wp_unslash( $authorization ) : ''; $query_token = rwpai_extract_mcp_query_token(); if ( preg_match( '/^Basic\s/i', (string) $authorization ) ) { return $result; } if ( '' === $authorization && null === $query_token ) { if ( is_user_logged_in() && current_user_can( 'manage_options' ) ) { return true; } return new WP_Error( 'unauthorized', 'Authentication required. Please provide a Bearer token or log in as an administrator.', array( 'status' => 401 ) ); } $token = '' !== $authorization ? rwpai_extract_mcp_bearer_token( $authorization ) : $query_token; if ( null === $token ) { return new WP_Error( 'unauthorized', 'Invalid Authorization header format. Expected "Bearer ".', array( 'status' => 401 ) ); } $auth_result = rwpai_authenticate_mcp_bearer_token( $token ); return null === $auth_result ? $result : $auth_result; } /** * Authenticate streamable MCP requests through the transport-level filter. * * @param mixed $result Existing authentication result. * @param WP_REST_Request|null $request Request object. * @return mixed */ function rwpai_transport_authenticate_mcp_request( $result, $request ) { if ( ! empty( $result ) || null === $request ) { return $result; } $authorization = $request->get_header( 'authorization' ); $query_token = rwpai_extract_mcp_query_token( $request ); if ( empty( $authorization ) && null === $query_token ) { return $result; } $token = ! empty( $authorization ) ? rwpai_extract_mcp_bearer_token( $authorization ) : $query_token; if ( null === $token ) { return $result; } $auth_result = rwpai_authenticate_mcp_bearer_token( $token ); return null === $auth_result ? $result : $auth_result; } /** * Register MCP auth hooks for the embedded server. * * @return void */ function rwpai_register_mcp_auth_hooks() { static $registered = false; if ( $registered ) { return; } add_filter( 'rest_authentication_errors', 'rwpai_rest_authenticate_mcp_request', 5 ); add_filter( 'wpmcp_authenticate_request', 'rwpai_transport_authenticate_mcp_request', 1, 2 ); $registered = true; }