Skip to main content
Glama
juanidives

geo-explorer

by juanidives

Geo-Explorer

What is Geo-Explorer

Geo-Explorer is a fictional study platform inspired by DIO (Digital Innovation One). The project simulates a learning track system with coding challenges and certificate issuance.

It serves as a study base for:

  • Developing CLI tools in TypeScript

  • Building an MCP Server that exposes the platform logic as tools invocable by AI agents (Bob, Claude Desktop, Cursor, etc.)

  • Defining local slash commands in Bob to trigger the tools directly in chat

  • Practicing unit tests with 100% coverage


Related MCP server: MCP Learning Project

Project structure

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

How to run

Prerequisites

  • Node.js ≥ 18

  • npm ≥ 9

Installation

# Na raiz do projeto
npm install

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

Build (type checking)

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

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

The MCP server build must be run at least once before registering it.


How to use the commands

The three CLI commands are run via npm run at the project root.


/trilha <tecnologia>

Displays the complete study plan for a track based on the technology name (or part of the name). The search is case-insensitive and accepts partial matches.

npm run trilha -- javascript

Output:

╔══════════════════════════════════════════════════════╗
  🎯  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]

Generates a random coding challenge. The nivel parameter is optional; when omitted, it uses the level recorded in the track. Accepted values for nivel: básico, intermediário, avançado (with or without accent, case-insensitive).

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

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

Output (example):

╔══════════════════════════════════════════════════════╗
  ⚔️   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

Issues a fictional certificate in Markdown. The certificate ID is deterministic — generated from the student's name and the track ID.

The command accepts two ways of passing arguments:

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

In the positional form the parser expects exactly two arguments (argv[0] → name, argv[1] → technology). Use the --name and --tech flags if you prefer a more explicit syntax or if you want to avoid depending on the shell quotes.

Output (in 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

Redirecting to file: npm run certificado -- --nome "Maria Silva" --tech "TypeScript" > certificado.md


How to use in Bob's chat

The project defines three local slash commands in .bob/commands/. After opening the project in Bob, they become available directly in the chat:

Command

Syntax

What it does

/trilha

/trilha <tecnologia>

Runs commands/trilha.ts and displays the study plan

/desafio

/desafio <tecnologia> [nivel]

Runs commands/desafio.ts and displays the generated challenge

/certificado

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

Runs commands/certificado.ts and renders the certificate

Examples of use in chat:

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

Bob interprets the arguments, assembles the correct command, and displays the formatted output in the chat itself.


How to run the tests

# Executa os testes sem cobertura
npm test

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

Current result

 ✔ 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

What it exposes

The MCP server at mcp/src/index.ts directly reuses the command logic in commands/ and exposes four tools:

Tool

Parameters

Description

listar_tecnologias

(none)

Lists all available technologies with level and total XP

buscar_trilha

tecnologia (string)

Returns the complete study plan for a technology

gerar_desafio

tecnologia (string), nivel (optional)

Generates a random coding challenge

gerar_certificado

nome (string), tecnologia (string)

Issues a certificate in Markdown

The transport used is stdio — the server is started as a child process by the MCP client.

How to register in Bob

  1. Build the server (needed only once):

    cd mcp
    npm install
    npm run build
  2. Copy the configuration template:

    cp .bob/mcp.example.json .bob/mcp.json
  3. Edit .bob/mcp.json by replacing the path with the absolute one on your machine:

    {
      "mcpServers": {
        "geo-explorer": {
          "command": "node",
          "args": ["/caminho/absoluto/para/geo-explorer/mcp/build/mcp/src/index.js"]
        }
      }
    }
  4. Bob automatically reloads the MCP servers when you save the file. After that, geo-explorer will appear as a connected server on Bob's MCP panel.

The .bob/mcp.json file is in .gitignore — each developer keeps their own absolute path locally.


Improvements made

Fixes found in manual testing

When validating the commands beyond the happy path, two defects appeared that the initial tests did not catch:

  • /certificado would hang when the technology had a space in its name ("Data Science"). The parsing depended on the position of the unquoted arguments and could not tell where the name ended. Fixed with the explicit --name and --tech flags, keeping the positional mode as a fallback.

  • /trilha displayed "Módulo 1, Módulo 2..." instead of the real names. The code generated the labels from the numero_de_modulos field and ignored the modulos array in the JSON — the data was correct, it was the code that read it that was wrong.

  • The buscar_trilha tool returned the first track in the catalog for an empty input, because "".includes("") is always true. The validation was in the CLI, but not in the MCP server, where the Zod schema accepts a string of blank spaces. Fixed at the root.

Measured coverage instead of estimated coverage

The goal was 70% coverage. Instead of asserting a number, I configured Vitest's v8 provider to actually measure the information, with the report saved to a file and a reproducible npm script. The CLI entrypoints were excluded from the calculation with an explicit justification, and the remaining uncovered branches received tests. Result: 100% of the testable logic, 59 tests.

Separation between pure logic and I/O

Each command was refactored into two layers: exported pure functions and a run() function isolated by the require.main === module guard. That made the code testable without mocking process.argv and allowed the MCP server to import the same logic without duplication.

Local configuration outside version control

The .bob/mcp.json requires an absolute path on the machine. Instead of putting the path of the actual file into version control, I placed .bob/mcp.example.json with a placeholder and ignored the real file — the same pattern as the .env.example.

Fixing incorrect documentation

At the end, I identified and corrected several issues in the documentation and comments:

  • The description of the parser said the command accepts a single string with lowercase letters, but the actual code expects two separate arguments.

  • The explanation for the modulos field stated the feature "could later be used to display multiple items," but the track array already could contain more than one module. The field is redundant and was made optional.

  • The documentation said the certificate ID is based on the track name, but the code defines it as the hash of the student's name and the track name.


What I learned

  • The agent works fast, but it doesn't check itself. The cycle that worked was the same every time: ask, read what it generated, test the error path, fix it. The bugs found appeared during manual testing and in explicit review, not in the agent's final summary. The agent described its own parser incorrectly twice — it was describing the intention, not the code.

  • Reader, not writer, makes the quality difference. The code that looked fine to a model only works when followed by a careful human review. I learned to keep reviewing, asking for feedback, and checking line by line instead of accepting the first plausible response.

  • Testability is a design requirement. Splitting logic into pure functions and leaving the side-effect boundaries at the main guard make the code much easier to make in isolation and keeps the command line and the MCP server sharing the same logic.

  • The MCP server doesn't need to know about the command line. By importing the same pure functions, the server gets the same behavior — and fixes like the "".includes("") are fixed in the shared layer, not duplicated in two places.

  • Testing 100% of the logic does not mean there are no bugs. There are always paths that don't pass through the tests — and the human behind the keyboard is the one who adds the missing one.

  • The most important part is reading the code the agent writes. Line by line, with a skeptical eye — that's where the much deeper layer of quality is built.

A
license - permissive license
Not graded
quality - not tested
B
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

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
  • F
    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.
    10
  • A
    license
    A
    quality
    C
    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

View all related MCP servers

Related MCP Connectors

  • MCP server for skill documentation, generated by doc2mcp.

  • A MCP server built for developers enabling Git based project management with project and personal…

  • MCP server for the Inistate platform: module discovery, entry management, and activity submission.

View all MCP Connectors

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/juanidives/geo-explorer'

If you have feedback or need assistance with the MCP directory API, please join our Discord server