Skip to main content
Glama
juanidives

geo-explorer

by juanidives

Geo-Explorer

Что такое Geo-Explorer

Geo-Explorer — это вымышленная учебная платформа, вдохновлённая DIO (Digital Innovation One). Проект имитирует систему учебных треков с заданиями по коду и выдачей сертификатов.

Он служит основой для изучения:

  • Разработки CLI-инструментов на TypeScript

  • Создания MCP-сервера, который предоставляет логику платформы как инструменты, вызываемые ИИ-агентами (Bob, Claude Desktop, Cursor и др.)

  • Определения локальных slash-команд в 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-сервера нужно выполнить хотя бы один раз перед его регистрацией.


Как использовать команды

Три 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 трека.

Команда принимает две формы передачи аргументов:

# 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"

В позиционной форме парсер ожидает ровно два аргумента (argv[0] → имя, argv[1] → технология). Используйте флаги --nome и --tech, если предпочитаете более явный синтаксис или хотите не зависеть от кавычек в shell.

Вывод (в 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

Проект определяет три локальные slash-команды в .bob/commands/. После открытия проекта в 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-сервер в mcp/src/index.ts напрямую переиспользует логику команд из commands/ и предоставляет четыре инструмента:

Инструмент

Параметры

Описание

listar_tecnologias

(нет)

Список всех доступных технологий с уровнем и общим XP

buscar_trilha

tecnologia (строка)

Возвращает полный план обучения по технологии

gerar_desafio

tecnologia (строка), nivel (необязательно)

Генерирует случайное задание по коду

gerar_certificado

nome (строка), tecnologia (строка)

Выдаёт сертификат в Markdown

Используемый транспорт — stdio — сервер запускается как дочерний процесс клиента MCP.

Как зарегистрировать в Bob

  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 появится как подключённый сервер в панели MCP в Bob.

Файл .bob/mcp.json находится в .gitignore — каждый разработчик хранит свой собственный абсолютный путь локально.


Выполненные улучшения

Исправления, найденные при ручном тестировании

При проверке команд за пределами счастливого пути обнаружились два дефекта, которые не ловили первые тесты:

  • /certificado зависал, когда в названии технологии был пробел ("Data Science"). Парсинг зависел от позиции аргументов и не различал, где заканчивается имя. Исправлено с помощью явных флагов --nome и --tech, с сохранением позиционного режима как запасного.

  • /trilha показывал "Модуль 1, Модуль 2..." вместо реальных названий. Код генерировал метки из поля numero_de_modulos и игнорировал массив modulos из JSON — данные были корректны, но тот, кто их потреблял, их не читал.

  • findTrilha возвращал первый трек из каталога при пустом вводе, потому что "".includes("") всегда истинно. Валидация существовала в CLI, но не в MCP-сервере, где схема Zod принимает строку из пробелов. Исправлено в источнике.

Измеренное покрытие вместо оценочного

Целью было 70% покрытия. Вместо того чтобы утверждать число, я настроил провайдер v8 в Vitest для реального измерения, с отчётом, записываемым в файл, и воспроизводимым скриптом npm. CLI-точки входа были исключены из расчёта с явным обоснованием, а обнаруженные оставшиеся ветви получили тесты. Результат: 100% на тестируемой логике, 59 тестов.

Разделение чистой логики и ввода-вывода

Каждая команда была рефакторизована на два слоя: экспортируемые чистые функции и функция run(), изолированная защитой require.main === module. Это сделало код тестируемым без мока process.argv и позволило MCP-серверу импортировать ту же логику без дублирования.

Локальная конфигурация вне системы контроля версий

.bob/mcp.json требует абсолютный путь машины. Вместо того чтобы версионировать путь, который работает только на моём компьютере, я версионировал .bob/mcp.example.json с плейсхолдером и игнорировал реальный файл — тот же паттерн, что и .env.example.

Проверка сгенерированной документации

Документация, созданная агентом, была проверена построчно и содержала неточности: неверное количество треков (15 вместо 35), описание парсера, не соответствовавшее коду, и обоснование моделирования, которое рационализировало избыточное поле вместо признания компромисса. Все они были исправлены по коду.


Что я узнал

  • Агент генерирует быстро, но не проверяет. Рабочий цикл был всегда одинаковым: запросить, прочитать результат, протестировать путь ошибки, исправить. Три бага этого проекта появились при ручном тестировании, а не в том, что агент сообщал как готовое. Он дважды описал собственный парсер неправильно — он описывал намерение, а не код.

  • Заявленное число — не измеренное число. Справочный проект заявлял 100% покрытия без единого установленного инструмента покрытия. Это разница между словами и демонстрацией, и она видна только если кто-то ищет.

  • Безопасность по умолчанию обычно оказывается самым слабым вариантом. Исходная инструкция требовала использовать credential.helper store, который записывает токен в открытом виде на диск. Я заменил его на Git Credential Manager, который выполняет то же требование с зашифрованным хранением. Токен GitHub остался в переменной окружения пользователя, никогда в файле проекта — решение, которое также соответствует требованию задания не отправлять учётные данные в репозиторий.

  • Документировать решение — это не то же самое, что документировать код. ARQUITECTURA.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