neuroverse

Camada de inteligência multilíngue + memória + segurança + voz para agentes de IA autônomos

Documentação

version node python license MCP tests npm

NeuroVerse MCP Server Card

NeuroVerse MCP Server Score

🧠 NeuroVerse

📦 Instalar via npm | 🐙 Repositório GitHub

Seu agente de IA só fala inglês. O NeuroVerse resolve isso.
Seu agente de IA esquece tudo. O NeuroVerse lembra.
Seu agente de IA pode fazer algo perigoso. O NeuroVerse impede isso.
Seu agente de IA está preso a um modelo. O NeuroVerse roteia para o melhor.

Inteligência multilíngue + memória + segurança + camada de voz para agentes de IA autônomos.


🚀 Novidades na v4.1

  • Raciocínio OpenRouter: Integrado o modelo stepfun/step-3.5-flash:free para tarefas analíticas de alto desempenho. Use a nova ferramenta neuroverse_reason para raciocínio profundo.
  • Tokens de Raciocínio: Rastreamento em tempo real dos tokens de raciocínio para cada solicitação.
  • Camada de Voz (v2.0): Suporte integrado para Whisper STT e Coqui TTS.

🚀 O que é o NeuroVerse?

Toda vez que você inicia um novo chat com Cursor, VS Code Copilot ou qualquer agente de IA compatível com MCP, ele começa do zero — sem memória, sem segurança, sem compreensão do seu idioma. NeuroVerse é um servidor MCP que dá aos seus agentes:

RecursoDescrição
🌐Inteligência MultilíngueEntende idiomas indianos mistos — Tamil, Hindi, Telugu, Kannada, Malayalam, Bengali + Inglês. Alternância de código? Sem problema.
🎙️Camada de VozSTT via Whisper e TTS via Coqui. Transcreve áudio do usuário e sintetiza respostas do agente.
🧠Extração de IntençãoExtração estruturada de intenção com LLM em primeiro lugar e fallback determinístico baseado em regras. Nunca perde um comando.
💾Memória em CamadasCurto prazo (sessão), Episódica (recente), Semântica (fatos de longo prazo) — todas com pontuação de importância.
🛡️Segurança em 3 Camadas (Kavach)Lista de bloqueio de palavras-chave → Classificador de risco de intenção → Juiz LLM. Bloqueia DROP DATABASE antes que seja tarde demais.
🤖Roteador Multi-Modelo (Marga)OpenAI · Anthropic · Sarvam AI · Ollama · OpenRouter — roteia cada tarefa para o melhor modelo automaticamente.
🔗Agente-para-Agente (Setu)Registro de agentes REST+JSON com fallback automático. Agentes chamando agentes chamando agentes.
Tudo AssíncronoFastAPI + asyncpg + httpx. Verificações de segurança em submilissegundos. Zero bloqueio.

⚡ NeuroVerse é uma camada de inteligência modular — não um monólito. Conecte o que você precisa. Ignore o que não precisa.


Sumário


🚀 Início Rápido

1. Instalação

Opção A: npm (recomendado) — use em qualquer lugar

npm install neuroverse

Opção B: A partir do código-fonte (Python)

git clone https://github.com/joshua400/neuroverse.git
cd neuroverse
python -m pip install -e ".[dev]"

💡 Dica: Se você instalou via npm, o caminho é node_modules/neuroverse/dist/index.js. Se a partir do código-fonte, use o caminho absoluto do seu diretório clonado.

2. Adicione o NeuroVerse à sua configuração MCP

NeuroVerse é um servidor MCP padrão (stdio). Adicione-o à configuração do seu host:

Cursor / VS Code Copilot / Claude Desktop (npm)

{
  "mcpServers": {
    "neuroverse": {
      "command": "npx",
      "args": ["neuroverse"]
    }
  }
}

A partir do código-fonte (Python)

{
  "mcpServers": {
    "neuroverse": {
      "command": "python",
      "args": ["mcp/server.py"],
      "cwd": "/path/to/neuroverse"
    }
  }
}

3. Diga ao seu agente para usar o NeuroVerse

Adicione isso ao arquivo de regras do seu agente (.md, .cursorrules, prompt do sistema, etc.):

## NeuroVerse Integration
- Use `neuroverse_process` to handle any user request — it auto-detects language, extracts intent, checks safety, and executes.
- Use `neuroverse_reason` for complex tasks requiring analytical reasoning (powered by OpenRouter).
- Use `neuroverse_store` / `neuroverse_recall` for persistent context across sessions.
- Use `neuroverse_execute` for any potentially dangerous action — it will block destructive operations.

É isso. Dois comandos que seu agente precisa conhecer:

ComandoQuandoO que acontece
neuroverse_process(text, user_id)Qualquer solicitação do usuárioDetecta idioma, extrai intenção, verifica segurança, executa
neuroverse_store(user_id, intent, ...)Fim do trabalhoSalva o contexto para a próxima sessão

Na próxima sessão, seu agente continua exatamente de onde parou — como se nunca tivesse esquecido.

Requisitos

  • Edição npm: Node.js 18+ (zero dependências de banco de dados — usa arquivos JSON)
  • Edição Python: Python 3.10+ + PostgreSQL (para memória persistente)

🤔 Por que o NeuroVerse?

Sem NeuroVerseCom NeuroVerse
Agente só entende inglêsAgente entende Tamil, Hindi, Telugu, Kannada + alternância de código com inglês
"anna file ah csv convert pannu" → ❌ erro"anna file ah csv convert pannu" → ✅ converte arquivo para CSV
Toda sessão começa do zeroAgente lembra o que fez — entre sessões, entre agentes
DROP DATABASE → 💀 seus dados se foramDROP DATABASE → 🛡️ bloqueado em < 1ms, zero tokens
Preso a um provedor de LLMRoteia para o melhor modelo para cada tarefa automaticamente
Dois agentes = caosAgente A passa para o Agente B perfeitamente

Eficiência de Tokens

A camada de segurança do NeuroVerse opera com custo zero de tokens — regex puro e correspondência de regras, sem desperdício de chamadas LLM:

Abordagem de SegurançaCusto por VerificaçãoLatência
Segurança baseada em LLM500–2.000 tokens1–5 segundos
Baseada em embeddings100–500 tokens200–500ms
NeuroVerse Kavach0 tokens< 1ms

Com mais de 100 chamadas de ferramentas por sessão, isso representa 50.000–200.000 tokens economizados em comparação com a segurança baseada em LLM.


⚙️ Como Funciona

User Input (any language)
        │
   ┌────┴────┐
   │  Vani   │ ← Language detection + keyword normalisation
   │ (भाषा)  │   Tamil/Hindi/Telugu → normalised internal format
   └────┬────┘
        │
   ┌────┴────┐
   │  Bodhi  │ ← LLM intent extraction + rule-based fallback
   │ (बोधि)  │   Returns structured JSON with confidence
   └────┬────┘
        │
   ┌────┴────┐
   │ Kavach  │ ← 3-layer safety: blocklist → risk → LLM judge
   │ (कवच)   │   Blocks dangerous actions at zero token cost
   └────┬────┘
        │
   ┌────┴────┐
   │  Marga  │ ← Routes to best model (OpenAI/Anthropic/Sarvam/Ollama)
   │ (मार्ग)  │   Based on task type: multilingual/reasoning/local
   └────┬────┘
        │
   ┌────┴────┐
   │ Smriti  │ ← Stores/recalls from tiered memory
   │ (स्मृति) │   Short-term + Episodic + Semantic (PostgreSQL)
   └────┬────┘
        │
   Tool Execution + Response

🌐 Inteligência Multilíngue — Vani

O Problema: Todo servidor MCP fala apenas inglês. 70% da Índia alterna de código diariamente.

"anna indha file ah csv convert pannu"
         ↓
"anna this file ah csv convert do"     ← keyword normalisation (not full translation)
         ↓
Intent: convert_format { output_format: "csv" }

Pipeline Híbrido (Regra + LLM)

Input → Language Detect (langdetect) → Code-Switch Split → Keyword Normalise → Output

Insight-chave: Não traduza completamente. Apenas normalize palavras-chave críticas do domínio. O resto permanece intacto — preservando contexto, tom e nuances.

Idiomas Suportados

IdiomaPalavras-chave MapeadasExemplo
🇮🇳 Tamilpannu → do, maathru → change, anuppu → send"file ah csv convert pannu"
🇮🇳 Hindikaro → do, banao → create, bhejo → send"report banao sales ka"
🇮🇳 Telugucheyyi → do, pampu → send, chupinchu → show"data chupinchu"
🇮🇳 KannadaSuporte chegando na v2
🇬🇧 InglêsPassagem direta"convert json to csv"

Detecção de Alternância de Código

{
  "languages": ["ta", "en"],
  "confidence": 0.92,
  "is_code_switched": true,
  "original_text": "anna indha file ah csv convert pannu",
  "normalized_text": "anna this file ah csv convert do"
}

🧠 Extração de Intenção — Bodhi

LLM em primeiro lugar. Fallback baseado em regras. Nunca falha.

LLM succeeds (confidence ≥ 0.5)?
   ├─ Yes → use LLM result
   └─ No  → rule-based parser (deterministic)

Estratégia LLM

# Prompt to LLM:
"Extract structured intent from the following input.
 Return ONLY valid JSON: {intent, parameters, confidence}"

Fallback Baseado em Regras (7 padrões)

PadrãoIntençãoPalavras-chave de Gatilho
Conversão de formatoconvert_formatconvert, csv, json, excel, pdf
Resumosummarizesummarise, summary, brief, tldr
Geração de relatóriosgenerate_reportreport, generate report
Exclusãodelete_datadelete, remove, drop, clean
Consulta de dadosquery_dataquery, search, find, fetch, get
Comunicaçãosend_messagesend, share, email, notify
Explicaçãoexplainexplain, describe, what is, how to

Saída

{
  "intent": "convert_format",
  "parameters": { "input_format": "json", "output_format": "csv" },
  "confidence": 0.87,
  "source": "rule"
}

A diferença-chave: o código decide — não o LLM. Se o LLM falhar, alucinar ou retornar lixo, o mecanismo de regras assume. Determinístico. Confiável.


💾 Memória em Camadas — Smriti

O Problema: Logs brutos são inúteis. Armazenar tudo desperdiça recursos. Sem pontuação de relevância.

Abordagem do NeuroVerse: Pontuar → Filtrar → Comprimir → Armazenar.

Três Camadas

CamadaArmazenamentoVida útilUso
Curto prazoDicionário em processoSessão atualContexto ativo, limitado a 50 por usuário
EpisódicaPostgreSQLAções recentesO que o agente fez recentemente
SemânticaPostgreSQLFatos de longo prazoConhecimento persistente sobre usuários, projetos, entidades

Pontuação de Importância

if importance_score >= 0.4:
    persist_to_database()   # worth remembering
else:
    skip()                  # noise

Apenas memórias importantes sobrevivem. Sem inchaço. Sem recuperação irrelevante.

Compressão de Contexto

❌ Bad:  "The user asked about sales data three times in the last hour and seemed frustrated..."
✅ Good: { "intent": "sales_query", "frequency": 3, "sentiment": "frustrated" }

Payloads JSON estruturados, NÃO despejos de texto bruto. Comprimidos. Indexáveis. Consultáveis.

Esquema de Memória (PostgreSQL)

CREATE TABLE memory_records (
    id          TEXT PRIMARY KEY,
    user_id     TEXT NOT NULL,
    tier        TEXT NOT NULL,          -- short_term | episodic | semantic
    intent      TEXT NOT NULL,
    language    TEXT DEFAULT 'en',
    data        JSONB DEFAULT '{}',     -- compressed structured payload
    importance  REAL DEFAULT 0.5,
    created_at  TIMESTAMPTZ DEFAULT NOW(),
    updated_at  TIMESTAMPTZ DEFAULT NOW()
);
-- Indexed: user_id, intent, tier

🛡️ Camada de Segurança — Kavach

"O escudo que nunca dorme."

Três Camadas — Defesa em Profundidade

Agent calls tool  →  MCP Server receives request
                            │
                ┌───────────┴───────────┐
                │   Layer 1: Blocklist  │  ← regex + keywords, < 0.1ms
                └───────────┬───────────┘
                            │ pass
                ┌───────────┴───────────┐
                │  Layer 2: Risk Score  │  ← intent → risk classification
                └───────────┬───────────┘
                            │ pass
                ┌───────────┴───────────┐
                │  Layer 3: LLM Judge   │  ← optional model-based check
                └───────────┬───────────┘
                            │ pass
                     Execute handler

Camada 1 — Lista de Bloqueio Baseada em Regras (Custo Zero)

Executa dentro do servidor MCP. Regex puro. Sem rede. Sem tokens.

Palavras-chave bloqueadas:

delete_all_data, drop_database, drop_table, system_shutdown,
format_disk, rm -rf, truncate, shutdown, reboot, erase_all, destroy

Padrões bloqueados (regex):

DROP (DATABASE|TABLE|SCHEMA)
DELETE FROM *
TRUNCATE TABLE
FORMAT [drive]:
rm (-rf|--force)

Camada 2 — Classificação de Risco de Intenção

Nível de RiscoIntençõesAção
🟢 BAIXOconvert_format, summarize, generate_report, query_data, explain✅ Permitir
🟡 MÉDIOsend_message, unknown⚠️ Bloquear se modo estrito
🔴 ALTOdelete_data❌ Bloquear sempre
⛔ CRÍTICOdrop_database, system_shutdown❌ Bloquear sempre

Camada 3 — Juiz de Segurança LLM (Opcional)

Se as Camadas 1–2 passarem, opcionalmente pergunte a um LLM: "Isso é seguro?"

// LLM returns:
{ "safe": false, "reason": "This action would delete all user data." }

Veredito de Segurança

{
  "allowed": false,
  "risk_level": "critical",
  "reason": "Blocked keyword detected: 'drop_database'",
  "blocked_by": "rule"
}

Custo de Tokens: Zero

Most AI safety:  Agent → "rm -rf /" → Safety LLM → 2,000 tokens burned
NeuroVerse:      Agent → "rm -rf /" → regex match → BLOCKED (0 tokens, < 1ms)

Modo Estrito

# .env
SAFETY_STRICT_MODE=true    # Also blocks MEDIUM risk (unknown/send)
SAFETY_STRICT_MODE=false   # Only blocks HIGH and CRITICAL

🤖 Roteador Multi-Modelo — Marga

O Problema: Dependência de fornecedor. Um modelo para tudo. Pagando demais.

Abordagem do NeuroVerse: Roteie cada tarefa para o melhor modelo. Automaticamente.

Lógica de Roteamento

def route_task(task):
    if task.type == "multilingual":
        return sarvam_model        # Best for Indian languages
    elif task.type == "reasoning":
        return claude_or_openai    # Best for complex analysis
    elif task.type == "local":
        return ollama              # Free, on-device, private
    else:
        return best_available      # Fallback chain

Provedores Suportados

ProvedorModelo PadrãoMelhor ParaCusto
🇮🇳 Sarvam AIsarvam-2b-v0.5Idiomas indianos, multilíngueBaixo
🧩 OpenRouterstepfun/step-3.5-flash:freeRaciocínio de alto desempenhoGrátis
🧠 Anthropicclaude-sonnet-4-20250514Raciocínio, análiseMédio
🤖 OpenAIgpt-4oTarefas gerais, códigoMédio
🦙 Ollamallama3Local, privado, offlineGrátis

Benefícios

Sem MargaCom Marga
CustoPague GPT-4 por tudoUse Ollama para tarefas simples
VelocidadeMesma latência para todas as tarefasModelos locais para tarefas rápidas
PrivacidadeTudo vai para a nuvemDados sensíveis permanecem locais
Dependência de fornecedorPreso a um provedorTroque a qualquer momento

Cadeia de Fallback

Se o seu provedor preferido estiver fora do ar ou não configurado:

OpenRouter → Anthropic → OpenAI → Sarvam → Ollama (local, always available)

🔗 Agente-para-Agente — Setu

Agentes chamando agentes chamando agentes.

Registro de Agentes

register_agent({
    "agent_name": "report_agent",
    "endpoint": "http://localhost:8001/generate",
    "capabilities": ["generate_report", "sales_analysis"]
})

Roteamento

{
  "target_agent": "report_agent",
  "task": "generate_sales_report",
  "payload": { "quarter": "Q1", "year": 2026 }
}

Fallback

Se o agente de destino estiver inacessível:

{
  "success": false,
  "error": "Agent unreachable: ConnectError",
  "fallback": true
}

O chamador pode recorrer à execução local. Sem falhas graves.


🧩 Ferramentas MCP

NeuroVerse expõe 6 ferramentas via Protocolo de Contexto de Modelo:

#Ferramenta (npm)Ferramenta (Python)Descrição
1neuroverse_processindia_mcp_process_multilingual_inputPipeline completo: detectar → normalizar → intenção → segurança → executar
2neuroverse_storeindia_mcp_store_memoryArmazenar um registro de memória no sistema em camadas
3neuroverse_recallindia_mcp_recall_memoryRecuperar memórias por usuário, intenção ou camada
4neuroverse_executeindia_mcp_safe_executeExecução segura de ponta a ponta (conveniência)
5neuroverse_routeindia_mcp_route_agentRoteirizar uma tarefa para um agente downstream registrado
6neuroverse_modelindia_mcp_model_routeConsultar o roteador multi-modelo (opcionalmente invocar)
7neuroverse_transcribeindia_mcp_transcribe_audioTranscrever áudio para texto via Whisper STT
8neuroverse_synthesizeindia_mcp_synthesize_speechSintetizar fala a partir de texto via Coqui TTS
9neuroverse_reasonN/ARaciocínio de alto desempenho via OpenRouter

Exemplo do Mundo Real

── Session 1 (Agent Alpha, 2pm) ───────────────────────────
india_mcp_process_multilingual_input({
    text: "anna indha sales data ah csv convert pannu",
    user_id: "alpha",
    execute: true
})
→ Language: Tamil+English (code-switched)
→ Intent: convert_format { output_format: "csv" }
→ Safety: ✅ allowed (LOW risk)
→ Execution: ✅ success

india_mcp_store_memory({
    user_id: "alpha",
    intent: "convert_format",
    tier: "episodic",
    data: { "file": "sales_q1.json", "output": "csv" },
    importance_score: 0.8
})

── Session 2 (Agent Beta, next day) ───────────────────────
india_mcp_recall_memory({
    user_id: "alpha",
    intent: "convert_format",
    limit: 5
})
→ "Agent Alpha converted sales_q1.json to CSV yesterday"
→ Beta picks up exactly where Alpha left off

🌐 API REST

O NeuroVerse também inclui uma camada REST FastAPI — para clientes não-MCP:

python app/main.py
# → http://localhost:8000/docs (Swagger UI)
EndpointMétodoDescrição
/healthGETVerificação de saúde
/api/processPOSTPipeline multilíngue completo
/api/memory/storePOSTArmazenar memória
/api/memory/recallPOSTRecuperar memórias

⚙️ Configuração

Todas as configurações via variáveis de ambiente (.env):

# Database (PostgreSQL required for persistent memory)
DATABASE_URL=postgresql+asyncpg://user:password@localhost:5432/neuroverse

# AI Model API Keys (configure the ones you have)
OPENAI_API_KEY=sk-...
ANTHROPIC_API_KEY=sk-ant-...
SARVAM_API_KEY=...

# Ollama (local, free)
OLLAMA_BASE_URL=http://localhost:11434

# Safety
SAFETY_STRICT_MODE=true     # Block MEDIUM risk actions too

# MCP Transport
MCP_TRANSPORT=stdio          # or streamable_http
MCP_PORT=8000

🧪 Testes

python -m pytest tests/ -v
tests/test_intent.py     — 10 passed  (rule-based + async + mock LLM + fallback)
tests/test_language.py   — 10 passed  (keyword normalisation + detection + code-switch)
tests/test_pipeline.py   —  8 passed  (full e2e: English, Tamil, Hindi, dangerous, edges)
tests/test_safety.py     — 12 passed  (blocklist, regex, risk classification, pipeline)

============================= 40 passed in 0.87s ==============================

O que é Testado

CategoriaTestesCobertura
Detecção de Idioma10Tâmil, Hindi, Inglês, entrada vazia, flag de alternância de código
Extração de Intenção10Todos os 7 padrões de regras, mock de LLM, falha de LLM, vazio
Mecanismo de Segurança12Palavras-chave, regex, níveis de risco, pipeline completo, modo estrito
Pipeline Completo8E2E Inglês, Tâmil, Hindi, comandos perigosos, casos extremos

🏗️ Arquitetura

Edição npm (Node.js / TypeScript)

npm/
├── src/
│   ├── core/
│   │   ├── language.ts       # Vani  — Language detection (zero deps)
│   │   ├── intent.ts         # Bodhi — Intent extraction (LLM + fallback)
│   │   ├── memory.ts         # Smriti — Tiered memory (JSON files)
│   │   ├── safety.ts         # Kavach — 3-layer safety engine
│   │   └── router.ts         # Marga — Multi-model AI router
│   ├── services/
│   │   ├── executor.ts       # Tool registry + retry engine
│   │   └── agent-router.ts   # Setu — Agent-to-Agent routing
│   ├── types.ts              # TypeScript interfaces & enums
│   ├── constants.ts          # Shared constants
│   └── index.ts              # MCP Server — 6 tools (McpServer + Zod)
├── package.json              # npm publish config
├── tsconfig.json
└── LICENSE                   # Apache-2.0

Edição Python

app/
├── core/
│   ├── language.py           # Vani  — Language detection (langdetect)
│   ├── intent.py             # Bodhi — Intent extraction (LLM + fallback)
│   ├── memory.py             # Smriti — Tiered memory (PostgreSQL)
│   ├── safety.py             # Kavach — 3-layer safety engine
│   └── router.py             # Marga — Multi-model AI router
├── models/schemas.py         # 12 Pydantic v2 models
├── services/
│   ├── executor.py           # Tool registry + retry engine
│   └── agent_router.py       # Setu — Agent-to-Agent routing
├── config.py                 # Settings from environment
└── main.py                   # FastAPI REST entry point
mcp/server.py                 # MCP Server (FastMCP) — 6 tools
tests/                        # 40 tests (pytest)

Dependências — Mínimas

npm (3 pacotes):

PacoteFinalidade
@modelcontextprotocol/sdkProtocolo MCP
zodValidação de esquema
axiosRequisições HTTP

Python (7 pacotes):

PacoteFinalidade
mcp[cli]SDK do Model Context Protocol
fastapi + uvicornCamada de API REST
pydanticValidação de entrada (v2)
langdetectIdentificação estatística de idioma
asyncpg + sqlalchemy[asyncio]Driver assíncrono PostgreSQL
httpxHTTP assíncrono para APIs de modelo

🚀 Roteiro

FaseStatusO quê
v1.0✅ ConcluídoAnálise multilíngue + extração de intenção + 5 ferramentas
v1.0✅ ConcluídoSistema de memória em camadas (PostgreSQL)
v1.0✅ ConcluídoMecanismo de segurança em 3 camadas (Kavach)
v1.0✅ ConcluídoRoteador multi-modelo (Marga) + Roteamento de agentes (Setu)
v2.0✅ ConcluídoCamada de voz (Whisper/Coqui) + Multilíngue estendido
v3.0✅ ConcluídoCache Redis + Recuperação semântica baseada em embeddings
v4.0✅ ConcluídoAprendizado por reforço (RLHF) + Indexação contextual Arachne
v4.1✅ ConcluídoIntegração da Camada de Raciocínio OpenRouter
v5.0🔮 FuturoMarketplace de agentes e plugins de sistemas externos

🔐 Segurança

MedidaImplementação
Gerenciamento de chaves de APISomente variáveis de ambiente — nunca no código
Sanitização de entradaPydantic v2 com restrições de campo em todas as entradas
Limitação de taxaPlanejado para v2.0
Travessia de caminhoN/A — sem acesso ao sistema de arquivos pelas ferramentas
Injeção SQLConsultas parametrizadas via SQLAlchemy
Armazenamento criptografadoDelegado ao TLS do PostgreSQL

🤝 Contribuindo

Contribuições são bem-vindas! Veja como começar:

  1. Faça um fork do repositório
  2. Crie um branch de funcionalidade (git checkout -b feature/amazing-feature)
  3. Faça commit das suas alterações (git commit -m 'feat: add amazing feature')
  4. Envie para o branch (git push origin feature/amazing-feature)
  5. Abra um Pull Request

Configuração de Desenvolvimento

# npm edition
git clone https://github.com/joshua400/neuroverse.git
cd neuroverse/npm
npm install
npm run build

# Python edition
cd neuroverse
python -m pip install -e ".[dev]"
python -m pytest tests/ -v    # All 40 should pass

📜 Licença

Apache-2.0


"Construí o NeuroVerse porque partia meu coração ver agentes esquecerem tudo a cada sessão — e não entenderem uma palavra de Tâmil."

Joshua Ragiland M
✉️ joshuaragiland@gmail.com
🌐 Site do Portfólio

Construído com 🧠 por Joshua — para os agentes do amanhã.