Skip to content

io.github.gigshow/decker

by gigshow · remote · no sign-in to list tools · v1.10.0 · published by GitHub user gigshow

Deterministic market-state engine for trading agents — state, gate, coordinates, with receipts.

Changes · 4

14 tools: 4 change things and 10 only read.

Scanned Oct 21, 2026

3 checks matched something in the tool definitions. No finding is not a safety guarantee. How the checks work.

claude mcp add --transport http decker https://api.decker-ai.com/api/v1/mcp --header 'X-API-Key: <your-x-api-key>'

Findings

Matches of fixed checks, with the text they matched.

2 warn1 info

Tools

Open a tool for its reasons and full description. Descriptions are the publisher's own words, shown as they are.

14 tools

Changes things 4Claude Code: ask
  • decker.close_positionAxis③ (Order/Execution) — closes (or partially reduces) an existing position through DECKER'S OWN execution engine (see decker.place_order for what that means — same account-linkag…No findings

    Why it is in this group

    • The name "decker.close_position" says "close": a word for a change.
    Description, as the server wrote it
    Axis③ (Order/Execution) — closes (or partially reduces) an existing position through DECKER'S OWN execution engine (see decker.place_order for what that means — same account-linkage requirement applies here for real positions). Unlike place_order, there is no crypto-6 restriction — this reduces risk, not adds it, so any symbol you actually hold (including HL-synthetic/KRX paper positions) can be closed. Mode is NOT chosen by the caller — this looks up whatever position(s) actually exist for the symbol (real via live exchange query, virtual via the paper ledger) and closes whichever are open; if both a real and a virtual position exist for the same symbol, both are closed and the response reports execution_mode as 'mixed'. No open position for the symbol = a clean not-found response, not an error — safe to call speculatively.
  • decker.place_orderAxis③ (Order/Execution) — unlike every other tool here, this one moves money.2 findings

    Why it is in this group

    • Nothing in its name or description says what it does, so it is counted as a write.

    Findings

    • Info

      The description mentions "credentials".

      Matched text

      description: "...Decker executes using whatever exchange credentials this user has separately linked to thei..."

      What this check looks for
    • Warn

      The description contains "every other tool", wording about other tools or servers.

      Matched text

      description: "Axis③ (Order/Execution) — unlike every other tool here, this one moves money. It places a..."

      What this check looks for
    Description, as the server wrote it
    Axis③ (Order/Execution) — unlike every other tool here, this one moves money. It places a market order through DECKER'S OWN execution engine (same path as the decker-ai.com chat trading UI, source='mcp') — it does NOT hand off to your own broker connection or exchange account; Decker executes using whatever exchange credentials this user has separately linked to their Decker account on the website. execution_mode (virtual|real) is NOT chosen by the caller — it is resolved server-side from this user's account settings (user_settings.execution_mode) AND the platform's real-trading kill switch; a real-money order requires both an explicit user opt-in AND role/tier eligibility (PRO/ENTERPRISE or admin) AND passing the tier's hard notional/leverage/daily-count caps (checked here before dispatch — violation blocks the order, does not downgrade it to virtual). The response always states which mode actually executed — treat 'virtual' in the response as authoritative even if you expected real. Restricted to the crypto-6 universe (BTCUSDT/ETHUSDT/SOLUSDT/BNBUSDT/XRPUSDT/DOGEUSDT) for this MCP path — HL-synthetic and KRX symbols are read-only via other tools. Call decker.validate_intent first to read the engine's current stance; this tool does not check it for you. Positions are tracked as ONE net row per user+symbol+mode, not per order — if you already hold a position on this symbol, this order nets into it and the response's pre_existing_position field says so. A later close_position call closes the combined total, not just what this call added.
  • decker.set_skill_overlayChange active trading skill overlay for this user.No findings

    Why it is in this group

    • The name "decker.set_skill_overlay" says "set": a word for a change.
    Description, as the server wrote it
    Change active trading skill overlay for this user. Immediately affects all subsequent get_signals calls and downstream channels.
  • decker.update_protective_stopsAxis③ (Order/Execution) — modifies the stop-loss and/or take-profit on an EXISTING open position.1 finding

    Why it is in this group

    • The name "decker.update_protective_stops" says "update": a word for a change.

    Findings

    • Warn

      The description names a tool "cancel_order" that this server does not list.

      Matched text

      description: "...an EXISTING open position. There is no cancel_order tool because Decker only places market order..."

      What this check looks for
    Description, as the server wrote it
    Axis③ (Order/Execution) — modifies the stop-loss and/or take-profit on an EXISTING open position. There is no cancel_order tool because Decker only places market orders (there is no resting order to cancel) — the actual gap this fills is modifying protective stops on a position you already hold. real: cancels the old exchange stop/take-profit order(s) and places new ones at the given price(s) (new order placed first, old one canceled only after — no unprotected window). virtual: updates the paper position's stop_loss/take_profit columns directly (polled by the paper monitor). Provide at least one of sl_price/tp_price — the other side, if omitted, is left at its current value. If both a real and a virtual position are open for this symbol, pass mode explicitly or the call is rejected asking which one.
Only reads 10Claude Code: allow
  • decker.get_assemblyTHE answer for 'what is the situation and what do I do on this symbol now' — one verdict per symbol, built from the per-timeframe judgment state (CR1); no scores or weights.No findings

    Why it is in this group

    • The name "decker.get_assembly" says "get": a word for reading.
    Description, as the server wrote it
    THE answer for 'what is the situation and what do I do on this symbol now' — one verdict per symbol, built from the per-timeframe judgment state (CR1); no scores or weights. READ IN THIS ORDER: (1) verdict = state (direction · phase) + action: 진입 enter now (a new signal) | 유지 hold the existing stance, NOT a new entry | 청산 exit | 대기 wait; `reason` says why, `until` names the close that would change it. (2) summary_ko = ready-to-show Korean lines. (3) entry / stop / target / rr = the prices (entry.mode says whether it is a new entry or on hold — when the action is not 진입 it never says 'now'; target may be null with target.reason, e.g. no coordinate at least 2% from the entry price; rr mixes the entry timeframe's stop with the target timeframe's target). (4) as_of = the bar this answer is based on. Default = the answer only (about 3KB per symbol; summary_ko already narrates the next closes and the last signal). Pass detail=true for the structured detail: path (nearby prices and what a close there means), watch (upcoming bar closes in time order and the question each decides), story (this / last signal), ladders, matrix_summary (every timeframe's row incl. gate). Omit `symbol` for all 14 symbols. Roles: frame = highest confirmed timeframe (sets direction and target); entry = lowest aligned timeframe whose signal is alive; 1w supplies direction/target only, never an entry. grade: 정렬 aligned | 되돌림 pullback against the frame | 전환 시험 frame under test | 재장전 no confirmed signal. Caveats: 정렬 does not mean every timeframe's gate is GO (check matrix_summary[].gate); entry.mode '지금' does not mean a new event this bar. Narrate or filter the result — do not re-decide coordinates.
  • decker.get_episodesPrice-axis EPISODE history — answers 'where did I buy/sell last time, what was the target value and the event chain then, and where did price move WITHOUT a signal (and which targe…No findings

    Why it is in this group

    • The name "decker.get_episodes" says "get": a word for reading.
    Description, as the server wrote it
    Price-axis EPISODE history — answers 'where did I buy/sell last time, what was the target value and the event chain then, and where did price move WITHOUT a signal (and which target values it passed = missing points)'. Read-only from the persisted event ledger (no recompute). `episodes` (newest first) = one target selection until the next: target {price, from_price, reason}, chain (primary-unit judgment events), signals {ts, side, entry, targets, resolved{status, close, bar_low, bar_high}}, left (target_left: MISSING = a target value price passed through with no judgment; MOVED), missing, signal_gap (no signal in that episode), move {start_close, end_close, pct}. `signal_gaps` (ascending) = the interval between consecutive signals with its price move and the missing points inside (last one is open). Missing points carry `sign` and `position` (price below/above the target at the pass) — classify on the read side; do not re-decide coordinates. History starts at the first persisted event of this generation.
  • decker.get_market_statePER-TIMEFRAME judgment state of a symbol, structured (consumer contract CR1) — the evidence behind decker.get_assembly's single verdict.No findings

    Why it is in this group

    • The name "decker.get_market_state" says "get": a word for reading.
    Description, as the server wrote itContains invisible characters, shown as [U+…]
    PER-TIMEFRAME judgment state of a symbol, structured (consumer contract CR1) — the evidence behind decker.get_assembly's single verdict. For 'what is the situation and what do I do' call decker.get_assembly first; use this when you need one timeframe's exact state. Per timeframe (top→short): stage = target_selected (대상선정) | pending (판정보류: the close is still inside the signal bar) | confirmed (확인) | failed (실패) | none; side = buy/sell (a failed signal asserts nothing about the opposite side); signal_time; signal_bar {time, low, high} (its edges decide confirm/fail); entry (= close at the signal); stop; target (take-profit: opposite-side confirmed-signal edge at least 2% from entry, else null + target_reason); unit_target (the price this timeframe is judging now — NOT the take-profit); units (the targets judged together, max 6, primary first); reverse_pending (a reversal on hold: the first reversing key appeared, the next judgment bar has not closed beyond the target); standing (the last confirmed signal's entry/stop/target while a new target is being selected); prev_signal; turn (reverse|same|null); levels (nearby prices). state_text = ready-to-show Korean lines (🟢▲ buy confirmed · 🔴▼ sell confirmed · ⚪ pending · 🟡 target selected / reversal on hold · ✖[U+FE0F] failed). timeframe_summary lists timeframes by (stage, side) — a listing, not a verdict; no scores, weights or probabilities anywhere. events = recent target_selected / signal / signal_resolved / reverse_failed / reverse_tested / conn_arrival, newest first, always including each timeframe's own latest 2 (pass `timeframe` for one timeframe's full history). as_of = the latest closed bar among the returned timeframes (it can be earlier than get_assembly.as_of, which is the 30m bar). Read as persisted (no recompute). A state reading, NOT a trade instruction. Crypto and Hyperliquid synthetics only (KRX: decker.get_reading). Before placing any order, check the intent with decker.validate_intent.
  • decker.get_positionsAxis③ (Order/Execution) — this user's actual exposure (each open row carries vs_verdict: does the held side match the current symbol verdict): real open futures positions (executio…No findings

    Why it is in this group

    • The name "decker.get_positions" says "get": a word for reading.
    Description, as the server wrote it
    Axis③ (Order/Execution) — this user's actual exposure (each open row carries vs_verdict: does the held side match the current symbol verdict): real open futures positions (execution_mode=real, with live sl_price/tp_price), virtual (paper) open positions, and the last 10 closed round-trips per mode. This is what your money actually did, distinct from decker.get_signals (axis②, what the engine recommends) — use this before deciding whether to place another order (avoid duplicate/over-exposure) and to check current protective stop/target on a real position.
  • decker.get_readingHow ONE timeframe looks right now, in plain language: state (phase, this timeframe's key direction, posture GO/WATCH/HOLD — a stance, not an order), mtf.by_tf (the same for other t…No findings

    Why it is in this group

    • The name "decker.get_reading" says "get": a word for reading.
    Description, as the server wrote it
    How ONE timeframe looks right now, in plain language: state (phase, this timeframe's key direction, posture GO/WATCH/HOLD — a stance, not an order), mtf.by_tf (the same for other timeframes), narrative, plus `assembly` = the symbol's single verdict (the same one decker.get_assembly returns: direction, action 진입/유지/청산/대기, entry/stop/target). ⚠ `state.direction` is only this timeframe's direction and can differ from `assembly.direction` — for the decision use `assembly` (direction_basis says which is which). For the full detail call decker.get_assembly with detail=true; for the structured per-timeframe judgment use decker.get_market_state. Engine-native raw fields are not exposed here.
  • decker.get_signalsActive trading signals for the current user (with Skill Overlay applied), in customer-facing shape: coordinates (entry/target/stop), decision (ENTER/WAIT/SKIP — is_actual_trigger=t…No findings

    Why it is in this group

    • The name "decker.get_signals" says "get": a word for reading.
    Description, as the server wrote it
    Active trading signals for the current user (with Skill Overlay applied), in customer-facing shape: coordinates (entry/target/stop), decision (ENTER/WAIT/SKIP — is_actual_trigger=true only for ENTER; WAIT/SKIP are standing candidates, not executed triggers), action_gate posture (GO/WATCH/HOLD — a stance, not an order command), progress, MTF verdict, and a plain-language summary_ko line. risk_reward_ratio is computed on the DISPLAYED coordinates (after overlay). Signals are retained rather than cut when they age (turn-retention policy) — read freshness_state (open|aged) / age_bars / freshness_sec before treating an old PENDING row as current. Filtered by symbols / min_progress / action_gate — action_gate here filters the CURRENT-MOMENT representative state, it does not search history (almost always 0 rows unless a gate is GO right now); for past GO events with their entry/target/stop and realized performance use decker.get_trigger_history instead. Before placing any order through any execution tool, check the intent with decker.validate_intent.
  • decker.get_trigger_historyACTION axis — actual historical GO triggers (not standing WATCH/HOLD candidates) for a symbol, with entry/target/stop coordinates and realized performance (mfe_pct/mae_pct/exit_rea…No findings

    Why it is in this group

    • The name "decker.get_trigger_history" says "get": a word for reading.
    Description, as the server wrote it
    ACTION axis — actual historical GO triggers (not standing WATCH/HOLD candidates) for a symbol, with entry/target/stop coordinates and realized performance (mfe_pct/mae_pct/exit_reason/exit_price from trigger_performance, null = still open). Distinct from decker.get_signals (which reflects only the current-moment state, not a searchable history — its action_gate filter answers 'what does symbol×tf look like right now', not 'when did this last fire'). Use this to answer 'what did the engine actually trigger recently and at what price' — decker.get_signals/get_market_state cannot answer that. direction is judgment_signals-native vocabulary ("long"/"short"), distinct from the "+"/"-" convention used by other tools — read as-is, no translation.
  • decker.get_user_skillsTrading skill catalog + currently active overlay for this user.No findings

    Why it is in this group

    • The name "decker.get_user_skills" says "get": a word for reading.
    Description, as the server wrote it
    Trading skill catalog + currently active overlay for this user. Returns 8 published skills (conservative_v0/standard_v0/aggressive_v0/default_v0/scalp_v0/tight_v0/wide_v0/swing_v0) and the user's selected one. Also returns symbol_skills: the symbols where this user's paper account turns the symbol verdict's entry event into an order (read-only here; turn on/off via REST /auto-order-rules/symbol-skills).
  • decker.get_viewReady-to-show Korean status card for a symbol — the same card the daily briefing sends, built from the same consumer contract (CR1) as decker.get_market_state, so direction and pri…No findings

    Why it is in this group

    • The name "decker.get_view" says "get": a word for reading.
    Description, as the server wrote it
    Ready-to-show Korean status card for a symbol — the same card the daily briefing sends, built from the same consumer contract (CR1) as decker.get_market_state, so direction and prices always agree with it. Shows the timeframes grouped 상위/중간/단기 with one line each (direction + stage + the price that decided it), the nearby prices to watch, and a short explanation of the chosen timeframe (tf, default 4h): what closed beyond what, whether the signal flips the previous one, entry/target/stop. Also returns direction (+/- only while that timeframe's signal is pending or confirmed; a failed or absent signal gives no direction — failure does not assert the opposite side), wait_target, invalidation, ref_price and recent self-scoring verdicts. Use this when you want text to show as-is; use decker.get_market_state when you want structured values to reason over. layer=STATE_VIEW: a market-state reading, NOT a trade instruction. Before placing any order through any execution tool, check the intent with decker.validate_intent.
  • decker.validate_intentPre-trade gate check for a proposed order intent.No findings

    Why it is in this group

    • The name "decker.validate_intent" says "validate": a word for reading.
    Description, as the server wrote it
    Pre-trade gate check for a proposed order intent. Call this BEFORE placing any order through any execution tool (e.g. a broker MCP's review→place flow). Checks the intent (symbol + side) against Decker's deterministic market state: engine action_gate (GO/WATCH/HOLD — a transition posture, not an order command), current structural state, and the active signal's direction / invalidation (stop) coordinates. Returns a stance reading, NOT an approval or rejection: the vocabulary is the engine gate as-is plus a mechanical tf_signal_alignment (aligned/opposed vs the active signal's direction). covered=false means the engine does not emit state for this symbol — treat as unknown, not as HOLD. top-level action_gate can be null even when covered=true — this is not a missing field, it means the current bar has no fresh trigger reading; check gate_null_reason ('no_gate_available' = neither the current bar nor the carried-forward signal had a gate at all, vs 'signal_stale' = a value existed but the underlying signal exceeded the staleness threshold and was deliberately suppressed rather than served as a confident-but-old answer). The order decision and responsibility remain with the calling agent/user. Every check is persisted to an auditable decision ledger (check_id). READ verdict_check FIRST: it compares the intent with the symbol's single verdict (the same one decker.get_assembly returns — direction, action 진입/유지/청산/대기, entry/stop/target, what would change it) and says in summary_ko whether a NEW entry exists now (entry_now) or the stance is only being held. The timeframe-level gate/signal fields below describe one timeframe (default: your open position's) and can be stale.

This is not a safety rating, and no finding is not a safety guarantee. The groups and findings come from fixed checks of the tool definitions the server returned on the date shown, not from its code or what it does when called. How the checks work.

Install

Pinned to version 1.10.0. Values in angle brackets are yours to fill in.

claude mcp add --transport http decker https://api.decker-ai.com/api/v1/mcp --header 'X-API-Key: <your-x-api-key>'

Run in a terminal.

Claude Code permissions

Allow the reads, ask before a change, deny the deletes. Paste into .claude/settings.json.

.claude/settings.json
{
  "permissions": {
    "allow": [
      "mcp__decker__decker_get_assembly",
      "mcp__decker__decker_get_market_state",
      "mcp__decker__decker_get_view",
      "mcp__decker__decker_get_reading",
      "mcp__decker__decker_get_signals",
      "mcp__decker__decker_get_episodes",
      "mcp__decker__decker_get_trigger_history",
      "mcp__decker__decker_get_positions",
      "mcp__decker__decker_validate_intent",
      "mcp__decker__decker_get_user_skills"
    ],
    "ask": [
      "mcp__decker__decker_set_skill_overlay",
      "mcp__decker__decker_place_order",
      "mcp__decker__decker_close_position",
      "mcp__decker__decker_update_protective_stops"
    ],
    "deny": []
  }
}

Tools that only read are allowed, tools that change things ask first, tools that delete or cancel are denied. It assumes the server is installed as decker. Review it before you use it.