mirror of
https://github.com/araxiaonline/TrinityCore.git
synced 2026-06-13 03:32:28 -04:00
feat(mcp): Complete Phase 1 - Working MCP server with database tools
MCP Server is fully operational: - Fixed JSON-RPC id field handling (can't use value() with nullptr) - Fixed params extraction for tools/call - All database tools working: db_query, db_execute, db_tables, db_describe - Server tools working: server_info, player_list Verified working: - Health check endpoint returns ok - tools/list returns all 9 registered tools - db_query successfully queries world database Documentation updated with: - Implementation notes and API learnings - File structure overview - Phase roadmap
This commit is contained in:
@@ -2,15 +2,17 @@
|
||||
|
||||
## Overview
|
||||
|
||||
The Araxia MCP Server embeds a Model Context Protocol server directly into the worldserver, enabling AI assistants (like Claude) to interact with the game server in real-time.
|
||||
The Araxia MCP Server embeds a Model Context Protocol server directly into the worldserver, enabling AI assistants (like Claude/Cascade) to interact with the game server in real-time.
|
||||
|
||||
**Status:** ✅ Phase 1 Complete (Nov 30, 2025)
|
||||
|
||||
## Features
|
||||
|
||||
- **Database Access**: Direct SQL queries to world, characters, and auth databases
|
||||
- **Server Status**: Real-time server info, player lists, uptime
|
||||
- **GM Commands**: Execute GM commands programmatically
|
||||
- **Eluna Integration**: (Coming) Execute Lua, inspect state, hot-reload
|
||||
- **AMS Bridge**: (Coming) Communicate with client addons
|
||||
- **Database Access**: ✅ Direct SQL queries to world, characters, and auth databases
|
||||
- **Server Status**: ✅ Real-time server info, player lists, uptime
|
||||
- **GM Commands**: ✅ Stub (needs ChatHandler integration)
|
||||
- **Eluna Integration**: ⏳ (Phase 2) Execute Lua, inspect state, hot-reload
|
||||
- **AMS Bridge**: ⏳ (Phase 4) Communicate with client addons
|
||||
|
||||
## Configuration
|
||||
|
||||
@@ -136,3 +138,41 @@ curl -X POST http://localhost:8765/mcp \
|
||||
### Can't connect remotely
|
||||
- Set `Araxia.MCP.AllowRemote = 1`
|
||||
- Ensure firewall allows port 8765
|
||||
|
||||
## Implementation Notes
|
||||
|
||||
### Dependencies (Header-Only)
|
||||
- **cpp-httplib** (`httplib.h`) - Embedded HTTP server
|
||||
- **nlohmann/json** (`json.hpp`) - JSON parsing and serialization
|
||||
|
||||
### TrinityCore API Learnings
|
||||
- Use `sConfigMgr->GetBoolDefault()`, `GetIntDefault()`, `GetStringDefault()` (not `GetOption<T>`)
|
||||
- `Field::GetString()` works for all field types (no `GetType()` method)
|
||||
- `QueryResultFieldMetadata` has `Alias` and `Name` (may be null)
|
||||
- JSON-RPC `id` field: use `request.contains("id") ? request["id"] : json(nullptr)`
|
||||
|
||||
### Files Created
|
||||
```
|
||||
src/araxiaonline/mcp/
|
||||
├── AraxiaMCPServer.cpp # Core server, JSON-RPC handling
|
||||
├── AraxiaMCPServer.h # Public interface, tool registration
|
||||
├── DatabaseTools.cpp # db_query, db_execute, db_tables, db_describe
|
||||
├── ServerTools.cpp # server_info, player_list, gm_command
|
||||
├── httplib.h # cpp-httplib (external)
|
||||
└── json.hpp # nlohmann/json (external)
|
||||
```
|
||||
|
||||
### Integration Points
|
||||
- `World.cpp` - `sMCPServer->Initialize()` in `SetInitialWorldSettings()`
|
||||
- `World.cpp` - `sMCPServer->Shutdown()` in destructor
|
||||
- `CMakeLists.txt` - Auto-collected via `CollectSourceFiles`
|
||||
|
||||
## Roadmap
|
||||
|
||||
| Phase | Feature | Status |
|
||||
|-------|---------|--------|
|
||||
| 1 | Database tools, server info | ✅ Complete |
|
||||
| 2 | Eluna integration (lua_eval, shared_data) | ⏳ Planned |
|
||||
| 3 | World object tools (creatures, GOs) | ⏳ Planned |
|
||||
| 4 | AMS bridge (client addon communication) | ⏳ Planned |
|
||||
| 5 | Event streaming (logs, world events) | ⏳ Planned |
|
||||
|
||||
@@ -217,19 +217,21 @@ void MCPServer::HandleMCPRequest(const std::string& body, std::string& response)
|
||||
|
||||
json MCPServer::ProcessJsonRpc(const json& request)
|
||||
{
|
||||
// Extract ID first (can be number, string, or null)
|
||||
json id = request.contains("id") ? request["id"] : json(nullptr);
|
||||
|
||||
// Validate JSON-RPC structure
|
||||
if (!request.contains("jsonrpc") || request["jsonrpc"] != "2.0")
|
||||
{
|
||||
return {
|
||||
{"jsonrpc", "2.0"},
|
||||
{"error", {{"code", -32600}, {"message", "Invalid Request"}}},
|
||||
{"id", request.value("id", nullptr)}
|
||||
{"id", id}
|
||||
};
|
||||
}
|
||||
|
||||
std::string method = request.value("method", "");
|
||||
json params = request.value("params", json::object());
|
||||
auto id = request.value("id", nullptr);
|
||||
json params = request.contains("params") ? request["params"] : json::object();
|
||||
|
||||
json result;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user