sapiens-mcp 1.46.0 → 1.46.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +8 -0
- package/dist/registry.js +23 -8
- package/dist/skills.js +73 -13
- package/dist/tools/gallery.js +58 -7
- package/dist/tools/profile.js +14 -0
- package/dist/tools/studios.js +41 -34
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -53,6 +53,14 @@ O Claude avisa o custo antes de gastar, e geração que falha é estornada. Publ
|
|
|
53
53
|
|
|
54
54
|
O servidor só conversa com o backend público do Sapiens (Convex). Sua identidade vem sempre do token de login, nunca de parâmetros soltos. Cada conta só mexe no que é dela.
|
|
55
55
|
|
|
56
|
+
## Sobre o Sapiens Sintéticos
|
|
57
|
+
|
|
58
|
+
O Sapiens Sintéticos é um Studio de IA que constrói Studios: ensino modelo de pensamento na Era Sintética pra cada pessoa montar o próprio sistema de criação, com voz e régua próprias. O método se chama Borderless: 5 pilares, 7 deltas e uma sequência de 7 fases pra tirar ideia do papel (Tesão, Cruzamento, Confronto Crítico, Prototipagem, MVP, Validação, Continuidade).
|
|
59
|
+
|
|
60
|
+
Em inglês o projeto assina **Synthetic Sapiens**: an AI studio that builds studios. The missing skill is not using AI, it is inventing the system the AI feeds. That system is a studio of your own, the personal computer of 2026.
|
|
61
|
+
|
|
62
|
+
Site oficial: [sapiensinteticos.com](https://www.sapiensinteticos.com) · Manifesto: [/manifesto](https://www.sapiensinteticos.com/manifesto) · Contexto pra máquina: [/llms.txt](https://www.sapiensinteticos.com/llms.txt)
|
|
63
|
+
|
|
56
64
|
---
|
|
57
65
|
|
|
58
66
|
Feito por [BorderLess](https://sapiensinteticos.com). Licença MIT.
|
package/dist/registry.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { ZodError } from "zod";
|
|
1
2
|
import { zodToJsonSchema } from "zod-to-json-schema";
|
|
2
3
|
import { pipeline, pipelineSchema } from "./tools/pipeline.js";
|
|
3
4
|
import { image, imageSchema } from "./tools/image.js";
|
|
@@ -58,7 +59,7 @@ export const TOOLS = {
|
|
|
58
59
|
handler: meta,
|
|
59
60
|
},
|
|
60
61
|
sapiens_skill: {
|
|
61
|
-
description: "As SKILLS da casa: o passo a passo travado de cada fluxo do Sapiens, servido pelo próprio connector (sem login, sem custo, sem rede). LEIA A SKILL ANTES DE OPERAR O FLUXO — é mais barato que errar uma geração que cobra Sinapses. Sub-actions: 'list' (índice: slug + quando usar cada uma), 'get' (o SKILL.md inteiro, passe name=<slug>). Slugs: primeiros-passos (porta de entrada e as 4 armadilhas: timeout que já cobrou, disjuntor anti-loop, saldo, sessão), voz-da-casa (DNA editorial, leia antes de redigir qualquer texto publicável), musica (Musicator em 4 passos + efeito sonoro), video (qual modelo, iterar barato no Mini, storyboard por referência, sonorize), imagem (prompt full-bleed na régua da casa, multi-referência, templates), studio (o perfil de empresa
|
|
62
|
+
description: "As SKILLS da casa: o passo a passo travado de cada fluxo do Sapiens, servido pelo próprio connector (sem login, sem custo, sem rede). LEIA A SKILL ANTES DE OPERAR O FLUXO — é mais barato que errar uma geração que cobra Sinapses. Sub-actions: 'list' (índice: slug + quando usar cada uma), 'get' (o SKILL.md inteiro, passe name=<slug>). Slugs: primeiros-passos (porta de entrada e as 4 armadilhas: timeout que já cobrou, disjuntor anti-loop, saldo, sessão), voz-da-casa (DNA editorial, leia antes de redigir qualquer texto publicável), musica (Musicator em 4 passos + efeito sonoro), video (qual modelo, iterar barato no Mini, storyboard por referência, sonorize), imagem (prompt full-bleed na régua da casa, multi-referência, templates), studio (fundar a casa, o perfil de empresa, o time, e por que o studio não entra na geração), tirinha (2 fases, a imagem sai SEM texto), forum-comunidade (mídia estruturada, menção, tese), companhia (o Sintético veste você), trilhas (missão e prova), minha-soul (instala o retrato do usuário como skill do projeto onde vocês estão). O mesmo conteúdo também sai como resource MCP em skill://sapiens/<slug>/SKILL.md pra quem lê resources.",
|
|
62
63
|
schema: skillSchema,
|
|
63
64
|
handler: skill,
|
|
64
65
|
},
|
|
@@ -68,7 +69,7 @@ export const TOOLS = {
|
|
|
68
69
|
handler: repertorio,
|
|
69
70
|
},
|
|
70
71
|
sapiens_gallery: {
|
|
71
|
-
description: "Browse, publicação e upload das imagens do user. Sub-actions: list (últimas N imagens, com prompt/model/url + isPublic), get (1 imagem com metadados, opcionalmente base64), publish (torna a PRÓPRIA imagem pública: entra na galeria pública + feed Pinterest, e ganha página indexável /imagem/<id> se o modelo não for degen — devolve publicPageUrl), unpublish (volta a privada), upload (traz pra galeria uma peça gerada FORA da casa, por sourceUrl https, filePath local ou base64; ADMIN por ora). Use list/get pra reusar imagem como referência (passe o imageId em sapiens_image mode=edit ou mode=variation) ou pra mostrar pro user o que ele já tem; publish quando o user quer divulgar a imagem dele. IMPORTANTE sobre upload: a peça entra PRIVADA e continua privada — o servidor recusa publicar e recusa compartilhar na comunidade, porque ela é do usuário e a responsabilidade é dele. O caminho pra ela virar coisa pública é usar como referência numa geração daqui e publicar o resultado.",
|
|
72
|
+
description: "Browse, publicação e upload das imagens do user. Sub-actions: list (últimas N imagens, com prompt/model/url + isPublic), get (1 imagem com metadados, opcionalmente base64), publish (torna a PRÓPRIA imagem pública: entra na galeria pública + feed Pinterest, e ganha página indexável /imagem/<id> se o modelo não for degen — devolve publicPageUrl), unpublish (volta a privada), upload (traz pra galeria uma peça gerada FORA da casa, por sourceUrl https, filePath local ou base64; ADMIN por ora), refs (acopla peças da casa como REFERÊNCIA numa peça que já existe, de upload ou de ingest; ADMIN, e só na própria peça). Use list/get pra reusar imagem como referência (passe o imageId em sapiens_image mode=edit ou mode=variation) ou pra mostrar pro user o que ele já tem; publish quando o user quer divulgar a imagem dele. IMPORTANTE sobre upload: a peça entra PRIVADA e continua privada — o servidor recusa publicar e recusa compartilhar na comunidade, porque ela é do usuário e a responsabilidade é dele. O caminho pra ela virar coisa pública é usar como referência numa geração daqui e publicar o resultado. O refs escreve só proveniência (de que ficha/folha a peça nasceu): não promove nada, e um upload continua sem publicar depois de ganhar referência.",
|
|
72
73
|
schema: gallerySchema,
|
|
73
74
|
handler: gallery,
|
|
74
75
|
},
|
|
@@ -98,7 +99,7 @@ export const TOOLS = {
|
|
|
98
99
|
handler: search,
|
|
99
100
|
},
|
|
100
101
|
sapiens_studios: {
|
|
101
|
-
description: "
|
|
102
|
+
description: "O SEU studio (o perfil de EMPRESA da casa do user) + o catálogo dos estúdios/experimentos Sapiens. Sub-actions: mine (o studio do user: nome/endereço público/marca/operador/tamanho do time), create (FUNDA um studio novo, exige name; nasce privado, de graça, teto de 4 por pessoa), list (catálogo com URL+status+tags+mcpReady), get (detalhe de 1 slug), publishable_url (formata URL /articles/<slug>). Use quando user pergunta 'que estúdios existem', 'qual o meu studio', ou diz 'quero abrir/fundar meu studio', 'criar a página da minha empresa'. Estúdios cobertos: helen-voice, musicator, persona-sapiens, personagem-atlas, sapiens-shorts, sapiens-video, text-post-builder, comic-builder, carrosel-editorial, comunidade, repertorio.",
|
|
102
103
|
schema: studiosSchema,
|
|
103
104
|
handler: studios,
|
|
104
105
|
},
|
|
@@ -148,7 +149,7 @@ export const TOOLS = {
|
|
|
148
149
|
handler: character,
|
|
149
150
|
},
|
|
150
151
|
sapiens_profile: {
|
|
151
|
-
description: "O 'tudo junto' do perfil do user (/u/<username>), user-tier. Agrega o que mora no perfil mas estava fora do MCP: identidade + nível/XP + saldo, badges (conquistas) e golden tools (favoritos do aitag). Sub-actions de LEITURA: get (card completo: identidade + nível + saldo + badges + golden tools), badges (só as conquistas, lista cheia), golden_tools (só os favoritos do aitag, lista cheia), notifications (suas notificações recentes do sino + contagem de não-lidas), mark_read (marca uma notificationId ou TODAS as não-lidas como lidas). Sub-actions de ESCRITA (mexem na SUA conta; identidade sempre da sessão): follow/unfollow (seguir/deixar de seguir outro user por followingId=users:_id, descoberto via sapiens_community participants/search_users), update_bio (edita a sua bio), update_username (troca o seu @; inválido/tomado volta {success:false,error}). FAVORITOS de ferramentas de IA (Golden Tools do aitag; o toolId vem de sapiens_repertorio action=search_tools): favorite_tool (favorita/desfavorita, estrela), favorite_lists (suas listas), create_favorite_list (listName+emoji/description/isPublic), add_to_favorite_list/remove_from_favorite_list (toolId+listId), delete_favorite_list (listId). As partes grandes do perfil NÃO são duplicadas aqui, têm tool própria: imagens geradas/publicadas=sapiens_gallery, repertório (filmes/séries/jogos/livros/música)=sapiens_repertorio, personagens=sapiens_character, persona/arquétipo MBTI=sapiens_persona action=my_profile, saldo detalhado por bucket=sapiens_meta action=subscription. Monta a partir de queries já em prod (sem custo).",
|
|
152
|
+
description: "O 'tudo junto' do perfil do user (/u/<username>), user-tier. Agrega o que mora no perfil mas estava fora do MCP: identidade + nível/XP + saldo, badges (conquistas) e golden tools (favoritos do aitag). Sub-actions de LEITURA: get (card completo: identidade + nível + saldo + badges + golden tools), soul (a sapiens-soul: retrato do momento no contrato sapiens.soul/v1, identidade + persona + repertório público + tese, derivado e datado; quando o user pedir 'minha soul' ou 'meu retrato do Sapiens' pro projeto dele, chame e salve como sapiens-soul.json — snapshot, não conexão viva), badges (só as conquistas, lista cheia), golden_tools (só os favoritos do aitag, lista cheia), notifications (suas notificações recentes do sino + contagem de não-lidas), mark_read (marca uma notificationId ou TODAS as não-lidas como lidas). Sub-actions de ESCRITA (mexem na SUA conta; identidade sempre da sessão): follow/unfollow (seguir/deixar de seguir outro user por followingId=users:_id, descoberto via sapiens_community participants/search_users), update_bio (edita a sua bio), update_username (troca o seu @; inválido/tomado volta {success:false,error}). FAVORITOS de ferramentas de IA (Golden Tools do aitag; o toolId vem de sapiens_repertorio action=search_tools): favorite_tool (favorita/desfavorita, estrela), favorite_lists (suas listas), create_favorite_list (listName+emoji/description/isPublic), add_to_favorite_list/remove_from_favorite_list (toolId+listId), delete_favorite_list (listId). As partes grandes do perfil NÃO são duplicadas aqui, têm tool própria: imagens geradas/publicadas=sapiens_gallery, repertório (filmes/séries/jogos/livros/música)=sapiens_repertorio, personagens=sapiens_character, persona/arquétipo MBTI=sapiens_persona action=my_profile, saldo detalhado por bucket=sapiens_meta action=subscription. Monta a partir de queries já em prod (sem custo).",
|
|
152
153
|
schema: profileSchema,
|
|
153
154
|
handler: profile,
|
|
154
155
|
},
|
|
@@ -226,9 +227,8 @@ Cliente que lê resources MCP acha o MESMO conteúdo em skill://sapiens/<slug>/S
|
|
|
226
227
|
REGRA DE OURO:
|
|
227
228
|
- PRIMEIRO CONTATO ou "o que você faz?"/"como começo?"/"o que dá pra fazer?": chame sapiens_meta action=start e MOSTRE o resultado na sua voz. Sem login, ele ensina a conectar; logado, traz saldo + primeiros poderes com exemplos. É a porta de entrada: não despeje a lista inteira de tools, deixe o start guiar.
|
|
228
229
|
- LOGO APÓS UM LOGIN BEM-SUCEDIDO (action=login retornou ok): chame action=start na sequência e mostre a porta de entrada. O recém-chegado não sabe o que pedir; não o deixe na tela em branco, guie a primeira jogada sem ele precisar perguntar.
|
|
229
|
-
- Se um tool voltar erro de validação ("exige X", "falta Y"), LEIA o erro e refaça a chamada COM o que falta. NUNCA repita igual a chamada que falhou: 3 falhas seguidas no mesmo tool fazem o cliente marcar o servidor como "unreachable" por ~56s (disjuntor anti-loop). Aí parece que "o MCP caiu", quando foi só argumento faltando.
|
|
230
230
|
- Antes de gerar algo caro (imagem/música/vídeo), cheque saldo: sapiens_meta action=credits (ou subscription). Saldo baixo, avise o usuário antes. Vídeo é o mais caro da casa: confirme com ele antes de disparar.
|
|
231
|
-
- REGRA DO TIMEOUT
|
|
231
|
+
- REGRA DO TIMEOUT: geração SÍNCRONA pode estourar o teto de ~120s do cliente e voltar 'Timeout' MESMO tendo gerado e COBRADO. Nunca repita às cegas: confira antes onde o resultado cairia (a tabela de onde conferir está na skill 'primeiros-passos').
|
|
232
232
|
- "sessionToken expirado" = refaça login: sapiens_meta action=login com o código de sapiensinteticos.com/conectar-claude.
|
|
233
233
|
- sapiens_meta action=formats devolve os schemas por formato; action=whoami diz tier (user/admin) + saldo. sapiens_image e sapiens_video action=models trazem o catálogo com o preço ATUAL: consulte em vez de chutar custo.
|
|
234
234
|
|
|
@@ -265,7 +265,7 @@ const TOOL_TITLES = {
|
|
|
265
265
|
sapiens_write: "Artigos do Perfil",
|
|
266
266
|
sapiens_quote_pop: "Coluna Sapiens/Repertório",
|
|
267
267
|
sapiens_search: "Buscar Artigos",
|
|
268
|
-
sapiens_studios: "
|
|
268
|
+
sapiens_studios: "Meu Studio & Estúdios",
|
|
269
269
|
sapiens_persona: "Persona (MBTI)",
|
|
270
270
|
sapiens_helen: "Voz Helen (TTS)",
|
|
271
271
|
sapiens_musicator: "Musicator",
|
|
@@ -353,8 +353,23 @@ export async function callTool(name, rawArgs) {
|
|
|
353
353
|
}
|
|
354
354
|
catch (e) {
|
|
355
355
|
return {
|
|
356
|
-
content: [
|
|
356
|
+
content: [
|
|
357
|
+
{ type: "text", text: `Erro: ${describeConvexError(e)}${retryHint(e)}` },
|
|
358
|
+
],
|
|
357
359
|
isError: true,
|
|
358
360
|
};
|
|
359
361
|
}
|
|
360
362
|
}
|
|
363
|
+
/**
|
|
364
|
+
* A regra do disjuntor viaja NO ERRO, não no handshake. Ela só passa a valer
|
|
365
|
+
* depois que uma chamada falhou, então cobrar ~300 chars de TODA conversa pra
|
|
366
|
+
* avisar de algo que talvez nunca aconteça é caro: aqui ela chega no instante
|
|
367
|
+
* exato em que aplica e custa zero nas outras. Só em erro de validação (Zod):
|
|
368
|
+
* erro de saldo ou de sessão tem o próprio conserto, e repetir a chamada
|
|
369
|
+
* idêntica não é o risco deles.
|
|
370
|
+
*/
|
|
371
|
+
function retryHint(e) {
|
|
372
|
+
if (!(e instanceof ZodError))
|
|
373
|
+
return "";
|
|
374
|
+
return " -> Refaça a chamada COM o campo corrigido. NUNCA repita idêntica: 3 falhas seguidas no mesmo tool fazem o cliente marcar o servidor como 'unreachable' por ~56s, e aí parece que o MCP caiu quando foi só argumento faltando.";
|
|
375
|
+
}
|
package/dist/skills.js
CHANGED
|
@@ -262,15 +262,24 @@ Aí não é geração base, é o Studio dela. Veja a skill \`studio\`.`,
|
|
|
262
262
|
},
|
|
263
263
|
{
|
|
264
264
|
name: "studio",
|
|
265
|
-
title: "Meu Studio
|
|
266
|
-
description: "O studio é a PÁGINA de portfólio da pessoa (obra, time, endereço público). Puxe quando ela falar do studio dela, quiser mostrar a casa
|
|
265
|
+
title: "Meu Studio",
|
|
266
|
+
description: "O studio é a PÁGINA de portfólio da empresa da pessoa (obra, time, endereço público), e você funda o dela pelo chat. Puxe quando ela falar do studio dela, quiser fundar um, mostrar a casa ou montar time.",
|
|
267
267
|
body: `## O que o studio é
|
|
268
268
|
|
|
269
|
-
O studio é a **página de portfólio** da pessoa: um endereço público (\`sapiensinteticos.com/studios/<slug>\`) com a obra, o time e o que a casa faz. Não é uma paleta de ferramentas, não tem níveis, e **não é identidade de geração**: isso morreu.
|
|
269
|
+
O studio é a **página de portfólio** da empresa da pessoa: um endereço público (\`sapiensinteticos.com/studios/<slug>\`) com a obra, o time e o que a casa faz. Não é uma paleta de ferramentas, não tem níveis, e **não é identidade de geração**: isso morreu.
|
|
270
270
|
|
|
271
271
|
Uma pessoa pode ter até 4 studios e integrar até 4. \`sapiens_studios action=mine\` mostra o primário dela: nome, endereço público, marca e tamanho do time. O servidor resolve pela SESSÃO, você nunca passa id.
|
|
272
272
|
|
|
273
|
-
|
|
273
|
+
## Fundar
|
|
274
|
+
|
|
275
|
+
\`sapiens_studios action=create name="<nome da casa>"\` funda. De graça, sem Sinapse.
|
|
276
|
+
|
|
277
|
+
- **Pergunte o nome, nunca invente.** O endereço público sai dele, em kebab-case, e é o que vai no cartão de visita da pessoa.
|
|
278
|
+
- \`description\` (uma linha) é opcional e aparece embaixo do nome. \`brandSlug\` ancora a marca dela, se ela já tiver uma.
|
|
279
|
+
- Nasce **privado**, com ela como fundadora. Publicar é decisão dela, na página.
|
|
280
|
+
- Bateu o teto de 4: o erro diz. Não insista, ela sai de um pra fundar outro.
|
|
281
|
+
|
|
282
|
+
Depois de fundar, entregue o link e pare. Vestir a página (capa, logo, sobre, seções, ordem da obra) é no modo edição da própria página, não por aqui.
|
|
274
283
|
|
|
275
284
|
## O studio NÃO entra na geração
|
|
276
285
|
|
|
@@ -286,15 +295,7 @@ Pergunte qual, não adivinhe.
|
|
|
286
295
|
|
|
287
296
|
Gente entra por convite, e o convite exige **follow mútuo**: os dois precisam já se seguir. Personagem do próprio elenco entra sem convite, é posse. Teto de 4 pessoas por casa.
|
|
288
297
|
|
|
289
|
-
A obra da página é automática por default: a soma dos Destaques de quem está no time. Se alguém empurrar uma peça à mão, ela passa a ser curada. Tudo isso se faz na página, não por aqui
|
|
290
|
-
|
|
291
|
-
## Emancipação
|
|
292
|
-
|
|
293
|
-
O passo grande: quando o membro quer a casa PRÓPRIA dele, site ou produto próprio, FORA do Sapiens.
|
|
294
|
-
|
|
295
|
-
\`sapiens_studios action=emancipar\` devolve o blueprint pra VOCÊ construir na infra DELE (Vercel, Convex e domínio dele), começando pela Fundação e seguindo um módulo por vez (\`action=module module=<slug>\`: fundacao, sapiens-connect, telegram, email, auth).
|
|
296
|
-
|
|
297
|
-
Confirme cada passo. Nunca hospede no Sapiens. Siga o gosto dele. É complexo: conduza com calma.`,
|
|
298
|
+
A obra da página é automática por default: a soma dos Destaques de quem está no time. Se alguém empurrar uma peça à mão, ela passa a ser curada. Tudo isso se faz na página, não por aqui.`,
|
|
298
299
|
},
|
|
299
300
|
{
|
|
300
301
|
name: "tirinha",
|
|
@@ -402,6 +403,65 @@ Sem bloco companion, opere na voz neutra da casa.`,
|
|
|
402
403
|
|
|
403
404
|
**O crédito em Sinapses sai na APROVAÇÃO dele, não na hora.** Não prometa Sinapse no momento do claim. Diga que a prova foi enviada e que o crédito vem quando for aprovada.`,
|
|
404
405
|
},
|
|
406
|
+
{
|
|
407
|
+
name: "minha-soul",
|
|
408
|
+
title: "Instalar a soul do usuário neste projeto",
|
|
409
|
+
description: "Transforma o retrato do usuário no Sapiens numa skill local do projeto atual, pra toda conversa nesta pasta já saber quem é o dono. Puxe quando ele disser 'instala minha soul', 'meu Claude precisa me conhecer', 'personaliza esse projeto comigo'.",
|
|
410
|
+
body: `## O que você vai fazer
|
|
411
|
+
|
|
412
|
+
Escrever a soul da pessoa como skill LOCAL do projeto onde vocês estão. Depois disso, toda conversa nesta pasta abre já sabendo quem é o dono: o gosto, o jeito de pensar, o repertório. Sem MCP no meio, sem chave, sem rede.
|
|
413
|
+
|
|
414
|
+
## Passo a passo
|
|
415
|
+
|
|
416
|
+
1. \`sapiens_profile action=soul\` devolve o contrato \`sapiens.soul/v1\`. Não cobra Sinapse.
|
|
417
|
+
2. Escreva \`.claude/skills/sapiens-soul/SKILL.md\` na raiz do projeto atual, no molde abaixo. Pasta que não existe, você cria. Arquivo que já existe, você sobrescreve: é o retrato de hoje.
|
|
418
|
+
3. Confirme em UMA linha: o caminho do arquivo e a data do retrato. Não despeje o JSON na conversa.
|
|
419
|
+
|
|
420
|
+
Se a pessoa não estiver dentro de um projeto (conversa sem pasta, claude.ai), diga onde o arquivo deveria morar e ofereça o conteúdo pra ela colar.
|
|
421
|
+
|
|
422
|
+
## O molde
|
|
423
|
+
|
|
424
|
+
O corpo em prosa é o que o modelo lê rápido; o JSON no fim é pra quem quiser o dado estruturado. Preencha com o que veio da soul e corte a seção que voltou vazia.
|
|
425
|
+
|
|
426
|
+
\`\`\`\`markdown
|
|
427
|
+
---
|
|
428
|
+
name: sapiens-soul
|
|
429
|
+
description: Quem é o dono deste projeto (nome, @, persona cognitiva, repertório e tese, vindos do Sapiens Sintéticos). Puxe antes de escrever copy, escolher exemplo, nomear coisa, decidir estética ou sugerir referência.
|
|
430
|
+
---
|
|
431
|
+
|
|
432
|
+
# A soul de <nome ou @handle>
|
|
433
|
+
|
|
434
|
+
Retrato de <data legível do generatedAt>, contrato sapiens.soul/v1. É um instantâneo, não uma conexão viva.
|
|
435
|
+
|
|
436
|
+
## Quem é
|
|
437
|
+
<subject: nome, @, bio, nível, badges, link do perfil>
|
|
438
|
+
|
|
439
|
+
## Como pensa
|
|
440
|
+
<cognition: código, persona, e os quatro eixos com polo e confiança, em uma linha cada>
|
|
441
|
+
|
|
442
|
+
## Repertório
|
|
443
|
+
<repertorio: total público, gêneros e tags que mais aparecem, nota média, pessoas que ele acompanha, e as obras recentes que dizem alguma coisa sobre o gosto>
|
|
444
|
+
|
|
445
|
+
## Tese
|
|
446
|
+
<tese, quando veio>
|
|
447
|
+
|
|
448
|
+
## Como usar isto
|
|
449
|
+
Escrevendo pra essa pessoa ou no lugar dela: puxe a referência do repertório dela antes de inventar uma. O jeito de decidir está nos eixos. Na dúvida entre duas opções, escolha a que combina com o que já está aqui.
|
|
450
|
+
|
|
451
|
+
## Dados brutos
|
|
452
|
+
\`\`\`json
|
|
453
|
+
<o contrato inteiro, como veio>
|
|
454
|
+
\`\`\`
|
|
455
|
+
\`\`\`\`
|
|
456
|
+
|
|
457
|
+
## Atualizar
|
|
458
|
+
|
|
459
|
+
O retrato envelhece. Quando a pessoa pedir, rode a action de novo e sobrescreva o arquivo. Nada mais precisa mudar.
|
|
460
|
+
|
|
461
|
+
## O que nunca entra
|
|
462
|
+
|
|
463
|
+
A soul é derivada e já sai filtrada da casa: saldo, transações, e-mail, contatos, conversas e criações privadas não viajam. Não tente completar o retrato com dado de outra tool.`,
|
|
464
|
+
},
|
|
405
465
|
];
|
|
406
466
|
export const SKILLS = Object.fromEntries(SKILL_LIST.map((s) => [s.name, s]));
|
|
407
467
|
/** Monta o SKILL.md completo (frontmatter do formato aberto + corpo). */
|
package/dist/tools/gallery.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
2
|
import { readFile } from "node:fs/promises";
|
|
3
|
-
import { convexAction, getSessionToken, isRemoteContext } from "../convexClient.js";
|
|
3
|
+
import { convexAction, convexMutation, getSessionToken, isRemoteContext, } from "../convexClient.js";
|
|
4
4
|
/**
|
|
5
5
|
* Galeria do usuário: browse, publicação e UPLOAD de peça de fora.
|
|
6
6
|
* Wrapper sobre `desktopMcp.galleryList` / `galleryGet` / `gallerySetPublic` e
|
|
@@ -27,7 +27,15 @@ import { convexAction, getSessionToken, isRemoteContext } from "../convexClient.
|
|
|
27
27
|
* e um motor terceiro só renderizou é ingest.
|
|
28
28
|
*/
|
|
29
29
|
export const gallerySchema = z.object({
|
|
30
|
-
action: z.enum([
|
|
30
|
+
action: z.enum([
|
|
31
|
+
"list",
|
|
32
|
+
"get",
|
|
33
|
+
"publish",
|
|
34
|
+
"unpublish",
|
|
35
|
+
"upload",
|
|
36
|
+
"ingest",
|
|
37
|
+
"refs",
|
|
38
|
+
]),
|
|
31
39
|
limit: z
|
|
32
40
|
.number()
|
|
33
41
|
.int()
|
|
@@ -42,7 +50,7 @@ export const gallerySchema = z.object({
|
|
|
42
50
|
imageId: z
|
|
43
51
|
.string()
|
|
44
52
|
.optional()
|
|
45
|
-
.describe("generatedImages:_id (obrigatório pra action=get/publish/unpublish)"),
|
|
53
|
+
.describe("generatedImages:_id (obrigatório pra action=get/publish/unpublish/refs)"),
|
|
46
54
|
includeBase64: z
|
|
47
55
|
.boolean()
|
|
48
56
|
.optional()
|
|
@@ -89,11 +97,18 @@ export const gallerySchema = z.object({
|
|
|
89
97
|
.string()
|
|
90
98
|
.optional()
|
|
91
99
|
.describe("action=ingest: resolução ('720p', '1080p'). Default 720p."),
|
|
100
|
+
// Aceita lista OU string com os ids separados por vírgula. O segundo formato
|
|
101
|
+
// existe porque alguns clientes MCP serializam array como texto ao repassar a
|
|
102
|
+
// chamada, e aí o servidor recusava com "Expected array, received string" sem
|
|
103
|
+
// que houvesse nada de errado com o pedido. Normalizado logo abaixo.
|
|
92
104
|
referenceImageIds: z
|
|
93
|
-
.array(z.string())
|
|
94
|
-
.max(8)
|
|
105
|
+
.union([z.array(z.string()), z.string()])
|
|
95
106
|
.optional()
|
|
96
|
-
.describe("action=ingest: generatedImages:_id das peças DA CASA que serviram de referência (folha de storyboard, ficha de personagem, frame inicial). Ficam acopladas à peça
|
|
107
|
+
.describe("action=ingest/refs: generatedImages:_id das peças DA CASA que serviram de referência (folha de storyboard, ficha de personagem, frame inicial). Ficam acopladas à peça e aparecem na ficha dela: é o que prova que a receita saiu daqui. Só peça sua entra, no máximo 8. Aceita lista ou os ids separados por vírgula."),
|
|
108
|
+
replace: z
|
|
109
|
+
.boolean()
|
|
110
|
+
.optional()
|
|
111
|
+
.describe("action=refs: false (default) SOMA às referências que já existem; true troca a lista inteira. Pra limpar tudo, mande a lista vazia com replace=true."),
|
|
97
112
|
uploadedSource: z
|
|
98
113
|
.string()
|
|
99
114
|
.optional()
|
|
@@ -190,6 +205,23 @@ async function resolveUploadBytes(args) {
|
|
|
190
205
|
}
|
|
191
206
|
throw new Error("action=upload exige a peça: sourceUrl (https), filePath (local, stdio) ou base64.");
|
|
192
207
|
}
|
|
208
|
+
/**
|
|
209
|
+
* Normaliza `referenceImageIds` pro formato que o Convex espera (lista).
|
|
210
|
+
*
|
|
211
|
+
* O schema aceita lista ou string com vírgulas porque cliente MCP que serializa
|
|
212
|
+
* array como texto existe de verdade, e o erro que ele produzia ("Expected
|
|
213
|
+
* array, received string") não dizia nada sobre como consertar. Aqui a diferença
|
|
214
|
+
* morre, e o backend continua recebendo sempre uma lista.
|
|
215
|
+
*/
|
|
216
|
+
function normalizeRefIds(raw) {
|
|
217
|
+
if (!raw)
|
|
218
|
+
return [];
|
|
219
|
+
const lista = Array.isArray(raw) ? raw : raw.split(",");
|
|
220
|
+
return lista
|
|
221
|
+
.map((id) => id.trim().replace(/^["'[]+|["'\]]+$/g, ""))
|
|
222
|
+
.filter(Boolean)
|
|
223
|
+
.slice(0, 8);
|
|
224
|
+
}
|
|
193
225
|
export async function gallery(args) {
|
|
194
226
|
const sessionToken = getSessionToken();
|
|
195
227
|
if (args.action === "list") {
|
|
@@ -257,11 +289,30 @@ export async function gallery(args) {
|
|
|
257
289
|
externalCost: args.externalCost,
|
|
258
290
|
aspectRatio: args.aspectRatio,
|
|
259
291
|
size: args.size,
|
|
260
|
-
referenceImageIds: args.referenceImageIds,
|
|
292
|
+
referenceImageIds: normalizeRefIds(args.referenceImageIds),
|
|
261
293
|
});
|
|
262
294
|
return {
|
|
263
295
|
...result,
|
|
264
296
|
aviso: "Peça NATIVA: entra na timeline, publica e vai pra comunidade como qualquer geração da casa. Custo em Sinapses é 0 e ela NÃO leva assinatura C2PA, porque o motor rodou fora. Use ingest só quando a receita (folha, personagem, prompt) foi da casa; peça achada pronta é action=upload.",
|
|
265
297
|
};
|
|
266
298
|
}
|
|
299
|
+
// refs: acopla peças da casa a uma peça que JÁ existe (upload ou ingest).
|
|
300
|
+
// A ingestão aceita refs no nascimento, mas quem sobe raramente tem os ids em
|
|
301
|
+
// mãos na hora; e o upload não tinha lugar nenhum pra dizer de onde veio a
|
|
302
|
+
// direção. Escreve proveniência e nada mais: upload continua sem publicar.
|
|
303
|
+
if (args.action === "refs") {
|
|
304
|
+
if (!args.imageId) {
|
|
305
|
+
throw new Error("action=refs exige imageId: a peça que RECEBE as referências. Use action=list pra achar.");
|
|
306
|
+
}
|
|
307
|
+
const referenceImageIds = normalizeRefIds(args.referenceImageIds);
|
|
308
|
+
if (!referenceImageIds.length && !args.replace) {
|
|
309
|
+
throw new Error("action=refs exige referenceImageIds: os ids das peças da casa que serviram de referência. Pra LIMPAR as referências, mande replace=true com a lista vazia.");
|
|
310
|
+
}
|
|
311
|
+
return await convexMutation("externalIngest:mcpAttachReferences", {
|
|
312
|
+
sessionToken,
|
|
313
|
+
imageId: args.imageId,
|
|
314
|
+
referenceImageIds,
|
|
315
|
+
replace: args.replace,
|
|
316
|
+
});
|
|
317
|
+
}
|
|
267
318
|
}
|
package/dist/tools/profile.js
CHANGED
|
@@ -18,6 +18,10 @@ import { convexQuery, convexMutation, getSessionToken } from "../convexClient.js
|
|
|
18
18
|
*
|
|
19
19
|
* Sub-actions:
|
|
20
20
|
* - get: card completo (identidade + nível + saldo + badges + golden tools).
|
|
21
|
+
* - soul: a sapiens-soul: retrato do momento (contrato sapiens.soul/v1,
|
|
22
|
+
* identidade + persona + repertório + tese, derivado e datado).
|
|
23
|
+
* Salve como sapiens-soul.json no projeto do usuário quando ele
|
|
24
|
+
* pedir "pega minha soul / meu retrato do Sapiens".
|
|
21
25
|
* - badges: só as conquistas (lista cheia).
|
|
22
26
|
* - golden_tools: só os favoritos do aitag (lista cheia).
|
|
23
27
|
* - notifications: suas notificações recentes (sino) + contagem de não-lidas.
|
|
@@ -33,6 +37,7 @@ import { convexQuery, convexMutation, getSessionToken } from "../convexClient.js
|
|
|
33
37
|
export const profileSchema = z.object({
|
|
34
38
|
action: z.enum([
|
|
35
39
|
"get",
|
|
40
|
+
"soul",
|
|
36
41
|
"badges",
|
|
37
42
|
"golden_tools",
|
|
38
43
|
"notifications",
|
|
@@ -119,6 +124,15 @@ function mapTools(rows) {
|
|
|
119
124
|
}
|
|
120
125
|
export async function profile(args) {
|
|
121
126
|
const sessionToken = getSessionToken();
|
|
127
|
+
// A soul: retrato do momento (contrato sapiens.soul/v1). Autentica pelo
|
|
128
|
+
// próprio sessionToken; token de membro tem acesso total, então vem inteira.
|
|
129
|
+
if (args.action === "soul") {
|
|
130
|
+
const soul = await convexQuery("soulContract:getForToken", { sessionToken });
|
|
131
|
+
return {
|
|
132
|
+
...soul,
|
|
133
|
+
note: "Snapshot datado (generatedAt), não é conexão viva. Salve como sapiens-soul.json no projeto do usuário; pra atualizar, rode a action de novo e sobrescreva o arquivo.",
|
|
134
|
+
};
|
|
135
|
+
}
|
|
122
136
|
// notifications/mark_read autenticam pelo próprio sessionToken (requireMcpUser
|
|
123
137
|
// no Convex), não precisam do resolveUser — atalham antes.
|
|
124
138
|
if (args.action === "notifications") {
|
package/dist/tools/studios.js
CHANGED
|
@@ -1,31 +1,42 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
|
-
import { convexAction,
|
|
2
|
+
import { convexAction, convexMutation, getSessionToken } from "../convexClient.js";
|
|
3
3
|
/**
|
|
4
|
-
*
|
|
4
|
+
* Duas coisas com o mesmo nome, e o `action` separa as duas:
|
|
5
5
|
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
6
|
+
* 1. O CATÁLOGO dos estúdios/experimentos da casa (`list`/`get`): info estática
|
|
7
|
+
* com URL do dashboard, status e tags, pro Claude rotear o user pro lugar
|
|
8
|
+
* certo quando ele pede coisa que o plugin não cobre.
|
|
9
|
+
* 2. O STUDIO DO MEMBRO (`mine`/`create`): a página de portfólio da empresa
|
|
10
|
+
* dele. Fundar é aqui; vestir a página (capa, logo, sobre, seções) e montar
|
|
11
|
+
* o time é na própria página, no modo edição.
|
|
10
12
|
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
13
|
+
* A Emancipação (o antigo "Nível 3", blueprint pra construir a casa própria na
|
|
14
|
+
* infra do membro) saiu em ago/2026 junto com os níveis: o studio virou perfil
|
|
15
|
+
* de empresa, não uma jornada. As queries `studioBlueprints:mcp*` seguem no
|
|
16
|
+
* backend só como aviso pra pacote publicado que ainda chama.
|
|
14
17
|
*/
|
|
15
18
|
export const studiosSchema = z.object({
|
|
16
19
|
action: z
|
|
17
|
-
.enum(["list", "get", "publishable_url", "mine", "
|
|
18
|
-
.describe("mine = o SEU studio (a página de portfólio da sua casa): nome, endereço público, marca, operador e tamanho do time.
|
|
19
|
-
"
|
|
20
|
-
"
|
|
20
|
+
.enum(["list", "get", "publishable_url", "mine", "create"])
|
|
21
|
+
.describe("mine = o SEU studio (a página de portfólio da sua casa): nome, endereço público, marca, operador e tamanho do time. " +
|
|
22
|
+
"create = FUNDA um studio novo na conta do user (exige 'name'). Nasce privado, com ele como fundador; publicar e vestir a página é na própria página. Teto de 4 por pessoa. " +
|
|
23
|
+
"list/get = catálogo de estúdios da casa. publishable_url = URL de artigo."),
|
|
21
24
|
studio: z
|
|
22
25
|
.string()
|
|
23
26
|
.optional()
|
|
24
27
|
.describe("Pra action=get: slug do estúdio (ex 'helen-voice', 'musicator', 'persona-sapiens', 'sapiens-shorts')."),
|
|
25
|
-
|
|
28
|
+
name: z
|
|
26
29
|
.string()
|
|
27
30
|
.optional()
|
|
28
|
-
.describe("Pra action=
|
|
31
|
+
.describe("Pra action=create: o nome da casa (obrigatório). O endereço público sai daí, em kebab-case. Pergunte ao user, não invente."),
|
|
32
|
+
description: z
|
|
33
|
+
.string()
|
|
34
|
+
.optional()
|
|
35
|
+
.describe("Pra action=create: uma linha do que a casa faz (até 200 chars). Opcional, mas é o que aparece embaixo do nome na página."),
|
|
36
|
+
brandSlug: z
|
|
37
|
+
.string()
|
|
38
|
+
.optional()
|
|
39
|
+
.describe("Pra action=create: marca da casa (slug de sapiens_brand). Opcional. Só passa marca que é do user."),
|
|
29
40
|
publishableId: z
|
|
30
41
|
.string()
|
|
31
42
|
.optional()
|
|
@@ -202,28 +213,24 @@ export async function studios(args) {
|
|
|
202
213
|
: "publishableId lookup ainda não suportado v1.3. Passe slug.",
|
|
203
214
|
};
|
|
204
215
|
}
|
|
205
|
-
// action=
|
|
206
|
-
//
|
|
207
|
-
if (args.action === "
|
|
208
|
-
const
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
return res; // { ok:false, error } — ex: sem studio montado ainda
|
|
212
|
-
return {
|
|
213
|
-
...res,
|
|
214
|
-
howto: "Blueprint-mestre da Emancipação (Nível 3). VOCÊ (o Claude do membro) constrói a casa dele NUMA PASTA NOVA, fora deste projeto, com Vercel + Convex + domínio DO MEMBRO. O Sapiens NÃO hospeda a casa. Conduza assim: (1) leia o `blueprint` (guia da Fundação) e execute passo a passo, confirmando com o membro ANTES de criar conta ou gastar (domínio); (2) o selo <meta name=\"sapiens-studio\"> é OBRIGATÓRIO pra verificação; (3) com a casa no ar, o membro submete a URL no Sapiens (Rito 'Studio no Ar', que paga Sinapses); (4) pra cada próximo módulo do `modules` que estiver 'ready', chame sapiens_studios action=module module=<slug>. Um módulo por vez, sem atropelar. É um passo grande: vá com calma e no gosto do membro.",
|
|
215
|
-
};
|
|
216
|
-
}
|
|
217
|
-
// action=module: o guia de UM módulo de infra, hidratado com a identidade do
|
|
218
|
-
// studio do membro. Chame depois da fundacao, um por vez.
|
|
219
|
-
if (args.action === "module") {
|
|
220
|
-
if (!args.module) {
|
|
221
|
-
throw new Error("action=module exige 'module' (slug do módulo de infra: fundacao, sapiens-connect, telegram, email, auth).");
|
|
216
|
+
// action=create: funda a casa. O servidor resolve o dono pelo sessionToken e
|
|
217
|
+
// devolve o endereço público já montado (quem chama não tem tela pra procurar).
|
|
218
|
+
if (args.action === "create") {
|
|
219
|
+
const name = (args.name ?? "").trim();
|
|
220
|
+
if (!name) {
|
|
221
|
+
throw new Error("action=create exige 'name' (o nome da casa). Pergunte ao user antes de inventar.");
|
|
222
222
|
}
|
|
223
223
|
const sessionToken = getSessionToken();
|
|
224
|
-
|
|
224
|
+
const res = await convexMutation("studios:mcpCreateStudio", {
|
|
225
225
|
sessionToken,
|
|
226
|
-
|
|
226
|
+
name,
|
|
227
|
+
description: args.description,
|
|
228
|
+
brandSlug: args.brandSlug,
|
|
227
229
|
});
|
|
230
|
+
return {
|
|
231
|
+
...res,
|
|
232
|
+
note: "Studio fundado, privado por enquanto. O user publica e veste a página (capa, logo, sobre, time, obra) em " +
|
|
233
|
+
`${APP}/studios/${res.slug} no modo edição. Convidar gente exige follow mútuo.`,
|
|
234
|
+
};
|
|
228
235
|
}
|
|
229
236
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "sapiens-mcp",
|
|
3
|
-
"version": "1.46.
|
|
3
|
+
"version": "1.46.2",
|
|
4
4
|
"description": "MCP server pra operar o Sapiens Sintéticos (sapiensinteticos.com) pelo Claude Code: gerar imagem, escrever artigo, voz, música e mais, na sua conta. Login pelo código de sapiensinteticos.com/conectar-claude.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|