# RiLiGar Storage: Master Implementation Guide (LLM-Ready) > Este é o guia definitivo para integração funcional do RiLiGar Storage em aplicações modernas. Ele contém a lógica para manipular coleções de dados, upload de blobs (arquivos) e consultas SQL integradas para um SaaS multi-tenant. > > **Servidor MCP** (`storage.manager.myinfrastructure.click/mcp/`) — Model Context Protocol, revisão `2026-07-28`. Permite que agentes de IA leiam e escrevam no storage por linguagem natural, autenticando por OAuth 2.1. **Documentação completa e separada em [/llms-mcp.txt](https://myinfrastructure.click/products/storage/llms-mcp.txt).** --- ## 0. Credenciais — LEIA ANTES DE ESCREVER CÓDIGO Se você é um agente de IA, decida primeiro **por onde vai falar com o Storage**. As duas vias têm credenciais diferentes, e escolher errado faz você pedir ao usuário algo que ele não precisava dar. ### Via MCP (preferencial para agentes) — nenhuma chave Se o seu host suporta Model Context Protocol, **use o MCP e autentique por OAuth 2.1**. Não peça API key: o usuário loga no navegador e aprova os escopos, e nenhum segredo passa pelo chat nem fica num arquivo de config. Você só precisa de um dado, e ele não é secreto — o **`tenantId`** da instância: ```bash claude mcp add --transport http riligar-storage \ https://storage.manager.myinfrastructure.click/mcp/ ``` Na primeira chamada o servidor responde `401` com `WWW-Authenticate`, o cliente descobre o authorization server sozinho e abre o navegador. Ver `/llms-mcp.txt` §2.2. **Como pedir o `tenantId` ao usuário** — use este texto: > Preciso do ID da instância de Storage para conectar. Ele está no seu **dashboard**, no > cartão **Acesso** da instância, aba **MCP** — o endereço mostrado termina com o ID. Pode > colar o endereço inteiro. O login é no navegador, então não preciso de chave secreta. Se o usuário não souber qual instância, conecte sem o `/`: o servidor recusa e **lista as instâncias da conta com a URL de cada uma** — apresente a lista e peça para ele escolher. ### Via SDK / backend / CI — aí sim, a API key A chave `stk_…` é necessária **só** quando você vai gerar código com o `@riligar/storage-sdk`, chamar a API HTTP direto, ou rodar em CI sem navegador. **Como pedir a API key ao usuário** — use este texto: > Preciso da API Key do seu Storage para o backend. Ela está no seu **dashboard**, na > **Chave de API** da instância. Ela aparece mascarada (`stk_•••••`) — use o botão de copiar > para pegar o valor inteiro. Começa com `stk_`. Detalhes que evitam ida e volta: - A chave **nunca aparece por extenso na tela**, só mascarada. O botão de copiar é o caminho. - Não existe "pedir ao administrador": a chave nasce da instância, no painel do próprio dono. - Perdeu a chave? Ela é rotacionável no painel — o que **invalida a anterior**. Só oriente rotacionar se o usuário confirmar que nada em produção usa a atual. ### Se o usuário ainda não tem conta, você se provisiona sozinho A `stk_` nasce de uma sessão autenticada — mas **você consegue essa sessão sem navegador**, pelo device flow do RiLiGar Auth. A pessoa lê um código de 8 caracteres no e-mail, informa a você, e daí em diante o percurso é seu: ```bash # 1. sessão (uma interação humana: o código do e-mail) POST https://auth.worker.myinfrastructure.click/auth/code/start {"email":"..."} POST https://auth.worker.myinfrastructure.click/auth/code/verify {"email":"...","code":"ABCD-EFGH"} → JWT # 2. a instância NASCE SOZINHA — não há nada para criar, só resolver POST https://storage.manager.myinfrastructure.click/me/resolve -H "authorization: Bearer " # → {"status":"success","data":{"tenant_id":"","api_key":"stk_...", ...}} ``` Campos em `snake_case`. O que identifica a instância é **`tenant_id`**, não `id`. A chave é recuperável: chamar de novo devolve a mesma, sem rotacionar nada. O percurso completo dos cinco produtos, e o que a RiLiGar é: https://myinfrastructure.click/llms.txt Se o usuário **já tem** a chave, peça — é mais rápido. Se ele não tem conta, use o caminho acima em vez de parar. O que você não pode é adivinhar, gerar código com placeholder e seguir em frente, ou inventar uma rota de "criar chave". --- ## 1. Estrutura do Sistema (Architecture) O RiLiGar Storage é composto por quatro partes principais: - **Manager**: Backend Elysia/Bun que gerencia o isolamento de tenants (SQLite por usuário) e R2. - **Dashboard**: Interface de gestão para desenvolvedores. - **SDK**: Cliente JS para manipulação programática. - **Auth**: Integração nativa com RiLiGar Auth para controle de acesso. ## 2. Conexão e Autenticação (User Access) Esta seção vale para o acesso via **SDK e API HTTP**. Para agentes falando MCP, a via é OAuth e não há chave — ver §0. 1. **Obter Credenciais**: A `api_key` (formato `stk_...`) sai do painel, na **Chave de API** da instância, pelo botão de copiar (o valor fica mascarado na tela). Não há outro caminho: sem sessão no painel, ninguém emite uma chave. 2. **Endpoint**: Utilize a URL base da API (ex: `https://storage.manager.myinfrastructure.click`). 3. **Headers**: Todas as requisições devem incluir o header `x-api-key: `. 4. **Isolamento**: Cada chave está vinculada a um `tenant_id` único, garantindo que seus dados (Coleções e Blobs) estejam isolados de outros usuários. 5. **Permissões**: A chave permite leitura/escrita em Coleções e Blobs, mas apenas leitura (`SELECT`) em consultas SQL Raw. 6. **Escopo**: uma `stk_` dá acesso total à instância dela — e só a ela. Não existe chave com escopo restrito; para leitura apenas, use OAuth com `auth:read`. ## 3. Referência do SDK (Manipulation) O SDK (`@riligar/storage-sdk`) é o ponto central para qualquer manipulação automatizada. ### Inicialização ```javascript import Storage from '@riligar/storage-sdk' const storage = new Storage('https://storage.manager.myinfrastructure.click', 'stk_your_api_key') ``` ### Módulo: Collections (JSON + Vector Storage) IAs devem usar este módulo para persistência de dados estruturados. O sistema é **schema-less** (o primeiro insert define as colunas). #### Operações de Escrita (UPSERT) ```javascript // O campo 'id' é opcional; se enviado e já existir, o registro será atualizado. await storage.collection('memories').insert({ id: "msg_123", content: "User prefers dark mode", tags: ["ui", "preference"], embedding: [0.1, 0.2, 0.3] // Campo vetorial para busca semântica }); ``` #### Operações em Massa (Bulk) O sistema suporta altas cargas de dados e é ideal para sincronizações em massa. O método realiza auto-inferência de esquema sob transações seguras (ACID). ```javascript // Insert massivo (Insere ou Atualiza) documentos simultâneos await storage.collection('memories').insertBulk([ { id: "msg_1", content: "A", tags: ["sys"] }, { id: "msg_2", content: "B", tags: ["sys"] } ]); // Exclusão em massa eficiente (chunks de ID) await storage.collection('memories').deleteBulk(["msg_1", "msg_2"]); ``` #### Operações de Leitura e Filtros Avançados O `select()` aceita filtros complexos baseados em operadores SQL: `$eq`, `$gt`, `$gte`, `$lt`, `$lte`, `$neq`, `$like`. ```javascript const myRecentDocs = await storage.collection('memories').select({ where: { tags: { $like: "ui" }, created_at: { $gt: "2024-01-01" } }, limit: 10, page: 1 }); ``` #### Busca Vetorial (Semantic Search) Para recuperar informações por similaridade de significado: ```javascript const context = await storage.collection('memories').select({ vectorIndex: 'embedding', // Nome da coluna que contém o array numérico vector: [0.1, 0.2, 0.3], // Embedding da query vectorTopK: 3 // Top 3 resultados mais próximos }); ``` ### Módulo: Blobs (R2 File Storage) Ideal para arquivos binários, imagens ou logs extensos. ```javascript // Retorna um objeto de tarefa para controle total const uploadTask = storage.blob.upload(file, (p) => { console.log(`Progresso: ${p.percent}% (${p.loaded}/${p.total} bytes)`); }); // Execução e Cancelamento try { const publicUrl = await uploadTask.execute(); // uploadTask.abort(); // Use para cancelar se necessário } catch (err) { console.error("Upload falhou ou foi abortado"); } ``` ### Módulo: SQL Raw (Power Analytics) Use para joins simples ou agregações complexas (somente leitura). ```javascript // Exemplo de agregação com parâmetros protegidos const results = await storage.sql( "SELECT category, count(*) as total FROM items WHERE price > ? GROUP BY category", [100] ); ``` ## 4. Servidor MCP (Model Context Protocol) Se você é um agente de IA, existe um caminho mais curto que escrever código com o SDK: o Storage expõe um servidor MCP e você pode falar com ele direto. - **Endpoint:** `https://storage.manager.myinfrastructure.click/mcp/` — o id da instância vem do Overview do painel, aba MCP. Sem ele o servidor recusa e lista as instâncias da conta. - **Revisão:** `2026-07-28` (stateless — sem `initialize`, sem sessão) - **Ferramentas:** 13 — 7 de leitura, 6 de escrita - **Autenticação:** OAuth 2.1 pelo RiLiGar Auth, e só. A chave serve à API REST, não ao MCP. ```bash claude mcp add --transport http riligar-storage https://storage.manager.myinfrastructure.click/mcp/ \ ``` Ferramentas: `list_collections`, `describe_collection`, `query_collection`, `vector_search`, `run_sql`, `get_stats`, `list_blobs`, `insert_document`, `insert_documents`, `delete_document`. ⛔ **Não existem como ferramenta**, deliberadamente: apagar a instância, apagar coleção inteira, rotacionar a chave e qualquer rota `/admin`. Um agente que leia instrução maliciosa não encontra gatilho para obedecer. **Documentação completa:** https://myinfrastructure.click/products/storage/llms-mcp.txt ## 5. Design System (Zen Aesthetics) Interfaces de armazenamento devem seguir o padrão RiLiGar Zen: - **Layout**: Monochrome (Grayscale), sem sombras, bordas 1px sólidas. - **Tipografia**: Mono para dados SQL, Sans-serif (Inter) para UI. - **Componentes**: Tabelas densas, botões com `radius: 0`. ## 6. O que NÃO existe Não invente estas APIs — verificado contra o `manager` em 27/08/2026: - **Realtime / subscriptions / webhooks.** Não há push de mudança, nem canal, nem callback de evento. Quem quer saber se algo mudou, consulta. - **Transações explícitas pelo SDK.** `insertBulk` é atômico internamente, mas não existe `begin`/`commit` exposto para agrupar operações suas. - **`JOIN` entre coleções pelo `select()`.** O filtro é de uma coleção só; para cruzar, use `storage.sql()` — que é somente leitura. - **`OR` em `where`.** As condições do `select()` combinam sempre com `AND`. - **Ancoragem de prefixo no `$like`.** O valor é envolvido em `%` automaticamente. - **Escrita via SQL Raw.** `storage.sql()` aceita apenas `SELECT`. `INSERT`/`UPDATE`/`DELETE` e qualquer DDL são recusados. - **Chave de API com escopo restrito.** Toda `stk_` é total na instância dela. Para leitura apenas, use OAuth com `auth:read`. - **Migrations ou schema declarado.** O esquema é inferido: o primeiro insert define o tipo da coluna, e não há como alterá-lo depois pelo SDK. - **Emitir uma API key por API.** A chave nasce no painel, com sessão. Ver §0. Existem, e às vezes são confundidos com ausentes: `GET /stats` (métricas do tenant), `GET /export` (dump SQLite da instância) e `POST /rotate-key` (rotação da chave — invalida a anterior). Os três são REST, e nenhum é ferramenta MCP, de propósito. Quem PERDEU a chave não consegue usar `POST /rotate-key`: ela autentica por `x-api-key`, a credencial que falta. Para esse caso existe `POST /me/tenants/:tenantId/rotate-key`, que autentica pelo JWT do Auth (o mesmo do painel) e devolve a chave nova uma única vez. É a saída para o 401 `Faltando x-api-key` quando o texto puro da chave se perdeu — ele só existe onde a chave nasceu. ## 7. Checklist para IAs (Action Plan) Ao manipular o sistema, a IA deve: 0. **Escolher a via antes de tudo**: MCP (OAuth, sem chave) para trabalhar como agente; SDK com `stk_` para servidor-a-servidor. O MCP não aceita chave. Se faltar a credencial, **parar e pedir ao usuário** com o texto do §0. 1. **Identificar o Tenant**: Garantir que a `api_key` está presente. 2. **Validar Esquema**: Lembrar que o primeiro insert define o tipo da coluna no SQLite. 3. **Tratar Vetores**: Ao salvar embeddings, usar o formato `[number, number, ...]`. 4. **Segurança**: Nunca expor a `stk_...` client-side em produção; preferir uso via Proxy ou Backend. 5. **Monitoramento**: Consultar a rota `/stats` para métricas de uso do tenant. 6. **Preferir o MCP**: se o seu host suporta Model Context Protocol, use o servidor MCP em vez de gerar código com o SDK — as ferramentas já validam schema e isolam a instância. Ver seção 4.