How MCP works in hamster-bot
The bot trades on the VPS by itself, using the keys and settings a person gave it. MCP opens a second entrance to the bot: through it, an AI agent on the same server controls the bot. The person talks to the agent from a phone.
87 tools
Who does what#
Bot
Trades around the clock according to its settings and stores the exchange keys. It needs neither the agent nor the phone to work.
Agent
Researches settings in the tester, starts and edits strategies, watches the bots and keeps a journal. It gives trading commands through the bot's tools.
Phone
A window into the agent's session. The session itself, its files and the MCP connection stay on the VPS.
The path of one command: “close the BTC position”#
- 1The person writes a message in the Claude app. It goes to the Anthropic cloud over HTTPS.
- 2Claude Code on the VPS polls the cloud itself and picks up the message. The model decides which tool to call.
- 3The agent calls
close_positionon/mcpwith theapi_token. The bot checks the token. - 4The MCP server turns the call into an ordinary request to
/api/*of the same bot and passes the same token. That is why MCP and the API share the same logic and checks. - 5The API passes the command to the bot core. The core takes the key of this account.
- 6The connector signs the request and sends it to the exchange. The result returns along the same chain and appears on the phone.
What happens if one of the parts goes down#
| What happened | Bot | Agent |
|---|---|---|
| Phone is off | Trades | The session keeps running on the VPS |
| SSH closed | Trades | Keeps working if started in tmux |
| VPS offline for more than 10 minutes | Cannot reach the exchange until the network returns | The claude remote-control process exits and must be started again |
| Agent stopped | Trades on the current settings, but nobody is watching it | Not working |
use_mcp is off | Trades | Cannot control the bot: /mcp returns 404 |
What the agent can do through MCP#
| Group | Tools | Examples |
|---|---|---|
| Tester | 42 | tester_run_mining, tester_run_batch, tester_portfolio_analysis39 more
|
| Bots | 10 | list_bots, get_balances, pause_bot, play_bot6 more
|
| Positions and orders | 9 | list_positions, market_order, close_position6 more
|
| Accounts | 8 | list_accounts, save_account, get_balance_history5 more
|
| Strategies | 7 | save_strategy, create_strategy_from_tester, delete_strategy4 more
|
| System and logs | 7 | get_errors, read_log_file, update_program4 more
|
| Settings | 4 | get_config, update_config, get_field_hints1 more
|
Of the 87 tools, 42 only read data (readOnlyHint), and 25 are marked as dangerous (destructiveHint): they trade, start bots or irreversibly change data. These are market orders, closing positions, cancelling orders, starting bots, saving and deleting strategies and keys, changing the config, shutting down and updating the program. The tester works on historical data and does not trade on the exchange.
Access limits#
- The token gives owner rights. With the
api_token, all 87 tools are available, including trading, deleting accounts and shutting down the program. There is no read-only mode. - Confirmation depends on the client. Dangerous tools are only marked; it is up to the MCP client to ask the person. In autonomous mode permissions are granted in advance, and the agent acts without asking.
- CLAUDE.md sets rules but does not protect. The agent follows risk limits and the ban on leaving its folder as instructions. If it has a shell under the same user as the bot, it can technically read the bot's files.
- The token is not always needed. When Telegram login is off, requests to
/mcpfrom the same machine pass without a token. This applies to any local process. - The web interface, API and MCP share one port. For an agent on the same VPS, the
127.0.0.1address is enough. From another machine the token travels in plain text, so over the internet you need an HTTPS proxy or an SSH tunnel.
How to run it on a VPS#
In the bot's
settings_program.json, no restart needed:"use_mcp": true
A session that survives closing SSH:
tmux new -s agent
Connect the agent to the bot:
claude mcp add --transport http hamster-bot http://127.0.0.1:<port>/mcp --header "Authorization: Bearer <api_token>"
Open the session for the phone:
claude remote-control --name "hamster-bot"
In the session chat: autonomous work on a schedule:
/loop 6h Continue working per CLAUDE.md
Connection details#
MCP is off by default. Instead of editing the file, you can enable it via the API: POST /api/settings/config with the body { "use_mcp": true }.
Address: http://127.0.0.1:<port>/mcp, Streamable HTTP transport. From another machine, use the server address instead of 127.0.0.1.
Instead of claude mcp add, the connection can be described in the project's .mcp.json file:
{
"mcpServers": {
"hamster-bot": {
"type": "http",
"url": "http://127.0.0.1:5000/mcp",
"headers": { "Authorization": "Bearer <api_token>" }
}
}
}Other clients connect to the same address if they support Streamable HTTP and custom request headers.
The access rules are the same as for the API (see Access). Besides the token, the hamster-bot-token cookie works with login enabled. A request with neither gets 401.
Argument names#
All tools use the same names: strategy — bot strategy name, account — account name, folder — tester settings folder. The old names are accepted as synonyms: name instead of strategy in get_strategy, copy_strategy, delete_strategy, name instead of account in get_account, get_account_symbols, delete_account, get_account_info, get_balance_history, compact_balance_history, path instead of folder in set_tester_settings_folder, create_tester_settings_folder, delete_tester_settings_folder. If neither the main name nor a synonym is present, the error names the expected field. strategy in draft_strategy, draft_tester_settings and get_settings_schema is a strategy code (zigzag, mrs2), not a name. For tester settings name is the settings set name.
An API error is returned to the agent as a tool error with the code and text, for example HTTP 404: {"success":false,"error":"Strategy not found"}. Very long responses are cut at 200,000 characters. read_tester_file returns text files in whole lines: a long response ends with the hint ... [lines A-B of N; continue with offset=B]. For long CSV files there are the parameters offset and limit (a page of lines), tail_lines (last N lines), contains (only lines with the text) and columns (only the needed columns); the CSV header is always kept. list_tester_files accepts contains, offset and limit. HTML reports are large, so to compare runs use tester_report_summaries, and for details of one run read_tester_report.
Research in the tester#
The agent can research a strategy on its own. A typical order:
get_field_hints— learn the meaning of strategy settings and tester config fields, including theparameter_miningsyntax;get_settings_schema— which fields the strategy actually reads: mining an ineffective field gives identical rows.create_tester_settings_folder— create your own folder for the experiment;copy_tester_settings_to_folder— copy the needed settings to it. Then passfolderto all tester tools.draft_tester_settingsandsave_tester_settings— create new settings for the needed exchange, pair and timeframe. Variants of existing settings need not be saved:overridessets them at run time.save_tester_config— set the period, fees,parameter_miningand a newname_commentfor the experiment; enablereport.enable_json_report. To compare with a live bot, place the period start (StartDate) on a boundary of the strategy'stime_frameand not earlier than the bot's start: the strategy works from the first candle of its timeframe that opens at or afterStartDate, so a start in the middle of a 4h candle moves the first orders to the next candle.WarmupDays(default 30) only warms up indicators with history beforeStartDate: on these days the strategy does not trade or accumulate state, and the live bot's position and orders are not restored from history. If a pair has less data thanWarmupDays, trading starts later (a warning in the response).tester_download_data— download candles and wait for completion intester_status. The period can be set withstartandend, by default: the config's start with warmup .. now (no need to change the config).download.resultshows up to which day each pair actually has data.tester_run_single— check one combination;tester_wait(orwait_secondsat start) waits for the run and returns metrics, warnings and report paths.tester_run_batch— compare several variants and check them on several periods with one call. Ortester_run_mining— go through all combinations: results in<name_comment>/reports_history.csv(read_tester_file);queue=truequeues the mining after the current one.read_tester_report— analyze a run: thesummarysection for comparison, results by pair, months, trades. For a set of strategies —tester_portfolio_analysis: T/CT groups, correlation, worst days, each strategy's contribution to drawdown.tester_report_summaries,tester_run_stressandwalk_forwardin the config — compare the best variants and check their robustness.send_tester_report_to_telegram— send the final report to the user in Telegram if asked.
One strategy per pair#
On one account, one pair (basic.symbol) can have only one strategy, both in live trading and in the tester. An account can have any number of pairs (even 200), and strategies on them can be different or identical, but the symbol must be unique among the account's strategies. A strategy on an occupied pair is saved but does not start (the log shows DUBLICATE SUMBOL ON API); check list_strategies by account and pair before save_strategy, copy_strategy (copy to a different pair) and create_strategy_from_tester. Tester settings running in one run must also be on different pairs; to compare several settings on one pair, run each separately (tester_run_batch items or mining with single_mode).
Reinvestment and comparing variants#
Position size from basic.balance_percentage_long/_short is calculated from the current balance, so profit is reinvested and the annual PnL % is inflated. To compare variants and periods fairly, disable size growth in one of these ways:
basic.use_fix = trueandbasic.my_fix_balance = 50: each order is calculated from 50 units of the quote currency (usually USDT), regardless of the balance.basic.max_balance = 2000: while the balance is lower, the bot works with the real balance; at a balance of 2350 the size is calculated from 2000, above the threshold reinvestment stops.basic.lot_long/basic.lot_short: a constant order size that goes to the exchange.
Some strategies may change this base size by their own logic. The parameters can be set through the run's overrides (set) or mined in parameter_mining.
Save and run responses contain warnings: fields the settings do not read. check_tester_settings checks a whole folder this way.
Moving to trading and monitoring#
create_strategy_from_tester moves verified settings to the bot — the strategy is created paused, and play_bot starts it after checking. The agent evaluates a live bot like this: after the day closes and its candles can be downloaded, it runs the tester on the same settings and period (import_tester_settings copies the strategy to the tester folder) and gets full statistics — normally they match live trading. The actual result is the balance history get_balance_history (written with monitoring.enabled on).
The server instructions and tool descriptions explain the main rule of live trading to the agent: a position and orders must not be left without control. A paused strategy does not manage them, so switching off is only in the order pause → cancel orders → close the position → delete (delete_strategy with full=true does this itself).
Logs#
Each bot (strategy on a pair) has its own log: log_<date>_<Exchange> <account> <pair> <timeframe> <strategy> <name>.log — levels, signals, placed and cancelled orders, fills, position changes and strategy errors; it shows why the bot did or did not trade. Each account has log_<account>_<date>.log: balances and positions from the exchange, exchange API responses and errors, position limiter, close_by_margin. The general program log is log_<date>.log (get_log), tester logs are TESTER_*.log. The date format in the names varies, so files are found by strategy or account name: list_log_files with contains, then read_log_file.
Usage examples#
Below are requests to the agent and the tool calls it makes. Arguments are shown in JSON, as the MCP client sends them. The lut_now folder, settings names and dates are examples.
Check a set variant without test copies#
“What happens if I double the trend strategies, but no more than 10% per pair, and turn off shorts for C_MU? Check on two periods.”
tester_run_single {
"settings": ["*"], "folder": "lut_now", "wait_seconds": 240,
"overrides": [
{ "match": "T_*", "mul": { "basic.balance_percentage_long": 2, "basic.balance_percentage_short": 2 }, "cap_pct": 10 },
{ "match": "C_MU", "set": { "basic.use_short": false } }
],
"periods": [["2026-05-01", "2026-08-01"], ["2026-08-01", "2026-10-26"]]
}Settings files do not change. The response for each period has summary (PnL, drawdowns, Ulcer, profit factor, trades, months), report paths, applied (what was changed) and warnings. Instead of a mask you can select settings by tag: { "tag": "hedge", "mul": { ... } }.
Compare several variants with one call#
tester_run_batch {
"folder": "lut_now", "parallel": 2, "wait_seconds": 240,
"periods": [["2026-05-01", "2026-08-01"], ["2026-08-01", "2026-10-26"]],
"runs": [
{ "name": "base", "settings": ["*"] },
{ "name": "T x2", "settings": ["*"], "overrides": [{ "match": "T_*", "mul": { "basic.balance_percentage_long": 2 } }] },
{ "name": "without L_X", "settings": ["*"], "overrides": [{ "match": "L_X", "exclude": true }] },
{ "name": "long only", "settings": ["*"], "sides": "long" }
]
}Each variant goes on each period; the response is a table of results. Without wait_seconds the agent waits for the batch through tester_wait_batch.
Find a parameter that is robust across several periods#
“Find the depth for T_BTC, but not fitted to one period.”
get_settings_schema { "strategy": "zz" }—zz.depthtakes effect only withzz.type = ZZ2; mining a field the settings do not read gives identical rows.Mining on three periods (each is a separate full run through the queue):
tester_run_mining { "settings": ["T_BTC"], "folder": "lut_now", "config": { "name_comment": "MCP_depth", "parameter_mining": [{ "name": "settings[*].zz.depth", "start": 4, "end": 20, "step": 2 }], "...": "the rest as in get_tester_config" }, "periods": [["2026-02-01", "2026-05-01"], ["2026-05-01", "2026-08-01"], ["2026-08-01", "2026-10-26"]] }The response contains
report_foldersof each period andwarnings(non-existent and ineffective parameters).- Wait for completion in
tester_status, thentester_mining_robustness { "folders": [...], "base": { "settings[*].zz.depth": 12 } }— a ranking by the plateau of all periods, the place of each period's best point in the overall ranking, and the points that are no worse than the starting one on any period.
Evaluate the hedge from trend strategies in a portfolio#
“Do T strategies help CT strategies in a drawdown?”
- Run the set with
report.enable_json_report: true(thedailysection is on by default). tester_portfolio_analysis { "path": "<report_json_path>", "groups": { "T": "T_*", "CT": "C_*" } }— group correlation, the worst week, the T group's PnL on CT's worst days (offset_percent) andleave_one_out: how much the portfolio drawdown would grow without each strategy. This replaces a separate run without each strategy.- Find the size of T against the rest of the set — portfolio mining without
single_mode: the parametersettings[T_*].basic.balance_percentage_long, rows are compared by the portfolioMaxDrawdownPercentandUlcerIndex.
Check a settings folder#
check_tester_settings { "folder": "lut_now" } — settings with changed fields that have no effect (a section of another strategy, a field of another zz.type, a disabled use_*, basic.leverage in the tester). The same warnings come when saving settings.
Repeat a run with an edit and hand the variant to the user#
Each run saves run_snapshot_*.json with the exact settings and config. The agent reads it (read_tester_file), edits it and runs tester_run_snapshot with the changed snapshot — the file does not change. For the user to run the variant themselves, the agent saves it to runs through save_tester_file: in the web interface (Tester, “Results (files)” tab) the file has “Run” and “Edit” buttons.
Move settings to trading and run the bot#
“Start T_BTC on the demo account and keep an eye on it.”
list_accounts— find the account.create_strategy_from_tester { "name": "T_BTC", "folder": "lut_now", "account": "demo_bybit" }— the strategy is created paused; the agent checks it (get_strategy,warnings) and starts it withplay_bot.- Monitoring during the day:
list_bots,list_positions,list_orders; the strategy log —list_log_files { "contains": "T_BTC" }andread_log_file; errors —get_errors. - After the day closes:
import_tester_settings(the strategy fromget_strategyto the tester folder),tester_download_data, a tester run for the past period — full statistics that normally match live trading. The actual result isget_balance_history(withmonitoring.enabled). A discrepancy is a reason to examine the strategy log. - Adjustment: check the change in the tester, then
save_strategy— changes apply to the running bot immediately.
Switch a strategy off#
delete_strategy { "name": "T_BTC", "full": true } — pause, cancel orders, close the position, delete. If orders or the position were not removed, the strategy stays paused and is not deleted: the agent checks list_orders and list_positions and finishes by hand in the same order, without skipping the pause.
Send a report#
“Send the final report to Telegram” — send_tester_report_to_telegram { "path": "<report_path>", "caption": "best variant by drawdown" }. Only tester report files are sent, to the tester notification chat.
Examples of requests to the agent:
- “Find the zigzag length for BTCUSDT 1h on Bybit over the last three months, check the best point on two other periods and with a stress test.”
- “Sync the lut_now folder with mrs-bybit and compare the set with doubled T strategies and without them by drawdown and Ulcer.”
- “Which lut_now strategies add drawdown to the portfolio, and which reduce it?”
- “Move the best variant to the demo account, start it and compare live trading with the tester every day.”
Examples: what you can ask the agent
Talk to the agent in plain language: it picks the tools, calls them one after another and explains the result.
Research in the tester
"Tune MRS2 for BTC over the last year and stress-test the best variants"
Sets up parameter mining, runs it, looks for a plateau rather than a single peak, runs tester_run_stress and tells you what survived.
"Run e2e_zz for September and explain why the strategy lost money. Break down the trades: longs vs shorts, duration, MAE/MFE. Suggest one change and test it"
Takes the trades from read_tester_report and finds patterns on its own: for example, that shorts lose money or that trades close before the MFE peak. Then it changes a parameter, reruns the test and shows the numbers before and after.
"Find the best zigzag length by mining, then prove it is not overfitting: walk-forward and a stress test"
Mining finds the "perfect" variant, walk_forward checks it on a period the optimizer never saw, and tester_run_stress under worse execution. The best mined variant usually drops noticeably on new data, and the agent shows it.
"Tune zigzag for BTCUSDT 1h on Bybit over the last 3 months and give a final recommendation"
The whole cycle in one sentence: field hints, settings, data download, runs, reading the results and a conclusion.
"Test the strategy on the top 10 Bybit pairs and keep the pairs where it works consistently"
tester_exchange_symbols, settings for several pairs, the by_symbol section and monthly returns from the JSON report.
"Show how the result depends on fees and slippage"
Mining over TakerFee and SlippagePercent in the tester config. It shows clearly why a strategy with a great backtest loses money in live trading.
"Compare the last two runs: where is the new version better and where is it worse?"
Reads the JSON reports and breaks the difference down by pair, month and drawdown.
"Copy the strategy from BTC to SOL and backtest it over six months"
Copies the settings to another pair, downloads the history, runs the backtest and tells you whether it is worth moving to a live account.
"Sync the lut_now folder with mrs-bybit and compare the set with doubled T strategies and without them by drawdown and Ulcer"
copy_tester_settings_to_folder, then tester_run_batch with overrides — no test copies of the settings, all variants in one call.
"Which lut_now strategies add drawdown to the portfolio and which reduce it?"
tester_portfolio_analysis: group correlation, worst days and leave_one_out — portfolio drawdown without each strategy, with no extra runs.
"Tune the zigzag length, check the best point on two other periods and with a stress test"
Mining with periods, then tester_mining_robustness shows whether the point holds on every period or is fitted to one.
Running bot: reading and analysis
"Morning summary: balance, open positions, errors overnight"
Balances, positions, orders, balance history and log errors — one sentence instead of five tabs. In Claude Code you can schedule the summary with /loop.
"Why didn't the ETH bot open a trade last night?"
Checks the log and errors for the night, the bot's state and the strategy filters, and explains the reason.
"Look into the errors from the last 24 hours"
Uses get_errors and get_account_info to find the cause — for example, an expired key or no futures permission — and explains it in plain words.
"Check my strategies for risky settings"
Compares every strategy with the field hints and points out the risks.
"Send a chart and the position of every bot in drawdown to Telegram"
Finds those bots and sends their chart and position to Telegram.
Control: with confirmation
Before real actions the agent shows what it is about to do, and the client asks for confirmation for every destructive tool, unless permissions were granted in advance (see Access limits).
"Create a live strategy with the parameters you found, but paused"
After the research: create_strategy_from_tester moves the verified tester settings to a paused bot. You review the settings and start the bot yourself.
"Move the best variant to the demo account, start it and compare live trading with the tester every day"
After the day closes it runs the tester on the same settings over the same period and compares with the balance history; a mismatch is investigated in the strategy log.
"Switch off the T_BTC strategy"
delete_strategy with full=true: pause, cancel orders, close the position, delete — the position is never left unmanaged.
"Explain what block_adds does and turn it on wherever there is a trend filter"
Reads the field hints, finds the right strategies and edits them.
"Pause all altcoin bots and cancel their orders"
Pausing and cancelling orders — all by words.
"Cut all positions on the account by half and pause the bots"
reduce_positions and pause_all_bots.