Skip to main content
Glama
roman-zaglauer

OctoBot MCP Server

get_job_result

Retrieve a completed backtest job's final report and trades, or the strategy comparison output. If the job is not yet complete, it returns an error naming the current state to avoid partial results.

Instructions

Fetch a completed backtest job's final report.

Requires state == "completed"; raises JobNotCompletedError naming the current state otherwise -- never returns partial results, even if OctoBot itself would technically serve a report for an in-progress run (or, for compare_strategies, if some but not all children have finished). Raises JobNotFoundError for an unknown job_id (same as get_job_status).

For kind: "backtest", output is {"report": <passthrough>, "trades": <passthrough>} from OctoBot's own GET /backtesting?update_type= backtesting_report response (NFR-8: no renaming/reshaping).

For kind: "compare_strategies" (milestone 10, docs/tasklist.md item 10), output is {"comparison": [...], "diff": ...} -- both already fully computed and stored (once, at completion -- INV-3) by _run_compare_strategies as this job's own result, so this function simply passes them through unchanged; see that function and _build_comparison_entry/_build_diff below for exactly how each is built.

Real report/trades shape, captured live against the OctoBot 2.1.1 test instance this milestone (resolves open question #3) -- data_files mode, DailyTradingMode profile, BTC/EUR on binance, exactly as OctoBot returned it (field names/nesting verbatim, values are example data from that one run):

{
  "report": {
    "bot_report": {
      "starting_portfolio": {"binance": {"BTC": {"available": 10.0, "total": 10.0}, "USDT": {...}}},
      "end_portfolio": {"binance": {"BTC": {...}, "EUR": {...}, "USDT": {...}}},
      "profitability": {"binance": -15.223942726263024},
      "market_average_profitability": {"binance": -16.839423647357034},
      "reference_market": "EUR",
      "trading_mode": "DailyTradingMode"
    },
    "chart_identifiers": [
      {"exchange_id": "...", "exchange_name": "binance", "symbol": "BTC/EUR", "time_frames": ["1m", "1h", "4h", "1d"]}
    ],
    "errors_count": 0,
    "symbol_report": [{"BTC/EUR": 0.8013392638261951}]
  },
  "trades": [
    {
      "SoR": "Simulated", "amount": "7.99127178", "cost": "535066.3103340852",
      "date": "2026-05-02 16:00:00", "exchange": "binance", "fee_cost": "535.0663103340852",
      "fee_currency": "EUR", "id": "b5eb50fd-...", "market": "EUR", "price": "66956.34",
      "ref_market_cost": 535066.3103340853, "symbol": "BTC/EUR", "time": 1777737600,
      "type": "SELL MARKET"
    },
    ...
  ]
}

Confirms the spec's own explicit warning was correct: profitability genuinely exists, but nested three levels deep (report.bot_report.profitability, itself keyed by exchange name, not a bare float) -- NOT at the top level of report as a naive read of the spec's placeholder field list (profitability/max_drawdown/ win_rate) might have assumed; max_drawdown/win_rate were not observed anywhere in this real payload at all. amount/cost/ fee_cost/price in each trade are numeric-looking strings, not JSON numbers (ref_market_cost IS a JSON number) -- passed through exactly as OctoBot sent them (NFR-8), not coerced. This tool does not hardcode or validate against any of these field names anywhere in its own code (per NFR-8/the spec's own instruction not to assume a field list) -- this is documentation of what was observed, not a schema this tool depends on.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
job_idYes

Schema Changelog

Changes observed during successful MCP inspections. Dates show when Glama detected each change.

  1. First observedv0.1.0

TDQS

A4.3/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations present, the description carries full responsibility and delivers thoroughly: error cases, no-partial-results guarantee, passthrough semantics, exact output structure, field types (strings vs numbers), and the fact that the tool does not validate or hardcode field names. This is exemplary behavioral disclosure.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness3/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is front-loaded with the core purpose and precondition, and the sections are logically organized. However, it is overlong, with internal references (milestone, NFR-8, INV-3, docs/tasklist) and a large live JSON example plus lengthy meta-commentary that could be trimmed without sacrificing essential guidance.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given there is no output schema or annotations, the description is exceptionally complete: it covers prerequisites, all error behavior, output shapes for both job kinds, passthrough guarantees, and real observed field types. An agent has essentially everything needed to call the tool and interpret its result.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The schema has 0% description coverage for the single job_id parameter. The description mentions job_id only in the error context ('Raises JobNotFoundError for an unknown job_id'), adding limited meaning beyond the schema. However, the tool name and the rest of the description make the parameter's purpose unambiguous, so minimal compensation is acceptable.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a specific verb and resource: 'Fetch a completed backtest job's final report.' It also clarifies the two job kinds (backtest and compare_strategies) and their distinct output shapes, making it easy to differentiate from sibling tools like get_job_status or list_jobs.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description clearly states when to use the tool: requires state == 'completed', otherwise raises JobNotCompletedError and never returns partial results. It also explains the two output variants. It doesn't explicitly name alternatives like get_job_status for checking state, but the precondition itself gives strong contextual guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.