← The evidence ledger
Evidence row 221387
Observed , by probe.mcp/1.
- Kind
- mcp.tools
- About
- endpoint 5998d6ba-d709-4350-8f9c-54bb4f86da04
- Recorded
- Previous row
- None: the first of its kind about this subject
- Body SHA-256
- 502604c6286c5fc59a46c415d5187cfe571f7c604448c2e938403879dddaba6f
- Leaf
- 0xb3a17a23f0d5d44fd78f4dece60d30ebe09d625750461ac07865354d8003712d
What was observed
{
"count": 14,
"tools": [
{
"description": "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.",
"inputSchema": {
"properties": {
"close_fraction": {
"default": 1,
"description": "Fraction of the current position to close, 0 < x <= 1. Default 1.0 = full close. E.g. 0.5 closes half.",
"exclusiveMinimum": 0,
"maximum": 1,
"type": "number"
},
"symbol": {
"description": "e.g. BTCUSDT, XYZ_GOLDUSD — whatever symbol you hold. Aliases resolve like other tools.",
"type": "string"
}
},
"required": [
"symbol"
],
"type": "object"
},
"name": "decker.close_position"
},
{
"description": "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), tf_states (EVERY timeframe's own state: judgment stage, open reversal test with its confirm price, engine action, next-bar label chain, recently missed targets — none folded by direction), knots (every timeframe's decision prices ordered by distance from the price, up and down, with which timeframes and roles sit on each — the ORDER in which transactions would be reached, not a probability). `reason` may end with '반대 방향 반전 보류 중: …' = other timeframes whose reversal test runs AGAINST the verdict's direction, i.e. is testing the current stance (a fact, not a vote; it never changes the action). 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.",
"inputSchema": {
"properties": {
"detail": {
"description": "Include path / watch / story / ladders / matrix_summary (about 20KB per symbol). Default false: the answer only.",
"type": "boolean"
},
"symbol": {
"description": "Optional symbol or alias (BTC, 비트코인, GOLD, 테슬라...). Omit for all 14 symbols.",
"type": "string"
}
},
"type": "object"
},
"name": "decker.get_assembly"
},
{
"description": "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.",
"inputSchema": {
"properties": {
"limit": {
"default": 5,
"description": "number of episodes",
"maximum": 20,
"minimum": 1,
"type": "integer"
},
"symbol": {
"description": "e.g. BTCUSDT",
"type": "string"
},
"timeframe": {
"enum": [
"30m",
"1h",
"4h",
"8h",
"1d",
"1w"
],
"type": "string"
}
},
"required": [
"symbol",
"timeframe"
],
"type": "object"
},
"name": "decker.get_episodes"
},
{
"description": "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 · ✖️ 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.",
"inputSchema": {
"properties": {
"events_limit": {
"default": 10,
"maximum": 50,
"minimum": 0,
"type": "integer"
},
"symbol": {
"description": "e.g. BTCUSDT, XYZ_GOLDUSD",
"type": "string"
},
"timeframe": {
"description": "Alias for a single-element `timeframes` (backward compatible).",
"enum": [
"30m",
"1h",
"4h",
"8h",
"1d",
"1w"
],
"type": "string"
},
"timeframes": {
"description": "Subset to return. Omit for all timeframes.",
"items": {
"enum": [
"30m",
"1h",
"4h",
"8h",
"1d",
"1w"
],
"type": "string"
},
"type": "array"
}
},
"required": [
"symbol"
],
"type": "object"
},
"name": "decker.get_market_state"
},
{
"description": "Axis③ (Order/Execution) — this user's actual exposure (each open row carries vs_verdict: does the held side match the current symbol verdict, plus `knots` = the decision prices nearest to the price above and below, with which timeframes sit on each — the ORDER in which transactions would be reached, not a probability; `exit_levels` only when the held side matches): 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.",
"inputSchema": {
"properties": {},
"type": "object"
},
"name": "decker.get_positions"
},
{
"description": "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.",
"inputSchema": {
"properties": {
"include_tfs": {
"description": "Comma-separated additional TFs (e.g. '1h,4h,1d').",
"type": "string"
},
"symbol": {
"description": "e.g. BTCUSDT",
"type": "string"
},
"tf": {
"default": "4h",
"enum": [
"15m",
"30m",
"1h",
"4h",
"8h",
"1d",
"1w"
],
"type": "string"
}
},
"required": [
"symbol"
],
"type": "object"
},
"name": "decker.get_reading"
},
{
"description": "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.",
"inputSchema": {
"properties": {
"action_gate": {
"description": "Engine action gate filter (3-layer grammar: gate = transition posture, not an order command). Rows where the engine emitted no gate for this bar (effective_action_gate null, e.g. KRX daily) are excluded when this filter is set.",
"enum": [
"GO",
"WATCH",
"HOLD"
],
"type": "string"
},
"limit": {
"default": 20,
"maximum": 100,
"minimum": 1,
"type": "integer"
},
"min_progress": {
"description": "Minimum progress_pct (0-100).",
"maximum": 100,
"minimum": 0,
"type": "number"
},
"symbols": {
"description": "Symbol filter (e.g. ['BTCUSDT','ETHUSDT']). Omit for all.",
"items": {
"type": "string"
},
"type": "array"
},
"timeframe": {
"description": "Signal horizon filter (30m=scalp, 1h=swing, 4h/8h/1d=position). The same symbol can hold OPPOSITE directions on different horizons — omit to get the latest active signal regardless of horizon (its timeframe field says which one you got; when a specific symbols[] was requested, a row's other_horizon_conflict field flags it if another horizon is ACTIVE with the opposite direction). Prefer decker.get_assembly for the composed cross-horizon judgment instead of guessing which horizon to pass here.",
"enum": [
"30m",
"1h",
"4h",
"8h",
"1d"
],
"type": "string"
}
},
"type": "object"
},
"name": "decker.get_signals"
},
{
"description": "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.",
"inputSchema": {
"properties": {
"limit": {
"default": 20,
"maximum": 50,
"minimum": 1,
"type": "integer"
},
"since": {
"description": "ISO8601 lower bound on trigger time (exclusive). Optional.",
"type": "string"
},
"symbol": {
"description": "e.g. BTCUSDT",
"type": "string"
},
"timeframe": {
"description": "Optional — omit for all timeframes.",
"enum": [
"30m",
"1h",
"4h",
"8h",
"1d"
],
"type": "string"
}
},
"required": [
"symbol"
],
"type": "object"
},
"name": "decker.get_trigger_history"
},
{
"description": "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).",
"inputSchema": {
"properties": {},
"type": "object"
},
"name": "decker.get_user_skills"
},
{
"description": "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.",
"inputSchema": {
"properties": {
"symbol": {
"description": "e.g. BTCUSDT, XYZ_GOLDUSD (crypto + HL TradFi synthetics; KRX daily lineage not yet covered by view v1)",
"type": "string"
},
"tf": {
"description": "Optional view timeframe — the grounded narrative is composed on this TF's bar (e.g. '1h' when the user asks about the 1-hour picture). Omit for the engine's default action TF (usually 4h, same as the daily briefing card).",
"enum": [
"30m",
"1h",
"4h",
"8h",
"1d"
],
"type": "string"
}
},
"required": [
"symbol"
],
"type": "object"
},
"name": "decker.get_view"
},
{
"description": "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.",
"inputSchema": {
"properties": {
"notional_usd": {
"description": "Order size in USD (quantity = notional_usd / current price). This is the value checked against the account's tier notional cap.",
"exclusiveMinimum": 0,
"type": "number"
},
"side": {
"description": "Order direction (buy/long or sell/short).",
"enum": [
"buy",
"long",
"sell",
"short"
],
"type": "string"
},
"symbol": {
"description": "Crypto-6 only for this MCP write path.",
"enum": [
"BTCUSDT",
"ETHUSDT",
"SOLUSDT",
"BNBUSDT",
"XRPUSDT",
"DOGEUSDT"
],
"type": "string"
}
},
"required": [
"symbol",
"side",
"notional_usd"
],
"type": "object"
},
"name": "decker.place_order"
},
{
"description": "Change active trading skill overlay for this user. Immediately affects all subsequent get_signals calls and downstream channels.",
"inputSchema": {
"properties": {
"skill_id": {
"description": "trading_skills.id (e.g. 'aggressive_v0').",
"type": "string"
}
},
"required": [
"skill_id"
],
"type": "object"
},
"name": "decker.set_skill_overlay"
},
{
"description": "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.",
"inputSchema": {
"properties": {
"mode": {
"description": "Only required when both a real and a virtual position are open for this symbol — says which one to modify.",
"enum": [
"real",
"virtual"
],
"type": "string"
},
"sl_price": {
"description": "New stop-loss price. Omit to leave the current stop unchanged.",
"exclusiveMinimum": 0,
"type": "number"
},
"symbol": {
"description": "e.g. BTCUSDT — must be a symbol you currently hold.",
"type": "string"
},
"tp_price": {
"description": "New take-profit price. Omit to leave the current target unchanged.",
"exclusiveMinimum": 0,
"type": "number"
}
},
"required": [
"symbol"
],
"type": "object"
},
"name": "decker.update_protective_stops"
},
{
"description": "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. ",
"inputSchema": {
"properties": {
"order_type": {
"description": "Optional, informational (market/limit/…) — recorded in the ledger, does not change the state verdict.",
"type": "string"
},
"side": {
"description": "Proposed order direction (buy/long = +, sell/short = -).",
"enum": [
"buy",
"long",
"sell",
"short"
],
"type": "string"
},
"symbol": {
"description": "e.g. BTCUSDT, SILVER, 테슬라 — aliases resolve to the engine symbol (XYZ_SILVERUSD, XYZ_TSLAUSD, …).",
"type": "string"
},
"timeframe": {
"description": "Gate horizon. Omit = your open position's entry TF if you hold one on this symbol, else decker.get_assembly's entry TF (the single judgment authority's current best-path TF), else the engine's default action TF (4h).",
"enum": [
"30m",
"1h",
"4h",
"8h",
"1d"
],
"type": "string"
}
},
"required": [
"symbol",
"side"
],
"type": "object"
},
"name": "decker.validate_intent"
}
]
}What the leaf hashes
{"body":"502604c6286c5fc59a46c415d5187cfe571f7c604448c2e938403879dddaba6f","id":221387,"kind":"mcp.tools","method":"probe.mcp/1","observed_us":1793027325242415,"prev":null,"subject":"5998d6ba-d709-4350-8f9c-54bb4f86da04","subject_kind":"endpoint"}Proof
Fold these into the leaf in order, hashing each sorted pair with keccak256, to reach the root of (296695 rows).
- 0xb3a1baf025de321c2de859cd3ace02fd07d4053f4df8cd629fd836d3ac635996
- 0xe52bf3ccc6a0c881513cba74d29705b8f3a6ef980a1cd9b38511093d62fbe6ae
- 0x0582c90892ec8b4d521e9d9d25fdf3b86a3a42f7494aa3d40cef40a7138b6f16
- 0xd79c51ed232f1053574a13fd9a686e4843ce976a07604f67ebf9bc81a8e67449
- 0x72157e5390f42710cc938b518369c73d1d91b4162040cb49941e9b9adc04157b
- 0x6c1a115cebce06574900b50545998daebee30551709ffa0953c839f815464157
- 0x2b3f55829d70197806aa540dda3d7dd8190a38b6750f054266caa947355872ea
- 0x586bdb7687a269ac39949e89c2081ed5b77656463f4a1cb65a49e3d75b29e58c
- 0xadafc16d116ead5edc3f88bfcb559a636d9650754ac1f6fa383c7092df3f8bf2
- 0xf04f1893fe6291cdbc16182b9a16bead5bf9b24bd4e846024218e2491f79cc69
- 0xc50bb1c2185da1e4294f4829be5412051ce30550dd05a2a26962841b3ba2399d
- 0x3d6ec9d5ef8daa604601742088e213da0a439db6eff6ce50ec3ffb264a60ddd3
- 0x3b1c0e225d1b1cb24cd5d5ea4af2de20ed68a1eaf8b61924ed1b81e4b9cf7e39
- 0x083427e39db4dd470662401f6db5db8fadf084fc4274cf8621b368416952b78b
- 0x1a74ed3b3756b9cd946da49701bcec120ec88645013da99fa9eea60b39e1a570
- 0x123ec8bee20ddc55223eeef5a4f4d6c4b6416515adbb911c56759f5cde56e452
- 0xd0651cb9bc8155eb52b5247d506e74b8a935057dc190ba52091702ac25ed3a40
- 0x9a9024edb5069d88a324facb310a5ce8e495214bbaa968f077bede437390194f
- 0x9b9ce5b74b9bab5121612ef6b64920a8d453cbf311096a423eef9702747e868a
- Day root
- 0xf43e8dcc3d451a4788b26be904c55e8c4c0fa75c9666796c51db38d37e2c0df8
- Chained
- 0x702d5ac508f08b0d1accf36af25822d8e5660367494edd17a642fb61e158a57a
- Published
- On Arc Testnet, block 69251483: 0x495162f8936e19f0039918feebe6c307f327cd6bf8c37219620b1970041fa9ae