Pensieve: notas com API, MCP e Skill para a sua IA

Olá meus Unicórnios! 🦄✨
Sabe aquela ideia que aparece no meio de uma reunião, aquela conta que vence dia 20, aquele "preciso lembrar de ligar para o dentista amanhã"? Eu anotava isso em três lugares diferentes e esquecia nos três. 😅
Foi daí que nasceu o Pensieve, um app de notas com lembretes que eu fiz. Quem leu Harry Potter reconhece o nome: é a penseira, a bacia onde se guardam as lembranças. Aqui a bacia é um mural de notas, e ela ainda avisa na hora certa. ✨
E como eu passo o dia conversando com IA, ele nasceu programável: tem uma API REST, um servidor MCP para o Claude, o ChatGPT e o Cursor, e uma Skill pronta para o Claude Code. Neste artigo eu mostro como o app funciona e depois cada uma dessas portas de entrada, com chamadas de verdade e as respostas que voltaram.
PensieveApp gratuito de notas com lembretes, no navegador, no celular e no computador, com API, MCP e Skill para IA.pensieve.com.br🧠 Como o Pensieve funciona
A ideia é ser simples a ponto de não dar preguiça. Uma nota é texto livre, sem título e sem formatação, com até 10 mil caracteres. Você digita, aperta Enter, e ela está salva.
Organizar é opcional. Quem quiser tem três ferramentas:
- Listas, com nome e uma de oito cores. A nota ganha a cor da lista no mural.
- Favoritas, que ficam sempre no topo.
- Busca que ignora acento e maiúscula e acha pelo começo da palavra: "backu" encontra "backups".

A parte de que eu mais gosto são os lembretes escritos em português. Você escreve "ligar pro dentista amanhã às 10h" e o Pensieve entende: a nota fica "ligar pro dentista" e o "amanhã às 10h" vira o aviso. Ele entende também repetição ("todo dia 5", "toda terça e quinta", "a cada 15 dias") e fim de série ("por 7 dias", "10 vezes"). E só cria o lembrete quando tem certeza: "reunião de segunda foi boa" continua sendo só uma nota. 😉

O aviso chega no navegador (Web Push), no celular (instalando o site como app) e num app para Windows, Mac e Linux que fica na bandeja do sistema. Tudo de graça: não existe plano pago, nem recurso trancado.
🔑 A chave da API
Tudo que vem daqui para baixo, exceto o MCP, usa uma chave pessoal. Ela é gerada dentro do app, em Minha conta › API, e começa com pk_.
Três coisas que vale saber antes de gerar:
- A chave aparece uma única vez. O Pensieve guarda só o hash dela, então copie na hora.
- Ela dá acesso total às suas notas. Trate como senha.
- Dá para ter até 10 chaves por conta. Crie uma por integração: se precisar revogar uma, as outras continuam funcionando.
Para não colar a chave dentro de script nenhum, guarde numa variável de ambiente. No Linux, no Mac ou no Git Bash:
export PENSIEVE_API_KEY=SUA_CHAVE_AQUI
No PowerShell do Windows, o jeito muda:
$env:PENSIEVE_API_KEY = "SUA_CHAVE_AQUI"
Essa variável vale só para aquela janela de terminal. Fechou, abriu outra, tem de definir de novo.
🌐 A API na prática
A API fica em https://www.pensieve.com.br/api/v1, fala JSON e aceita a chave no cabeçalho Authorization: Bearer. Para começar, a chamada que confirma que a chave funciona e diz de quem ela é:
curl https://www.pensieve.com.br/api/v1/me \
-H "Authorization: Bearer $PENSIEVE_API_KEY"
A resposta traz o dono da conta. Troquei o nome e o e-mail por fictícios aqui:
{
"user": {
"id": 1,
"name": "Unicórnio de Teste",
"email": "[email protected]"
}
}
Se a barra invertida no fim da linha for novidade: ela só diz ao terminal que o comando continua na linha de baixo. Dá para escrever tudo numa linha só, se preferir.
Criar uma nota
O único campo obrigatório é o content, o texto da nota:
curl -X POST https://www.pensieve.com.br/api/v1/notes \
-H "Authorization: Bearer $PENSIEVE_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "content": "Comprar pergaminho e tinta nova para a pena" }'
A API responde 201 (não 200) com a nota criada:
{
"note": {
"id": 16,
"content": "Comprar pergaminho e tinta nova para a pena",
"listId": null,
"isFavorite": false,
"isArchived": false,
"archivedAt": null,
"remindAt": null,
"repeat": null,
"createdAt": "2026-09-26T01:35:30.000Z",
"updatedAt": "2026-09-26T01:35:30.000Z",
"deletedAt": null,
"purgeAt": null
}
}
Repare nos campos: listId é a lista, isFavorite a estrela, remindAt o lembrete e repeat a repetição. Os dois últimos, deletedAt e purgeAt, só se preenchem quando a nota vai para a lixeira.
Criar uma lista
Lista tem nome e cor em hexadecimal:
curl -X POST https://www.pensieve.com.br/api/v1/lists \
-H "Authorization: Bearer $PENSIEVE_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "name": "Exemplo do blog", "color": "#2f7d5b" }'
{
"list": {
"id": 4,
"name": "Exemplo do blog",
"color": "#2F7D5B",
"position": 2,
"noteCount": 0,
"createdAt": "2026-09-26T01:35:30.000Z"
}
}
Mandei a cor em minúsculas e ela voltou em maiúsculas: a API normaliza. E o nome é único na conta, sem diferenciar maiúsculas. Tentei criar de novo como "exemplo do blog", tudo minúsculo, e veio um 409:
{
"error": {
"message": "Você já tem uma lista com esse nome.",
"fields": {
"name": "Nome já usado."
}
}
}
Um lembrete que repete
Aqui mora a parte mais legal da API. Para um lembrete que repete toda segunda e quinta às 9h, você manda três campos: remindAt (o primeiro aviso), repeat (a regra) e timeZone (o fuso):
curl -X POST https://www.pensieve.com.br/api/v1/notes \
-H "Authorization: Bearer $PENSIEVE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"content": "Alimentar a coruja",
"listId": 4,
"remindAt": "2026-09-28T09:00:00-03:00",
"repeat": { "freq": "weekly", "days": [1, 4] },
"timeZone": "America/Sao_Paulo"
}'
{
"note": {
"id": 17,
"content": "Alimentar a coruja",
"listId": 4,
"isFavorite": false,
"isArchived": false,
"archivedAt": null,
"remindAt": "2026-09-28T12:00:00.000Z",
"repeat": {
"freq": "weekly",
"interval": 1,
"days": [
1,
4
]
},
"createdAt": "2026-09-26T01:35:43.000Z",
"updatedAt": "2026-09-26T01:35:43.000Z",
"deletedAt": null,
"purgeAt": null
}
}
Eu mandei 9h e voltou 12:00:00.000Z. Calma, não é erro! 😅 As respostas vêm sempre em UTC (o Z no fim), e 9h em Brasília são 12h em UTC. Na hora de mostrar para alguém, converta de volta para o fuso da pessoa.
Nos days, 0 é domingo, 1 é segunda, e assim por diante até 6, sábado. As regras de repetição são estas:
| Regra | O que faz |
|---|---|
{ "freq": "daily" } | todo dia |
{ "freq": "daily", "interval": 15 } | a cada 15 dias |
{ "freq": "weekdays" } | de segunda a sexta |
{ "freq": "weekly", "days": [1, 4] } | toda segunda e quinta |
{ "freq": "monthly" } | todo mês, no dia do primeiro aviso |
{ "freq": "yearly" } | todo ano, na data do primeiro aviso |
{ "freq": "daily", "count": 7 } | todo dia, 7 vezes no total |
{ "freq": "weekly", "days": [2], "until": "2026-12-15" } | toda terça, até 15/12 (inclusive) |
Buscar, editar e adiar
A busca é o parâmetro q, e ela acha por trecho: "pergam" encontra "pergaminho".
curl "https://www.pensieve.com.br/api/v1/notes?q=pergam&limit=20" \
-H "Authorization: Bearer $PENSIEVE_API_KEY"
{
"notes": [
{
"id": 16,
"content": "Comprar pergaminho e tinta nova para a pena",
"listId": null,
"isFavorite": false,
"isArchived": false,
"archivedAt": null,
"remindAt": null,
"repeat": null,
"createdAt": "2026-09-26T01:35:30.000Z",
"updatedAt": "2026-09-26T01:35:30.000Z",
"deletedAt": null,
"purgeAt": null
}
],
"total": 1,
"limit": 20,
"offset": 0
}
Com limit, a resposta ganha total e offset para paginar. Sem ele, vêm todas as notas do filtro de uma vez. Dá para combinar a busca com filter (favorites, alerts, nolist, archived, trash) e com listId: ?filter=alerts&listId=4 traz só as notas com lembrete daquela lista.
Para editar, o PATCH recebe só o que muda. Aqui eu favoritei a nota e movi para a lista:
curl -X PATCH https://www.pensieve.com.br/api/v1/notes/16 \
-H "Authorization: Bearer $PENSIEVE_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "isFavorite": true, "listId": 4 }'
No PATCH, null significa "tirar": "listId": null tira da lista, "remindAt": null remove o lembrete e a repetição, e "repeat": null para de repetir mas mantém o próximo aviso. E "isArchived": true tira a nota do mural sem mandar para a lixeira.
Adiar é uma rota própria. O snooze joga o próximo aviso para daqui a N minutos, contando de agora:
curl -X POST https://www.pensieve.com.br/api/v1/notes/17/snooze \
-H "Authorization: Bearer $PENSIEVE_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "minutes": 30 }'
{
"note": {
"id": 17,
"content": "Alimentar a coruja",
"listId": 4,
"isFavorite": false,
"isArchived": false,
"archivedAt": null,
"remindAt": "2026-09-26T02:05:55.000Z",
"repeat": {
"freq": "weekly",
"interval": 1,
"days": [
1,
4
]
},
"createdAt": "2026-09-26T01:35:43.000Z",
"updatedAt": "2026-09-26T01:35:55.000Z",
"deletedAt": null,
"purgeAt": null
}
}
A chamada saiu às 01:35:55 em UTC, e o remindAt foi para 02:05:55, meia hora depois. A regra de repetição continua lá: depois desse aviso adiado, a série volta ao horário normal.
Excluir não é apagar
O DELETE responde 204, sem corpo nenhum, e manda a nota para a lixeira:
curl -X DELETE https://www.pensieve.com.br/api/v1/notes/18 \
-H "Authorization: Bearer $PENSIEVE_API_KEY"
Ela aparece no filtro trash, agora com deletedAt e purgeAt preenchidos:
{
"notes": [
{
"id": 18,
"content": "Polir a varinha",
"listId": 4,
"isFavorite": false,
"isArchived": false,
"archivedAt": null,
"remindAt": "2026-10-01T23:00:00.000Z",
"repeat": {
"freq": "weekly",
"interval": 1,
"days": [
1,
4
]
},
"createdAt": "2026-09-26T01:35:44.000Z",
"updatedAt": "2026-09-26T01:36:08.000Z",
"deletedAt": "2026-09-26T01:36:08.000Z",
"purgeAt": "2026-10-26T01:36:08.000Z"
}
]
}
O purgeAt é a data em que ela some de vez: 30 dias depois. Até lá, um POST /notes/18/restore traz a nota de volta, com lembrete e tudo. Apagar na hora é o DELETE /notes/18/permanent, e ele só funciona com a nota já na lixeira. Tentei com a nota fora dela e veio 404, "Nota não encontrado(a)". É uma trava de propósito: ninguém apaga para sempre sem passar pela lixeira. 🗑️
Várias notas de uma vez
Para importar uma lista de tarefas, o /notes/batch cria de 1 a 50 notas numa chamada só. E ele é tudo ou nada: mandei duas notas, a segunda vazia, e a resposta foi um 422 apontando exatamente qual:
{
"error": {
"message": "Verifique os dados informados.",
"fields": {
"notes.1.content": "A nota não pode ficar vazia."
}
}
}
O notes.1 é a segunda nota (a contagem começa no zero). Conferi as contagens da conta depois: a primeira nota, que estava certa, também não foi criada. Nada de lote salvo pela metade.
⏰ As armadilhas das datas
Se você só for ler um pedaço deste artigo, leia este. 🙏 Quase todo erro com a API do Pensieve vai ser de data.
1. Data sem fuso é recusada. Mandei um lembrete com "remindAt": "2026-09-28T09:00:00", sem o -03:00 no fim, e veio 422:
{
"error": {
"message": "Verifique os dados informados.",
"fields": {
"remindAt": "Data/hora inválida."
}
}
}
A mensagem diz "inválida", mas a data está certinha. O que falta é o fuso. Sem ele, 9h de onde? A API prefere recusar a adivinhar. Mande sempre -03:00 (Brasília) ou o horário em UTC com Z.
2. O primeiro aviso pode mudar de dia. Criei uma nota com a regra "segunda e quinta", mas com o remindAt numa quarta, 30/09 às 20h. O aviso voltou assim:
"remindAt": "2026-10-01T23:00:00.000Z"
Isso é quinta, 01/10, às 20h de Brasília. Como quarta não está na regra, a API pulou para o próximo dia válido. Faz sentido, mas se o seu código mostrar para a pessoa "lembrete marcado para quarta" usando o que enviou, vai mentir. Confira sempre o remindAt que voltou.
3. Repetição tem regras próprias. Duas combinações dão 422. repeat sem remindAt:
{
"error": {
"message": "Defina a data e a hora do primeiro aviso.",
"fields": {
"repeat": "Escolha a data e a hora."
}
}
}
E count junto com until, porque a série termina por um ou pelo outro:
{
"error": {
"message": "Verifique os dados informados.",
"fields": {
"repeat.count": "Escolha data final ou número de vezes, não os dois."
}
}
}
Repare que todo erro vem no mesmo formato: uma message em português e, em fields, o campo exato que precisa de conserto. Dá para mostrar isso direto para quem está usando o seu sistema.
🪤 O acento que virou interrogação
Esta me pegou no meio do caminho. Criei no lote uma nota "Devolver o livro de feitiços", com o JSON escrito direto no -d do curl, no Git Bash do Windows. A API respondeu 201, tudo lindo, e a nota foi salva assim:
"content": "Devolver o livro de feiti�os"
O "ç" virou "�". 😳 A culpa não é da API: é o caminho entre o terminal e o curl no Windows, que entregou o texto sem ser em UTF-8. A saída é tirar o JSON da linha de comando. Crie um arquivo nota.json num editor que salve em UTF-8 (o VS Code já salva assim):
{ "content": "Devolver o livro de feitiços" }
E mande o arquivo com --data-binary e um @ antes do nome:
curl -X POST https://www.pensieve.com.br/api/v1/notes \
-H "Authorization: Bearer $PENSIEVE_API_KEY" \
-H "Content-Type: application/json" \
--data-binary @nota.json
Aí o "feitiços" chegou inteiro. O --data-binary manda o arquivo exatamente como está, byte a byte. E se você vai escrever notas com acento de verdade, o script em Node logo abaixo não tem esse problema.
🟩 Um script em Node, sem instalar nada
O curl é ótimo para experimentar, mas para usar no dia a dia um script é mais confortável. Este aqui cria uma nota, cria um lembrete, busca, manda para a lixeira e, de propósito, tenta um lembrete sem fuso para ver o erro. Ele usa o fetch que já vem no Node 18 ou mais novo: não precisa de npm install nenhum.
Salve como notas.js:
// notas.js: cria, busca e apaga notas no Pensieve usando só o fetch do Node 18+
// Rode com: PENSIEVE_API_KEY=sua_chave node notas.js
const BASE = "https://www.pensieve.com.br/api/v1";
const CHAVE = process.env.PENSIEVE_API_KEY;
if (!CHAVE) {
console.error("Defina a variável de ambiente PENSIEVE_API_KEY.");
process.exit(1);
}
async function chamarApi(metodo, caminho, corpo) {
const resposta = await fetch(BASE + caminho, {
method: metodo,
headers: {
"Authorization": "Bearer " + CHAVE,
"Content-Type": "application/json",
},
body: corpo ? JSON.stringify(corpo) : undefined,
});
// O DELETE responde 204, sem corpo nenhum: chamar .json() aqui daria erro
if (resposta.status === 204) {
return null;
}
const dados = await resposta.json();
// resposta.ok aceita 200 e 201 (criar nota devolve 201, não 200)
if (!resposta.ok) {
const campos = JSON.stringify(dados.error.fields || {});
throw new Error(`HTTP ${resposta.status}: ${dados.error.message} ${campos}`);
}
return dados;
}
async function criarNota(texto) {
const dados = await chamarApi("POST", "/notes", { content: texto });
return dados.note;
}
async function criarLembrete(texto, dataHora) {
// A data PRECISA ter o fuso no fim (-03:00). Sem ele, a API responde 422.
const dados = await chamarApi("POST", "/notes", {
content: texto,
remindAt: dataHora,
timeZone: "America/Sao_Paulo",
});
return dados.note;
}
async function buscarNotas(trecho) {
const dados = await chamarApi("GET", "/notes?q=" + encodeURIComponent(trecho));
return dados.notes;
}
async function apagarNota(id) {
await chamarApi("DELETE", "/notes/" + id);
}
async function principal() {
try {
const nota = await criarNota("Comprar penas de escrever e um tinteiro");
console.log("Nota criada:", nota.id, "-", nota.content);
const lembrete = await criarLembrete("Levar a coruja ao veterinário", "2026-10-02T15:30:00-03:00");
console.log("Lembrete criado:", lembrete.id, "- avisa em", lembrete.remindAt);
const achadas = await buscarNotas("tinteiro");
console.log("Busca por 'tinteiro':", achadas.length, "nota(s)");
await apagarNota(nota.id);
console.log("Nota", nota.id, "foi para a lixeira");
// De propósito: uma data sem fuso, para ver o erro
await criarLembrete("Esta não vai ser salva", "2026-10-02T15:30:00");
} catch (erro) {
console.error("Deu erro:", erro.message);
}
}
principal();
Dois detalhes do chamarApi evitam bugs que eu já vi muita gente cometer:
- O
ifdo 204 vem antes do.json(). ODELETEresponde sem corpo, eresposta.json()num corpo vazio estoura umSyntaxError. Sem esseif, a nota vai para a lixeira e o seu script acusa erro assim mesmo. - O teste é
resposta.ok, nãostatus === 200. Criar nota devolve 201. Quem escreve=== 200na mão trata toda criação como falha.
Para rodar, no Linux, no Mac ou no Git Bash, a variável vai na frente do comando:
PENSIEVE_API_KEY=SUA_CHAVE_AQUI node notas.js
No PowerShell, defina a variável antes e rode em seguida:
$env:PENSIEVE_API_KEY = "SUA_CHAVE_AQUI"
node notas.js
A saída:
Nota criada: 22 - Comprar penas de escrever e um tinteiro
Lembrete criado: 23 - avisa em 2026-10-02T18:30:00.000Z
Busca por 'tinteiro': 1 nota(s)
Nota 22 foi para a lixeira
Deu erro: HTTP 422: Verifique os dados informados. {"remindAt":"Data/hora inválida."}
A última linha é o erro de propósito, e ele aparece com o campo exato que falhou. O lembrete das 15h30 de Brasília voltou como 18h30 em UTC, igualzinho ao do curl. E esquecendo a variável, o script para logo na primeira linha útil:
Defina a variável de ambiente PENSIEVE_API_KEY.
📖 A documentação interativa
Não precisa decorar nada disso. A API tem uma referência interativa em /api/v1/docs, gerada da especificação OpenAPI 3.1. Lá estão todos os endpoints, com os parâmetros e as respostas.

O botão Authorize recebe a sua chave e deixa testar as chamadas ali mesmo, pelo navegador. E o arquivo /api/v1/openapi.json importa direto no Postman ou no Insomnia, com todas as rotas prontas.
Os erros que você pode encontrar cabem numa tabela:
| Código | Quando acontece |
|---|---|
| 401 | Chave ausente (API_KEY_MISSING) ou inválida e revogada (API_KEY_INVALID) |
| 404 | A nota ou a lista não existe, ou é de outra conta |
| 409 | Já existe uma lista com esse nome |
| 422 | Dado inválido; o campo vem em fields |
| 429 | Mais de 120 requisições por minuto com a mesma chave |
O 401 sem chave nenhuma já diz o que fazer:
{
"error": {
"message": "Informe sua API Key no cabeçalho Authorization: Bearer pk_…",
"code": "API_KEY_MISSING"
}
}
🧩 A Skill: a IA aprende a usar a API
Uma Skill é um arquivo Markdown com nome, descrição e instruções, no formato Agent Skills. Ela não é código: é um manual que a IA lê e segue. A do Pensieve fica publicada em https://www.pensieve.com.br/api/v1/skill.md e ensina ao agente os endpoints, as datas com fuso, os lembretes recorrentes e as boas maneiras.
O arquivo começa com um cabeçalho (o frontmatter, entre duas linhas de ---) com o nome pensieve e uma descrição. A descrição termina assim:
Use quando a pessoa pedir para anotar algo, lembrar de algo numa data/hora ou com frequência, adiar um lembrete, ou organizar/consultar suas notas e listas no Pensieve.
Quando você pede "me lembra de pagar o aluguel todo dia 5", essa descrição é o que faz a IA perceber que a Skill serve para o pedido. E o resto do arquivo diz como agir. Algumas regras que estão lá dentro:
- Nunca mostrar, repetir ou registrar a chave nas respostas.
- Buscar antes de editar (
GET /notes?q=trecho) e perguntar se vier mais de uma nota. Nada de adivinhar oid. - Perguntar antes de criar uma lista que não existe.
- Confirmar antes de excluir, citando o texto da nota.
- Se a pessoa não disser o fuso, usar
America/Sao_Paulo.
Para instalar no Claude Code, a Skill vai numa pasta com o nome dela, dentro de ~/.claude/skills. O ~ é a sua pasta de usuário. O mkdir -p cria a pasta (e as de cima, se faltarem), e o curl -o baixa o arquivo com o nome certo:
mkdir -p ~/.claude/skills/pensieve
curl -o ~/.claude/skills/pensieve/SKILL.md https://www.pensieve.com.br/api/v1/skill.md
Depois é só deixar a chave na variável PENSIEVE_API_KEY, como no começo do artigo. É esse o nome que a Skill manda a IA usar nos comandos.

No app do Claude, a pasta com o arquivo vai em Configurações › Capacidades. Em outros agentes, dá para colar o conteúdo do skill.md nas instruções do sistema. E se você quiser entender como se escreve uma Skill dessas para a sua própria API, eu contei o passo a passo em Criando uma Skill para IAs usarem a sua API. 🪄
🔌 O MCP: a IA ganha ferramentas
A Skill ensina a IA a chamar a API. O MCP (Model Context Protocol) vai por outro caminho: o Pensieve é um servidor que entrega à IA ferramentas prontas, cada uma com nome, descrição e parâmetros. A IA não monta curl nenhum: ela chama create_note e pronto.
O servidor fica em https://www.pensieve.com.br/api/mcp. No Claude, no ChatGPT, no Cursor ou no VS Code, você adiciona esse endereço como conector personalizado, e abre uma janela do Pensieve para você entrar e autorizar (OAuth 2.1 com PKCE). Repare: não precisa copiar chave nenhuma. As IAs conectadas aparecem em Minha conta › API, onde dá para desconectar cada uma.
No Claude Code, é um comando:
claude mcp add --transport http pensieve https://www.pensieve.com.br/api/mcp
Para cliente que não fala OAuth, dá para mandar a chave no cabeçalho, num mcp.json:
{
"mcpServers": {
"pensieve": {
"type": "http",
"url": "https://www.pensieve.com.br/api/mcp",
"headers": {
"Authorization": "Bearer SUA_CHAVE_AQUI"
}
}
}
}

Pedi ao servidor a lista de ferramentas (o método tools/list do protocolo) e vieram quinze:
| Ferramenta | O que faz |
|---|---|
search | Busca notas pelo texto |
fetch | Lê uma nota pelo id |
whoami | Nome e e-mail da conta conectada |
list_notes | Lista notas com filtros e paginação |
get_note_counts | Contagens: todas, favoritas, com lembrete, sem lista, arquivadas e lixeira |
create_note | Cria uma nota, com lembrete e repetição se quiser |
create_notes | Cria de 1 a 50 notas numa chamada |
update_note | Altera ou arquiva uma nota |
snooze_note | Adia o lembrete |
delete_note | Manda para a lixeira |
restore_note | Tira da lixeira |
list_lists | Todas as listas, na ordem da pessoa |
create_list | Cria uma lista |
update_list | Renomeia ou muda a cor |
delete_list | Exclui a lista; as notas ficam "Sem lista" |
Vêm também três prompts prontos: organizar_sem_lista (sugere uma lista para cada nota solta e move depois da sua confirmação), resumo_da_semana (notas dos últimos 7 dias e lembretes dos próximos 7) e conversa_em_notas (tira as decisões e tarefas da conversa e salva como notas).
O MCP em ação
Com o conector ligado no Claude, o pedido "me lembra de tomar a poção de ânimo todo dia às 8h, por uma semana" virou uma chamada à create_note com estes argumentos:
{
"content": "Tomar a poção de ânimo",
"listId": 4,
"remindAt": "2026-09-28T08:00:00-03:00",
"repeat": {
"freq": "daily",
"count": 7
},
"timeZone": "America/Sao_Paulo"
}
O "por uma semana" virou count: 7, e a data veio com fuso, do jeito que a API exige. A resposta:
{
"note": {
"id": 24,
"content": "Tomar a poção de ânimo",
"listId": 4,
"isFavorite": false,
"isArchived": false,
"archivedAt": null,
"remindAt": "2026-09-28T11:00:00.000Z",
"repeat": {
"freq": "daily",
"interval": 1,
"count": 7
},
"createdAt": "2026-09-26T01:36:55.000Z",
"updatedAt": "2026-09-26T01:36:55.000Z",
"deletedAt": null,
"purgeAt": null,
"url": "https://www.pensieve.com.br/app?nota=24"
}
}
É a mesma nota da API REST, com um campo a mais no fim: a url. Ela abre a nota direto no mural, e é por isso que a IA consegue responder "anotei, está aqui" com um link clicável. ✨
E a search devolve um formato mais enxuto, só com id, título e link. Buscando por "coruja":
{
"results": [
{
"id": "23",
"title": "Levar a coruja ao veterinário",
"url": "https://www.pensieve.com.br/app?nota=23"
},
{
"id": "17",
"title": "Alimentar a coruja",
"url": "https://www.pensieve.com.br/app?nota=17"
}
]
}
Para ler a nota inteira, a IA chama a fetch com o id. E se você quer ver como é construir um MCP desses por dentro, com a ponte de OAuth, eu escrevi sobre isso em Criando um MCP para uma API com OAuth.
🎁 E o que mais vem junto
Fora a parte de IA, o Pensieve tem umas coisas que eu faço questão de mencionar, porque são justamente as que costumam ser pagas por aí:
- Exportação em JSON, Markdown ou CSV, com listas, lembretes e repetições. Suas notas saem com você.
- App para Windows, Mac e Linux, com notificação nativa e botão "Adiar 10 min".
- Site instalável como app no celular e no computador, direto do navegador.
- Arquivo e lixeira de 30 dias, com desfazer.
- Atalhos de teclado:
Nescreve,/busca,Ffavorita.
Tudo isso, e a API, a Skill e o MCP, está em qualquer conta, de graça. A página com toda a parte técnica é esta:
Pensieve para desenvolvedoresAPI REST, documentação OpenAPI, Skill para agentes e servidor MCP do Pensieve.pensieve.com.brPor hoje é só, meus unicórnios! 🦄✨
Que a magia do arco-íris continue brilhando em suas vidas! Até mais! 🌈🌟
Perguntas frequentes
O Pensieve é gratuito?
Por que a API responde 422 "Data/hora inválida"?
remindAt foi enviado sem fuso, como 2026-09-28T09:00:00. A API exige ISO 8601 com fuso: 2026-09-28T09:00:00-03:00 ou com Z no fim.Por que o lembrete volta com um horário diferente do que eu mandei?
12:00:00.000Z. É o mesmo instante: converta para o fuso da pessoa na hora de mostrar.Qual a diferença entre a Skill e o MCP do Pensieve?
create_note, search e outras) que o Claude, o ChatGPT e o Cursor conectam com login OAuth, sem copiar chave.Excluir uma nota pela API apaga de vez?
DELETE /notes/{id} manda a nota para a lixeira, de onde ela volta com POST /notes/{id}/restore por até 30 dias. Apagar de vez é o DELETE /notes/{id}/permanent, que só funciona com a nota já na lixeira.Por que o acento da minha nota virou um ponto de interrogação?
-d do curl chegou sem UTF-8, e "feitiços" virou "feiti�os". Grave o JSON num arquivo e envie com --data-binary @nota.json, ou use um script em Node.Leia também
API Mágica: CEP e Pix de graça, sem cartão
Lancei a API Mágica: CEP, QR Code Pix, geradores e mais, de graça. Veja como consultar e gerar com Node.js em poucas linhas.
Resend: enviando e recebendo e-mails com Node.js
Tutorial da Resend com Node.js: criar a chave, enviar com fetch, verificar o domínio e receber e-mails por webhook conferindo a assinatura.
Node.js: testando scripts de scraping no ScrapingCourse
O ScrapingCourse é um site feito para treinar scraping. Cinco desafios dele em Node.js, e a armadilha real que cada um esconde.


