Skip to main content
Glama
roman-zaglauer

OctoBot MCP Server

compare_strategies

Launch multiple backtest configs as one combined job, then poll a single job ID for progress and compare strategy results.

Instructions

Compare 2+ backtest configs sequentially and return one combined job.

Not confirm-gated (ADR-0003): same reasoning as start_backtest -- only ever starts simulations. configs is a list (len(configs) >= 2) of dicts, each shaped exactly like one of start_backtest's own mode-specific input shapes ({"mode": "data_files", "files": [...], ...} or {"mode": "current_bot_data", "exchange_id": ..., ...}), plus an optional "label" key used as that config's own config_label in get_job_result's later comparison/diff output (see _child_config_label) -- stripped before being validated/passed to start_backtest's own mode builders, which know nothing about it. name is accepted (per the spec's input shape) but not otherwise used: neither this tool's own output nor get_job_result's compare_strategies output shape (both fully spec'd) has anywhere to put it.

Every config is validated (same rules start_backtest itself applies) BEFORE any job -- parent or child -- is created, so a bad configs entry never leaves a dangling queued job behind: raises CompareStrategiesStartFailedError naming the offending configs[i] for len(configs) < 2, an unknown mode, a missing required field for that mode, or an unrecognized field name.

Creates one parent job (kind: "compare_strategies") with one child kind: "backtest" job per config (job.child_job_ids, in the same order as configs), then spawns ONE background asyncio.Task (tracked via store.track_watcher_task, same as start_backtest) running _run_compare_strategies, which submits each child sequentially through the shared backtest_execution_lock -- see that function's own docstring for the full sequencing/failure-isolation/cancellation behavior.

Output: {"job_id": str, "state": "queued"|"running", "sub_job_count": int} -- returns immediately, same non-blocking pattern as start_backtest (always "queued" in practice, since asyncio.create_task never runs any of the background task synchronously before this function returns). Poll get_job_status(job_id) for combined progress/ETA and each child's own live state (sub_jobs); call get_job_result(job_id) once state == "completed".

Progress notifications (milestone 11, ADR-0002 decision point 3): if THIS call (the parent) carries a progressToken, notifications report the COMBINED progress across all children (the exact same formula get_job_status already uses for polling reads), never one child's own raw percentage -- see _run_compare_strategies/ _make_compare_strategies_on_tick's own docstrings. Children are never independently callable, so they never carry their own token.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
nameNo
configsYes

Schema Changelog

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

  1. First observedv0.1.0

TDQS

A4.7/5.0
Behavior5/5

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

With no annotations provided, the description carries the full burden of behavioral disclosure, and it delivers extensively: it states the tool is not confirm-gated, only starts simulations, validates all configs before creating jobs, avoids dangling queued jobs, returns immediately, always reports 'queued' in practice, and submits children sequentially through a shared lock. It also explains combined progress notification semantics and that children are never independently callable.

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

Conciseness4/5

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

The description is long but well-structured: it opens with a one-sentence summary, then adds parameter semantics, validation behavior, job structure, output shape, polling guidance, and progress notification details in labeled sections. It could be slightly tighter around internal docstring references and ADR details, but every part contributes to correct invocation.

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 the absence of both annotations and output schema, the description is remarkably complete. It specifies the output JSON shape, error conditions and exception behavior, job hierarchy, asynchronous non-blocking behavior, polling/result instructions, and progress token semantics—everything an agent needs to invoke the tool correctly and interpret its immediate result.

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

Parameters5/5

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

The schema provides almost no parameter meaning—configs is just an array of generic objects and name is loosely typed. The description compensates fully by specifying configs must be a list of length >= 2, each shaped like start_backtest's mode-specific inputs, with an optional label key that is stripped before validation, and by explicitly stating name is accepted but unused.

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 first sentence, 'Compare 2+ backtest configs sequentially and return one combined job,' uses a specific verb, resource, and result. It clearly distinguishes compare_strategies from siblings like start_backtest by emphasizing the multi-config and combined-job behavior.

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 explains the tool is for comparing multiple backtest configs and explicitly references polling via get_job_status and retrieving results via get_job_result. It does not explicitly state 'use start_backtest for a single config,' but the '2+' constraint and repeated comparison to start_backtest make the usage context clear.

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