feat: add MCP server for AI agent interactions - #49
Conversation
Implements an HTTP-based MCP (Model Context Protocol) server that exposes
Morpheus bot data and functionality to AI agents through a clean tool-based API.
Endpoints:
- GET /api/mcp - Server info and available tools
- GET /api/mcp/health - Health check
- GET /api/mcp/tools - List all available tools with parameter schemas
- POST /api/mcp/call/{toolName} - Execute a tool with parameters
Tools:
- get_user_stats - User statistics (balance, XP, level, messages, quotes)
- get_guild_info - Guild/server information with settings
- get_economy_summary - Economy overview (balances, UBI pool, vault, stocks)
- get_activity_overview - Global activity metrics
- get_guilds - List all servers with activity stats
- get_users - Paginated user list
- get_quotes - Paginated quotes with filtering
- get_quote_by_id - Single quote details
- get_recent_logs - Recent bot logs with severity filtering
- get_stock_summary - Stock market gainers/losers
- get_leaderboard - Activity leaderboard by XP or messages
Closes vycdev#3
vycdev
left a comment
There was a problem hiding this comment.
Thanks for putting this together. The database-query layer builds and its tests pass, but this HTTP surface is not safe or MCP-compatible yet. Before merging, it needs enforced authentication and authorization, rate limiting, restricted/validated origins, standard MCP protocol support (or explicit REST API naming), endpoint-level security/protocol tests, and careful review of which data may be exposed. In particular, unapproved quotes and recent logs should not be broadly accessible. The current MCP_API_KEY and MCP_API_URLS settings give a false sense of protection/configurability because neither is actually applied.
|
|
||
| RouteGroupBuilder api = app | ||
| .MapGroup("/api/mcp") | ||
| .RequireCors(CorsPolicyName); |
There was a problem hiding this comment.
Blocking: this group only applies CORS; McpApiOptions.ApiKey is never validated. The health endpoint can report authEnabled: true while every tool remains callable without a key, including tools returning users, balances, unapproved quotes, and logs. Add authentication/authorization middleware or an endpoint filter, plus integration tests for missing, incorrect, and correct credentials.
| corsOptions.AddPolicy(CorsPolicyName, policy => | ||
| { | ||
| policy | ||
| .AllowAnyOrigin() |
There was a problem hiding this comment.
Blocking for a network-facing data API: AllowAnyOrigin() permits any browser origin, while MCP's HTTP transport requires validating the Origin header to prevent DNS-rebinding attacks. Use an explicit configured allowlist and test rejected origins.
| })); | ||
|
|
||
| // Call a specific tool | ||
| api.MapPost("/call/{toolName}", async ( |
There was a problem hiding this comment.
This is a custom REST call endpoint, not the MCP protocol expected by standard clients. MCP uses JSON-RPC with initialization and tools/list / tools/call over its transport endpoint. Please implement the standard protocol (preferably with an MCP SDK), or present this explicitly as an agent-friendly REST API rather than an MCP server.
| Env.Load(".env"); | ||
|
|
||
| DashboardApiOptions dashboardOptions = DashboardApiOptions.FromEnvironment(); | ||
| McpApiOptions mcpOptions = McpApiOptions.FromEnvironment(); |
There was a problem hiding this comment.
MCP_API_URLS has no effect: mcpOptions.Urls is loaded here, but the host is bound only with dashboardOptions.Urls. This silently exposes the new routes on the dashboard listener instead of the configured MCP URL. Either intentionally share and document one listener or wire the configuration correctly.
|
Addressed the requested changes in
The MCP-focused tests pass 14/14. The full suite reports 314 passing and the same two invariant-globalization failures in This was generated by an AI agent (vycdev2). Please verify any changes before merging or applying. |
Summary
ModelContextProtocol.AspNetCoreStreamable HTTP transport at/api/mcp.MCP_API_KEYis configured, require bearer authentication, validate exact configured origins, and apply per-client fixed-window rate limiting before authentication.DASHBOARD_API_URLSlistener rather than loading an unused MCP listener setting.Verification
dotnet build --consoleLoggerParameters:ErrorsOnly— passed: 0 errors (2 warnings reported).dotnet test Morpheus.Tests/Morpheus.Tests.csproj --no-build --filter "FullyQualifiedName~Mcp"— passed: 14/14.dotnet test --no-build— 314 passed, 2 failed: pre-existingMiscModuleTests.NormalizeTimeUntilEventName_NormalizesCasecases requiretr-TR, which is unavailable because this runner hasDOTNET_SYSTEM_GLOBALIZATION_INVARIANT=1.git diff --check— passed.Risk
Closes #3
This was generated by an AI agent (vycdev2). Please verify any changes before merging or applying.