decker

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

Should I use this

Quality & Safety

B
Description quality
100%
Schema completeness
87%
Naming quality
50%
Poisoning risk
80%
Permission match
100%
Protocol compliance
100%

Findings (16)

  • HIGHTool poisoning patterns detected
  • MEDIUMTool description contains suspicious base64-like encoded stringin decker.place_order
  • LOWTool 'decker.get_assembly' doesn't follow camelCase/snake_casein decker.get_assembly
  • LOWTool 'decker.get_market_state' doesn't follow camelCase/snake_casein decker.get_market_state
  • LOWTool 'decker.get_view' doesn't follow camelCase/snake_casein decker.get_view
  • LOWTool 'decker.get_reading' doesn't follow camelCase/snake_casein decker.get_reading
  • LOWTool 'decker.get_signals' doesn't follow camelCase/snake_casein decker.get_signals
  • LOWTool 'decker.get_episodes' doesn't follow camelCase/snake_casein decker.get_episodes
  • LOWTool 'decker.get_trigger_history' doesn't follow camelCase/snake_casein decker.get_trigger_history
  • LOWTool 'decker.get_positions' doesn't follow camelCase/snake_casein decker.get_positions

Based on automated analysis of tool definitions and protocol compliance.

Context Cost

~10,862Tokens (tool definitions)
~4.0 KBTypical response size
Significant attention impact (8.49% of 128k context)

This is the approximate number of tokens consumed each time the server's tools are loaded into a model's context. Higher counts reduce the attention available for other tasks.

Install

One-Click Install

Add this to your `claude_desktop_config.json` file:

{
  "mcpServers": {
    "decker": {
      "url": "https://api.decker-ai.com/api/v1/mcp"
    }
  }
}

Remote endpoints

https://api.decker-ai.com/api/v1/mcpstreamable-http

What it can do

Tool inventory

Tools (14)

🟢 Read-only🟡 Write🔴 Delete⚪ Unknown
🟡decker.get_assembly(symbol, detail)

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.

Input Schema

{
  "type": "object",
  "properties": {
    "symbol": {
      "type": "string",
      "description": "Optional symbol or alias (BTC, 비트코인, GOLD, 테슬라...). Omit for all 14 symbols."
    },
    "detail": {
      "type": "boolean",
      "description": "Include path / watch / story / ladders / matrix_summary (about 20KB per symbol). Default false: the answer only."
    }
  }
}
🟢decker.get_market_state(symbol, timeframes, timeframe, events_limit)

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.

Input Schema

{
  "type": "object",
  "properties": {
    "symbol": {
      "type": "string",
      "description": "e.g. BTCUSDT, XYZ_GOLDUSD"
    },
    "timeframes": {
      "type": "array",
      "items": {
        "type": "string",
        "enum": [
          "30m",
          "1h",
          "4h",
          "8h",
          "1d",
          "1w"
        ]
      },
      "description": "Subset to return. Omit for all timeframes."
    },
    "timeframe": {
      "type": "string",
      "enum": [
        "30m",
        "1h",
        "4h",
        "8h",
        "1d",
        "1w"
      ],
      "description": "Alias for a single-element `timeframes` (backward compatible)."
    },
    "events_limit": {
      "type": "integer",
      "minimum": 0,
      "maximum": 50,
      "default": 10
    }
  },
  "required": [
    "symbol"
  ]
}

Output Schema

{
  "type": "object",
  "properties": {
    "symbol": {
      "type": "string"
    },
    "as_of": {
      "type": [
        "string",
        "null"
      ],
      "format": "date-time",
      "description": "가장 최근 평가 봉의 마감 시각"
    },
    "price": {
      "type": [
        "number",
        "null"
      ],
      "description": "가장 최근 평가 봉의 종가"
    },
    "state_text": {
      "type": [
        "string",
        "null"
      ],
      "description": "사용자에게 그대로 보여 줄 수 있는 현재 상태 문면 — 상위·중간·단기로 묶어 시간대마다 방향+단계, 마지막에 주목 가격. 해석·전망 문장은 없다(그건 호출자 몫). 시간대 행이 없으면 null"
    },
    "ladder": {
      "type": "object",
      "properties": {
        "up": {
          "type": "array",
          "items": {
            "type": "object",
            "properties": {
              "price": {
                "type": "number"
              },
              "distance_pct": {
                "type": "number"
              },
              "at": {
                "type": "array",
                "items": {
                  "type": "object",
                  "properties": {
                    "timeframe": {
                      "type": "string",
                      "enum": [
                        "1w",
                        "1d",
                        "8h",
                        "4h",
                        "1h",
                        "30m"
                      ]
                    },
                    "kind": {
                      "type": "string",
                      "enum": [
                        "unit_target",
                        "next_unit_target",
                        "connection",
                        "candidate",
                        "signal_edge",
                        "decision"
                      ]
                    },
                    "edge": {
                      "type": [
                        "string",
                        "null"
                      ],
                      "enum": [
                        "confirm",
                        "fail",
                        null
                      ]
                    },
                    "reads": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        },
        "down": {
          "type": "array",
          "items": {
            "type": "object",
            "properties": {
              "price": {
                "type": "number"
              },
              "distance_pct": {
                "type": "number"
              },
              "at": {
                "type": "array",
                "items": {
                  "type": "object",
                  "properties": {
                    "timeframe": {
                      "type": "string",
                      "enum": [
                        "1w",
                        "1d",
                        "8h",
                        "4h",
                        "1h",
                        "30m"
                      ]
                    },
                    "kind": {
                      "type": "string",
                      "enum": [
                        "unit_target",
                        "next_unit_target",
                        "connection",
                        "candidate",
                        "signal_edge",
                        "decision"
                      ]
                    },
                    "edge": {
                      "type": [
                        "string",
                        "null"
                      ],
                      "enum": [
                        "confirm",
                        "fail",
                        null
                      ]
                    },
                    "reads": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        }
      },
      "description": "현재가 위·아래 가까운 순서로 각 8개. 같은 가격은 한 점이고 at 에 그 가격이 어느 시간대에서 어떤 역할인지(kind) 모두 나열된다 — 하위 시간대가 닿는 가격이 상위 시간대의 대상·후보·신호봉 경계이면 그 한 사건이 두 시간대의 사건이다(상위는 하위의 조각이 모여 만들어진다). signal_edge.edge: confirm=그 방향 확인 경계 · fail=반대(실패) 경계. reads=그 칸의 사건 문장(역할→사건 표) + 그 시간대의 다음 마감 시각(판정은 종가). 우세·점수 없음"
    },
    "timeframe_summary": {
      "type": "object",
      "properties": {
        "confirmed": {
          "type": "object",
          "properties": {
            "buy": {
              "type": "array",
              "items": {
                "type": "string"
              }
            },
            "sell": {
              "type": "array",
              "items": {
                "type": "string"
              }
            }
          }
        },
        "pending": {
          "type": "object",
          "properties": {
            "buy": {
              "type": "array",
              "items": {
                "type": "string"
              }
            },
            "sell": {
              "type": "array",
              "items": {
                "type": "string"
              }
            }
          }
        },
        "failed": {
          "type": "object",
          "properties": {
            "buy": {
              "type": "array",
              "items": {
                "type": "string"
              }
            },
            "sell": {
              "type": "array",
              "items": {
                "type": "string"
              }
            }
          }
        },
        "target_selected": {
          "type": "array",
          "items": {
            "type": "string"
          }
        }
      },
      "description": "시간대 행을 단계(confirmed 확인·pending 판정보류·failed 실패)와 방향(buy·sell)별로 나열만 한다. 우세·점수·투표 없음 — 실패는 반대 방향을 뜻하지 않는다. target_selected = 대상선정 중인 시간대 목록"
    },
    "timeframes": {
      "type": "array",
      "description": "상위→단기 순. 각 시간대가 낸 상태를 나란히 — 시간대 간 종합 판정은 없다(종합은 호출자 몫).",
      "items": {
        "type": "object",
        "required": [
          "timeframe",
          "stage",
          "side"
        ],
        "properties": {
          "timeframe": {
            "type": "string",
            "enum": [
              "1w",
              "1d",
              "8h",
              "4h",
              "1h",
              "30m"
            ]
          },
          "bar_close_time": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time",
            "description": "이 시간대의 마지막 평가 봉 마감 시각"
          },
          "next_close_time": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time",
            "description": "이 시간대의 진행 중인 봉이 닫히는 시각(마지막 평가 봉 마감 + 시간대 길이). 상위 봉은 하위 봉들이 모여 닫힌다"
          },
          "closes_with": {
            "type": "array",
            "items": {
              "type": "string",
              "enum": [
                "1w",
                "1d",
                "8h",
                "4h",
                "1h",
                "30m"
              ]
            },
            "description": "진행 중인 봉이 이 시간대와 같은 시각에 닫히는 다른 시간대 목록 — 겹치는 하위 봉의 종가가 상위 판정의 결정적 순간이다"
          },
          "close": {
            "type": [
              "number",
              "null"
            ],
            "description": "그 봉 종가"
          },
          "stage": {
            "type": "string",
            "enum": [
              "target_selected",
              "pending",
              "confirmed",
              "failed",
              "none"
            ],
            "description": "target_selected=대상선정 · pending=판정보류 · confirmed=확인 · failed=실패 · none=신호 없음. failed = that signal's judgment broke (the close crossed the signal bar's opposite edge) — it does NOT assert the opposite direction; read the timeframe's own fields (signal_bar / resolved_close / confirmed_at) for which price decided it."
          },
          "side": {
            "type": [
              "string",
              "null"
            ],
            "enum": [
              "buy",
              "sell",
              null
            ],
            "description": "buy=매수 · sell=매도"
          },
          "signal_time": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time",
            "description": "신호 시각(판단봉 2를 봉인하는 S 봉)"
          },
          "signal_bar": {
            "type": [
              "object",
              "null"
            ],
            "properties": {
              "time": {
                "type": [
                  "string",
                  "null"
                ],
                "format": "date-time"
              },
              "low": {
                "type": [
                  "number",
                  "null"
                ]
              },
              "high": {
                "type": [
                  "number",
                  "null"
                ]
              }
            },
            "description": "신호봉(판단봉 2) — 종가가 이 범위 밖으로 나가면 확인/실패, 안이면 판정보류"
          },
          "confirmed_at": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time",
            "description": "결말(확인/실패)이 난 봉 시각"
          },
          "resolved_close": {
            "type": [
              "number",
              "null"
            ],
            "description": "결말을 정한 종가"
          },
          "signal_position": {
            "type": [
              "string",
              "null"
            ],
            "enum": [
              "for",
              "against",
              "inside",
              null
            ],
            "description": "확인·실패 신호의 지금 종가가 신호봉 대비 어디인가(신호 방향 반영) — for=신호 방향 경계 밖 · against=반대 경계 밖(불리; 신호 결과 stage 는 첫 결말로 고정이고 이후 이탈은 위치로만 남는다) · inside=신호봉 안"
          },
          "entry": {
            "type": [
              "number",
              "null"
            ],
            "description": "체결 기준 가격 = 신호 시점 종가"
          },
          "stop": {
            "type": [
              "number",
              "null"
            ]
          },
          "target": {
            "type": [
              "number",
              "null"
            ],
            "description": "**목표가** — 진입가 대비 2% 이상 거리의 반대 측 확인 신호 경계(신호 이후 청산 좌표). 없으면 null. 판정 중인 대상 가격은 unit_target"
          },
          "target_reason": {
            "type": [
              "string",
              "null"
            ],
            "description": "target 이 null 인 이유"
          },
          "target_source_tf": {
            "type": [
              "string",
              "null"
            ],
            "enum": [
              "1w",
              "1d",
              "8h",
              "4h",
              "1h",
              null
            ],
            "description": "목표가 **상위 시간대**의 확인된 반대 신호 경계(연계 좌표, 규칙표 R20.5·C4)일 때 그 시간대(예: '1w'). 자기 시간대 좌표면 null. 거리는 진입가 대비 단계 규칙 그대로이며 상위 시간대 좌표라 멀 수 있다"
          },
          "target_rr": {
            "type": [
              "number",
              "null"
            ],
            "description": "확인된 목표 좌표(target)가 없는 자리(신고점·신저점)에서 **손익비 2:1 기계값**. 새 상수 없이 손절 거리의 2배에서 파생되며 자동주문의 목표와 같은 값이다. 좌표가 아니라 계산값이므로 target 과 섞이지 않는다. target 이 있으면 null"
          },
          "unit_target": {
            "type": [
              "number",
              "null"
            ],
            "description": "이 시간대가 지금 판정 중인 **대상**(대상 가격, 앵커 C). 신호 이후 청산 좌표인 **목표가(target)와 다르다**"
          },
          "unit_target_touch": {
            "type": [
              "string",
              "null"
            ],
            "enum": [
              "break",
              "inside",
              null
            ]
          },
          "units": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "unit_target": {
                  "type": "number"
                },
                "zone": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "enum": [
                    "buy",
                    "sell",
                    null
                  ]
                },
                "stage": {
                  "type": "string",
                  "enum": [
                    "target_selected",
                    "reverse_pending",
                    "confirmed",
                    "reverse_failed"
                  ]
                },
                "primary": {
                  "type": "boolean"
                },
                "touch_kind": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "enum": [
                    "break",
                    "inside",
                    null
                  ]
                },
                "touched_at": {
                  "type": [
                    "string",
                    "null"
                  ]
                },
                "holds": {
                  "type": "integer"
                },
                "reverse_side": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "enum": [
                    "buy",
                    "sell",
                    null
                  ]
                }
              }
            },
            "description": "이 시간대가 **함께 보고 있는 대상 목록**(최대 6, 1순위 먼저). 한 시간대에서 대상은 하나가 아니다 — 1순위가 판정 중이어도 이전부터 있던 다른 대상이 터치되면 보조 유닛으로 각자 판정한다(수평·수직). unit_target = 그 대상 가격 · zone = 대상 자리(buy = 아래서 산 자리 · sell = 위에서 판 자리) · stage = target_selected 대상선정 | reverse_pending 반전 보류(테스트·보류 포함) | confirmed 확정 | reverse_failed 추세 변경 안 됨 · primary = 1순위 여부 · touch_kind = 터치 종류(break 종가로 돌파 · inside 꼬리만) · touched_at = 터치 봉 시각 · holds = 보류 이월 횟수 · reverse_side = 반전 측. 신호·결말(stage 최상위)과 별개 층이고 신호 아님."
          },
          "reverse_pending": {
            "type": [
              "object",
              "null"
            ],
            "properties": {
              "side": {
                "type": "string",
                "enum": [
                  "buy",
                  "sell"
                ],
                "description": "buy=매수 · sell=매도 (반전 측)"
              },
              "holds": {
                "type": "integer",
                "description": "보류를 넘긴 횟수(0 = 첫 시험 직후)"
              },
              "confirm": {
                "type": [
                  "object",
                  "null"
                ],
                "properties": {
                  "progress_price": {
                    "type": "number"
                  },
                  "unit_target_price": {
                    "type": "number"
                  },
                  "side_of_price": {
                    "type": "string",
                    "enum": [
                      "above",
                      "below"
                    ]
                  }
                }
              },
              "fail_side": {
                "type": [
                  "string",
                  "null"
                ],
                "enum": [
                  "buy",
                  "sell",
                  null
                ]
              },
              "unit_target": {
                "type": "number"
              }
            },
            "description": "이 시간대가 지금 판정 중인 **반전**이 보류 상태일 때만 있다(그 외 null). side = 반전 측(대상 쪽의 반대: 대상이 매수 자리면 sell) · unit_target = 그 대상(기준 가격) · holds = 보류를 넘긴 횟수(0 = 첫 시험 직후) · confirm = 반전이 확인되려면 다음 판단봉이 progress_price 보다 side_of_price 쪽으로 진전하고 대상(unit_target_price)을 넘어 마감해야 한다 · fail_side = 이 측의 키가 나오면 반전 실패(대상이 방어됨, 진행 유지). 신호(stage)와 별개 — 직전 신호가 확인이어도 새 대상의 반전이 보류일 수 있다."
          },
          "action_switch": {
            "type": [
              "object",
              "null"
            ],
            "properties": {
              "need": {
                "type": "string",
                "enum": [
                  "required",
                  "exit",
                  "pending",
                  "not_required"
                ]
              },
              "side": {
                "type": [
                  "string",
                  "null"
                ],
                "enum": [
                  "buy",
                  "sell",
                  null
                ]
              },
              "stance": {
                "type": [
                  "string",
                  "null"
                ],
                "enum": [
                  "buy",
                  "sell",
                  null
                ]
              },
              "unit_target": {
                "type": [
                  "number",
                  "null"
                ]
              },
              "close_vs_target": {
                "type": [
                  "string",
                  "null"
                ],
                "enum": [
                  "above",
                  "below",
                  "at",
                  null
                ]
              },
              "mismatch": {
                "type": "boolean"
              },
              "exit_edge": {
                "type": [
                  "number",
                  "null"
                ]
              },
              "reversal_tests": {
                "type": "object",
                "properties": {
                  "buy": {
                    "type": "integer"
                  },
                  "sell": {
                    "type": "integer"
                  }
                }
              }
            },
            "description": "이 시간대 루프의 현재 위치가 사용자에게 주는 **행동전환 결정**(저자 10-11 교정 #9·#10: 런타임은 스냅샷이라 모든 상태가 결정을 낸다). need = required 전환 필요(이 봉에서 신호 확정, side 로 진입·반대 측이면 청산 후 리버스) · exit 청산(이 봉에서 직전 신호 실패 — stance 측 판단 근거 붕괴) · pending 전환 대기(확정 전, 반전 가설이 시험 중 — side = 후보 방향, 가설이 양방향이면 null) · not_required 전환 불필요(stance = 직전 신호 측 유지, 없으면 행동 없음). exit_edge = need=exit 를 정한 사건이 '확인된 신호의 신호봉 반대 경계 종가 이탈'일 때 그 경계 가격(매수=저가·매도=고가) — 표면이 경계를 추정하지 않도록 엔진이 싣는다, 다른 사건이 정한 행동이면 null · reversal_tests = 살아 있는 반전 가설 수(1순위+보조 유닛, 방향별 — 순위·승격 없음) · mismatch = 최근 키와 종가 위상이 엇갈림(양방향 동시 테스트) · close_vs_target = 1순위 대상 가격 대비 종가 위치. 신호(stage)·반전 보류와 별개 층이고 엔진 한 곳에서만 나온다. 가설도 신호도 없으면 null."
          },
          "label_next": {
            "type": [
              "object",
              "null"
            ],
            "properties": {
              "state": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "hi": {
                "type": [
                  "number",
                  "null"
                ]
              },
              "lo": {
                "type": [
                  "number",
                  "null"
                ]
              },
              "next": {
                "type": "object",
                "properties": {
                  "F": {
                    "type": [
                      "string",
                      "null"
                    ]
                  },
                  "B": {
                    "type": [
                      "string",
                      "null"
                    ]
                  },
                  "I": {
                    "type": [
                      "string",
                      "null"
                    ]
                  },
                  "W": {
                    "type": [
                      "string",
                      "null"
                    ]
                  }
                }
              }
            },
            "description": "1순위 대상의 라벨이 **다음 한 봉**에 어떻게 되는지의 읽기. state = 지금 라벨 위치 · hi/lo = 직전 봉의 고가·저가(다음 봉이 이 두 가격에 대해 고가 갱신 F · 저가 갱신 B · 둘 다 아님 I · 둘 다 W 로 갈린다 — 종가가 아니다) · next = 움직임별 다음 라벨. 판정 입력이 아니라 읽기. 엔진이 아직 내지 않은 세대는 null."
          },
          "missed": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "time": {
                  "type": [
                    "string",
                    "null"
                  ]
                },
                "price": {
                  "type": "number"
                },
                "sign": {
                  "type": [
                    "string",
                    "null"
                  ]
                },
                "position": {
                  "type": [
                    "string",
                    "null"
                  ],
                  "enum": [
                    "above",
                    "below",
                    "at",
                    null
                  ]
                },
                "judging": {
                  "type": [
                    "number",
                    "null"
                  ]
                }
              }
            },
            "description": "판정 없이 지나간 break(미싱)의 최근 몇 건(최신 먼저). 판정 중인 1순위가 있는 동안 태어난 대상이 터치브레이크되면 판정 대상이 아니라 미싱으로 남는다 — **상태**일 뿐 스윙 반전이 아니다. time = 그 봉 시각 · price = 그 대상 가격 · sign = 대상 부호 · position = 그 봉 종가가 대상의 위(above)/아래(below) · judging = 그때 판정 중이던 1순위 대상 가격."
          },
          "prev_signal": {
            "type": [
              "object",
              "null"
            ],
            "properties": {
              "side": {
                "type": [
                  "string",
                  "null"
                ],
                "enum": [
                  "buy",
                  "sell",
                  null
                ],
                "description": "buy=매수 · sell=매도"
              },
              "stage": {
                "type": "string",
                "enum": [
                  "target_selected",
                  "pending",
                  "confirmed",
                  "failed",
                  "none"
                ],
                "description": "target_selected=대상선정 · pending=판정보류 · confirmed=확인 · failed=실패 · none=신호 없음. failed = that signal's judgment broke (the close crossed the signal bar's opposite edge) — it does NOT assert the opposite direction; read the timeframe's own fields (signal_bar / resolved_close / confirmed_at) for which price decided it."
              },
              "signal_time": {
                "type": [
                  "string",
                  "null"
                ],
                "format": "date-time"
              }
            }
          },
          "standing": {
            "type": [
              "object",
              "null"
            ],
            "properties": {
              "side": {
                "type": "string",
                "enum": [
                  "buy",
                  "sell"
                ]
              },
              "signal_time": {
                "type": [
                  "string",
                  "null"
                ],
                "format": "date-time"
              },
              "entry": {
                "type": [
                  "number",
                  "null"
                ]
              },
              "stop": {
                "type": [
                  "number",
                  "null"
                ]
              },
              "target": {
                "type": [
                  "number",
                  "null"
                ]
              },
              "target_rr": {
                "type": [
                  "number",
                  "null"
                ]
              }
            },
            "description": "**유지 중인 입장의 기준 신호**(단계가 대상선정일 때만, 직전 신호가 확인이고 아직 실패하지 않았을 때). 새 대상이 선정되어도 직전 확인 신호의 입장은 유지된다(action_switch.stance) — 그 입장의 진입가·손절·목표를 신호 단계 필드(entry·stop·target)와 섞지 않고 따로 싣는다. side = 유지되는 입장 · signal_time = 그 신호 시각 · entry = 체결 기준(신호 시점 종가) · stop = 손절 · target = 목표 좌표 · target_rr = 좌표가 없을 때 손익비 기계값. 신호 단계(pending·confirmed·failed)이거나 직전 확인 신호가 없으면 null"
          },
          "turn": {
            "type": [
              "string",
              "null"
            ],
            "enum": [
              "reverse",
              "same",
              null
            ],
            "description": "신호가 살아 있는 단계(pending·confirmed)에서 직전 신호와 방향이 바뀌면 reverse(기존 행동을 바꾸는 신호), 같으면 same(이어짐). 실패(failed)·신호 없음·직전 신호 없음은 null"
          },
          "levels": {
            "type": [
              "object",
              "null"
            ],
            "properties": {
              "up": {
                "type": "array",
                "items": {
                  "type": "object"
                }
              },
              "down": {
                "type": "array",
                "items": {
                  "type": "object"
                }
              }
            },
            "description": "주목 가격 — 종가 위·아래 가까운 가격 3개씩 {price, distance_pct, kind}. kind=unit_target(지금 판정 중인 대상 가격)|next_unit_target(다음 대상)|connection(과거 판정지점)|candidate(아직 닿지 않은 대상 후보). ⚠ 목표가(target)와 다른 말이다"
          }
        }
      }
    },
    "events": {
      "type": "array",
      "description": "최근 사건(새것 먼저). 대상선정·신호·신호 결말·추세 변경 안 됨(reverse_failed: 1순위 대상의 반전이 실패한 판정 결과, side = 유지되는 추세 쪽 — 신호 아님)·반전 테스트(reverse_tested: 1순위 대상의 반전 첫 키 결과, status beyond|short — 신호 아님)·이전 판정 가격 도달(conn_arrival: 가격이 이전에 판정이 끝난 기준 가격에 닿음 — 방향·결말 판정 아님).",
      "items": {
        "type": "object",
        "required": [
          "time",
          "timeframe",
          "kind"
        ],
        "properties": {
          "time": {
            "type": [
              "string",
              "null"
            ],
            "format": "date-time"
          },
          "timeframe": {
            "type": "string",
            "enum": [
              "1w",
              "1d",
              "8h",
              "4h",
              "1h",
              "30m"
            ]
          },
          "kind": {
            "type": "string",
            "enum": [
              "target_selected",
              "signal",
              "signal_resolved",
              "conn_arrival",
              "reverse_failed",
              "reverse_tested"
            ],
            "description": "conn_arrival(이전 판정 가격 도달) = 가격이 이전에 판정이 끝난 가격에 닿았다는 사실. 방향·결말 판정이 아니며 텔레그램으로는 보내지 않는다. reverse_failed(추세 변경 안 됨, 엔진 `judge_failed`) = 1순위 대상의 판정 결과 중 반전이 실패한 것 — side = 유지되는 추세 쪽, price = 그 대상. 신호가 아니라 판정 결과 사실이며(진입·청산 사용은 진입 모드 층의 몫, 게이트는 WATCH) 텔레그램 채널 없음. reverse_tested(반전 테스트, 엔진 `judge_test`) = 1순위 대상의 B 국면 첫 반대 키 결과 — side = 반전 쪽 키, price = 대상, status = beyond(테스트 S 종가가 대상 너머 = 최소 조건 충족)|short. 신호 아님·텔레그램 없음. 보조 유닛의 결과는 표면에 올리지 않는다."
          },
          "side": {
            "type": [
              "string",
              "null"
            ],
            "enum": [
              "buy",
              "sell",
              null
            ],
            "description": "buy=매수 · sell=매도"
          },
          "status": {
            "type": [
              "string",
              "null"
            ],
            "enum": [
              "confirmed",
              "failed",
              "beyond",
              "short",
              null
            ],
            "description": "signal_resolved 의 결말(confirmed|failed) · reverse_tested 의 최소 조건(beyond = 테스트 S 종가가 대상 너머 마감 · short = 못 넘음)"
          },
          "price": {
            "type": [
              "number",
              "null"
            ],
            "description": "signal/signal_resolved=종가 · 그 외=대상 가격"
          }
        }
      }
    },
    "missing_timeframes": {
      "type": "array",
      "items": {
        "type": "string"
      },
      "description": "아직 평가값이 없는 시간대"
    }
  },
  "required": [
    "symbol",
    "as_of",
    "price",
    "timeframes",
    "events",
    "missing_timeframes"
  ]
}
🟢decker.get_view(symbol, tf)

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.

Input Schema

{
  "type": "object",
  "properties": {
    "symbol": {
      "type": "string",
      "description": "e.g. BTCUSDT, XYZ_GOLDUSD (crypto + HL TradFi synthetics; KRX daily lineage not yet covered by view v1)"
    },
    "tf": {
      "type": "string",
      "enum": [
        "30m",
        "1h",
        "4h",
        "8h",
        "1d"
      ],
      "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)."
    }
  },
  "required": [
    "symbol"
  ]
}
⚪decker.get_reading(symbol, tf, include_tfs)

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.

Input Schema

{
  "type": "object",
  "properties": {
    "symbol": {
      "type": "string",
      "description": "e.g. BTCUSDT"
    },
    "tf": {
      "type": "string",
      "enum": [
        "15m",
        "30m",
        "1h",
        "4h",
        "8h",
        "1d",
        "1w"
      ],
      "default": "4h"
    },
    "include_tfs": {
      "type": "string",
      "description": "Comma-separated additional TFs (e.g. '1h,4h,1d')."
    }
  },
  "required": [
    "symbol"
  ]
}
🟢decker.get_signals(symbols, min_progress, action_gate, timeframe, limit)

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.

Input Schema

{
  "type": "object",
  "properties": {
    "symbols": {
      "type": "array",
      "items": {
        "type": "string"
      },
      "description": "Symbol filter (e.g. ['BTCUSDT','ETHUSDT']). Omit for all."
    },
    "min_progress": {
      "type": "number",
      "minimum": 0,
      "maximum": 100,
      "description": "Minimum progress_pct (0-100)."
    },
    "action_gate": {
      "type": "string",
      "enum": [
        "GO",
        "WATCH",
        "HOLD"
      ],
      "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."
    },
    "timeframe": {
      "type": "string",
      "enum": [
        "30m",
        "1h",
        "4h",
        "8h",
        "1d"
      ],
      "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."
    },
    "limit": {
      "type": "integer",
      "minimum": 1,
      "maximum": 100,
      "default": 20
    }
  }
}
🟢decker.get_episodes(symbol, timeframe, limit)

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.

Input Schema

{
  "type": "object",
  "properties": {
    "symbol": {
      "type": "string",
      "description": "e.g. BTCUSDT"
    },
    "timeframe": {
      "type": "string",
      "enum": [
        "30m",
        "1h",
        "4h",
        "8h",
        "1d",
        "1w"
      ]
    },
    "limit": {
      "type": "integer",
      "minimum": 1,
      "maximum": 20,
      "default": 5,
      "description": "number of episodes"
    }
  },
  "required": [
    "symbol",
    "timeframe"
  ]
}
🟢decker.get_trigger_history(symbol, timeframe, since, limit)

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.

Input Schema

{
  "type": "object",
  "properties": {
    "symbol": {
      "type": "string",
      "description": "e.g. BTCUSDT"
    },
    "timeframe": {
      "type": "string",
      "enum": [
        "30m",
        "1h",
        "4h",
        "8h",
        "1d"
      ],
      "description": "Optional — omit for all timeframes."
    },
    "since": {
      "type": "string",
      "description": "ISO8601 lower bound on trigger time (exclusive). Optional."
    },
    "limit": {
      "type": "integer",
      "minimum": 1,
      "maximum": 50,
      "default": 20
    }
  },
  "required": [
    "symbol"
  ]
}
🟢decker.get_positions

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.

Input Schema

{
  "type": "object",
  "properties": {}
}
🟡decker.validate_intent(symbol, side, order_type, timeframe)

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.

Input Schema

{
  "type": "object",
  "properties": {
    "symbol": {
      "type": "string",
      "description": "e.g. BTCUSDT, SILVER, 테슬라 — aliases resolve to the engine symbol (XYZ_SILVERUSD, XYZ_TSLAUSD, …)."
    },
    "side": {
      "type": "string",
      "enum": [
        "buy",
        "long",
        "sell",
        "short"
      ],
      "description": "Proposed order direction (buy/long = +, sell/short = -)."
    },
    "order_type": {
      "type": "string",
      "description": "Optional, informational (market/limit/…) — recorded in the ledger, does not change the state verdict."
    },
    "timeframe": {
      "type": "string",
      "enum": [
        "30m",
        "1h",
        "4h",
        "8h",
        "1d"
      ],
      "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)."
    }
  },
  "required": [
    "symbol",
    "side"
  ]
}
⚪decker.get_user_skills

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).

Input Schema

{
  "type": "object",
  "properties": {}
}
🟡decker.set_skill_overlay(skill_id)

Change active trading skill overlay for this user. Immediately affects all subsequent get_signals calls and downstream channels.

Input Schema

{
  "type": "object",
  "properties": {
    "skill_id": {
      "type": "string",
      "description": "trading_skills.id (e.g. 'aggressive_v0')."
    }
  },
  "required": [
    "skill_id"
  ]
}
🟢decker.place_order(symbol, side, notional_usd)

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.

Input Schema

{
  "type": "object",
  "properties": {
    "symbol": {
      "type": "string",
      "enum": [
        "BTCUSDT",
        "ETHUSDT",
        "SOLUSDT",
        "BNBUSDT",
        "XRPUSDT",
        "DOGEUSDT"
      ],
      "description": "Crypto-6 only for this MCP write path."
    },
    "side": {
      "type": "string",
      "enum": [
        "buy",
        "long",
        "sell",
        "short"
      ],
      "description": "Order direction (buy/long or sell/short)."
    },
    "notional_usd": {
      "type": "number",
      "exclusiveMinimum": 0,
      "description": "Order size in USD (quantity = notional_usd / current price). This is the value checked against the account's tier notional cap."
    }
  },
  "required": [
    "symbol",
    "side",
    "notional_usd"
  ]
}
⚪decker.close_position(symbol, close_fraction)

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.

Input Schema

{
  "type": "object",
  "properties": {
    "symbol": {
      "type": "string",
      "description": "e.g. BTCUSDT, XYZ_GOLDUSD — whatever symbol you hold. Aliases resolve like other tools."
    },
    "close_fraction": {
      "type": "number",
      "exclusiveMinimum": 0,
      "maximum": 1,
      "default": 1,
      "description": "Fraction of the current position to close, 0 < x <= 1. Default 1.0 = full close. E.g. 0.5 closes half."
    }
  },
  "required": [
    "symbol"
  ]
}
🔴decker.update_protective_stops(symbol, sl_price, tp_price, mode)

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.

Input Schema

{
  "type": "object",
  "properties": {
    "symbol": {
      "type": "string",
      "description": "e.g. BTCUSDT — must be a symbol you currently hold."
    },
    "sl_price": {
      "type": "number",
      "exclusiveMinimum": 0,
      "description": "New stop-loss price. Omit to leave the current stop unchanged."
    },
    "tp_price": {
      "type": "number",
      "exclusiveMinimum": 0,
      "description": "New take-profit price. Omit to leave the current target unchanged."
    },
    "mode": {
      "type": "string",
      "enum": [
        "real",
        "virtual"
      ],
      "description": "Only required when both a real and a virtual position are open for this symbol — says which one to modify."
    }
  },
  "required": [
    "symbol"
  ]
}

Community

Rate this Server

Evidence

Recent observations

verifiedversion not recorded14 tools
verifiedversion not recorded16 tools
verifiedversion not recorded16 tools
verifiedversion not recorded15 tools
verifiedversion not recorded15 tools
verifiedversion not recorded14 tools