beplus-mcp 0.14.0 → 0.17.0

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.
Files changed (2) hide show
  1. package/dist/index.js +89 -13
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -486,8 +486,13 @@ var IMAGE_MODELS = [
486
486
  "google/nano-banana-2",
487
487
  "google/nano-banana-pro",
488
488
  "openai/gpt-image-2",
489
+ "openai/gpt-image-1",
490
+ "bytedance/seedream-5.0-lite",
491
+ "bytedance/seedream-5.0-pro",
489
492
  "midjourney"
490
493
  ];
494
+ var SEEDREAM_LITE_SIZES = ["2K", "3K", "4K"];
495
+ var SEEDREAM_PRO_SIZES = ["1K", "2K"];
491
496
  var VIDEO_MODELS = [
492
497
  "bytedance/seedance-2.0",
493
498
  "bytedance/seedance-2.0-fast",
@@ -581,21 +586,33 @@ function registerGenerationTools(server, client, cfg) {
581
586
  title: "Gerar imagem",
582
587
  description: "Gera uma imagem a partir de um prompt usando o IA Lab da BePlus. R\xE1pido (~10-30s). Consome diamantes da conta vinculada. Apenas `prompt` \xE9 obrigat\xF3rio; passe `reference_images` (URLs p\xFAblicas OU caminhos de arquivo local \u2014 o MCP sobe pro R2 automaticamente) para image-to-image. Veja custos com estimate_cost / list_models." + TEAM_GATING_NOTE,
583
588
  inputSchema: {
584
- prompt: z.string().min(1).max(4e3).describe("Descri\xE7\xE3o da imagem desejada."),
585
- model: z.enum(IMAGE_MODELS).default(DEFAULTS.imageModel).describe("nano-banana-2 = barato/r\xE1pido; nano-banana-pro = melhor qualidade; gpt-image-2 = OpenAI."),
589
+ // Sem teto local: quem conhece o limite de cada provedor é o backend, e
590
+ // ele responde com quanto reduzir. Um `.max()` aqui rejeitava prompts
591
+ // que o modelo aceita (Seedream/nano-banana não têm limite publicado).
592
+ prompt: z.string().min(1).describe("Descri\xE7\xE3o da imagem desejada."),
593
+ model: z.enum(IMAGE_MODELS).default(DEFAULTS.imageModel).describe(
594
+ "nano-banana-2 = barato/r\xE1pido; nano-banana-pro = melhor qualidade; gpt-image-2 = OpenAI; gpt-image-1 = OpenAI, \xDANICO que faz fundo transparente de verdade (PNG/WebP com alpha) \u2014 o gpt-image-2 N\xC3O faz, use este pra recorte/sticker; seedream-5.0-lite = mais barato do cat\xE1logo, \xFAnico que chega a 4K, gera s\xE9ries e mant\xE9m o ESTILO da imagem de refer\xEAncia; seedream-5.0-pro = acabamento fotorrealista, s\xF3 at\xE9 2K \u2014 preserva o personagem da refer\xEAncia mas costuma reinterpretar o estilo (um vetor flat volta em 3D)."
595
+ ),
586
596
  aspect_ratio: z.enum(ASPECT_RATIOS).optional().describe("Propor\xE7\xE3o (nano-banana). Padr\xE3o 1:1."),
587
597
  resolution: z.enum(IMAGE_RESOLUTIONS).optional().describe("Resolu\xE7\xE3o (nano-banana): 1K/2K/4K. Padr\xE3o 1K."),
588
598
  reference_images: z.array(z.string().min(1)).max(16).optional().describe(
589
- "Imagens de refer\xEAncia (image-to-image): URL p\xFAblica OU caminho de arquivo local (o MCP faz upload pro R2 automaticamente). At\xE9 14 (nano-banana) / 16 (gpt-image-2)."
599
+ "Imagens de refer\xEAncia (image-to-image): URL p\xFAblica OU caminho de arquivo local (o MCP faz upload pro R2 automaticamente). At\xE9 14 (nano-banana) / 16 (gpt-image-1/2)."
590
600
  ),
591
601
  google_search: z.boolean().optional().describe("nano-banana-2: aterra a imagem em busca web do Google (fatos atuais). Padr\xE3o false."),
592
602
  image_search: z.boolean().optional().describe("nano-banana-2: usa busca de imagens do Google como refer\xEAncia visual. Padr\xE3o false."),
593
- size: z.enum(["1024x1024", "1536x1024", "1024x1536", "auto"]).optional().describe("Tamanho (gpt-image-2)."),
594
- quality: z.enum(["low", "medium", "high", "auto"]).optional().describe("Qualidade (gpt-image-2)."),
595
- background: z.enum(["opaque", "transparent", "auto"]).optional().describe("Fundo (gpt-image-2). transparent s\xF3 com output_format png/webp. Padr\xE3o opaque."),
596
- moderation: z.enum(["low", "auto"]).optional().describe("Modera\xE7\xE3o (gpt-image-2). Padr\xE3o low."),
597
- output_format: z.enum(["png", "jpeg", "webp"]).optional().describe("Formato de sa\xEDda (gpt-image-2). Padr\xE3o png."),
598
- output_compression: z.number().int().min(0).max(100).optional().describe("Compress\xE3o 0-100 (gpt-image-2, s\xF3 jpeg/webp). Padr\xE3o 90."),
603
+ size: z.enum(["1024x1024", "1536x1024", "1024x1536", "auto", "1K", "2K", "3K", "4K"]).optional().describe(
604
+ "Tamanho. gpt-image-1/2: 1024x1024/1536x1024/1024x1536/auto. Seedream Lite: 2K/3K/4K (padr\xE3o 2K). Seedream Pro: 1K/2K apenas \u2014 o Pro N\xC3O faz 3K/4K."
605
+ ),
606
+ batch_images: z.number().int().min(2).max(15).optional().describe(
607
+ "Seedream 5.0 LITE apenas: gera uma s\xE9rie de imagens relacionadas numa chamada (2-15). Cada imagem \xE9 cobrada. O Seedream Pro N\xC3O suporta \u2014 passar aqui devolve erro."
608
+ ),
609
+ quality: z.enum(["low", "medium", "high", "auto"]).optional().describe("Qualidade (gpt-image-1/2)."),
610
+ background: z.enum(["opaque", "transparent", "auto"]).optional().describe(
611
+ "Fundo (gpt-image-1/2). `transparent` S\xD3 funciona no gpt-image-1 e s\xF3 com output_format png/webp \u2014 o gpt-image-2 rejeita (limita\xE7\xE3o do modelo na OpenAI, n\xE3o d\xE1 pra contornar por prompt). Padr\xE3o opaque."
612
+ ),
613
+ moderation: z.enum(["low", "auto"]).optional().describe("Modera\xE7\xE3o (gpt-image-1/2). Padr\xE3o low."),
614
+ output_format: z.enum(["png", "jpeg", "webp"]).optional().describe("Formato de sa\xEDda (gpt-image-1/2). Padr\xE3o png."),
615
+ output_compression: z.number().int().min(0).max(100).optional().describe("Compress\xE3o 0-100 (gpt-image-1/2, s\xF3 jpeg/webp). Padr\xE3o 90."),
599
616
  seed: z.number().int().optional(),
600
617
  // ── Midjourney (model="midjourney") — params completos ──
601
618
  version: z.enum(["8.1", "7", "6.1", "6", "niji-7", "niji-6"]).optional().describe("Midjourney: vers\xE3o (padr\xE3o 8.1). --oref (character_reference) for\xE7a V7; --cref for\xE7a V6; anime = niji-7."),
@@ -619,6 +636,43 @@ function registerGenerationTools(server, client, cfg) {
619
636
  try {
620
637
  const isGoogle = args.model.startsWith("google/");
621
638
  const isMidjourney = args.model === "midjourney";
639
+ const isSeedreamLite = args.model === "bytedance/seedream-5.0-lite";
640
+ const isSeedreamPro = args.model === "bytedance/seedream-5.0-pro";
641
+ const isSeedream = isSeedreamLite || isSeedreamPro;
642
+ if (isSeedream) {
643
+ const allowed = isSeedreamPro ? SEEDREAM_PRO_SIZES : SEEDREAM_LITE_SIZES;
644
+ if (args.size && !allowed.includes(args.size)) {
645
+ return errorResult(
646
+ `${args.model} aceita size ${allowed.join("/")} (voc\xEA pediu ${args.size}). ` + (isSeedreamPro ? "O Pro n\xE3o faz 3K/4K \u2014 use o seedream-5.0-lite para resolu\xE7\xF5es maiores." : "O Lite n\xE3o faz 1K \u2014 use o seedream-5.0-pro se quiser a resolu\xE7\xE3o menor.")
647
+ );
648
+ }
649
+ if (args.batch_images && isSeedreamPro) {
650
+ return errorResult(
651
+ "O seedream-5.0-pro n\xE3o suporta gera\xE7\xE3o em s\xE9rie (batch_images). Use bytedance/seedream-5.0-lite para gerar v\xE1rias imagens relacionadas de uma vez."
652
+ );
653
+ }
654
+ if (args.output_format === "webp") {
655
+ return errorResult(`${args.model} aceita apenas png ou jpeg (webp n\xE3o \xE9 suportado).`);
656
+ }
657
+ const maxRefs = isSeedreamPro ? 10 : 14;
658
+ if (args.reference_images && args.reference_images.length > maxRefs) {
659
+ return errorResult(
660
+ `${args.model} aceita no m\xE1ximo ${maxRefs} imagens de refer\xEAncia (voc\xEA passou ${args.reference_images.length}).`
661
+ );
662
+ }
663
+ } else if (args.batch_images) {
664
+ return errorResult("batch_images s\xF3 existe no bytedance/seedream-5.0-lite.");
665
+ }
666
+ if (args.background === "transparent") {
667
+ if (args.model !== "openai/gpt-image-1") {
668
+ return errorResult(
669
+ `${args.model} n\xE3o suporta fundo transparente. S\xF3 o openai/gpt-image-1 devolve PNG/WebP com canal alpha de verdade \u2014 troque o model.`
670
+ );
671
+ }
672
+ if (args.output_format === "jpeg") {
673
+ return errorResult("Fundo transparente exige output_format png ou webp \u2014 JPEG n\xE3o tem canal alpha.");
674
+ }
675
+ }
622
676
  const reference_images = await resolveRefs(cfg, args.reference_images);
623
677
  let style_reference;
624
678
  if (isMidjourney && args.style_reference) {
@@ -632,7 +686,12 @@ function registerGenerationTools(server, client, cfg) {
632
686
  reference_images,
633
687
  google_search: args.google_search,
634
688
  image_search: args.image_search,
635
- size: args.size,
689
+ size: args.size ?? (isSeedream ? "2K" : void 0),
690
+ // Série do Seedream Lite: o backend lê o par sequential_image_generation
691
+ // + max_images (nomes da API da BytePlus). `batch_images` é só o nome
692
+ // amigável exposto aqui.
693
+ sequential_image_generation: isSeedreamLite && args.batch_images ? "auto" : void 0,
694
+ max_images: isSeedreamLite && args.batch_images ? args.batch_images : void 0,
636
695
  quality: isMidjourney ? args.mj_quality : args.quality,
637
696
  background: args.background,
638
697
  moderation: args.moderation,
@@ -759,7 +818,9 @@ ${BUDGET_BLOCKED_GUIDANCE}`);
759
818
  title: "Gerar v\xEDdeo",
760
819
  description: "Gera um v\xEDdeo curto usando o IA Lab da BePlus. LENTO (geralmente 1-5+ min). Aguarda at\xE9 ~2 min; se n\xE3o terminar, retorna o generation_id e o status \u2014 ent\xE3o use check_generation. Consome diamantes (mais caro para dura\xE7\xF5es/resolu\xE7\xF5es maiores). Suporta image-to-video (`first_frame_image`), \xFAltimo frame (`last_frame_image`), refer\xEAncias de imagem/v\xEDdeo/\xE1udio, prompt negativo, \xE1udio gerado e mais \u2014 os campos aceitos variam por modelo (consulte list_models). `kling-v2.6-motion-control` usa `first_frame_image` + `motion_video`. Imagens com rosto de pessoa REAL s\xE3o bloqueadas pela modera\xE7\xE3o do provedor (use ilustra\xE7\xF5es/personagens)." + TEAM_GATING_NOTE,
761
820
  inputSchema: {
762
- prompt: z.string().min(1).max(4e3).describe("Descri\xE7\xE3o do v\xEDdeo desejado."),
821
+ // Sem teto local — ver nota em generate_image. O Seedance não publica
822
+ // limite; o Kling publica 2500 e o backend recusa dizendo quanto cortar.
823
+ prompt: z.string().min(1).describe("Descri\xE7\xE3o do v\xEDdeo desejado."),
763
824
  model: z.enum(VIDEO_MODELS).default(DEFAULTS.videoModel).describe("seedance-2.0-fast = barato/r\xE1pido; seedance-2.0 = melhor; kling-v3-video = alternativa."),
764
825
  aspect_ratio: z.enum(ASPECT_RATIOS).optional().describe("Propor\xE7\xE3o. Padr\xE3o 16:9."),
765
826
  resolution: z.enum(VIDEO_RESOLUTIONS).optional().describe("480p/720p/1080p/4K (1080p/4K S\xD3 no seedance-2.0 standard; fast e mini aceitam apenas 480p/720p). Padr\xE3o 720p."),
@@ -952,14 +1013,29 @@ ${list}${flagsLine(status)}` }, ...blocks] };
952
1013
  const model = g?.model ?? p?.model ?? "(modelo desconhecido)";
953
1014
  const prompt = g?.prompt ?? p?.prompt ?? "(sem prompt)";
954
1015
  const configs = g?.input_params ?? p?.configs ?? {};
955
- const inputs = p?.input_image_urls ?? [];
1016
+ const meta = g?.metadata ?? {};
1017
+ const asUrls = (v) => Array.isArray(v) ? v.filter((x) => typeof x === "string" && !!x) : [];
1018
+ const asUrl = (v) => typeof v === "string" && v ? v : void 0;
1019
+ const pick = (fromDb, fromTag) => {
1020
+ const db = asUrls(fromDb);
1021
+ return db.length > 0 ? db : asUrls(fromTag);
1022
+ };
1023
+ const images = pick(meta.input_image_urls, p?.input_image_urls);
1024
+ const refVideos = pick(meta.reference_video_urls, p?.reference_video_urls);
1025
+ const refAudios = pick(meta.reference_audio_urls, p?.reference_audio_urls);
1026
+ const motionVideo = asUrl(meta.motion_video_url) ?? asUrl(p?.motion_video_url);
1027
+ const endImage = asUrl(meta.end_image_url) ?? asUrl(p?.end_image_url);
956
1028
  const lines = [
957
1029
  `\u{1F9EC} Dados da gera\xE7\xE3o (${r.source === "db" ? "registro da conta" : "metadata do arquivo"}):`,
958
1030
  `\u2022 Modelo: ${model}`,
959
1031
  `\u2022 Prompt: ${prompt}`,
960
1032
  `\u2022 Configs: ${JSON.stringify(configs)}`
961
1033
  ];
962
- if (inputs.length) lines.push(`\u2022 Inputs: ${inputs.join(", ")}`);
1034
+ if (images.length) lines.push(`\u2022 Imagens de entrada: ${images.join(", ")}`);
1035
+ if (endImage) lines.push(`\u2022 Frame final: ${endImage}`);
1036
+ if (refVideos.length) lines.push(`\u2022 V\xEDdeos de refer\xEAncia: ${refVideos.join(", ")}`);
1037
+ if (refAudios.length) lines.push(`\u2022 \xC1udios de refer\xEAncia: ${refAudios.join(", ")}`);
1038
+ if (motionVideo) lines.push(`\u2022 V\xEDdeo de motion control: ${motionVideo}`);
963
1039
  if (p?.generation_id) lines.push(`\u2022 generation_id: ${p.generation_id}`);
964
1040
  return textResult(lines.join("\n"));
965
1041
  } catch (e) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "beplus-mcp",
3
- "version": "0.14.0",
3
+ "version": "0.17.0",
4
4
  "description": "Conector MCP da equipe BePlus — gere imagens/vídeos/áudio e consulte calls, projetos e clientes pela sua conta BePlus (diamantes, limites e histórico aplicados pela plataforma).",
5
5
  "type": "module",
6
6
  "bin": {