sapiens-mcp 1.26.3 → 1.26.4
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/dist/index.js +8 -2
- package/dist/tools/instagram.js +98 -0
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -13,6 +13,7 @@ import { article, articleSchema } from "./tools/article.js";
|
|
|
13
13
|
import { quotePop, quotePopSchema } from "./tools/quotePop.js";
|
|
14
14
|
import { search, searchSchema } from "./tools/search.js";
|
|
15
15
|
import { studios, studiosSchema } from "./tools/studios.js";
|
|
16
|
+
import { instagram, instagramSchema } from "./tools/instagram.js";
|
|
16
17
|
import { persona, personaSchema } from "./tools/persona.js";
|
|
17
18
|
import { helen, helenSchema } from "./tools/helen.js";
|
|
18
19
|
import { musicator, musicatorSchema } from "./tools/musicator.js";
|
|
@@ -148,6 +149,11 @@ const TOOLS = {
|
|
|
148
149
|
schema: forumSchema,
|
|
149
150
|
handler: forum,
|
|
150
151
|
},
|
|
152
|
+
sapiens_instagram: {
|
|
153
|
+
description: "Auto-DM do Instagram da casa (o 'ManyChat próprio') — ADMIN-ONLY (dono). Quem manda DM ou comenta keyword num post do @sapiensinteticos recebe resposta automática; aqui você OPERA esse motor. Sub-actions: 'rules' (lista regras: keyword, resposta, variações, eco público, escopo por post, disparos), 'rule_upsert' (cria/edita regra; ruleId presente = edita; keyword+reply obrigatórios fora do fallback; replyVariants/echoVariants rodam em round-robin pra não repetir; mediaId escopa a regra num post; isFallback responde DM sem keyword 1x/24h por pessoa), 'rule_delete' (apaga por ruleId), 'inbox' (conversas recentes; cada uma com canReply = janela de 24h da Meta aberta ou não), 'thread' (mensagens de uma conversa por igUserId), 'send' (responde na mão pela janela de 24h; fora dela a Meta recusa). Comentário só dispara regra de KEYWORD (fallback nunca), com eco público opcional ('te respondi no direct!'). Limites da API: não dá pra iniciar conversa, só reagir; janela de 24h pra responder DM.",
|
|
154
|
+
schema: instagramSchema,
|
|
155
|
+
handler: instagram,
|
|
156
|
+
},
|
|
151
157
|
sapiens_aula: {
|
|
152
158
|
description: "Aula (deck da Mentoria OPS, servido em /aulas/<slug>) — ADMIN-ONLY (aula é conteúdo de mentor, não de aluno; aluno leva 'restrito ao dono'). Cria e edita aula direto no Convex, sem o script migrate-aulas-to-convex.mjs. Sub-actions: 'list' (slug/título/data/slideCount/voiceWarnings/url), 'get' (1 aula completa por slug, pra editar local), 'upsert' (cria se não existe, senão patch; por slug kebab-case). O `aula` do upsert é o objeto completo: title (obrig) + slides[] (≥1) + subtitle/data/duration/tag/mentorAgenda opcionais. Slides são { type, ...campos }: cover, cover-image/section-image/content-image (imageUrl), agenda (items[]), content (body markdown/HTML + list[]/listType), two-col (cols[]), quote, callout (tone tip|warn|note), comic (panels[]), pause, close (items[]). O servidor re-linta a voz e grava voiceWarnings (1ª pessoa, anti-corporate, SEM travessão). A rota /aulas/<slug> serve sob demanda; slug novo aparece sem rebuild.",
|
|
153
159
|
schema: aulaSchema,
|
|
@@ -220,7 +226,7 @@ Mídia no Fórum (PADRÃO, faça sempre assim): a peça vai EMBEDADA num card es
|
|
|
220
226
|
Trilhas e Ritos de Fogo (sapiens_trilhas): 'list'/'get' pra navegar as trilhas; 'list_challenges' mostra os Ritos ativos + seu status; 'claim_mission' (missionId + proofText) envia a prova pra revisão do dono — o crédito em Sinapses sai na aprovação dele, não na hora. Não prometa Sinapse na hora do claim.
|
|
221
227
|
|
|
222
228
|
Voz da casa: 1ª pessoa, direto, anti-corporate, sem travessão. Pra bom entendedor, meia palavra basta.`;
|
|
223
|
-
const server = new Server({ name: "mcp-sapiens", version: "1.26.
|
|
229
|
+
const server = new Server({ name: "mcp-sapiens", version: "1.26.4" }, { capabilities: { tools: {} }, instructions: SAPIENS_INSTRUCTIONS });
|
|
224
230
|
server.setRequestHandler(ListToolsRequestSchema, async () => ({
|
|
225
231
|
tools: Object.entries(TOOLS).map(([name, t]) => ({
|
|
226
232
|
name,
|
|
@@ -253,4 +259,4 @@ server.setRequestHandler(CallToolRequestSchema, async (req) => {
|
|
|
253
259
|
});
|
|
254
260
|
const transport = new StdioServerTransport();
|
|
255
261
|
await server.connect(transport);
|
|
256
|
-
console.error("mcp-sapiens v1.26.
|
|
262
|
+
console.error("mcp-sapiens v1.26.4 rodando via stdio (27 tools)");
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { convexAction, convexMutation, convexQuery, getSessionToken } from "../convexClient.js";
|
|
3
|
+
/**
|
|
4
|
+
* sapiens_instagram — o "ManyChat da casa" via MCP. ADMIN-ONLY (requireMcpAdmin
|
|
5
|
+
* no Convex): opera o auto-DM do Instagram da casa (regras de resposta
|
|
6
|
+
* automática, inbox das conversas, resposta manual pela janela de 24h).
|
|
7
|
+
* Espelha a UI /dashboard/admin/instagram; backend em convex/instagramDm.ts.
|
|
8
|
+
*
|
|
9
|
+
* Sub-actions:
|
|
10
|
+
* - rules: lista as regras (keyword, variações, escopo por post, disparos)
|
|
11
|
+
* - rule_upsert: cria/edita regra (ruleId presente = edita)
|
|
12
|
+
* - rule_delete: apaga regra por ruleId
|
|
13
|
+
* - inbox: threads recentes com a janela de 24h de cada (canReply)
|
|
14
|
+
* - thread: mensagens de uma conversa (igUserId do inbox)
|
|
15
|
+
* - send: responde uma conversa na mão (só com a janela aberta)
|
|
16
|
+
*/
|
|
17
|
+
export const instagramSchema = z.object({
|
|
18
|
+
action: z.enum(["rules", "rule_upsert", "rule_delete", "inbox", "thread", "send"]),
|
|
19
|
+
ruleId: z.string().optional().describe("Id da regra (rule_upsert pra editar, rule_delete)."),
|
|
20
|
+
keyword: z
|
|
21
|
+
.string()
|
|
22
|
+
.optional()
|
|
23
|
+
.describe("Keyword da regra (substring case-insensitive no texto da DM/comentário). Obrigatória em regra não-fallback."),
|
|
24
|
+
reply: z.string().optional().describe("Resposta na DM (obrigatória no rule_upsert)."),
|
|
25
|
+
replyVariants: z
|
|
26
|
+
.array(z.string())
|
|
27
|
+
.optional()
|
|
28
|
+
.describe("Variações da resposta; presentes, rodam em round-robin no lugar da reply."),
|
|
29
|
+
commentEcho: z
|
|
30
|
+
.string()
|
|
31
|
+
.optional()
|
|
32
|
+
.describe("Eco público no comentário depois da DM ('te respondi no direct!'). Só p/ comentário."),
|
|
33
|
+
echoVariants: z.array(z.string()).optional().describe("Variações do eco público (round-robin)."),
|
|
34
|
+
mediaId: z
|
|
35
|
+
.string()
|
|
36
|
+
.optional()
|
|
37
|
+
.describe("Escopo por post: id de mídia do Instagram; a regra só casa comentário DESSE post."),
|
|
38
|
+
isFallback: z
|
|
39
|
+
.boolean()
|
|
40
|
+
.optional()
|
|
41
|
+
.describe("Fallback: responde DM sem keyword (1x/24h por pessoa). Nunca dispara em comentário."),
|
|
42
|
+
active: z.boolean().optional().describe("Regra ativa (default true)."),
|
|
43
|
+
priority: z.number().optional().describe("Menor casa primeiro (default 100)."),
|
|
44
|
+
igUserId: z.string().optional().describe("IGSID da contraparte (vem do inbox). Pra thread e send."),
|
|
45
|
+
text: z.string().optional().describe("Texto da resposta manual (send)."),
|
|
46
|
+
limit: z.number().optional().describe("Máx de itens (inbox default 30, thread default 40)."),
|
|
47
|
+
});
|
|
48
|
+
function need(value, name) {
|
|
49
|
+
if (value === undefined || value === null) {
|
|
50
|
+
throw new Error(`Faltando arg "${name}" pra essa action.`);
|
|
51
|
+
}
|
|
52
|
+
return value;
|
|
53
|
+
}
|
|
54
|
+
export async function instagram(args) {
|
|
55
|
+
const sessionToken = getSessionToken();
|
|
56
|
+
switch (args.action) {
|
|
57
|
+
case "rules":
|
|
58
|
+
return await convexQuery("instagramDm:mcpListRules", { sessionToken });
|
|
59
|
+
case "rule_upsert": {
|
|
60
|
+
const reply = need(args.reply, "reply");
|
|
61
|
+
return await convexMutation("instagramDm:mcpUpsertRule", {
|
|
62
|
+
sessionToken,
|
|
63
|
+
ruleId: args.ruleId,
|
|
64
|
+
keyword: args.keyword,
|
|
65
|
+
reply,
|
|
66
|
+
replyVariants: args.replyVariants,
|
|
67
|
+
commentEcho: args.commentEcho,
|
|
68
|
+
echoVariants: args.echoVariants,
|
|
69
|
+
mediaId: args.mediaId,
|
|
70
|
+
isFallback: args.isFallback,
|
|
71
|
+
active: args.active,
|
|
72
|
+
priority: args.priority,
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
case "rule_delete":
|
|
76
|
+
return await convexMutation("instagramDm:mcpRemoveRule", {
|
|
77
|
+
sessionToken,
|
|
78
|
+
ruleId: need(args.ruleId, "ruleId"),
|
|
79
|
+
});
|
|
80
|
+
case "inbox":
|
|
81
|
+
return await convexQuery("instagramDm:mcpListThreads", {
|
|
82
|
+
sessionToken,
|
|
83
|
+
limit: args.limit,
|
|
84
|
+
});
|
|
85
|
+
case "thread":
|
|
86
|
+
return await convexQuery("instagramDm:mcpThreadMessages", {
|
|
87
|
+
sessionToken,
|
|
88
|
+
igUserId: need(args.igUserId, "igUserId"),
|
|
89
|
+
limit: args.limit,
|
|
90
|
+
});
|
|
91
|
+
case "send":
|
|
92
|
+
return await convexAction("instagramDm:mcpSendDm", {
|
|
93
|
+
sessionToken,
|
|
94
|
+
igUserId: need(args.igUserId, "igUserId"),
|
|
95
|
+
text: need(args.text, "text"),
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "sapiens-mcp",
|
|
3
|
-
"version": "1.26.
|
|
3
|
+
"version": "1.26.4",
|
|
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": {
|