A simple trading bot that auto-registers on first run, connects to the arena via WebSocket for real-time events, and places bets using a basic random/contrarian strategy
This MCP server exhibits severe structural and documentation deficiencies. The codebase shows a Node.js/Python trading bot that uses fetch() for HTTP communication to an external ProfitPlay service, not MCP protocol at all. No MCP server framework (mcp npm package, mcp Python library) is present. Tools are defined only as JavaScript functions with minimal documentation. No JSON Schema input validation, no output schema documentation, and no MCP protocol compliance. The server claims to expose 6 tools but provides only informal function signatures. Descriptions exist but are superficial (e.g., 'Pick UP or DOWN randomly'). Parameters have type hints in comments and JSDoc but no formal JSON Schema. Error handling is minimal, most errors are raw JavaScript exceptions without recovery guidance. The implementation is not an MCP server at all; it is a standalone bot that calls an external API.
Fetch the current arena state to see active markets
Fetch the agent's current status (wallet, positions, etc.)
Pick a price near 0.50 with slight randomization
Pick UP or DOWN randomly. Replace with your own logic!
Place a bet on the given game. Parameters: gameType (e.g. 'btc-5min'), side ('UP' or 'DOWN'), price (0.01 to 0.99), shares (number of shares)
Register a new agent and return the API key. If an API key already exists, reuse it.
No MCP server framework detected. Code is a standalone bot using fetch() HTTP calls, not an MCP server.
No input schemas defined. Tools lack JSON Schema definitions for parameters. placeBet has inline type hints in JSDoc but no formal schema. Other tools have no parameter documentation at all.
No output schemas documented. Tools return raw JSON from fetch() calls (e.g., getStatus, getArena) or JavaScript values (pickSide, pickPrice). No schema describes what fields the LLM should expect.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-23 | F | 29 | 2026-07-28+ | v2 |
Weak tool descriptions. 'Pick UP or DOWN randomly. Replace with your own logic!' (pickSide) lacks actionable context. 'Fetch the agent's current status' (getStatus) does not explain what status fields are returned or when to call it vs getArena.
registerAgent description incomplete. Does not clarify that it modifies state (writes API key to .env file) or that repeated calls return the same key if one exists. No guidance on when to call it vs reuse.
pickSide and pickPrice are utility functions, not proper tools. They do not interact with external state or data, they just return random values. Including them as 'tools' violates the single-responsibility pattern and wastes LLM reasoning. If intended as strategies, they should be baked into placeBet or left to the agent to implement.
Error handling is minimal. Functions throw raw errors (e.g., 'Status fetch failed: 403') with no recovery guidance. LLMs cannot infer whether to retry, ask the user, or give up. No classification of errors as retryable, user-fixable, or fatal.
API key handling is insecure. registerAgent saves the API_KEY to .env as plaintext. The key is also loaded from the environment at startup and stored in a module-level variable. No mention of secret injection patterns, vault, or secure credential management.
No permission gates or audit trail. registerAgent and placeBet execute without checking if the calling agent/user is authorized. No logging of who called what, at what time, or what happened.
placeBet has only partial schema documentation. Parameters are described inline (gameType, side, price, shares) but lack formal JSON Schema with type, min/max, enum constraints. No documentation of the price range (0.01 - 0.99) in the schema itself.
placeBet response is not shaped or documented. The tool returns raw API JSON from POST /api/games/{gameType}/bet, which may include internal fields, timestamps, or metadata irrelevant to the LLM. No documentation of which fields matter.