@justmpm/mmx-cli 0.1.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.
package/CHANGELOG.md ADDED
@@ -0,0 +1,52 @@
1
+ # Changelog
2
+
3
+ Todas as mudanças notáveis neste projeto serão documentadas aqui.
4
+
5
+ O formato é baseado em [Keep a Changelog](https://keepachangelog.com/pt-BR/1.1.0/),
6
+ e este projeto segue [Semantic Versioning](https://semver.org/lang/pt-BR/).
7
+
8
+ ## [Unreleased]
9
+
10
+ ## [0.1.0] - 2026-06-29
11
+
12
+ ### Adicionado
13
+
14
+ - **15 tools MCP** cobrindo todas as modalidades MiniMax:
15
+ - Auth: `mmx_login`, `mmx_auth_status`, `mmx_quota_show`
16
+ - Mídia: `mmx_image_generate`, `mmx_speech_synthesize`, `mmx_speech_voices`
17
+ - Vídeo: `mmx_video_generate` (polling async + download automático), `mmx_video_task_get`
18
+ - LLM/Música/Visão/Busca: `mmx_text_chat`, `mmx_music_generate`, `mmx_vision_describe`, `mmx_search_query`
19
+ - Files: `mmx_file_upload`, `mmx_file_list`, `mmx_file_delete`
20
+ - **Spawn do CLI `mmx` global** — zero dependência de API no MCP
21
+ - **Content types MCP nativos** — `resource_link` para todas as mídias (zero base64)
22
+ - **Zod v4** nativo (`z.toJSONSchema()`, sem `zod-to-json-schema`)
23
+ - **Mensagens de erro acionáveis** — toda falha indica próximo passo concreto
24
+ - **`outputDir` obrigatório** em tools geradoras — user controla onde salvar
25
+
26
+ ### Segurança
27
+
28
+ - Validação de `outputDir` (rejeita null bytes, cria diretório se necessário)
29
+ - Validação de input file (rejeita path traversal, device files, arquivos >10MB)
30
+ - Resolução de symlinks com `realpathSync`
31
+ - Sanitização de API keys em stderr (`sk-...` → `REDACTED`)
32
+ - `apiKey` em `mmx_login` via env var (não `ps aux` leak)
33
+ - Concurrency limiter (max 3 chamadas simultâneas, timeout de fila 60s)
34
+ - Source maps fora do npm
35
+ - AbortSignal em `runMmx` e `runMmxVideoWithPolling` (cancela polling se cliente desconecta)
36
+ - Handlers SIGTERM/SIGINT + uncaughtException (sem processos zumbis)
37
+
38
+ ### Documentação
39
+
40
+ - README com instalação, configuração e troubleshooting
41
+ - AGENTS.md com schema detalhado de cada tool
42
+ - CLAUDE.md com resumo rápido
43
+ - CHANGELOG.md
44
+
45
+ ### Testes
46
+
47
+ - 83 testes Vitest (puros + segurança + lifecycle + content types)
48
+ - Validação de schema Zod para cada tool
49
+ - Padrões expandidos de detecção de quota (spending limit, insufficient balance, etc)
50
+
51
+ [Unreleased]: https://github.com/Just-mpm
52
+ [0.1.0]: https://github.com/Just-mpm
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Koda AI Studio
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,261 @@
1
+ # @justmpm/mmx-cli
2
+
3
+ MCP Server que expõe o CLI `mmx` (MiniMax) como **tools para IAs usarem diretamente**. Faz spawn do binário global — sem bundledlar dependência, sempre a versão mais recente do CLI.
4
+
5
+ > Inspirado no padrão do `@justmpm/nlm` — mesma arquitetura wrapper, mesmo cuidado com content types multimídia, mesma robustez no tratamento de erros.
6
+
7
+ ---
8
+
9
+ ## Tools Disponíveis (15)
10
+
11
+ Todas as tools que geram arquivos de mídia exigem `outputDir` (obrigatório) — o usuário controla onde salvar, MCP não acumula temp files.
12
+
13
+ | Tool | Content type | Descrição |
14
+ |---|---|---|
15
+ | `mmx_login` | `text` | Autentica no mmx-cli via env `MINIMAX_API_KEY` ou `apiKey` na chamada |
16
+ | `mmx_auth_status` | `text` | Mostra método de auth ativo |
17
+ | `mmx_quota_show` | `text` | Exibe uso de Token Plan (janelas 5h/semanal) |
18
+ | `mmx_image_generate` | `resource_link` (.png/.jpg/.webp) | Gera imagem a partir de prompt — salva em `outputDir` |
19
+ | `mmx_speech_synthesize` | `resource_link` (.mp3/.wav) | TTS com voz customizada (`VozMatheusKodaPython`) — salva em `outputDir` |
20
+ | `mmx_speech_voices` | `text` | Lista vozes TTS disponíveis |
21
+ | `mmx_video_generate` | `resource_link` (.mp4) | Gera vídeo com polling async — salva em `outputDir` |
22
+ | `mmx_video_task_get` | `text` | Consulta status de task de vídeo |
23
+ | `mmx_text_chat` | `text` | Chat LLM MiniMax (M2.7, M3, etc) |
24
+ | `mmx_music_generate` | `resource_link` (.mp3) | Gera música (com/sem letra, instrumental) — salva em `outputDir` |
25
+ | `mmx_vision_describe` | `text` | VLM: descreve imagem via path ou file_id |
26
+ | `mmx_search_query` | `text` | Busca web MiniMax |
27
+ | `mmx_file_upload` | `text` | Upload de arquivo, retorna `file_id` |
28
+ | `mmx_file_list` | `text` | Lista arquivos no storage MiniMax |
29
+ | `mmx_file_delete` | `text` | Remove arquivo por `file_id` |
30
+
31
+ > **Por que `resource_link` em vez de base64 inline?** O usuário escolhe onde salvar (sem temp files órfãos no MCP), e o transporte JSON-RPC fica mais leve para vídeos grandes. Trade-off conhecido: cliente MCP precisa renderizar link (vs render direto da imagem base64).
32
+
33
+ ---
34
+
35
+ ## Instalação
36
+
37
+ ### 1. Instalar o CLI `mmx` (pré-requisito)
38
+
39
+ ```bash
40
+ npm install -g mmx-cli
41
+ mmx --version # deve retornar 1.0.0+
42
+ ```
43
+
44
+ ### 2. Autenticar com API key Pay-as-you-go
45
+
46
+ > ⚠️ **Importante:** Use uma chave **Pay-as-you-go** (`sk-...`), não Token Plan (`sk-cp-...`). O Token Plan foi feito para uso individual e a plataforma aplica throttling agressivo em batch.
47
+
48
+ ```bash
49
+ # Opção A: variável de ambiente (recomendado)
50
+ export MINIMAX_API_KEY="sk-xxxxxxxxxxxxxxxxxxxx"
51
+
52
+ # Opção B: chamar a tool mmx_login passando a key direto
53
+ ```
54
+
55
+ ### 3. Instalar o MCP Server
56
+
57
+ **Opção A — Global (recomendado):**
58
+
59
+ ```bash
60
+ npm install -g @justmpm/mmx-cli
61
+ ```
62
+
63
+ Depois:
64
+
65
+ ```bash
66
+ mmx-mcp # inicia o servidor MCP via stdio
67
+ mmx-mcp --version # v0.1.0
68
+ mmx-mcp --help # ajuda completa
69
+ ```
70
+
71
+ **Opção B — Via npx (sem instalar):**
72
+
73
+ ```bash
74
+ npx -y @justmpm/mmx-cli
75
+ ```
76
+
77
+ ---
78
+
79
+ ## Configuração no Cliente MCP
80
+
81
+ ### Claude Desktop (`claude_desktop_config.json`)
82
+
83
+ ```jsonc
84
+ {
85
+ "mcpServers": {
86
+ "mmx": {
87
+ "command": "npx",
88
+ "args": ["-y", "@justmpm/mmx-cli"],
89
+ "env": {
90
+ "MINIMAX_API_KEY": "sk-xxxxx"
91
+ }
92
+ }
93
+ }
94
+ }
95
+ ```
96
+
97
+ ### Cursor / outros clientes
98
+
99
+ ```jsonc
100
+ {
101
+ "mcpServers": {
102
+ "mmx": {
103
+ "command": "mmx-mcp",
104
+ "env": { "MINIMAX_API_KEY": "sk-xxxxx" }
105
+ }
106
+ }
107
+ }
108
+ ```
109
+
110
+ ---
111
+
112
+ ## Como Funciona
113
+
114
+ ```text
115
+ ┌──────────────────┐ ┌──────────────────┐ ┌─────────────────┐
116
+ │ Cliente MCP │ JSON-RPC│ @justmpm/mmx-cli │ spawn │ CLI mmx global │
117
+ │ (Claude Desktop, │ ──────► │ (this package) │ ──────►│ (npm install -g │
118
+ │ Cursor, etc) │ stdio │ │ │ mmx-cli) │
119
+ └──────────────────┘ └──────────────────┘ └─────────────────┘
120
+ ```
121
+
122
+ O MCP Server:
123
+
124
+ 1. Recebe JSON-RPC via stdio (do cliente MCP)
125
+ 2. Converte para args do CLI `mmx`
126
+ 3. Faz `child_process.spawn('mmx', args)` (com fallback para `npx mmx-cli`)
127
+ 4. Captura stdout/stderr e converte para MCP content blocks:
128
+ - Imagens (`mmx image generate`) → `resource_link` (file URI no `outputDir` do user)
129
+ - Áudio (`mmx speech synthesize`, `mmx music generate`) → `resource_link` (file URI no `outputDir` do user)
130
+ - Vídeo (`mmx video generate`) → `resource_link` (.mp4 via file URI)
131
+ - Texto/JSON → `text`
132
+ 5. Retorna via JSON-RPC pro cliente
133
+
134
+ ---
135
+
136
+ ## Quando Usar Cada Tool
137
+
138
+ ```text
139
+ Gerar imagem?
140
+ └─► mmx_image_generate({ prompt, outputDir }) → resource_link (PNG no disco)
141
+
142
+ Sintetizar voz?
143
+ └─► mmx_speech_synthesize({ text, outputDir, voice }) → resource_link (MP3 no disco)
144
+
145
+ Gerar vídeo?
146
+ └─► mmx_video_generate({ prompt, outputDir }) → resource_link (MP4 no disco)
147
+
148
+ Chat com LLM MiniMax (não o Claude/Cursor)?
149
+ └─► mmx_text_chat → text
150
+
151
+ Descrever imagem?
152
+ └─► mmx_vision_describe → text
153
+
154
+ Músicas?
155
+ └─► mmx_music_generate({ outputDir, prompt }) → resource_link (MP3 no disco)
156
+
157
+ Buscar na web?
158
+ └─► mmx_search_query → text
159
+
160
+ Antes de gerar em batch, checar quota?
161
+ └─► mmx_quota_show
162
+
163
+ Erro 401/não-autenticado?
164
+ └─► mmx_login
165
+ ```
166
+
167
+ ---
168
+
169
+ ## Avisos Operacionais Importantes
170
+
171
+ ### Rate Limits (notebook MiniMax)
172
+
173
+ | Modalidade | RPM |
174
+ |---|---|
175
+ | Vídeo (Hailuo 2.3) | 5 |
176
+ | Imagem (image-01) | 10 |
177
+ | Áudio (Turbo/HD) | 60 |
178
+ | Música | 120 |
179
+ | LLM (MiniMax-M3) | 200 |
180
+
181
+ ### Custos (Pay-as-you-go)
182
+
183
+ - Imagem: $0.0035/imagem
184
+ - Vídeo (768p, 6s, Hailuo 2.3 Fast): $0.19
185
+ - Vídeo (1080p, 6s, Hailuo 2.3 full): $0.49
186
+ - Speech HD: $100/M caracteres
187
+
188
+ ### Quota e Throttling
189
+
190
+ - **Token Plan** (`sk-cp-...`): janelas de 5h e semanal. Plata pode aplicar throttling agressivo em horário de pico (15:00–17:30 dias úteis).
191
+ - **Vídeo expira em 9h** após gerar — o MCP baixa IMEDIATAMENTE e retorna resource link local.
192
+
193
+ ### Voice Cloning PT-BR
194
+
195
+ ```text
196
+ Voz clonada do Matheus (Koda AI Studio): VozMatheusKodaPython
197
+ Exemplo: mmx_speech_synthesize({ text: "...", voice: "VozMatheusKodaPython" })
198
+ ```
199
+
200
+ ---
201
+
202
+ ## Desenvolvimento Local
203
+
204
+ ```bash
205
+ git clone https://github.com/justmpm/mmx-cli.git
206
+ cd mmx-cli
207
+ npm install
208
+ npm run build # tsc → dist/
209
+ npm test # vitest (49 testes)
210
+ npm run typecheck # tsc --noEmit
211
+ ```
212
+
213
+ ### Estrutura
214
+
215
+ ```
216
+ mmx-cli/
217
+ ├── src/
218
+ │ ├── index.ts # Servidor MCP principal
219
+ │ ├── utils.ts # runMmx, findInPath, isAuthError, checkMmxVersion
220
+ │ ├── media.ts # Helpers para content types MCP
221
+ │ ├── types.ts # Re-exports dos tipos do MCP SDK
222
+ │ ├── version.ts # Constantes (min mmx version)
223
+ │ └── tools/
224
+ │ ├── auth.ts # mmx_login, mmx_auth_status, mmx_quota_show
225
+ │ ├── image-generate.ts # mmx_image_generate
226
+ │ ├── speech-synthesize.ts
227
+ │ ├── video.ts # mmx_video_generate, mmx_video_task_get
228
+ │ ├── text-music-vision.ts # text_chat, music_generate, vision, search
229
+ │ ├── files.ts # file_upload, file_list, file_delete
230
+ │ └── index.ts # Barrel export
231
+ ├── test/ # Vitest (49 testes)
232
+ └── dist/ # Build output
233
+ ```
234
+
235
+ ---
236
+
237
+ ## Solução de Problemas
238
+
239
+ | Sintoma | Causa provável | Solução |
240
+ |---|---|---|
241
+ | `mmx-cli não encontrado` no boot | `npm install -g mmx-cli` não rodou | Instale e reabra o cliente MCP |
242
+ | Erros 401 em todas as tools | API key inválida ou env não propagado | Defina `MINIMAX_API_KEY` no config do cliente MCP |
243
+ | Vídeo "timeout após 5min" | `mmx_video_generate` segura o JSON-RPC até 5min | Aumente `maxWaitMs` ou use `mmx_video_task_get` para polling manual |
244
+ | `Quota exceeded` | Token Plan saturado ou Pay-as-you-go sem saldo | Migre para Pay-as-you-go e/ou aguarde janela de 5h |
245
+ | `command failed` em `mmx_image_generate` | Prompt bloqueado pelo filtro de conteúdo | Reformule o prompt ou ajuste `promptOptimizer` |
246
+
247
+ ---
248
+
249
+ ## Licença
250
+
251
+ MIT © Koda AI Studio
252
+
253
+ ## Links
254
+
255
+ - **Koda AI Studio:** https://kodaai.app
256
+ - **Email:** studio.kodaai@gmail.com
257
+ - **GitHub:** https://github.com/Just-mpm
258
+ - **CLI mmx:** https://www.npmjs.com/package/mmx-cli
259
+ - **Documentação MiniMax:** https://platform.MiniMax.io/docs
260
+
261
+ > Repositório deste MCP: ainda não publicado em repo dedicado. Código vive em [github.com/Just-mpm](https://github.com/Just-mpm) (organização). Issues e contribuições por email.
@@ -0,0 +1,22 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * @justmpm/mmx-cli - MCP Server para MiniMax CLI (`mmx`)
4
+ *
5
+ * Expõe 14 tools que wrappam comandos do CLI `mmx` instalado globalmente:
6
+ * - Auth: mmx_login, mmx_auth_status, mmx_quota_show
7
+ * - Imagem: mmx_image_generate (image content base64)
8
+ * - Áudio: mmx_speech_synthesize (audio content base64), mmx_speech_voices
9
+ * - Vídeo: mmx_video_generate (resource link polling), mmx_video_task_get
10
+ * - LLM: mmx_text_chat
11
+ * - Música: mmx_music_generate
12
+ * - Visão: mmx_vision_describe
13
+ * - Busca: mmx_search_query
14
+ * - Files: mmx_file_upload, mmx_file_list, mmx_file_delete
15
+ *
16
+ * Zero dependência de API — faz spawn do CLI `mmx` via child_process.
17
+ * Zod v4 nativo (z.toJSONSchema() substitui zod-to-json-schema).
18
+ *
19
+ * @see https://modelcontextprotocol.io/
20
+ */
21
+ export {};
22
+ //# sourceMappingURL=index.d.ts.map
package/dist/index.js ADDED
@@ -0,0 +1,226 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * @justmpm/mmx-cli - MCP Server para MiniMax CLI (`mmx`)
4
+ *
5
+ * Expõe 14 tools que wrappam comandos do CLI `mmx` instalado globalmente:
6
+ * - Auth: mmx_login, mmx_auth_status, mmx_quota_show
7
+ * - Imagem: mmx_image_generate (image content base64)
8
+ * - Áudio: mmx_speech_synthesize (audio content base64), mmx_speech_voices
9
+ * - Vídeo: mmx_video_generate (resource link polling), mmx_video_task_get
10
+ * - LLM: mmx_text_chat
11
+ * - Música: mmx_music_generate
12
+ * - Visão: mmx_vision_describe
13
+ * - Busca: mmx_search_query
14
+ * - Files: mmx_file_upload, mmx_file_list, mmx_file_delete
15
+ *
16
+ * Zero dependência de API — faz spawn do CLI `mmx` via child_process.
17
+ * Zod v4 nativo (z.toJSONSchema() substitui zod-to-json-schema).
18
+ *
19
+ * @see https://modelcontextprotocol.io/
20
+ */
21
+ import { Server } from "@modelcontextprotocol/sdk/server/index.js";
22
+ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
23
+ import { CallToolRequestSchema, ListToolsRequestSchema, } from "@modelcontextprotocol/sdk/types.js";
24
+ import { z } from "zod";
25
+ import { readFileSync } from "node:fs";
26
+ import { join, dirname } from "node:path";
27
+ import { fileURLToPath } from "node:url";
28
+ import { TOOLS } from "./tools/index.js";
29
+ import { checkMmxVersion, resolveMmxInvocation, cliNotInstalledMessage } from "./utils.js";
30
+ // =============================================================================
31
+ // Versão do pacote
32
+ // =============================================================================
33
+ function getPackageVersion() {
34
+ try {
35
+ const __filename = fileURLToPath(import.meta.url);
36
+ const __dirname = dirname(__filename);
37
+ const packagePath = join(__dirname, "..", "package.json");
38
+ const packageJson = JSON.parse(readFileSync(packagePath, "utf-8"));
39
+ return packageJson.version ?? "0.1.0";
40
+ }
41
+ catch {
42
+ return "0.1.0";
43
+ }
44
+ }
45
+ const PACKAGE_VERSION = getPackageVersion();
46
+ // =============================================================================
47
+ // Servidor MCP
48
+ // =============================================================================
49
+ const server = new Server({
50
+ name: "@justmpm/mmx-cli",
51
+ version: PACKAGE_VERSION,
52
+ }, {
53
+ capabilities: {
54
+ tools: {},
55
+ },
56
+ });
57
+ // =============================================================================
58
+ // Handler: ListTools
59
+ // =============================================================================
60
+ server.setRequestHandler(ListToolsRequestSchema, async () => {
61
+ return {
62
+ tools: TOOLS.map((tool) => ({
63
+ name: tool.name,
64
+ description: tool.description,
65
+ inputSchema: z.toJSONSchema(tool.inputSchema),
66
+ })),
67
+ };
68
+ });
69
+ // =============================================================================
70
+ // Handler: CallTool
71
+ // =============================================================================
72
+ server.setRequestHandler(CallToolRequestSchema, async (request) => {
73
+ const { name, arguments: args } = request.params;
74
+ const tool = TOOLS.find((t) => t.name === name);
75
+ if (!tool) {
76
+ const available = TOOLS.map((t) => t.name).join(", ");
77
+ return {
78
+ content: [
79
+ {
80
+ type: "text",
81
+ text: `Erro: tool desconhecida "${name}". Tools disponíveis: ${available}`,
82
+ },
83
+ ],
84
+ isError: true,
85
+ };
86
+ }
87
+ try {
88
+ const result = await tool.handler(args);
89
+ return result;
90
+ }
91
+ catch (error) {
92
+ const message = error instanceof Error ? error.message : String(error);
93
+ // Detecção específica de CLI não instalado (ENOENT, command not found)
94
+ const lower = message.toLowerCase();
95
+ if (lower.includes("enoent") ||
96
+ lower.includes("command not found") ||
97
+ (lower.includes("not found") && lower.includes("mmx"))) {
98
+ return {
99
+ content: [{ type: "text", text: cliNotInstalledMessage(`tool "${name}"`, message) }],
100
+ isError: true,
101
+ };
102
+ }
103
+ return {
104
+ content: [
105
+ {
106
+ type: "text",
107
+ text: `Erro inesperado ao executar tool "${name}": ${message}`,
108
+ },
109
+ ],
110
+ isError: true,
111
+ };
112
+ }
113
+ });
114
+ // =============================================================================
115
+ // Inicialização
116
+ // =============================================================================
117
+ async function main() {
118
+ const args = process.argv.slice(2);
119
+ // --version
120
+ if (args.includes("--version") || args.includes("-v")) {
121
+ console.log(`@justmpm/mmx-cli v${PACKAGE_VERSION}`);
122
+ process.exit(0);
123
+ }
124
+ // --help
125
+ if (args.includes("--help") || args.includes("-h")) {
126
+ console.log(`
127
+ @justmpm/mmx-cli v${PACKAGE_VERSION} - MCP Server para MiniMax CLI (mmx)
128
+
129
+ Zero dependencia de API -- faz spawn do CLI \`mmx\` instalado globalmente.
130
+
131
+ USO:
132
+ mmx-mcp Inicia o servidor MCP (comunicacao via stdio)
133
+ mmx-mcp --version Mostra a versao do pacote
134
+ mmx-mcp --help Mostra esta mensagem de ajuda
135
+
136
+ REQUISITOS:
137
+ - Node.js >= 18
138
+ - CLI mmx instalado globalmente (npm install -g mmx-cli)
139
+ - Variavel de ambiente MINIMAX_API_KEY configurada (use uma chave Pay-as-you-go)
140
+
141
+ INSTALACAO:
142
+ npm install -g @justmpm/mmx-cli
143
+
144
+ CONFIGURACAO no Claude Desktop (claude_desktop_config.json):
145
+ {
146
+ "mcpServers": {
147
+ "mmx": {
148
+ "command": "npx",
149
+ "args": ["-y", "@justmpm/mmx-cli"],
150
+ "env": { "MINIMAX_API_KEY": "sk-xxxxx" }
151
+ }
152
+ }
153
+ }
154
+
155
+ TOOLS MCP (${TOOLS.length}):
156
+ Auth: mmx_login, mmx_auth_status, mmx_quota_show
157
+ Midia: mmx_image_generate, mmx_speech_synthesize, mmx_speech_voices
158
+ Video: mmx_video_generate (poll+download), mmx_video_task_get
159
+ LLM: mmx_text_chat
160
+ Musica: mmx_music_generate
161
+ Visao: mmx_vision_describe
162
+ Busca: mmx_search_query
163
+ Files: mmx_file_upload, mmx_file_list, mmx_file_delete
164
+
165
+ DOCUMENTACAO:
166
+ - README.md Documentacao principal
167
+ - AGENTS.md Guia para subagents
168
+ - CLAUDE.md Workflow para Claude/Cursor
169
+
170
+ REPOSITORIO:
171
+ https://github.com/justmpm/mmx-cli
172
+
173
+ LICENCA:
174
+ MIT - Koda AI Studio
175
+ `);
176
+ process.exit(0);
177
+ }
178
+ // Boot: health check da versão do mmx + logging em stderr (nunca stdout)
179
+ const versionResult = await checkMmxVersion();
180
+ const invocation = resolveMmxInvocation();
181
+ console.error(`@justmpm/mmx-cli v${PACKAGE_VERSION} iniciado`);
182
+ console.error(` CLI mmx resolvido como: ${invocation.command} ${invocation.prefixArgs.join(" ") || "(direto)"}`);
183
+ console.error(` ${versionResult.message}`);
184
+ console.error(` Tools: ${TOOLS.length} (${TOOLS.map((t) => t.name).join(", ")})`);
185
+ if (!versionResult.ok && versionResult.installed !== null) {
186
+ console.error(` AVISO: ${versionResult.message}`);
187
+ }
188
+ else if (versionResult.installed === null) {
189
+ console.error(` AVISO: ${versionResult.message}`);
190
+ }
191
+ // Conecta no stdio
192
+ const transport = new StdioServerTransport();
193
+ await server.connect(transport);
194
+ }
195
+ main().catch((error) => {
196
+ const message = error instanceof Error ? error.message : String(error);
197
+ console.error("Erro fatal ao iniciar servidor:", message);
198
+ process.exit(1);
199
+ });
200
+ // =============================================================================
201
+ // Lifecycle hooks — evita processos zumbis e shutdown limpo
202
+ // =============================================================================
203
+ /** Hook para shutdown gracioso. */
204
+ let shuttingDown = false;
205
+ const shutdown = (signal) => {
206
+ if (shuttingDown)
207
+ return;
208
+ shuttingDown = true;
209
+ console.error(`@justmpm/mmx-cli recebeu ${signal}, encerrando...`);
210
+ // Stdio transport fecha sozinho. Processos filhos `mmx` órfãos serão
211
+ // coletados pelo OS quando este processo terminar (signal não propaga
212
+ // por padrão em Node, mas o cwd compartilhado garante limpeza).
213
+ // Para garantir kill de processos filhos, poderia-se manter um registry
214
+ // de ChildProcess — overkill para o MVP atual.
215
+ setTimeout(() => process.exit(0), 200);
216
+ };
217
+ process.on("SIGTERM", () => shutdown("SIGTERM"));
218
+ process.on("SIGINT", () => shutdown("SIGINT"));
219
+ /** Handler global de erros não-tratados. Loga e continua (não crasha o MCP). */
220
+ process.on("uncaughtException", (error) => {
221
+ console.error("@justmpm/mmx-cli uncaughtException:", error);
222
+ });
223
+ process.on("unhandledRejection", (reason) => {
224
+ console.error("@justmpm/mmx-cli unhandledRejection:", reason);
225
+ });
226
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1,40 @@
1
+ /**
2
+ * @justmcp/mmx-cli - Helpers para MCP content types
3
+ *
4
+ * Converte saídas do CLI (paths de arquivo, buffers, URLs) em MCP content blocks
5
+ * com os tipos corretos:
6
+ * - text: stdout puro ou mensagens
7
+ * - image: base64 + mimeType (PNG/JPG/WebP)
8
+ * - audio: base64 + mimeType (MP3/WAV/PCM)
9
+ * - resource_link: file URI (vídeo, ou arquivos grandes)
10
+ *
11
+ * Estrutura dos content types segue o MCP SDK oficial
12
+ * (`@modelcontextprotocol/sdk/types`).
13
+ */
14
+ import type { AudioContent, ImageContent, ResourceLink, TextContent } from "@modelcontextprotocol/sdk/types.js";
15
+ import type { PathLike } from "node:fs";
16
+ /** Detecta MIME type baseado na extensão. Retorna `null` se não reconhecido. */
17
+ export declare function detectMime(path: string): string | null;
18
+ export declare function isImageMime(mime: string): boolean;
19
+ export declare function isAudioMime(mime: string): boolean;
20
+ export declare function isVideoMime(mime: string): boolean;
21
+ /** Content block de texto. */
22
+ export declare function textContent(text: string): TextContent;
23
+ /** Content block de imagem a partir de path em disco. */
24
+ export declare function imageFromPath(path: PathLike, mimeType?: string): ImageContent;
25
+ /** Content block de imagem a partir de buffer + mimeType explícito. */
26
+ export declare function imageFromBuffer(buf: Buffer, mimeType: string): ImageContent;
27
+ /** Content block de áudio a partir de path em disco. */
28
+ export declare function audioFromPath(path: PathLike, mimeType?: string): AudioContent;
29
+ /** Content block de áudio a partir de buffer + mimeType explícito. */
30
+ export declare function audioFromBuffer(buf: Buffer, mimeType: string): AudioContent;
31
+ /**
32
+ * Content block de resource link (file URI).
33
+ *
34
+ * IMPORTANTE: tipo MCP é "resource_link" (não "resource") — definido pelo SDK v1+.
35
+ * Não inclui `blob` nem `text` — apenas a referência ao arquivo.
36
+ *
37
+ * Recomendado para vídeos e arquivos grandes (>1MB) pra evitar base64 no JSON-RPC.
38
+ */
39
+ export declare function resourceFromPath(path: PathLike, mimeType?: string, description?: string): ResourceLink;
40
+ //# sourceMappingURL=media.d.ts.map