Skip to main content
Glama
shogo-hs

guidepost-mcp

by shogo-hs

guidepost-mcp

안내 트리 다이어그램을 MCP 경유로 탐색하게 하는 서버. 에이전트가 답변의 라벨을 던지면 다음에 무엇을 확인·안내해야 하는지가 규칙 기반으로 반환된다. 끝까지 탐색하면 안내 완료.

자기 루프형 에이전트는 유연한 대신, 같은 문의라도 매번 다른 경로를 통과한다. 환불·본인 확인처럼 빼놓을 수 없는 응대에서는 이것이 감사에도 에스컬레이션 판단에도 견디지 못한다. 판단이 필요한 곳을 트리 다이어그램으로 외부에 고정하고, 말로 표현하는 부분만 에이전트에게 맡긴다.

CS 전용이 아니다. 트리 다이어그램의 어휘를 도메인에 의존시키지 않았으므로, 절차를 순서대로 진행하는 업무 전반에 사용할 수 있다.

  顧客の発話                      guidepost-mcp (MCP · 8127)
      │                    ┌──────────────────────────┐
  ┌───▼────────┐  values   │ flows/*.yaml ← 起動時に   │
  │  エージェント  ├──────────▶│   メモリ常駐(読むだけ)  │
  │             │◀──────────┤ engine = 純関数で遷移     │
  └────────────┘  next     │ SQLite = runs / steps    │
      │  発話をラベルに        └──────────┬───────────────┘
      │  落とすのはこちら側                │ 読み取り専用
      ▼                              ┌───▼──────────┐
   顧客へ返す                          │ Web UI (SSR)  │ いま樹形図のどこにいるか
                                     └───────────────┘

자연문 → 라벨의 해석은 에이전트 측이 가진다. 서버는 받은 라벨을 보고 전이할 뿐이므로 LLM 호출이 늘어나지 않는다. 실측(Raspberry Pi 5)은 전이 계산이 p95 0.006ms, SQLite 포함 p95 0.76ms, HTTP의 MCP를 통한 엔드투엔드 p95 9.1ms. 음성 응대 1턴의 합계는 약 2.5초이므로, HTTP 포함해도 0.4%에 해당한다. 내역과 그 예산을 어떻게 책정했는지는 docs/research/voice-agent-latency-budget.md.

트리 다이어그램 작성법

flows/<flow_id>.yaml이 1개의 트리 다이어그램. 노드는 4종류뿐이다.

kind

역할

분기

ask

1개의 확인 사항을 묻고, 답변의 라벨로 분기한다

함

tell

1개의 안내를 전달한다

안 함

collect

독립된 여러 항목을 순서 무관하게 모은다

안 함

end

종단. outcome을 가진다

안 함

id: payment_failed
title: 支払いが失敗した
entry: n_error_code
max_unmatched: 3          # 聞き直しの上限
max_branch_fanout: 3      # これより枝が多いと畳まない
branch_depth: 2           # 枝を辿って結末を探す深さ
on_unknown: broaden       # 分からないと言われたとき。broaden / escalate
on_stuck: 原因が絞れないため、決済窓口の担当者に引き継ぐ

nodes:
  - id: n_error_code
    kind: ask
    say: 決済画面に出ているエラーコードを確認する     # 逐語原稿ではなく「何を伝えるか」
    accepts:                                      # ラベル → そのラベルに落とす条件
      E01: カードが拒否された
      E02: 残高不足・限度額超過
    next:
      E01: n_card_age
      E02: n_balance
      __other__: n_symptom        # 想定外のラベルの逃がし先(任意)
      __unknown__: n_generic      # 分からないときの逃がし先(任意)

  - id: n_identity
    kind: collect
    say: 本人確認に必要な情報を集める
    on_unknown: escalate          # 重要な手続きなので畳ませない
    slots:
      order_id:
        ask: 注文番号を聞く
        required: true            # 埋まらないと進めない
      phone: 登録の電話番号を聞く   # 短い書き方(任意扱い)
    next: n_verify

  - id: n_resolved
    kind: end
    outcome: resolved
    say: 解消したことを確認し、対応を締める

say는 축어 원고가 아니라 "무엇을 전할지"의 소재. 말투는 에이전트가 상황에 맞춘다. 1노드 = 1개의 확인 사항 또는 1개의 안내로 유지한다.

작성했으면 검증한다. 도달 불가능한 노드나 행선지가 없는 라벨은 작성 시점에는 동작하므로 실행 시까지 알아차릴 수 없다.

uv run guidepost-mcp lint flows/          # CI でも回している
uv run guidepost-mcp show payment_failed --flows flows   # 樹形図を木で表示
uv run guidepost-mcp drafts               # 預かっている草案の一覧
uv run guidepost-mcp approve refund_request   # 草案を検査し直して flows/ へ移す
uv run guidepost-mcp discard refund_request   # 草案を捨てる

Related MCP server: sop-mcp

MCP 도구

도구

역할

guide_flows(category)

인수 없이 카테고리 목록과 건수, category 지정 시 그 안의 플로우 목록

guide_start(flow_id, subject, agent)

run을 시작. run_id + 첫 번째 노드 + 색인

guide_answer(run_id, choice, values, utterance)

답변을 던짐. 아래 5상태 중 하나가 반환됨

guide_state(run_id)

현재 위치·경로·수집된 값. 복귀 및 인계용

guide_revise(run_id, to_node, clear)

되돌아감. 수정된 값을 버림

guide_close(run_id, outcome, reason)

끝까지 가지 않고 마감함

guide_draft(yaml)

트리 다이어그램을 초안으로서 맡김. lint 지적이 반환됨. 응대에는 나오지 않음

입구 선정은 2단계, 트리 다이어그램 등록은 초안까지만

트리 다이어그램이 늘어나면 전체를 반환할 수 없으므로, guide_flows()는 먼저 카테고리(flows/categories.yaml 에 정의)와 각 건수를 반환하고, guide_flows(category=...)로 그 안의 목록을 반환한다. 어떤 카테고리에도 해당하지 않는다면 억지로 맞추지 말고 트리 다이어그램 없이 응대한다.

guide_draft는 트리 다이어그램을 맡아둘 뿐, flows/에도 guide_flows()에도 나오지 않는다. 사람이 guidepost-mcp approve로 통과시켜야 비로소 정본이 된다. 트리 다이어그램 생성은 이 서버 밖의 작업이며, 응대 중에 생성할 것도 상정하지 않는다(판단의 이유는 docs/adr/0011-draft-intake.md).

답변은 축적되고, 채워진 만큼 자동으로 전진한다

고객이 "E01이 떠 있고, 카드는 3년 전 거예요"라고 한 번에 말하면, 답을 가지고 있는데도 한 문제씩 다시 묻는 것은 피하고 싶다. values에 아는 것을 전부 넘기면, 채워진 만큼 진행하고, 채워지지 않은 첫 번째 노드에서 멈춘다.

  収集済み: {n_error_code: E01, n_card_age: over_1y}

  n_error_code ──E01──▶ n_card_age ──over_1y──▶ n_expiry_check ──?──▶ …
   ✓ 聞かずに通過        ✓ 聞かずに通過           ▲ ここで止まる

건너뛴 노드는 skipped로 반환된다. 이후 노드의 id를 에이전트가 알 수 있도록, guide_start가 색인(각 노드/슬롯이 무엇을 묻는지에 대한 1줄)을 1회만 전달한다.

collect의 순서 무관도 같은 메커니즘. 어떤 순서로 채워도, 갖춰지는 시점에 통과한다.

"모르겠다"로 멈추지 않는다

문의한 사람이 답을 가지고 있지 않은 것은 흔한 일이다. 집요하게 다시 물어봐도 나오지 않는다.

   guide_answer
        ├─ ラベルが accepts にある ──────────▶ advanced / completed
        ├─ accepts に無い ──────────────────▶ unmatched(聞き直す)
        │                                       │ max_unmatched 回で下へ
        └─ choice="__unknown__" ──────────┐   │
                                          ▼   ▼
                               next.__unknown__ があるか
                                  ├─ ある ─▶ advanced(逃がし先へ)
                                  └─ 無い ─▶ on_unknown は
                                              ├─ escalate ─▶ stalled(有人へ)
                                              └─ broaden ──▶ 枝を畳めるか
                                                   ├─ できる ─▶ branched
                                                   └─ 無理 ───▶ stalled

branched는 가지가 확정되지 않은 채, 각 가지의 결말을 나란히 안내하는 상태. "E01이시면 카드사로, E02이시면 잔액을 확인해 주세요"를 구성할 재료가 반환된다. 모든 가지가 합류하는 노드가 있으면 common에 들어가므로 "어느 경우든 마지막에 ○○"로 묶을 수 있다.

환불·본인 확인처럼 모호한 채로 안내하면 해가 되는 절차는 on_unknown: escalate를 작성해 접지 않는다. 접을 수 없는 노드는 lint가 지목하므로, 거기에만 대처하면 된다.

시작

uv sync
uv run uvicorn guidepost_mcp.web:app --host 127.0.0.1 --port 8127
uv run python scripts/mcp_smoke.py            # 実プロトコルで 1 周辿る
uv run python scripts/mcp_smoke.py --parallel # 2 本の run を交互に進める

Web UI는 http://127.0.0.1:8127/. 진행 중인 run이 목록화되고, /r/<run_id>에서 트리 다이어그램 위에 현재 위치·지나온 경로·선행 조회로 건너뛴 노드·가지를 접은 노드가 색상으로 구분된다.

에이전트 측에서는 HTTP의 MCP로 연결한다.

from langchain_mcp_adapters.client import MultiServerMCPClient

client = MultiServerMCPClient(
    {
        "guidepost-mcp": {"url": "http://127.0.0.1:8127/mcp/", "transport": "streamable_http"},
    }
)
tools = await client.get_tools()

버전

판의 정본은 pyproject.toml의 version 하나로, SemVer를 따른다(0.x 동안은 minor에서 파괴적 변경이 들어올 수 있음). 변경 이력은 CHANGELOG.md.

무엇을 바꾸면 파괴적 변경인지는 docs/adr/0009-versioning.md에 정의되어 있다. 요점은 트리 다이어그램의 YAML 스키마와 MCP 도구의 계약(도구명·인수· 반환값의 키·status의 5값)이며, next의 지시문 문면은 포함하지 않는다.

flows/*.yaml의 version은 응대 절차의 판으로, 이 라이브러리의 판과는 무관하다.

설계 배경

왜 라벨 해석을 에이전트 측에 두는지, 왜 "모르겠다"로 가지를 접는지, 왜 Web UI를 읽기 전용으로 했는지는 docs/adr/에 이유와 함께 기록되어 있다 (목록은 docs/adr/README.md). 판단의 재료가 된 조사 자료는 docs/research/에 있다.

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    D
    maintenance
    Provides browser automation capabilities using Playwright's accessibility tree, enabling LLMs to interact with web pages through structured data without screenshots or vision models. It's designed for specialized agentic loops that benefit from persistent state and iterative reasoning over page structure.
    Apache 2.0
  • A
    license
    A
    quality
    A
    maintenance
    Enables AI agents to execute multi-step Standard Operating Procedures step by step, with enforcement of completion at each step, making LLM behavior predictable and auditable.
    5
    3
    Apache 2.0