protogrid

Search / io.github.gigshow/decker

decker

R1· needs a key

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

v1.10.0 · active · repository · website · descriptor JSON · versions

An agent can connect on its own if it already holds X_API_KEY, X_API_KEY.Remote endpoint behind a static API key or header. The registry never sees the value; the agent fills the placeholder.
Quality60needs work
Trust90of 100
Uptime, 30 days99%
Latency p50495 ms

Connect

8 clients · secrets stay placeholders
{
  "mcpServers": {
    "decker": {
      "type": "http",
      "url": "https://api.decker-ai.com/api/v1/mcp",
      "headers": {
        "X-API-Key": "${X_API_KEY}",
        "Authorization": "${X_API_KEY}"
      }
    }
  }
}
claude mcp add --transport http decker https://api.decker-ai.com/api/v1/mcp --header "X-API-Key: ${X_API_KEY}" --header "Authorization: ${X_API_KEY}"
[mcp_servers.decker]
url = "https://api.decker-ai.com/api/v1/mcp"
env_http_headers = { "X-API-Key" = "X_API_KEY", "Authorization" = "X_API_KEY" }
{
  "$schema": "https://opencode.ai/config.json",
  "mcp": {
    "decker": {
      "type": "remote",
      "url": "https://api.decker-ai.com/api/v1/mcp",
      "enabled": true,
      "headers": {
        "X-API-Key": "{env:X_API_KEY}",
        "Authorization": "{env:X_API_KEY}"
      }
    }
  }
}
{
  "mcpServers": {
    "decker": {
      "type": "http",
      "url": "https://api.decker-ai.com/api/v1/mcp",
      "headers": {
        "X-API-Key": "${X_API_KEY}",
        "Authorization": "${X_API_KEY}"
      }
    }
  },
  "deeplink": "cursor://anysphere.cursor-deeplink/mcp/install?name=decker&config=eyJ0eXBlIjoiaHR0cCIsInVybCI6Imh0dHBzOi8vYXBpLmRlY2tlci1haS5jb20vYXBpL3YxL21jcCIsImhlYWRlcnMiOnsiWC1BUEktS2V5IjoiJHtYX0FQSV9LRVl9IiwiQXV0aG9yaXphdGlvbiI6IiR7WF9BUElfS0VZfSJ9fQ%3D%3D"
}
{
  "servers": {
    "decker": {
      "type": "http",
      "url": "https://api.decker-ai.com/api/v1/mcp",
      "headers": {
        "X-API-Key": "${X_API_KEY}",
        "Authorization": "${X_API_KEY}"
      }
    }
  }
}
{
  "mcpServers": {
    "decker": {
      "httpUrl": "https://api.decker-ai.com/api/v1/mcp",
      "headers": {
        "X-API-Key": "${X_API_KEY}",
        "Authorization": "${X_API_KEY}"
      }
    }
  }
}
extensions:
  "decker":
    enabled: true
    name: "decker"
    type: streamable_http
    uri: "https://api.decker-ai.com/api/v1/mcp"
    headers:
      "X-API-Key": "${X_API_KEY}"
      "Authorization": "${X_API_KEY}"
    timeout: 300

Placeholders to fill from your own secret store: ${X_API_KEY}, ${X_API_KEY}. The registry never accepts secret values.

Quality 60 / 100needs work

protocol75 · weight 25
  • warn
    protocol.modernnewest supported version is 2024-11-05; 2026-07-28 not supported, older versions are deprecated until 2027-07-28
  • n/a
    protocol.statelessonly applies to 2026-07-28 servers
  • pass
    protocol.transportstreamable HTTP
  • n/a
    protocol.list_ttlonly applies to 2026-07-28 servers
authorizationn/a · weight 15
  • n/a
    auth.prm, auth.as_metadata, auth.cimdno remote uses OAuth
  • n/a
    auth.secret_in_urlno templated URL
tool hygiene64 · weight 30
  • pass
    tools.descriptionsevery tool has a description
  • warn
    tools.description_length6 tools have descriptions over 1,024 characters, which crowds the context
  • pass
    tools.schemasevery tool has an object input schema
  • fail
    tools.annotationsno tool declares readOnlyHint or destructiveHint, so clients cannot tell safe calls from risky ones
  • fail
    tools.directory_hintsno tool declares all four of readOnlyHint, destructiveHint, idempotentHint and openWorldHint; missing: decker.get_view (readOnlyHint, destructiveHint, idempotentHint, openWorldHint); decker.get_user_skills (readOnlyHint, destructiveHint, idempotentHint, openWorldHint); decker.validate_intent (readOnlyHint, destructiveHint, idempotentHint, openWorldHint); …
  • pass
    tools.token_costabout 6,097 tokens to load every tool
  • pass
    tools.api_dumptools are not a one-to-one API dump
stability25 · weight 15
  • warn
    stability.changes32 tool changes in 30 days
  • fail
    stability.rug_pull5 tools kept their name but changed most of their description in 30 days; review before trusting them
dependenciesn/a · weight 15
  • n/a
    deps.known_vulns, deps.mcp_sdk_version, deps.resolvableno npm or PyPI package

17 tools, about 6,097 tokens to load them all · tool set cc4ad2f2943d · tools last changed 2026-10-19 · checked 2026-10-19 10:20 UTC

Tool changes

  • decker.get_episodesadded

    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_statechangedoutput schema
  • decker.get_assemblychangeddescription
    before

    Multi-timeframe path per symbol (STRATEGY_LAYER §8.4), built from the same per-timeframe judgment state as decker.get_market_state (CR1) — no weights, scores or thresholds. frame = the highest timeframe with a confirmed signal (its side is the path direction; upper TF supplies direction and target, lower TF supplies the entry). Each timeframe row is classified frame | aligned | counter (confirmed, opposite side = a pullback in progress) | hint. grade = phase in plain words: 정렬 (no counter row) | 되돌림 (counter row exists, frame signal still alive) | 전환 시험 (frame signal is against / reversal pending) | 재장전 (no confirmed signal). entry = the lowest-timeframe aligned row whose signal is still alive (for/inside the signal bar), GO first; mode 지금 only when that signal's close is on its favorable side, otherwise 대기. stop/target/RR come from those rows' own coordinates. cond = the frame signal's fail edge (a close beyond it starts a reversal test). path = nearby price coordinates with what a close there means for the frame / entry piece / counter rows; onward = next targets in the path direction. watch = THE watch list, in time order: each upcoming bar close (timeframes closing at the same instant are one overlapping group) with every timeframe's state and the question that close decides — which side of which judged price (target, signal-bar edge, reversal-hold price) the close lands; a price also judged by a higher timeframe is flagged (this close is a hint for that one). summary_ko = ready-to-show Korean lines; ladder_upper / ladder_near = nearest coordinates (4h+ only / all timeframes) with `reads` and that timeframe's next close (KST); markers = which ladder point entry/stop/target sits on. Omit symbol for all 14 universe symbols. Narrate or filter the result — do not re-decide coordinates. ⚠ 정렬 does not mean every timeframe's gate is GO: check matrix_summary[].gate and .position. ⚠ entry.mode='지금' means the entry row's signal is on its favorable side now; it does NOT mean the engine confirmed a new event on this bar — check the entry row's gate.

    after · 90% of words in common

    Multi-timeframe path per symbol (STRATEGY_LAYER §8.4), built from the same per-timeframe judgment state as decker.get_market_state (CR1) — no weights, scores or thresholds. READ `verdict` FIRST: the one state + one action for the symbol right now (state = direction · phase; action = 진입 enter | 유지 hold | 청산 exit | 대기 wait, the engine's own action words; `reason` says why, `until` names the close that would change it). Everything below is supporting detail. frame = the highest timeframe with a confirmed signal (its side is the path direction; upper TF supplies direction and target, lower TF supplies the entry). Each timeframe row is classified frame | aligned | counter (confirmed, opposite side = a pullback in progress) | hint. grade = phase in plain words: 정렬 (no counter row) | 되돌림 (counter row exists, frame signal still alive) | 전환 시험 (frame signal is against / reversal pending) | 재장전 (no confirmed signal). entry = the lowest-timeframe aligned row whose signal is still alive (for/inside the signal bar), GO first; mode 지금 only when that signal's close is on its favorable side, otherwise 대기. stop/target/RR come from those rows' own coordinates. cond = the frame signal's fail edge (a close beyond it starts a reversal test). path = nearby price coordinates with what a close there means for the frame / entry piece / counter rows; onward = next targets in the path direction. watch = THE watch list, in time order: each upcoming bar close (timeframes closing at the same instant are one overlapping group) with every timeframe's state and the question that close decides — which side of which judged price (target, signal-bar edge, reversal-hold price) the close lands; a price also judged by a higher timeframe is flagged (this close is a hint for that one). summary_ko = ready-to-show Korean lines; ladder_upper / ladder_near = nearest coordinates (4h+ only / all timeframes) with `reads` and that timeframe's next close (KST); markers = which ladder point entry/stop/target sits on. Omit symbol for all 14 universe symbols. Narrate or filter the result — do not re-decide coordinates. ⚠ 정렬 does not mean every timeframe's gate is GO: check matrix_summary[].gate and .position. ⚠ entry.mode='지금' means the entry row's signal is on its favorable side now; it does NOT mean the engine confirmed a new event on this bar — check the entry row's gate.

  • decker.get_market_statechangedoutput schema
  • decker.get_assemblychangeddescriptionmeaning changed
    before

    Multi-timeframe optimal-path assembly per symbol (STRATEGY_LAYER §8): one deterministic machine verdict combining all live timeframes — direction, grade (aligned | structure+pullback | exhaustion-reversal), entry (now vs wait, with source TF), stop (risk stop), target (upper-TF target), RR, and a conditional switch coordinate on mixed structure. Upper TF supplies the target (slower = higher success), lower TF supplies the entry. This is the single judgment authority — narrate or filter it, do not re-decide coordinates. Omit symbol for all 14 universe symbols. ⚠ grade='aligned' means no OPPOSING-direction row exists among the active timeframes — it does NOT mean every timeframe's gate is GO/actionable right now. Check matrix_summary[].gate per timeframe before treating 'aligned' as 'all timeframes tradeable now'. ⚠ entry.mode='지금'(now) is a pure price-geometry verdict (STRATEGY_LAYER §8 R3 — is current price within the exhaustion-reversal zone or the ±0.3% entry band), independent of any timeframe's trigger/gate state — it does NOT mean the engine has confirmed a break event on this bar. Check the entry TF's row in matrix_summary[].gate before treating entry.mode='지금' as 'a trigger just fired, act now'.

    after · 34% of words in common

    Multi-timeframe path per symbol (STRATEGY_LAYER §8.4), built from the same per-timeframe judgment state as decker.get_market_state (CR1) — no weights, scores or thresholds. frame = the highest timeframe with a confirmed signal (its side is the path direction; upper TF supplies direction and target, lower TF supplies the entry). Each timeframe row is classified frame | aligned | counter (confirmed, opposite side = a pullback in progress) | hint. grade = phase in plain words: 정렬 (no counter row) | 되돌림 (counter row exists, frame signal still alive) | 전환 시험 (frame signal is against / reversal pending) | 재장전 (no confirmed signal). entry = the lowest-timeframe aligned row whose signal is still alive (for/inside the signal bar), GO first; mode 지금 only when that signal's close is on its favorable side, otherwise 대기. stop/target/RR come from those rows' own coordinates. cond = the frame signal's fail edge (a close beyond it starts a reversal test). path = nearby price coordinates with what a close there means for the frame / entry piece / counter rows; onward = next targets in the path direction. watch = THE watch list, in time order: each upcoming bar close (timeframes closing at the same instant are one overlapping group) with every timeframe's state and the question that close decides — which side of which judged price (target, signal-bar edge, reversal-hold price) the close lands; a price also judged by a higher timeframe is flagged (this close is a hint for that one). summary_ko = ready-to-show Korean lines; ladder_upper / ladder_near = nearest coordinates (4h+ only / all timeframes) with `reads` and that timeframe's next close (KST); markers = which ladder point entry/stop/target sits on. Omit symbol for all 14 universe symbols. Narrate or filter the result — do not re-decide coordinates. ⚠ 정렬 does not mean every timeframe's gate is GO: check matrix_summary[].gate and .position. ⚠ entry.mode='지금' means the entry row's signal is on its favorable side now; it does NOT mean the engine confirmed a new event on this bar — check the entry row's gate.

  • decker.get_market_statechangedoutput schema
  • decker.get_price_axis_statechangeddescriptionmeaning changed
    before

    [DEPRECATED — use decker.get_market_state (CR1); this raw price-axis dump is superseded and will be removed after usage telemetry shows zero calls.] Price-axis (close-based target selection) state, read from engine_bar_state as persisted (Store-Output-Read, no recomputation). One voice: `signal` is the current state — side (+ buy / - sell), the signal bar (judgment bar '2' sealed by S) with its low/high, entry candidates (target, close two bars before the signal, bar-2 open, bar-2 close), and the outcome stated as WHAT crossed WHAT: status 'confirmed' = a close beyond the signal-bar edge in the signal's direction (resolved_ts, resolved_close), 'failed' = beyond the opposite edge, 'inside' = 판정보류 (close still inside the signal bar). `prev`/`history` = earlier signals with the same fields. active_target = the target this unit is labeling from (price, touch_kind, touched_ts); label = this bar's labeler output (t1/t2/1/2/+S/-S); pending_targets/rolling_target/conn_stems = coordinates. goal = exit target measured from the entry (signal bar-2 open): nearest opposite confirmed-signal edge at least 2% away, plus `ladder` = nearest such level at >=2% / >=4% / >=8% from entry (empty tier = no structure there, never filled with a percentage); goal.price null + reason = no level >=2% from entry. event_flow = the persisted event history (oldest→newest, last 20): target_selected / signal / signal_resolved (signal bar confirmed/failed with the close that decided it) / reverse_failed (the primary target's reversal attempt failed = trend unchanged, not a signal) / reverse_tested (first reversing key on the primary target, status beyond|short, not a signal) / conn_arrival — compare the current state against how the events flowed. Omit timeframe for the multi-timeframe view: one row per TF {readable, target, signal, close} — side by side, no cross-TF verdict (cross_tf_verdict stays null). IMPORTANT — action_gate is always null BY DESIGN: this axis is diagnostic-only and not wired to any gate or order path. For GO/WATCH/HOLD use decker.get_market_state (MAIN axis). null when the engine has not evaluated the symbol/TF.

    after · 9% of words in common

    [DEPRECATED — use decker.get_market_state (CR1). Raw price-axis state dump; superseded and will be removed.]

  • decker.get_engine_state_rawchangeddescriptionmeaning changed
    before

    [DEPRECATED — use decker.get_market_state (consumer contract CR1). Kept only for KRX symbols and until usage telemetry shows zero calls; will be removed.] Market State v0 — current engine structural state for a symbol/timeframe (latest evaluated bar, persisted engine emit read as-is, zero recompute). DOMAIN FRAME (why this engine exists): the market is read as a TARGET GAME — every coordinate comes from a *verified anchor* (a past level where a triggered move actually succeeded). The `game` block tells you the context that matters: game.status = forming_target (new anchor set, awaiting test) | testing_target (price is testing whether the declared target holds) | direction_resolved (game decided, price traveling); game.target = WHO is being judged (anchor id/phase/band); game.progress_dest = where price goes if the move proceeds (the opposing verified anchor to conquer); game.reverse_dest = where it goes if the move fails (the opposite house — also the stop logic's home); game.why_gate = full gate derivation chain; game.zt_regime = output canonicality (restored = deterministic delta lineage). action_gate alone (GO/WATCH/HOLD) is only a posture — the game context is the information. RAW CONTRACT: fields are engine-native vocabulary (c_state, hold_reason, R_* risk enums …), NOT customer-facing prose — for a human-language view use decker.get_view (with tf) or decker.get_reading. layer=STATE: this is a market-state reading, NOT a trade instruction. Absent fields are null (engine did not emit that axis — no filling). IMPORTANT: top-level state.c_state/action_gate/trigger_kind reflect the TRIGGER SNAPSHOT (only populated on a bar that actually had a trigger event) — null on most bars is normal, not a data gap. For the always-present, every-bar-populated view of the same axes use game.phase.c_state / game.phase.action_gate instead (different freshness, same underlying engine state machine). Don't read a null top-level field as 'engine has no state' — check game.phase first. current_price (top-level, 2026-09-03): {price, bar_ts} — the single latest completed-bar close for this symbol ACROSS ALL timeframes (not just the requested tf), useful when comparing multiple timeframes' target bands against one 'now' price. null for KRX individual-stock symbols. Before placing any order through any execution tool, check the intent with decker.validate_intent.

    after · 10% of words in common

    [DEPRECATED — use decker.get_market_state (consumer contract CR1). Raw per-bar engine state dump (Market State v0); kept only for KRX symbols and will be removed.]

  • decker.get_market_statechangeddescription, output schema
    before

    Current swing-judgment state of a symbol across timeframes, as structured data (consumer contract CR1). Per timeframe (top→short): stage = target_selected (대상선정) | pending (판정보류: the close is still inside the signal bar) | confirmed (확인) | failed (실패) | none; side = buy/sell; signal_time; signal_bar {time, low, high} (the bar whose edges decide confirm/fail); confirmed_at / resolved_close; entry (= close at the signal, the fill basis); stop; target (the take-profit 목표가: opposite-side confirmed-signal edge at least 2% from entry, else null + target_reason; levels[].kind uses unit_target for the judged price, never `target`); unit_target (the price this timeframe is judging now = the 대상/anchor; NOT the take-profit — that is `target`); units = the targets this timeframe is watching together (max 6, primary first; secondary units judge concurrently when another earlier target is touched while the primary is judging): [{unit_target, zone buy|sell (buy = bought-from-below place, sell = sold-from-above place), stage target_selected|reverse_pending|confirmed|reverse_failed (추세 변경 안 됨), primary, touch_kind, touched_at, holds, reverse_side}] — not signals; reverse_pending = null, or {side, unit_target, holds, confirm, fail_side} when the reversal of that target is on hold (반전 보류: the first reversing key appeared but the next judgment bar has not yet closed beyond the target — side = the reversing side, independent of stage: a confirmed sell signal can coexist with a buy reversal on hold; fail_side = the key that would mean the target held and the move continues); prev_signal; turn = reverse (the signal flips the previous signal's direction = it changes the standing action) | same (continues it) | null; levels = nearby prices above/below the close. state_text = ready-to-show Korean status (title with price, then two compact lines: 상위·중간 / 단기, timeframes without a signal omitted, a failed row carries the price that decided it, plus nearby prices; no interpretation). Marks in state_text: color = state, shape = direction — 🟢▲ buy confirmed · 🔴▼ sell confirmed (action-worthy) · ⚪▲/⚪▼ pending (signal exists, unconfirmed) · 🟡 target selected / reversal on hold (반전 보류) · ✖️ failed (void signal, NOT the opposite side). timeframe_summary = the same rows merely listed by (stage, side), e.g. confirmed.buy = ['1d','4h'] (plus reverse_pending.buy/sell) — a listing, not a verdict: no weights, scores or votes, and failed is NOT counted as the opposite side. events = recent target_selected / signal / signal_resolved / reverse_failed (추세 변경 안 됨: the primary target's reversal attempt failed, side = the trend that holds, not a signal) / reverse_tested (반전 테스트: the first reversing key on the primary target; side = reversing side, status beyond = that key's close is past the target = minimum condition met, short = not; not a signal) / conn_arrival, newest first, always including each timeframe's own latest 2 events (so slow timeframes such as 1w/1d are not pushed out by 30m/1h activity; pass `timeframe` for one timeframe's full history). Each timeframe reports its own state side by side — there is NO cross-timeframe verdict, no probability/confidence/bias fields; combining timeframes into a view is the caller's job. HOW TO ANSWER: this tool is the source of truth for direction. Show state_text, then explain in your own words using only these values (what each timeframe confirmed/failed/is waiting on, and which prices to watch); do not invent probabilities or targets. decker.get_view shows the same values as ready-made text. Read as persisted (no recompute). layer=STATE: a market-state reading, NOT a trade instruction. Crypto and Hyperliquid synthetics only (KRX: use decker.get_reading). Before placing any order through any execution tool, check the intent with decker.validate_intent.

    after · 96% of words in common

    Current swing-judgment state of a symbol across timeframes, as structured data (consumer contract CR1). Per timeframe (top→short): stage = target_selected (대상선정) | pending (판정보류: the close is still inside the signal bar) | confirmed (확인) | failed (실패) | none; side = buy/sell; signal_time; signal_bar {time, low, high} (the bar whose edges decide confirm/fail); confirmed_at / resolved_close; entry (= close at the signal, the fill basis); stop; target (the take-profit 목표가: opposite-side confirmed-signal edge at least 2% from entry, else null + target_reason; levels[].kind uses unit_target for the judged price, never `target`); unit_target (the price this timeframe is judging now = the 대상/anchor; NOT the take-profit — that is `target`); units = the targets this timeframe is watching together (max 6, primary first; secondary units judge concurrently when another earlier target is touched while the primary is judging): [{unit_target, zone buy|sell (buy = bought-from-below place, sell = sold-from-above place), stage target_selected|reverse_pending|confirmed|reverse_failed (추세 변경 안 됨), primary, touch_kind, touched_at, holds, reverse_side}] — not signals; reverse_pending = null, or {side, unit_target, holds, confirm, fail_side} when the reversal of that target is on hold (반전 보류: the first reversing key appeared but the next judgment bar has not yet closed beyond the target — side = the reversing side, independent of stage: a confirmed sell signal can coexist with a buy reversal on hold; fail_side = the key that would mean the target held and the move continues); prev_signal; standing = null, or {side, signal_time, entry, stop, target, target_rr}: the standing stance's reference signal while a new target is being selected (stage=target_selected after a confirmed signal) — the entry/stop/target of that confirmed signal, kept apart from the stage-bound entry/stop/target above (those stay null until a signal is current); turn = reverse (the signal flips the previous signal's direction = it changes the standing action) | same (continues it) | null; levels = nearby prices above/below the close. state_text = ready-to-show Korean status (title with price, then two compact lines: 상위·중간 / 단기, timeframes without a signal omitted, a failed row carries the price that decided it, plus nearby prices; no interpretation). Marks in state_text: color = state, shape = direction — 🟢▲ buy confirmed · 🔴▼ sell confirmed (action-worthy) · ⚪▲/⚪▼ pending (signal exists, unconfirmed) · 🟡 target selected / reversal on hold (반전 보류) · ✖️ failed (void signal, NOT the opposite side). timeframe_summary = the same rows merely listed by (stage, side), e.g. confirmed.buy = ['1d','4h'] (plus reverse_pending.buy/sell) — a listing, not a verdict: no weights, scores or votes, and failed is NOT counted as the opposite side. events = recent target_selected / signal / signal_resolved / reverse_failed (추세 변경 안 됨: the primary target's reversal attempt failed, side = the trend that holds, not a signal) / reverse_tested (반전 테스트: the first reversing key on the primary target; side = reversing side, status beyond = that key's close is past the target = minimum condition met, short = not; not a signal) / conn_arrival, newest first, always including each timeframe's own latest 2 events (so slow timeframes such as 1w/1d are not pushed out by 30m/1h activity; pass `timeframe` for one timeframe's full history). Each timeframe reports its own state side by side — there is NO cross-timeframe verdict, no probability/confidence/bias fields; combining timeframes into a view is the caller's job. HOW TO ANSWER: this tool is the source of truth for direction. Show state_text, then explain in your own words using only these values (what each timeframe confirmed/failed/is waiting on, and which prices to watch); do not invent probabilities or targets. decker.get_view shows the same values as ready-made text. Read as persisted (no recompute). layer=STATE: a market-state reading, NOT a trade instruc

  • decker.get_market_statechangeddescription, output schema
    before

    Current swing-judgment state of a symbol across timeframes, as structured data (consumer contract CR1). Per timeframe (top→short): stage = target_selected (대상선정) | pending (판정보류: the close is still inside the signal bar) | confirmed (확인) | failed (실패) | none; side = buy/sell; signal_time; signal_bar {time, low, high} (the bar whose edges decide confirm/fail); confirmed_at / resolved_close; entry (= close at the signal, the fill basis); stop; target (the take-profit 목표가: opposite-side confirmed-signal edge at least 2% from entry, else null + target_reason; levels[].kind uses unit_target for the judged price, never `target`); unit_target (the price this timeframe is judging now = the 대상/anchor; NOT the take-profit — that is `target`); reverse_pending = null, or {side, unit_target, holds, confirm, fail_side} when the reversal of that target is on hold (반전 보류: the first reversing key appeared but the next judgment bar has not yet closed beyond the target — side = the reversing side, independent of stage: a confirmed sell signal can coexist with a buy reversal on hold; fail_side = the key that would mean the target held and the move continues); prev_signal; turn = reverse (the signal flips the previous signal's direction = it changes the standing action) | same (continues it) | null; levels = nearby prices above/below the close. state_text = ready-to-show Korean status (title with price, then two compact lines: 상위·중간 / 단기, timeframes without a signal omitted, a failed row carries the price that decided it, plus nearby prices; no interpretation). Marks in state_text: color = state, shape = direction — 🟢▲ buy confirmed · 🔴▼ sell confirmed (action-worthy) · ⚪▲/⚪▼ pending (signal exists, unconfirmed) · 🟡 target selected / reversal on hold (반전 보류) · ✖️ failed (void signal, NOT the opposite side). timeframe_summary = the same rows merely listed by (stage, side), e.g. confirmed.buy = ['1d','4h'] (plus reverse_pending.buy/sell) — a listing, not a verdict: no weights, scores or votes, and failed is NOT counted as the opposite side. events = recent target_selected / signal / signal_resolved / reverse_failed (추세 변경 안 됨: the primary target's reversal attempt failed, side = the trend that holds, not a signal) / reverse_tested (반전 테스트: the first reversing key on the primary target; side = reversing side, status beyond = that key's close is past the target = minimum condition met, short = not; not a signal) / conn_arrival, newest first, always including each timeframe's own latest 2 events (so slow timeframes such as 1w/1d are not pushed out by 30m/1h activity; pass `timeframe` for one timeframe's full history). Each timeframe reports its own state side by side — there is NO cross-timeframe verdict, no probability/confidence/bias fields; combining timeframes into a view is the caller's job. HOW TO ANSWER: this tool is the source of truth for direction. Show state_text, then explain in your own words using only these values (what each timeframe confirmed/failed/is waiting on, and which prices to watch); do not invent probabilities or targets. decker.get_view shows the same values as ready-made text. Read as persisted (no recompute). layer=STATE: a market-state reading, NOT a trade instruction. Crypto and Hyperliquid synthetics only (KRX: use decker.get_reading). Before placing any order through any execution tool, check the intent with decker.validate_intent.

    after · 93% of words in common

    Current swing-judgment state of a symbol across timeframes, as structured data (consumer contract CR1). Per timeframe (top→short): stage = target_selected (대상선정) | pending (판정보류: the close is still inside the signal bar) | confirmed (확인) | failed (실패) | none; side = buy/sell; signal_time; signal_bar {time, low, high} (the bar whose edges decide confirm/fail); confirmed_at / resolved_close; entry (= close at the signal, the fill basis); stop; target (the take-profit 목표가: opposite-side confirmed-signal edge at least 2% from entry, else null + target_reason; levels[].kind uses unit_target for the judged price, never `target`); unit_target (the price this timeframe is judging now = the 대상/anchor; NOT the take-profit — that is `target`); units = the targets this timeframe is watching together (max 6, primary first; secondary units judge concurrently when another earlier target is touched while the primary is judging): [{unit_target, zone buy|sell (buy = bought-from-below place, sell = sold-from-above place), stage target_selected|reverse_pending|confirmed|reverse_failed (추세 변경 안 됨), primary, touch_kind, touched_at, holds, reverse_side}] — not signals; reverse_pending = null, or {side, unit_target, holds, confirm, fail_side} when the reversal of that target is on hold (반전 보류: the first reversing key appeared but the next judgment bar has not yet closed beyond the target — side = the reversing side, independent of stage: a confirmed sell signal can coexist with a buy reversal on hold; fail_side = the key that would mean the target held and the move continues); prev_signal; turn = reverse (the signal flips the previous signal's direction = it changes the standing action) | same (continues it) | null; levels = nearby prices above/below the close. state_text = ready-to-show Korean status (title with price, then two compact lines: 상위·중간 / 단기, timeframes without a signal omitted, a failed row carries the price that decided it, plus nearby prices; no interpretation). Marks in state_text: color = state, shape = direction — 🟢▲ buy confirmed · 🔴▼ sell confirmed (action-worthy) · ⚪▲/⚪▼ pending (signal exists, unconfirmed) · 🟡 target selected / reversal on hold (반전 보류) · ✖️ failed (void signal, NOT the opposite side). timeframe_summary = the same rows merely listed by (stage, side), e.g. confirmed.buy = ['1d','4h'] (plus reverse_pending.buy/sell) — a listing, not a verdict: no weights, scores or votes, and failed is NOT counted as the opposite side. events = recent target_selected / signal / signal_resolved / reverse_failed (추세 변경 안 됨: the primary target's reversal attempt failed, side = the trend that holds, not a signal) / reverse_tested (반전 테스트: the first reversing key on the primary target; side = reversing side, status beyond = that key's close is past the target = minimum condition met, short = not; not a signal) / conn_arrival, newest first, always including each timeframe's own latest 2 events (so slow timeframes such as 1w/1d are not pushed out by 30m/1h activity; pass `timeframe` for one timeframe's full history). Each timeframe reports its own state side by side — there is NO cross-timeframe verdict, no probability/confidence/bias fields; combining timeframes into a view is the caller's job. HOW TO ANSWER: this tool is the source of truth for direction. Show state_text, then explain in your own words using only these values (what each timeframe confirmed/failed/is waiting on, and which prices to watch); do not invent probabilities or targets. decker.get_view shows the same values as ready-made text. Read as persisted (no recompute). layer=STATE: a market-state reading, NOT a trade instruction. Crypto and Hyperliquid synthetics only (KRX: use decker.get_reading). Before placing any order through any execution tool, check the intent with decker.validate_intent.

Showing the latest 10. Full history: list_changes · trend: quality JSON.

Checks run on what our credential-free, read-only probes observe; tools are never called and no code audit is performed. How it is computed.

Trust 90 / 100

provenance90
liveness100
freshness65
hygiene100

+repository +namespace-matches-repo +website +reachable +uptime-99% ~updated-99d-ago

Derived from observable signals (official registry feed and our own credential-free probes); no code audit performed. How it is computed.

Endpoints

remoteauthreachableuptime 30dp50protocollast ok
https://api.decker-ai.com/api/v1/mcp streamable-httpapi_key ${X_API_KEY}yes99%495 ms2024-11-052026-10-19

Tools (17)

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-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.get_assemblyMulti-timeframe path per symbol (STRATEGY_LAYER §8.4), built from the same per-timeframe judgment state as decker.get_market_state (CR1) — no weights, scores or thresholds. READ `verdict` FIRST: the one state + one action for the symbol right now (state = direction · phase; action = 진입 enter | 유지 hold | 청산 exit | 대기 wait, the engine's own action words; `reason` says why, `until` names the close that would change it). Everything below is supporting detail. frame = the highest timeframe with a confirmed signal (its side is the path direction; upper TF supplies direction and target, lower TF supplies the entry). Each timeframe row is classified frame | aligned | counter (confirmed, opposite side = a pullback in progress) | hint. grade = phase in plain words: 정렬 (no counter row) | 되돌림 (counter row exists, frame signal still alive) | 전환 시험 (frame signal is against / reversal pending) | 재장전 (no confirmed signal). entry = the lowest-timeframe aligned row whose signal is still alive (for/inside the signal bar), GO first; mode 지금 only when that signal's close is on its favorable side, otherwise 대기. stop/target/RR come from those rows' own coordinates. cond = the frame signal's fail edge (a close beyond it starts a reversal test). path = nearby price coordinates with what a close there means for the frame / entry piece / counter rows; onward = next targets in the path direction. watch = THE watch list, in time order: each upcoming bar close (timeframes closing at the same instant are one overlapping group) with every timeframe's state and the question that close decides — which side of which judged price (target, signal-bar edge, reversal-hold price) the close lands; a price also judged by a higher timeframe is flagged (this close is a hint for that one). summary_ko = ready-to-show Korean lines; ladder_upper / ladder_near = nearest coordinates (4h+ only / all timeframes) with `reads` and that timeframe's next close (KST); markers = which ladder point entry/stop/target sits on. Omit symbol for all 14 universe symbols. Narrate or filter the result — do not re-decide coordinates. ⚠ 정렬 does not mean every timeframe's gate is GO: check matrix_summary[].gate and .position. ⚠ entry.mode='지금' means the entry row's signal is on its favorable side now; it does NOT mean the engine confirmed a new event on this bar — check the entry row's gate.
decker.get_engine_state_raw[DEPRECATED — use decker.get_market_state (consumer contract CR1). Raw per-bar engine state dump (Market State v0); kept only for KRX symbols and will be removed.]
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 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_stateCurrent swing-judgment state of a symbol across timeframes, as structured data (consumer contract CR1). Per timeframe (top→short): stage = target_selected (대상선정) | pending (판정보류: the close is still inside the signal bar) | confirmed (확인) | failed (실패) | none; side = buy/sell; signal_time; signal_bar {time, low, high} (the bar whose edges decide confirm/fail); confirmed_at / resolved_close; entry (= close at the signal, the fill basis); stop; target (the take-profit 목표가: opposite-side confirmed-signal edge at least 2% from entry, else null + target_reason; levels[].kind uses unit_target for the judged price, never `target`); unit_target (the price this timeframe is judging now = the 대상/anchor; NOT the take-profit — that is `target`); units = the targets this timeframe is watching together (max 6, primary first; secondary units judge concurrently when another earlier target is touched while the primary is judging): [{unit_target, zone buy|sell (buy = bought-from-below place, sell = sold-from-above place), stage target_selected|reverse_pending|confirmed|reverse_failed (추세 변경 안 됨), primary, touch_kind, touched_at, holds, reverse_side}] — not signals; reverse_pending = null, or {side, unit_target, holds, confirm, fail_side} when the reversal of that target is on hold (반전 보류: the first reversing key appeared but the next judgment bar has not yet closed beyond the target — side = the reversing side, independent of stage: a confirmed sell signal can coexist with a buy reversal on hold; fail_side = the key that would mean the target held and the move continues); prev_signal; standing = null, or {side, signal_time, entry, stop, target, target_rr}: the standing stance's reference signal while a new target is being selected (stage=target_selected after a confirmed signal) — the entry/stop/target of that confirmed signal, kept apart from the stage-bound entry/stop/target above (those stay null until a signal is current); turn = reverse (the signal flips the previous signal's direction = it changes the standing action) | same (continues it) | null; levels = nearby prices above/below the close. state_text = ready-to-show Korean status (title with price, then two compact lines: 상위·중간 / 단기, timeframes without a signal omitted, a failed row carries the price that decided it, plus nearby prices; no interpretation). Marks in state_text: color = state, shape = direction — 🟢▲ buy confirmed · 🔴▼ sell confirmed (action-worthy) · ⚪▲/⚪▼ pending (signal exists, unconfirmed) · 🟡 target selected / reversal on hold (반전 보류) · ✖️ failed (void signal, NOT the opposite side). timeframe_summary = the same rows merely listed by (stage, side), e.g. confirmed.buy = ['1d','4h'] (plus reverse_pending.buy/sell) — a listing, not a verdict: no weights, scores or votes, and failed is NOT counted as the opposite side. events = recent target_selected / signal / signal_resolved / reverse_failed (추세 변경 안 됨: the primary target's reversal attempt failed, side = the trend that holds, not a signal) / reverse_tested (반전 테스트: the first reversing key on the primary target; side = reversing side, status beyond = that key's close is past the target = minimum condition met, short = not; not a signal) / conn_arrival, newest first, always including each timeframe's own latest 2 events (so slow timeframes such as 1w/1d are not pushed out by 30m/1h activity; pass `timeframe` for one timeframe's full history). Each timeframe reports its own state side by side — there is NO cross-timeframe verdict, no probability/confidence/bias fields; combining timeframes into a view is the caller's job. HOW TO ANSWER: this tool is the source of truth for direction. Show state_text, then explain in your own words using only these values (what each timeframe confirmed/failed/is waiting on, and which prices to watch); do not invent probabilities or targets. decker.get_view shows the same values as ready-made text. Read as persisted (no recompute). layer=STATE: a market-state reading, NOT a trade instruction. Crypto and Hyperliquid synthetics only (KRX: use decker.get_reading). Before placing any order through any execution tool, check the intent with decker.validate_intent.
decker.get_positionsAxis③ (Order/Execution) — this user's actual exposure: 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_price_axis_state[DEPRECATED — use decker.get_market_state (CR1). Raw price-axis state dump; superseded and will be removed.]
decker.get_readingAI-synthesized market reading for a symbol/timeframe, in customer-facing language: current state description, directional bias scores, bidirectional break targets, MTF verdict per timeframe, and an execution hint (stance + long/short setups). Engine-native raw fields are NOT exposed here — use the REST raw contract (GET /public/reading) or decker.get_market_state for those . execution_hint.preferred_direction is derived from key_direction alone and is NOT guaranteed to have a matching long_setup/short_setup (they come from an independent break-target resolver) — check that the setup for the preferred side is non-null before treating preferred_direction as an actionable side.
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=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_state_timelineMarket State v0 — per-bar state timeline for a symbol/timeframe (v0 per-bar schema — NOT the structured CR1 of decker.get_market_state; for the persisted event list use decker.get_market_state `events` or GET /public/state/{symbol}/{tf}/events; each item carries a SLIM `game` tag {status, target_id, zt_regime, provenance} instead of the full game block — read status transitions across bars to see how the target game unfolded (forming → testing → resolved/failed); ascending by bar_ts). Bars the engine did not emit are simply absent (honest gaps, no filling).
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_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. 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.
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 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.place_orderAxis③ (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. 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. 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.
decker.validate_intentPre-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 side_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).

Schemas: list_tools.

Similar MCP servers

Official server.json
{
  "name": "io.github.gigshow/decker",
  "$schema": "https://static.modelcontextprotocol.io/schemas/2025-12-11/server.schema.json",
  "remotes": [
    {
      "url": "https://api.decker-ai.com/api/v1/mcp",
      "type": "streamable-http",
      "headers": [
        {
          "name": "X-API-Key",
          "isSecret": true,
          "isRequired": true,
          "description": "Decker API key — free tier available (issue at decker-ai.com Settings → API Keys or via Telegram /apikey)"
        }
      ]
    }
  ],
  "version": "1.10.0",
  "repository": {
    "url": "https://github.com/gigshow/decker-ai",
    "source": "github"
  },
  "websiteUrl": "https://decker-ai.com/mcp",
  "description": "Deterministic market-state engine for trading agents — state, gate, coordinates, with receipts."
}