Skip to main content
Glama
roman-zaglauer

OctoBot MCP Server

close_position

Closes an open trading position by symbol and side, returning confirmation when the position is closed.

Instructions

Close one open position, identified by symbol and side.

Maps to POST /api/positions?action=close_position -- action is a query parameter, not a JSON body field (same pattern as cancel_order above). A genuine spec correction: the spec names this tool's parameter position_id, but OctoBot positions have no id concept at all -- confirmed against source (Services/Interfaces/web_interface/ models/trading.py::_dump_position, the exact function behind get_positions()'s response, builds each position dict with symbol/side/contract/... keys but no id key, unlike _dump_order's sibling function which does include "id": order.order_id). The real route calls interfaces_util.close_positions( [{"symbol": ..., "side": ...}]) -- packages/services/ octobot_services/interfaces/util/position.py -- which reads exactly positions_desc["symbol"]/positions_desc["side"]. side is submitted as OctoBot's own PositionSide enum's literal value ("long"/ "short"/"both"/"unknown", confirmed against octobot_trading.enums.PositionSide) -- the exact same string get_positions()'s own side field already uses, so a value read from that response can be passed straight through as both symbol and side here.

Success: OctoBot returns HTTP 200 with the literal JSON string "Position closed", returned unchanged (NFR-8). Failure -- no matching open position on any connected exchange -- raises PositionCloseRejectedError with OctoBot's own extracted error text (always, in practice, the literal "Impossible to close position: position already closed.").

Not confirm-gated: the user was explicitly asked about the spec's own footnote flagging this tool as "revisitable" given its irreversible effect, and chose to keep it ungated (milestone 13.6), per ADR-0003's original reasoning that this is routine, expected trading-bot activity. No confirm parameter exists on this tool at all.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
sideYes
symbolYes

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 fully carries behavioral disclosure. It details the exact HTTP route, the fact that action is a query parameter, the success response literal, the failure exception type and message, the absence of a confirm parameter, and the irreversible nature of the operation. This is far beyond the minimum.

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 front-loaded with a crisp purpose statement, followed by detailed sections. While the spec-correction and source-code references add length, they are informative and serve to prevent misuse. There is some redundancy in the repeated 'confirmed against' phrasing, so it is not perfectly concise, but every paragraph earns its place.

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 lack of annotations, output schema, and schema-level parameter descriptions, this description is unusually complete. It covers the endpoint, parameter semantics, success behavior, failure behavior, and confirm-gating decision. An agent has everything needed to invoke the tool correctly and interpret the 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?

Schema description coverage is 0%, so the description must compensate, and it does thoroughly. It explains that symbol and side are the actual keys used by OctoBot, corrects the spec's position_id misconception, and lists the valid side enum values ('long'/'short'/'both'/'unknown'). It also tells the agent that values from get_positions() can be fed directly into this tool.

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 concrete action and resource: 'Close one open position, identified by symbol and side.' It clearly names the tool's function and distinguishes it from sibling tools like get_positions (which reads) and cancel_order (which cancels orders). The resource and identifier mechanism are unmistakable.

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 provides clear context for when to use the tool: to close a position, with symbol and side as input. It even instructs that values can be passed straight through from get_positions() output. It does not explicitly name alternative tools or exclusions, but given the tool name and the absence of a sibling close-position operation, usage context is strong.

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