๐ง Debugging FluentCommunity API Integration
A Complete Guide to Fixing WordPress REST API Proxy Issues
FluentMCP v1.5.4 โ v1.7.0 | November 25-26, 2025
15 Versions Released 7 Critical Bugs Fixed 100% Tests Passing 4 Hours Debugging
๐ฏ Executive Summary
This document chronicles the debugging process for fixing 7 failing FluentCommunity API endpoints in the FluentMCP WordPress plugin. The issues spanned incorrect HTTP methods, wrong parameter names, database table mismatches, and missing plugin version headers.
๐จ The Initial Problem
Impact: Core functionality (update post, comments CRUD, bulk operations) completely broken
Root Cause: Multiple integration issues between MCP tool schema, WordPress REST API, and FluentCommunity API
Failing Tests
| Tool | Error | Root Cause | Fixed In |
|---|---|---|---|
fc_update_post |
404 Not Found | Using PUT instead of POST | v1.5.6 |
fc_create_comment |
422 Unprocessable | Wrong parameter name (message vs comment) | v1.5.7 |
fc_update_comment |
400 Bad Request | Missing post_id + wrong table name | v1.6.9 |
fc_delete_comment |
400 Bad Request | Missing post_id + wrong table name | v1.6.9 |
fc_add_space_member |
400 Bad Request | Direct DB access instead of API | v1.5.8 |
fc_bulk_create_posts |
404 Not Found | Endpoint not implemented | v1.5.9 |
| Plugin Version | Shows wrong version | Header not updated | v1.6.9 |
๐ Detailed Bug Analysis
Bug #1: Update Post – Wrong HTTP Method
404 Not FoundEndpoint:
PUT /fc-manager/v1/posts/{id}
๐ Key Lesson: Always Check the API Routes File
The Problem: The MCP tool was sending PUT requests, but FluentCommunity’s API routes only registered POST for updates.
Evidence from api.php:
// Line 42: FluentCommunity API routes
Route::post('/{spaceSlug}/feeds/{feedId}', [FeedsController::class, 'patchBySlug']);
The Fix: Changed the plugin route registration to accept POST instead of PUT.
// Before (v1.5.5)
array(
'methods' => 'PUT',
'callback' => 'fmcp_rest_update_post',
)
// After (v1.5.6)
array(
'methods' => 'POST', // Changed to POST
'callback' => 'fmcp_rest_update_post',
)
Bug #2: Create Comment – Wrong Parameter Name
422 Unprocessable EntitySent:
{"message": "Comment text"}Expected:
{"comment": "Comment text"}
๐ Key Lesson: API Documentation Can Be Wrong – Check the Controller
The Problem: Official API docs said to use message parameter, but the controller expected comment.
Evidence from CommentsController.php:
// Line 165: validateCommentText method
protected function validateCommentText($request)
{
$comment = $request->get('comment'); // Expects 'comment', not 'message'!
if (!$comment) {
return new \WP_Error('invalid_comment', __('Comment text is required'));
}
// ...
}
The Fix: Added parameter mapping in the proxy function to convert message โ comment.
// Added to fmcp_map_parameters_for_fluentcommunity()
if (strpos($endpoint, 'comments') !== false) {
if (isset($params['message']) && !isset($params['comment'])) {
$params['comment'] = $params['message'];
unset($params['message']);
}
}
Bug #3 & #4: Update/Delete Comment – Multiple Issues
400 Bad Request then 404 Not FoundIssues:
- MCP tool doesn’t send
post_idparameter - Wrong database table name (
fcom_commentsvsfcom_post_comments) - Route registered for PUT but MCP sends POST
๐ Key Lesson: Use Debug Logging to See Actual Request Data
The Problem: We were guessing what parameters the MCP tool was sending. Adding debug logging revealed the truth.
Debug Output (v1.6.7):
=== UPDATE COMMENT - INCOMING REQUEST ===
All params: {"id":"5","message":"Test"}
Route: /fc-manager/v1/comments/5
Method: PUT
URL params: {"id":"5"}
Body params: {}
Extracted comment_id: 5
Extracted post_id: // EMPTY! MCP tool doesn't send it!
Database Error:
WordPress database error Table 'iwpdfd6_fcom_comments' doesn't exist
// Should be 'fcom_post_comments'!
The Fix (3 parts):
1. Auto-lookup post_id from database:
if (!$post_id) {
global $wpdb;
$table = $wpdb->prefix . 'fcom_post_comments'; // Correct table name
$post_id = $wpdb->get_var($wpdb->prepare(
"SELECT post_id FROM $table WHERE id = %d",
$comment_id
));
if (!$post_id) {
return new WP_Error('comment_not_found', 'Comment not found', array('status' => 404));
}
}
2. Accept both PUT and POST methods:
register_rest_route($namespace, '/comments/(?P\d+)', array(
array(
'methods' => array('PUT', 'POST'), // Accept both
'callback' => 'fmcp_rest_update_comment',
),
));
3. Use the proxy function (not manual request building):
// Simple and clean - proxy handles everything
return fmcp_proxy_to_fluentcommunity(
$request,
'feeds/' . $post_id . '/comments/' . $comment_id,
'POST'
);
Bug #5: Add Space Member – Wrong Approach
400 Bad RequestIssue: Direct database INSERT instead of using FluentCommunity API
๐ Key Lesson: Always Use the API, Never Direct Database Access
The Problem: The function was doing direct database inserts, bypassing FluentCommunity’s validation and hooks.
Before (v1.5.7):
// BAD: Direct database access
global $wpdb;
$table = $wpdb->prefix . 'fcom_space_user';
$wpdb->insert($table, array(
'space_id' => $space_id,
'user_id' => $user_id,
'role' => $role
));
After (v1.5.8):
// GOOD: Use the API endpoint
$slug = fmcp_get_space_slug_by_id($space_id);
return fmcp_proxy_to_fluentcommunity(
$request,
'spaces/' . $slug . '/members',
'POST'
);
Bug #6: Bulk Create Posts – Missing Endpoint
404 Not FoundIssue: Endpoint
/posts/bulk was never registered
// Register the route
register_rest_route($namespace, '/posts/bulk', array(
'methods' => 'POST',
'callback' => 'fmcp_rest_bulk_create_posts',
));
// Implementation
function fmcp_rest_bulk_create_posts($request) {
$posts = $request->get_param('posts');
$results = array();
foreach ($posts as $post_data) {
$post_request = new WP_REST_Request('POST', '/fc-manager/v1/posts');
foreach ($post_data as $key => $value) {
$post_request->set_param($key, $value);
}
$results[] = fmcp_rest_create_post($post_request);
}
return rest_ensure_response($results);
}
Bug #7: Plugin Version Not Updating
Issue: Plugin header version wasn’t being updated
๐ Key Lesson: Update BOTH the VERSION File AND Plugin Header
The Problem: We were updating the VERSION file but not the plugin header comment.
What WordPress Reads:
/**
* Plugin Name: FluentMCP
* Version: 1.6.2 // โ WordPress reads THIS, not the VERSION file!
* Author: 1WD LLC
*/
The Fix: Update both locations in every release.
// 1. Update plugin header
sed -i 's/Version: 1.6.9/Version: 1.7.0/' fluent-mcp.php
// 2. Update VERSION file
echo "1.7.0" > VERSION
// 3. Create release
zip -r fluent-mcp-v1.7.0.zip fluent-mcp.php VERSION CHANGELOG.md
๐ Version History Timeline
๐ ๏ธ Debugging Methodology That Worked
1. Create a Test Sandbox Script
Instead of creating 15 plugin versions, we should have created a standalone test script first:
// test-api.php - Direct API testing
$auth = base64_encode("username:password");
$context = stream_context_create([
'http' => [
'method' => 'POST',
'header' => "Authorization: Basic $auth\r\nContent-Type: application/json\r\n",
'content' => json_encode(['comment' => 'Test'])
]
]);
$response = file_get_contents("https://site.com/wp-json/fluent-community/v2/feeds/56/comments/5", false, $context);
echo $response;
2. Add Comprehensive Debug Logging
Log EVERYTHING about the incoming request:
error_log('=== DEBUG ===');
error_log('All params: ' . json_encode($request->get_params()));
error_log('Method: ' . $request->get_method());
error_log('Route: ' . $request->get_route());
error_log('Body: ' . json_encode($request->get_body_params()));
error_log('URL params: ' . json_encode($request->get_url_params()));
3. Test Directly Against the API
Use PowerShell/curl to bypass the plugin and test the actual FluentCommunity API:
# PowerShell direct test
$auth = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes("user:pass"))
Invoke-RestMethod -Uri "https://site.com/wp-json/fluent-community/v2/feeds/56/comments/5" `
-Method Post `
-Headers @{Authorization="Basic $auth"} `
-Body (@{comment="Test"} | ConvertTo-Json) `
-ContentType "application/json"
4. Read the Source Code, Not Just the Docs
The official API documentation was WRONG about parameter names. Always verify in the controller:
- โ
Check
api.phpfor routes and HTTP methods - โ
Check
Controller.phpfor parameter names and validation - โ
Check
Migrations/for database table names - โ Don’t trust documentation alone
๐ฏ Critical Lessons Learned
WordPress REST API Best Practices
- Use
set_body_params()for POST/PUT/PATCH: Justset_param()isn’t enough for body parameters - Accept multiple HTTP methods: Use
array('PUT', 'POST')for flexibility - Always use the proxy pattern: Don’t build
WP_REST_Requestmanually - Update plugin header version: WordPress reads the comment, not the VERSION file
FluentCommunity API Quirks
- Comments use
commentnotmessage: Despite what the docs say - Table name is
fcom_post_comments: Notfcom_comments - Updates use POST not PUT: Check
api.phproutes - Spaces need slugs not IDs: For most operations
Debugging Strategy
- Create test sandbox FIRST: Don’t iterate on production plugin
- Add debug logging early: See actual request data
- Test API directly: Use PowerShell/curl to isolate issues
- Read source code: Controllers > Documentation
- Use the MCP connection: Test tools directly from the agent
๐ Final Results
โ All Tests Passing (v1.7.0)
| Tool | Status | Test Result |
|---|---|---|
fc_update_post |
โ Working | POST method, correct parameters |
fc_create_comment |
โ Working | messageโcomment mapping |
fc_update_comment |
โ Working | Auto post_id lookup, correct table |
fc_delete_comment |
โ Working | Auto post_id lookup, correct table |
fc_add_space_member |
โ Working | Using API endpoint |
fc_bulk_create_posts |
โ Working | Endpoint implemented |
fc_list_comments |
โ Working | Always worked |
๐ฎ Future Recommendations
- Create automated tests: PHPUnit tests for each endpoint
- Add parameter validation: Validate before proxying to FluentCommunity
- Implement caching: Cache slug lookups to reduce DB queries
- Add rate limiting: Protect against API abuse
- Better error messages: Return specific error details to users
- Version check script: Automate checking both header and VERSION file match
๐ Code Snippets Library
Correct Way to Proxy to FluentCommunity
function fmcp_rest_update_comment($request) {
$comment_id = $request->get_param('id') ?: $request->get_param('comment_id');
$post_id = $request->get_param('post_id');
// Auto-lookup post_id if not provided
if (!$post_id) {
global $wpdb;
$table = $wpdb->prefix . 'fcom_post_comments';
$post_id = $wpdb->get_var($wpdb->prepare(
"SELECT post_id FROM $table WHERE id = %d",
$comment_id
));
if (!$post_id) {
return new WP_Error('comment_not_found', 'Comment not found', array('status' => 404));
}
}
// Use the proxy - it handles everything
return fmcp_proxy_to_fluentcommunity(
$request,
'feeds/' . $post_id . '/comments/' . $comment_id,
'POST'
);
}
Parameter Mapping Function
function fmcp_map_parameters_for_fluentcommunity($params, $endpoint, $method = 'GET') {
// Map 'message' to 'comment' for comment endpoints
if (strpos($endpoint, 'comments') !== false) {
if (isset($params['message']) && !isset($params['comment'])) {
$params['comment'] = $params['message'];
unset($params['message']);
}
}
// Wrap parameters for space updates
if ($endpoint === 'spaces' && $method === 'PUT' && !empty($params)) {
$params = array('data' => $params);
}
return $params;
}
Proper Route Registration
register_rest_route($namespace, '/comments/(?P\d+)', array(
array(
'methods' => array('PUT', 'POST'), // Accept both methods
'callback' => 'fmcp_rest_update_comment',
'permission_callback' => 'fmcp_rest_permission_check'
),
array(
'methods' => 'DELETE',
'callback' => 'fmcp_rest_delete_comment',
'permission_callback' => 'fmcp_rest_permission_check'
)
));
๐ Acknowledgments
This debugging session was a collaborative effort that required:
- โ Reading FluentCommunity source code
- โ Testing with PowerShell direct API calls
- โ Using MCP tools for live testing
- โ Extensive debug logging
- โ Patience through 15 version iterations
Key Takeaway: When debugging API integrations, always verify your assumptions by testing directly against the API and reading the source code. Documentation can be outdated or wrong.
