mcpField
I
IYT Test

IYT Test

リモート
iyt.rycrentals.com科学・教育02 日前に更新
リポジトリ公式サイト

IYT Test について

IYT Test は、Telegram ミニアプリ、ウェブサイトのコンテンツ、公開読み取り専用 MCP サーバーを通じて、セーリング資格や競技規則の学習を支援します。セーリング学習者や AI アシスタント向けに、問題集、理論記事、模擬試験、解答確認、図を英語とロシア語で提供します。

主な機能

  1. 01複数のセーリングレベルの問題集
  2. 02模擬試験と解答確認
  3. 03理論記事とセクション検索
  4. 04SVG のセーリング図
  5. 05英語とロシア語のコンテンツ

活用シーン

  1. 01セーリングレベル別の問題を練習
  2. 02資格試験の模擬試験を実施
  3. 03解答に関連する理論を復習
  4. 04学習用のセーリング図を取得

MCP 対応

公開リモート MCP サーバーは、読み取り専用ツールで問題集、理論記事、解答、試験、図を提供します。ログイン不要でユーザー状態を保存せず、`en` と `ru` の言語引数に対応します。

設定

リモートサーバーはインストール不要です。クライアントを選んで設定をコピーするか、ワンクリックで導入できます。

エンドポイントhttps://iyt.rycrentals.com/api/mcp
インストールコマンドをコピー
Claude CodeTerminal
Cursor.cursor/mcp.json
VS Code.vscode/mcp.json
Claude Desktopclaude_desktop_config.json
Windsurf~/.codeium/windsurf/mcp_config.json

コマンドはターミナルで実行し、JSON は各クライアントの MCP 設定に貼り付けて再起動します。認可が必要なサーバーは初回接続時にログインを求めます。

ツール

詳細

IYT テスト

IYT 認定レベル向けの練習問題です。Telegram ミニアプリとウェブサイトで提供します。各問題は「前方にこの標識が見えます。安全な水域はどこですか?」のような状況を示し、可能な場合は図で表します。選択肢は4つで、ルールを示す1行の注記が付きます。最初のレベルは Bareboat Skipper(100問、10トピック)です。

ステータス(2026-11-02):デザインと問題バンクが完成しました。Telegram ミニアプリ(練習、模擬試験、進捗、プロフィール)と小規模なボットを開発し、デプロイ済みです(Vercel)。ウェブサイトは未着手です。

リポジトリの内容

README.md                       this file
docs/
  PLAN.md                       goal, decisions, next steps
  question-bank.md              JSON format of a bank, authoring rules, how to build it
  figures.md                    the figure spec: every type, its fields, an example
  figure-style.md               the agreed look of the rendered figures (cameras, looks, own boat, lights, annotations)
  design.md                     look & feel, components, the 21 screens, how to use the viewer
  data-model.md                 proposed database (Supabase) and how progress is computed
  theory.md                     the theory articles: format of an article, authoring rules, check and build
  superpowers/plans/            implementation plans (theory articles: 2026-11-05-theory-articles.md)
  design/
    flows.html                  hi-fi user flows (viewer: pages / overview, day / night)
    questions.html              the whole bank as the student sees it, filter by topic
    flows.css  flows.js         viewer + test UI pieces
    app.css                     app tokens and base components (day and night)
    test-icons.js               the app's icon set (24 grid, 2 px line) + svg()/paintIcons(), shared by the viewer and the app
    icons.html                  the icon sheet: every glyph at 24 px and in the topic circle, day / night
    icons.js                    older base set (Telegram chrome in the mockups; a few basics follow Lucide)
    figures.js                  figure generator (JSON spec → SVG)
    figure-style-spike.html     reference renderer for figure-style.md (three.js from a CDN; open over HTTP)
    figure-schematic.js         plan-view schematic renderer (the companion diagram to every realistic figure)
    figure-style/               sample renders of the ten example questions; hires/ at 2560 × 1600, schematic/ their plan views
    logo-black.svg              RYC logo
data/
  build_bank.py                 source of the Bareboat Skipper bank — edit here, then run
  build_level.py                builds the other levels from bank/<level>/<topic>.json (+ .ru.json)
  bank/<level>/<topic>.json     VHF Radio Operator, International Crew, Flotilla Skipper: 20 questions per topic; Charter Check-in: 50; Yachtmaster Coastal, Offshore and Ocean, Racing Rules of Sailing: 100
  questions/<level>.json        the built banks the apps read
  questions/<level>.ru.json     Russian translation of each bank (overlay)
  i18n.py                       extract strings to translate / check an overlay
  theory/<level>/<topic>.json   theory articles, one per topic of every level (+ .ru.json): 90 in all, each with figures
  check_theory.mjs              checks the articles against docs/theory.md and the banks (npm run check:theory)
miniapp/
  index.html  app.js  app.css   the Telegram mini app (static, no framework, no backend)
  build.mjs                     builds miniapp/dist (the folder to host): the app, design files, fonts and minified banks,
                                each linked file renamed after its content (h/…) so phones cache it for good, and the
                                list of banks written into index.html so only the current level's bank loads at start
  fonts/                        Merriweather and Carlito (woff2, Latin + Cyrillic, OFL), served with the app
  pages.mjs  site.css            the site around the app: a page per level and per theory article (EN + RU), sitemap, llms.txt
  site.mjs                      the public address, the bot and the IndexNow key
  indexnow.mjs                  npm run seo:ping: tells Bing and Yandex which pages changed
bot/
  core.mjs                      the bot's replies: /start /exam /progress /settings open the app, /daily asks a question
  daily.mjs                     the daily question of the day to everyone who has it on
  bot.mjs                       runs core.mjs by long polling (local testing)
  scripts/setup.mjs             sets the bot's name, descriptions, commands and menu button
  scripts/webhook.mjs           points Telegram at the Vercel webhook, or removes it
api/
  telegram.mjs                  Vercel function: Telegram's webhook, runs core.mjs
  daily.mjs                     Vercel cron (09:00 UTC daily): runs bot/daily.mjs
  settings.mjs                  the app's question-of-the-day switch (users.daily_question), checked with Telegram initData
  admin.mjs                     every student's results, flagged and reported questions (admins can take a flag off), joins/answers/wrong answers per hour and day for the admins (ADMINS in settings.mjs — @fullcrimp; ADMIN_USERNAMES adds more)
  mcp.mjs                       the MCP server: the banks and the theory articles as tools for AI assistants (public, read-only)

ミニアプリ

npm run dev                     # http://localhost:5173 — works in a normal browser too

画面は docs/design/flows.html に従っています。A1–A9 は練習(設定シート、確認 → 解説 → 次へ、結果、間違えた問題)、B1–B5 は模擬試験(全トピックから出題される40問、アプリを閉じている間は一時停止するタイマー、フラグ+グリッド、合否)、C1 は進捗、C2 はプロフィール(テーマ、シャッフル、リセット)です。習熟度は同じ問題に2回連続で正解すると達成となります。進捗は Telegram CloudStorage(ブラウザーでは localStorage)にユーザーごとに保存されるため、現時点ではサーバーやデータベースはありません。Telegram 内ではネイティブの戻る、メイン、セカンダリボタンとハプティクスを使用し、Telegram の外では同じバーを描画します。 ディープリンク:?screen=exam|progress|profile|practice|level、または同じ値を指定した startapp=。 言語:英語とロシア語のインターフェースに対応しています(プロフィールで切り替えるまでは Telegram の言語設定に従います。選択した言語はテーマと同様に保存されます)。1000問すべてが data/questions/bareboat-skipper.ru.json に翻訳されています(用語についてはdocs/glossary-ru.mdを参照)。詳しくはdocs/question-bank.mdをご覧ください。

https://iyt.rycrentals.com で公開中で、@iyt_test_bot に接続されています。ボットのメニューボタンからアプリを開けます。また、ボット自体も同じ Vercel プロジェクト上のウェブフック(api/telegram.mjs)として動作します。最初から再設定するには、以下の手順を実行します。

  1. .env.local に TELEGRAM_BOT_TOKEN、WEBAPP_URL、TELEGRAM_WEBHOOK_SECRET(openssl rand -hex 32)を設定し、Vercel プロジェクトの Production 環境にも同じ3つを設定します。
  2. npx vercel deploy --prod を実行します。miniapp/dist をビルドし、ウェブフック関数も同じ場所にデプロイします。
  3. npm run bot:setup を実行します。名前、説明、コマンド、メニューボタン(アプリへのリンク)を設定します。 次に、@BotFather でボットを Main Mini App に設定します(Bot Settings → Configure Mini App → Enable Mini App、WEBAPP_URL を送信)。ボットのプロフィールに「開く」ボタンが表示され、t.me/iyt_test_bot?startapp=<screen> リンクからアプリを直接開けるようになります。Telegram にはこれを設定する API がありません。npm run bot:setup -- --check を実行すると、有効になっているか確認できます。
  4. npm run bot:webhook を実行し、Telegram が更新を WEBAPP_URL/api/telegram に送信するよう設定します(-- --check を付けると状態を確認できます)。

ボットの変更をローカルで試すには、npm run bot:webhook -- --delete を実行してから npm run bot(ロングポーリング)を実行します。終了後に再度 npm run bot:webhook を実行してください。Telegram はウェブフックまたはポーリングのいずれか一方にのみ配信します。

今日の問題

毎日(Vercel cron、UTC で 0 9 * * * — ドバイ時間 13:00、モスクワ時間 12:00)、ボットは有効にしている各ユーザーに、A〜D のボタン付きのテキスト問題を 1 問送信します。回答と解説は同じメッセージに返されます。その日に出題される問題は全員同じです。ボットは、メッセージを送信した各ユーザーを Supabase の users に保存します(daily_question はデフォルトで有効)。

  • ユーザーごと:今日の問題の下、および /settings に切り替えボタンがあります(「今日の問題:オン/オフ」)。
  • ボット全体:Vercel の環境変数で DAILY_QUESTION=off にすると、全員への送信が停止します(ユーザー個別の設定はそのままです)。
  • ボットをブロックしたユーザーにはその旨が記録され(blocked_at)、再びメッセージを送信するまで配信対象から除外されます。

Vercel で必要なもの:SUPABASE_URL、SUPABASE_SECRET_KEY、CRON_SECRET(openssl rand -hex 32)、およびマイグレーション supabase/migrations/20261102150000_daily_question.sql。試すには、npm run bot:daily -- --to <your chat id> を実行します(ロシア語にするには --ru を追加)。今日の問題が指定したチャットに送信されます。npm run bot:daily -- --dry を実行すると、配信対象の人数を数えます。

このバージョンには含まれません(docs/data-model.md にある Supabase バックエンドが必要です):DE/ES、連続記録リマインダー、ウェブサイトとのデバイス間同期、理論解説、共有画像。

検索エンジンと AI アシスタント

検索エンジンや多くの AI クローラーは JavaScript を実行せずにページを読み込むため、ビルドではアプリに加えて、サイトをプレーンなページとして書き出します(miniapp/pages.mjs。アプリ独自の CSS に重ねて miniapp/site.css でスタイルを設定)。公開先は https://iyt.rycrentals.com です(miniapp/site.mjs の SITE)。

アドレスページ
/アプリ。<noscript> 内の Home のコピーから、すべてのレベルにリンクします
/<level>レベル:問題、トピック、模擬試験、および記事付きの全トピック
/<level>/<topic>トピックの理論記事と図、その後にサンプル問題(各セクションにつき 1 問。図がある場合は図付き)と、回答、解説、および説明セクションへのリンク
/aboutIYT Test の内容と対象外の内容、著者、MCP サーバー
/ru、/ru/<level>、/ru/<level>/<topic>、/ru/about同じ内容のロシア語版。/ru にはレベルの一覧が表示されます

各ページには専用のタイトルと説明、canonical リンク、別の言語版への hreflang リンク、リンクプレビュー用タグ、および構造化データ(パンくずリスト、トピックページの Article と Quiz)があります。手作業で記述するのは pages.mjs 内の文字列だけです。新しい記事やレベルを追加すると、次回のビルドでページが生成されます。各セクションの冒頭文(docs/theory.md の qa。学習者が尋ねそうな質問に 1、2 文で答えるもの)は、見出しの下と、検索エンジンや AI アシスタントが引用する文章を含むページの FAQPage データに追加されます。ビルドではさらに、robots.txt(AI クローラーを名指しして許可します。コンテンツは無料で、MCP サーバーも提供しているため、検索と学習の両方を許可します)、sitemap.xml(各ページと別言語版)、llms.txt(AI アシスタント向けのサイトマップ)、404.html、IndexNow キーファイル、pages.json(各アドレスとそのページのハッシュ)も書き出します。npm run dev は、Vercel と同様に(cleanUrls)、ページを拡張子なしのアドレスで配信します。

本番環境にデプロイした後:

  • npm run seo:ping を実行すると、前回の通知以降に新規作成、変更、削除されたページを Bing と Yandex に(IndexNow 経由で)通知します(公開中の pages.json と、git の対象外である miniapp/.indexnow-sent.json を比較します)。-- --dry を付けると対象の一覧を表示し、-- --all を付けるとすべてのページを送信し、-- --check を付けるとキーファイルが公開されているかだけを確認します。
  • 手動で一度だけ設定します(いずれも自分のアカウントが必要です):Google Search Console に iyt.rycrentals.com を追加し、指定された DNS TXT レコードで確認します(rycrentals.com ゾーンに設定)。その後、sitemap.xml を送信します。次に、Bing Webmaster Tools で「Import from Google Search Console」を選択します。最後に、Yandex Webmaster でサイトを追加し、DNS またはメタタグで確認して、サイトマップを追加します。

MCP サーバー

api/mcp.mjs は、問題バンクと理論記事を AI アシスタント(Claude、ChatGPT、およびModel Context Protocolに対応するその他のもの)に提供します。学生は https://iyt.rycrentals.com/api/mcp をリモート MCP サーバー(カスタムコネクター)として追加し、自分のアシスタントで学習できます。これは公開されており、読み取り専用です。サインインは不要で、何も保存されず、アプリがすでに提供しているものだけを返します。 接続方法は https://iyt.rycrentals.com/mcp に記載されています(miniapp/pages.mjs の mcpBody にあり、ツール一覧もあります。ツールを追加したら、そこに行を追加してください)。アプリのホーム画面では、フィードバックカードの上にあるカードからこのページにリンクしています。 サイト、アプリ、ボット、サーバーがユーザーについて保存する情報は https://iyt.rycrentals.com/privacy に記載されています(miniapp/pages.mjs の文字列、privBody)。いずれかが新たな情報を保存するようになったら、ここを変更してください。

ツール提供する内容
list_levelsレベル、トピック、試験の設定、記事があるトピック
get_questionsレベル、トピック、難易度を指定したランダムな問題(答えは含まれません)
check_answer正誤、正解の選択肢、注記、および解説が載っている理論セクション
search_questions単語で検索した問題
start_mock_exam, grade_examトピック全体にわたる試験相当の問題セット。その後、得点、合格または不合格、間違えた問題、読むべき内容を返します
question_of_the_dayその日にボットが送信する問題
list_theory, get_theory, search_theory記事とそのセクション。図へのリンク付きのテキストとして提供します
explain_question答えと、その根拠となるセクションを含む問題
practice_section理論セクションで扱う問題
get_figureSVG マークアップ形式の図

すべてのツールは lang(en または ru)を受け取ります。まだ翻訳されていない内容は英語で返されます。図にはそれぞれ専用のアドレスがあります。問題の図は /api/mcp?figure=bs-001、理論セクションの n 番目の図は /api/mcp?figure=<level>/<topic>/<section>/<n> です。図は docs/design/figures.js により、当日の色を指定して描画される SVG 画像です。カードの図(スクリプト、チェックリスト)はテキストとして提供されます。

依存関係も状態もありません。この関数は HTTP 経由で JSON-RPC(initialize、tools/list、tools/call)に応答し、同梱された問題バンク、記事、figures.js を読み込みます(vercel.json → includeFiles)。そのため、デプロイすると新しい記事がアシスタントに反映されます。デプロイに対して試すには、次を実行します。

curl -s https://iyt.rycrentals.com/api/mcp -H 'content-type: application/json' \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"get_questions","arguments":{"level":"bareboat-skipper","count":1}}}'

公式 MCP Registry には、server.json に基づいて io.github.nikolai-shilin/iyt-test として登録されています(Glama と PulseMCP はレジストリの内容を複製します)。新しいツールや変更した説明は、新しい version(api/mcp.mjs の serverInfo.version も同様)とともに公開します。公開済みのバージョンは変更できません。

brew install mcp-publisher
mcp-publisher validate
mcp-publisher login github      # as nikolai-shilin: the name must start with io.github.<your GitHub login>/
mcp-publisher publish

表示する

画面を確認するには、docs/design/flows.html をブラウザーで直接開きます。questions.html は問題バンクの JSON を読み込むため、ローカルサーバーが必要です。

npx serve docs/design          # then http://localhost:3000/questions.html

フロー内では矢印キーでページを移動します。#A4、#D1 は画面へのリンクです。「Overview」を選ぶと、すべてのレーンを一度に表示します。

問題を編集する

問題は data/build_bank.py に Python の呼び出しとして記述されています(問題、正解、3 つの誤答、注記、参照先、図の仕様)。これを実行すると、答えが A~D に均等に分散された JSON が再生成されます。

python3 data/build_bank.py

その後、questions.html を再読み込みして問題を確認します。形式とルールについては、docs/question-bank.md を参照してください。 図の種類については、docs/figures.md を参照してください。

レベル

レベル問題数ステータス
VHF Radio Operator200 (10 トピック × 20)完了 — data/questions/vhf-radio-operator.json
International Crew200 (10 トピック × 20)完了 — data/questions/international-crew.json
Flotilla Skipper200 (10 トピック × 20)完了 — data/questions/flotilla-skipper.json
Bareboat Skipper1000 (10 トピック × 100)完了 — data/questions/bareboat-skipper.json
Racing Rules of Sailing (IYT のコースではありません)1000 (10 トピック × 100)完了 — data/questions/racing-rules.json
Charter Check-in (IYT のコースではありません)500 (10 トピック × 50)完了 — data/questions/charter-checkin.json
ICC (International Certificate of Competency)—予定
Yachtmaster Coastal1000 (10 トピック × 100)完了 — data/questions/yachtmaster-coastal.json
Yachtmaster Offshore1000 (10 トピック × 100)完了 — data/questions/yachtmaster-offshore.json
Yachtmaster Ocean1000 (10 トピック × 100)完了 — data/questions/yachtmaster-ocean.json

順序は IYT のコース進行に沿っています。 Racing Rules of Sailing(World Sailing、2025–2028;Russian Sailing Federation によるロシア語版 ППГ-25)は、レースコース上の状況(優先権、マークルーム、スタート、ペナルティ、プロテスト)を扱うため、IYT のレベルの後に続きます。Charter Check-in は、ベースでの土曜日に行うチェックインです。書類と契約、艇の確認、セール、エンジン、電気系統、水とガス、計器、安全装備、アンカー関連装備とディンギー、備品、デポジット、金曜日のチェックアウトを扱います。

問題は学習用に作成されたもので、IYT の公式試験問題ではありません。模擬試験のデフォルト設定(Bareboat Skipper と Flotilla Skipper は 60 分で 40 問、Yachtmaster Coastal と Offshore は 90 分で 50 問、Yachtmaster Ocean は 120 分で 50 問、VHF と International Crew は 45 分で 30 問、合格点は 70 %)は、公開前に最新の IYT 試験に照らして確認する必要があります。

コメント

MCP は初めてですか?

プロトコルの概要から最初のサーバーの導入まで、よくある疑問にまとめて答えます。

AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。