Skip to main content
Glama
geo-explorer

geo-explorer

by juanidives

Geo-Explorer

Geo-Explorer とは

Geo-Explorer は、DIO (Digital Innovation One) に想定した、架空の学習プラットフォームです。このプロジェクトは、コードチャレンジと証明書の発行を備えた学習パスシステムをシミュレーションします。

以下の学習の基盤として役立ちます。

  • TypeScript での CLI ツール開発

  • プラットフォームのロジックを、AI エージェント(Bob、Claude Desktop、Cursor など)から呼び出し可能なツールとして公開する MCP Server の構築

  • チャットからツールを直接呼び出すための、Bob における ローカルスラッシュコマンド の定義

  • カバレッジ 100% を目指すユニットテストの実践


Related MCP server: LearnFlow AI

プロジェクト構成

geo-explorer/
│
├── commands/               # Comandos CLI executáveis via npm run
│   ├── lib/
│   │   └── trilhas.ts      # Leitura de data/trilhas_dio.json e função findTrilha()
│   ├── trilha.ts           # /trilha <tecnologia>
│   ├── desafio.ts          # /desafio <tecnologia> [nivel]
│   └── certificado.ts      # /certificado --nome "<nome>" --tech "<tecnologia>" (flags) ou posicional
│
├── data/
│   └── trilhas_dio.json    # Base de dados com 35 trilhas DIO
│
├── mcp/                    # MCP Server (pacote independente)
│   ├── src/
│   │   └── index.ts        # Entry-point do servidor MCP (stdio transport)
│   ├── build/              # Saída compilada (gerada por npm run build, não versionada)
│   ├── package.json
│   ├── tsconfig.json
│   └── README.md           # Documentação específica do servidor MCP
│
├── tests/                  # Testes unitários (Vitest)
│   ├── trilha.test.ts
│   ├── desafio.test.ts
│   └── certificado.test.ts
│
├── .bob/
│   ├── commands/           # Slash commands locais do Bob
│   │   ├── trilha.md
│   │   ├── desafio.md
│   │   └── certificado.md
│   ├── mcp.example.json    # Template de registro do MCP Server (versionado)
│   └── mcp.json            # Configuração local do MCP Server (não versionada)
│
├── package.json
├── tsconfig.json
└── vitest.config.mts

実行方法

前提条件

  • Node.js ≥ 18

  • npm ≥ 9

インストール

# Na raiz do projeto
npm install

# Para o servidor MCP (pacote separado)
cd mcp
npm install

ビルド(型チェック)

# Raiz — verifica os tipos sem emitir arquivos
npm run build

# MCP Server — compila TypeScript para JavaScript em mcp/build/
cd mcp
npm run build

MCP サーバーのビルドは、サーバーを登録する前に少なくとも 1 回実行しておく必要があります。


コマンドの使い方

3 つの CLI コマンドは、プロジェクトのルートで npm run から実行します。


/trilha <tecnologia>

テクノロジーの名前(または名前の一部)をもとに、学習パスの完全な学習プランを表示します。検索は 大文字と小文字を区別せず、部分一致にも対応しています。

npm run trilha -- javascript

出力:

╔══════════════════════════════════════════════════════╗
  🎯  PLANO DE ESTUDOS — JAVASCRIPT DEVELOPER
╚══════════════════════════════════════════════════════╝

  Tecnologia   : JavaScript
  Nível        : Básico
  Total de XP  : 12.000 XP
  Acesso       : Por período
  Promoção     : ✅ Disponível
  Lives ao vivo: 4

── MÓDULOS ──────────────────────────────────────────
  1. Fundamentos de JavaScript e ambiente de execução
  2. Tipos de dados, variáveis e operadores
  3. Estruturas de controle e funções
  4. Manipulação do DOM e eventos
  5. ES6+: arrow functions, promises e async/await
  6. Projeto final: aplicação web interativa

── BADGES DISPONÍVEIS ───────────────────────────────
  🏅 JS Fundamentals
  🏅 DOM Master
  🏅 ES6+ Hero

  Bons estudos! 🚀

/desafio <tecnologia> [nivel]

ランダムなコードチャレンジを生成します。nivel パラメーターはオプションです。省略すると、学習パスに登録されているレベルが使われます。レベルに指定できる値は、básico、intermediário、avançado です(アクセントの有無は問わず、大文字と小文字も区別しません)。

# Sem nível (usa o nível da trilha)
npm run desafio -- typescript

# Com nível explícito
npm run desafio -- python avançado

出力(例):

╔══════════════════════════════════════════════════════╗
  ⚔️   DESAFIO DE CÓDIGO — TYPESCRIPT
╚══════════════════════════════════════════════════════╝

  Nível      : Intermediário
  Trilha base: Formação TypeScript Fullstack

── ENUNCIADO ────────────────────────────────────────

  Implemente uma classe Stack (pilha) com os métodos push, pop, peek e isEmpty.

── CRITÉRIOS DE AVALIAÇÃO ───────────────────────────

  ✔  Código legível e bem estruturado
  ✔  Tratamento de casos extremos (edge cases)
  ✔  Complexidade de tempo e espaço adequada ao nível
  ✔  Testes mínimos demonstrando o funcionamento

  Boa sorte! 💪

/certificado

Markdown 形式の架空の証明書を発行します。証明書 ID は決定的です——受講者名と学習パス ID から生成されます。

このコマンドは、引数の渡し方として 2つの形式 に対応しています。

# Forma recomendada — flags explícitas; cada flag coleta todos os tokens
# até a flag seguinte, então valores com espaços funcionam normalmente
npm run certificado -- --nome "Maria Silva" --tech "TypeScript"
npm run certificado -- --nome "Ana Lima" --tech "Data Science"

# Forma posicional — o primeiro argumento vira nome e o segundo vira tecnologia;
# aspas fazem o shell entregar cada valor como um único elemento de argv,
# então espaços dentro de cada valor funcionam normalmente
npm run certificado -- "Ana Lima" "TypeScript"
npm run certificado -- "Ana" "Data Science"

位置指定形式では、パーサーはちょうど 2 つの引数を受け取ります(argv[0] → 氏名、argv[1] → テクノロジー)。より明示的な構文を使いたい場合や、シェルの引用符に依存せずに済ませたい場合は、--nome と --tech フラグを使用してください。

出力(Markdown):

# 🎓 CERTIFICADO DE CONCLUSÃO

---

**A Digital Innovation One certifica que**

## Maria Silva

**concluiu com êxito a trilha:**

# Formação TypeScript Fullstack

---

| Campo              | Detalhe                            |
|--------------------|------------------------------------|
| **Tecnologia**     | TypeScript                         |
| **Nível**          | Intermediário                      |
| **Módulos**        | 9 módulos concluídos               |
| **XP conquistado** | 22.000 XP                          |
| **Lives ao vivo**  | 6 aulas                            |
| **Emitido em**     | <data de hoje>                     |
| **Certificado ID** | `DIO-002-XXXXXXXX`                 |

---

### Badges conquistadas

- 🏅 TS Beginner
- 🏅 TS Advanced
- 🏅 Fullstack Badge

ファイルへのリダイレクト: npm run certificado -- --nome "Maria Silva" --tech "TypeScript" > certificado.md


Bob のチャットでの使い方

このプロジェクトには、.bob/commands/ に ローカルスラッシュコマンド が 3 つ定義されています。Bob でプロジェクトを開くと、チャット内で直接使用できるようになります。

コマンド

構文

説明

/trilha

/trilha <tecnologia>

commands/trilha.ts を実行し、学習プランを表示する

/desafio

/desafio <tecnologia> [nivel]

commands/desafio.ts を実行し、生成されたチャレンジを表示する

/certificado

/certificado "<nome>" "<tecnologia>"

commands/certificado.ts を実行し、証明書を上描画する

チャットでの使用例:

/trilha react
/desafio java intermediário
/certificado "Ana Lima" "Data Science"

Bob が引数を解釈し、正しいコマンドを組み立てて、チャット内に整形された出力を表示します。


テストの実行方法

# Executa os testes sem cobertura
npm test

# Executa os testes com relatório de cobertura
npm run test:coverage

現在の結果

 ✔ tests/trilha.test.ts        (14 testes)
 ✔ tests/certificado.test.ts   (24 testes)
 ✔ tests/desafio.test.ts       (20 testes)

 Test Files  3 passed (3)
      Tests  58 passed (58)
   Duration  1.71s

 % Coverage report from v8
------------------|---------|----------|---------|---------|
 File             | % Stmts | % Branch | % Funcs | % Lines |
------------------|---------|----------|---------|---------|
 All files        |     100 |      100 |     100 |     100 |
  commands        |     100 |      100 |     100 |     100 |
   certificado.ts |     100 |      100 |     100 |     100 |
   desafio.ts     |     100 |      100 |     100 |     100 |
   trilha.ts      |     100 |      100 |     100 |     100 |
  commands/lib    |     100 |      100 |     100 |     100 |
   trilhas.ts     |     100 |      100 |     100 |     100 |
------------------|---------|----------|---------|---------|

Statements : 100% (49/49) | Branches : 100% (28/28) | Functions : 100% (14/14) | Lines : 100% (43/43)

MCP Server

公開される機能

mcp/src/index.ts の MCP サーバーは、commands/ 内のコマンドロジックを直接再利用し、次の 4 つのツールを公開しています。

ツール

パラメータ

説明

listar_tecnologias

(なし)

利用可能なすべてのテクノロジーを、レベルと合計 XP 付きで一覧表示する

buscar_trilha

tecnologia (文字列)

指定したテクノロジーの完全な学習プランを返す

gerar_desafio

tecnologia (文字列)、nivel (任意オプション)

ランダムなコードチャレンジを生成する

gerar_certificado

nome (文字列)、tecnologia (文字列)

Markdown 形式の証明書を発行する

使用されるトランスポートは stdio です——サーバーは MCP クライアントによって子プロセスとして起動されます。

Bob への登録方法

  1. サーバーをビルドします(必要なのは1回だけです)。

    cd mcp
    npm install
    npm run build
  2. 設定テンプレートをコピーします:

    cp .bob/mcp.example.json .bob/mcp.json
  3. .bob/mcp.json を編集し、パスを自分のマシンの絶対パスに置き換えます:

    {
      "mcpServers": {
        "geo-explorer": {
          "command": "node",
          "args": ["/caminho/absoluto/para/geo-explorer/mcp/build/mcp/src/index.js"]
        }
      }
    }
  4. Bob はファイルを保存すると MCP サーバーを自動的に再読み込みします。その後、geo-explorer は Bob の MCP パネルに接続済みサーバーとして表示されます。

.bob/mcp.json は .gitignore に含まれているため、各開発者が自分のローカル絶対パスを管理します。


実施した改善

手動テストで見つかった修正点

ハッピーパス以外のケースも検証したところ、初期のテストでは検出されない 2 つの欠陥が明らかになりました。

  • /certificado は、テクノロジー名に空白が含まれる場合("Data Science")に停止しました。解析が引数の位置に依存しており、氏名の終わりを判定できていませんでした。明示的な --nome と --tech フラグで修正し、位置指定モードはフォールバックとして残しました。

  • /trilha は、実際の名前の代わりに "Módulo 1, Módulo 2..." を表示していました。コードが numero_de_modulos フィールドからラベルを生成し、JSON 上の modulos 配列を無視していたためです。もデータの方が正しく、読み取る側が正しく読んでいませんでした。

  • findTrilha は、空の入力に対してカタログの最初の学習パスを返しました。これは "".includes("") が常に真だからです。バリデーションは CLI にはありましたが、Zod スキーマが空白文字を受け入れてしまう MCP サーバー側にはありませんでした。語源で修正しました。

推定ではなく測定によるカバレッジ

目標はカバレッジ 70% でした。数値を主張する代わりに、Vitest の v8 プロバイダーを設定して実際に測定し、レポートをファイルに出力し、再現可能な npm スクリプトを作成しました。CLI エントリーポイントは明示的な理由を付けて計算対象から除外し、残った未カバーのブランチにはテストを追加しました。結果: テスト可能なロジックに対するカバレッジは 100%、テスト数は 59 です。

純粋ロジックの分離

各コマンドは、2 つの層にリファクタリングしました。エクスポートされる純粋関数と、require.main === module ガードによって分離された run() 関数です。これにより、process.argv のモックなしでテストが可能になり、MCP サーバーは重複なしで同じロジックをインポートできるようになりました。

バージョン管理対象外のローカル設定

.bob/mcp.json にはマシンの絶対パスが必要です。自分のコンピュータでしか動かないパスであってもバージョン管理する代わりに、プレースホルダー入り .bob/mcp.example.json をバージョン管理し、実際のファイルは無視しました——.env.example と同じパターンです。

生成ドキュメントのレビュー

エージェントが生成したドキュメントを 1 行ごとにレビューしたところ、不正確な記述がありました。学習パスの数の誤り(35 ではなく 15)、コードと一致しないパーサーの記述、そしてトレードオフを認める代わりに冗長なフィールドを正当化するモデリング上の説明などです。これらはすべて、コードと照合して修正しました。


学んだこと

  • エージェントは生成は速いが、検証はしない。 有効だったサイクルは常に同じでした。指示する → 出力を読み、既読する → エラーパスをテストする → 修正する、という流れです。このプロジェクトの 3 つのバグはすべて手動テストで見つかり、エージェントが「完了」と報告した内容の中では見つかりませんでした。エージェントは自分のパーサーの説明を 2 回誤りました。意図した動作を書いており、実際のコードを書いていないのです。

  • 「数字を主張すること」は「数字を持つ」こととは別だということを。 参照プロジェクトは、カバレッジツールを何も導入していないにもかかわらず、カバレッジ 100% を宣言していました。これは「言う」ことと「実証」することの違いであり、その違いは誰かが見ようとしなければないままです。

  • 「デフォルトで安全な(社員)」とは限らない選択肢。 元の指示は credential.helper store を使うものでしたが、これはトークンを平文でディスクに保存します。私は、同じ要件にを暗号化ストレージで満たす Git Credential Manager に変更しました。GitHub のトークンはユーザー環境変数に置き、プロジェクトのファイルには一度も置きませんでした。これは、リポジトリに資格情報を送信しないように求める課題のガイドラインにも沿った判断です。

  • 「決定を文書化」することは「コードを文書化」することは違います。 ARQUITETURA.md の各セクションが「問題」「破棄した代替案」「選択理由」を記録するようになって初めて、そのファイルは有用になりました。コードが何をしているかを記述することは冗長です——コードはすでにそこにあるのですから。


Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    D
    maintenance
    A comprehensive learning platform for Model Context Protocol development that teaches MCP concepts through hands-on modules including text processing, file operations, and database integration. Designed as an educational tool with progressive difficulty levels from basic to advanced MCP server development.
    MIT
  • A
    license
    Not graded
    quality
    D
    maintenance
    AI-powered MCP server that transforms learning by finding best YouTube tutorials, generating personalized learning paths, and tracking progress for any tech skill.
    11
    MIT
  • A
    license
    A
    quality
    D
    maintenance
    An MCP server that exposes certifications, projects, and an AI engineering learning roadmap as callable tools for MCP clients like Claude Desktop.
    4
    1
    MIT