instantclips-mcp 1.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/LICENSE +21 -0
- package/README.es.md +195 -0
- package/README.md +179 -0
- package/README.zh-CN.md +172 -0
- package/bin/instantclips-mcp.js +318 -0
- package/package.json +46 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Instant Studio, Inc.
|
|
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.es.md
ADDED
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
# MCP de InstantClips
|
|
2
|
+
|
|
3
|
+
[English](README.md) · **Español** · [简体中文](README.zh-CN.md)
|
|
4
|
+
|
|
5
|
+
[InstantClips](https://instantclips.ai) convierte un producto de comercio electrónico en vídeos
|
|
6
|
+
verticales cortos para TikTok, Instagram Reels y Stories. Funciona como un **servidor MCP alojado**,
|
|
7
|
+
por lo que Claude Code, Codex, Cursor, VS Code, la aplicación de Claude, ChatGPT o cualquier otro
|
|
8
|
+
cliente MCP pueden hacer lo mismo que la aplicación web: importar un producto, preparar la
|
|
9
|
+
dirección creativa y renderizar el vídeo.
|
|
10
|
+
|
|
11
|
+
**El servidor del producto permanece alojado.** Este repositorio contiene su guía de conexión, los
|
|
12
|
+
metadatos de registro, un cliente HTTP de ejemplo y un pequeño adaptador stdio de código abierto
|
|
13
|
+
para los clientes que no pueden conectarse directamente a un servidor remoto. El adaptador se
|
|
14
|
+
limita a transportar mensajes MCP al endpoint alojado; las definiciones de las herramientas y la
|
|
15
|
+
implementación del producto permanecen en un único lugar.
|
|
16
|
+
|
|
17
|
+
## Endpoint
|
|
18
|
+
|
|
19
|
+
| | |
|
|
20
|
+
| ---------- | ------------------------------------------ |
|
|
21
|
+
| Endpoint | `https://app.instantclips.ai/mcp` |
|
|
22
|
+
| Transporte | Streamable HTTP, sin estado |
|
|
23
|
+
| Método | `POST`, JSON-RPC 2.0 |
|
|
24
|
+
| Auth | `Authorization: Bearer <token>` |
|
|
25
|
+
|
|
26
|
+
Genera un token en **[app.instantclips.ai/settings#ai-access](https://app.instantclips.ai/settings#ai-access)**.
|
|
27
|
+
El token da acceso a tu propia cuenta: las mismas marcas, productos, créditos y límites del plan
|
|
28
|
+
que en la aplicación web. Al iniciar sesión se crea una cuenta si todavía no tienes una, con
|
|
29
|
+
créditos gratuitos para empezar.
|
|
30
|
+
|
|
31
|
+
Al abrir el endpoint en un navegador, aparece la página de configuración en lugar de un error de
|
|
32
|
+
protocolo, con botones de instalación de un clic que introducen el token por ti.
|
|
33
|
+
|
|
34
|
+
## Instalación
|
|
35
|
+
|
|
36
|
+
Conéctate directamente al endpoint alojado siempre que tu cliente admita Streamable HTTP. Usa el
|
|
37
|
+
adaptador stdio descrito abajo solo para clientes y procesos automatizados que requieran un comando
|
|
38
|
+
local.
|
|
39
|
+
|
|
40
|
+
### Claude Code
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
claude mcp add --transport http instantclips https://app.instantclips.ai/mcp --header "Authorization: Bearer YOUR_TOKEN"
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
### Codex
|
|
47
|
+
|
|
48
|
+
Añade lo siguiente a `~/.codex/config.toml`; la configuración se aplica a la CLI, la aplicación y
|
|
49
|
+
la extensión del IDE:
|
|
50
|
+
|
|
51
|
+
```toml
|
|
52
|
+
[mcp_servers.instantclips]
|
|
53
|
+
url = "https://app.instantclips.ai/mcp"
|
|
54
|
+
http_headers = { Authorization = "Bearer YOUR_TOKEN" }
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
Para no guardar el token en el archivo, sustituye el encabezado por
|
|
58
|
+
`bearer_token_env_var = "INSTANTCLIPS_TOKEN"` y expórtalo como variable de entorno en tu shell.
|
|
59
|
+
|
|
60
|
+
### Clientes que solo admiten stdio y procesos sin interfaz
|
|
61
|
+
|
|
62
|
+
El paquete npm `instantclips-mcp` es un adaptador ligero de stdio a HTTPS. Lee el token del entorno,
|
|
63
|
+
fija InstantClips como endpoint de destino y reenvía el protocolo sin modificarlo:
|
|
64
|
+
|
|
65
|
+
```json
|
|
66
|
+
{
|
|
67
|
+
"mcpServers": {
|
|
68
|
+
"instantclips": {
|
|
69
|
+
"command": "npx",
|
|
70
|
+
"args": ["-y", "instantclips-mcp"],
|
|
71
|
+
"env": {
|
|
72
|
+
"INSTANTCLIPS_TOKEN": "YOUR_TOKEN"
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
Para comprobar la conexión de forma automatizada, incluidos los nombres actuales de las
|
|
80
|
+
herramientas:
|
|
81
|
+
|
|
82
|
+
```bash
|
|
83
|
+
INSTANTCLIPS_TOKEN="your-token" npx -y instantclips-mcp --check --json
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
El token solo se acepta mediante `INSTANTCLIPS_TOKEN`, nunca como argumento de línea de comandos,
|
|
87
|
+
por lo que no aparece en la lista de procesos. Se requiere Node.js 20 o posterior.
|
|
88
|
+
|
|
89
|
+
### Cursor y VS Code
|
|
90
|
+
|
|
91
|
+
La [página de configuración](https://app.instantclips.ai/settings#ai-access) incluye botones de
|
|
92
|
+
instalación de un clic. Una vez generado el token, los botones lo introducen por ti.
|
|
93
|
+
|
|
94
|
+
### Aplicación de Claude y ChatGPT
|
|
95
|
+
|
|
96
|
+
Estos clientes se conectan mediante su propia configuración de conectores, no mediante un archivo.
|
|
97
|
+
Apunta el conector a `https://app.instantclips.ai/mcp` y autentícate con el mismo token: como
|
|
98
|
+
encabezado de solicitud en Claude y como clave de API en ChatGPT. Los encabezados de solicitud de
|
|
99
|
+
Claude siguen en beta y ChatGPT requiere el modo de desarrollador; su disponibilidad depende de tu
|
|
100
|
+
cuenta y de las políticas de tu espacio de trabajo.
|
|
101
|
+
|
|
102
|
+
### Cualquier otro cliente
|
|
103
|
+
|
|
104
|
+
OpenClaw, Hermes o un agente que hayas creado: conéctalo a la URL mediante Streamable HTTP con un
|
|
105
|
+
encabezado `Authorization: Bearer`. El protocolo no contiene nada específico de InstantClips, por
|
|
106
|
+
lo que cualquier cliente compatible con MCP ya puede comunicarse con el servidor.
|
|
107
|
+
|
|
108
|
+
## Herramientas
|
|
109
|
+
|
|
110
|
+
El flujo de trabajo, en orden:
|
|
111
|
+
|
|
112
|
+
1. **Importar** — usa `import_product_from_url` para una página de tienda o
|
|
113
|
+
`create_product_from_images` cuando no haya una página que leer.
|
|
114
|
+
2. **Esperar el borrador** — consulta `get_product` periódicamente hasta que terminen la importación
|
|
115
|
+
y la preparación de la dirección creativa.
|
|
116
|
+
3. **Revisarlo y orientarlo** — la dirección se devuelve como texto: gancho, enfoque del contenido,
|
|
117
|
+
formato, pautas de ejecución y restricciones. `update_video_direction` permite editarla y
|
|
118
|
+
`redraft_video_direction` propone otro enfoque.
|
|
119
|
+
4. **Renderizar** — usa `generate_video`.
|
|
120
|
+
5. **Recoger el resultado** — consulta `get_video` periódicamente para obtener el MP4 terminado y
|
|
121
|
+
un enlace público para compartirlo.
|
|
122
|
+
|
|
123
|
+
Las marcas funcionan de la misma manera: `list_brands`, `create_brand`, `set_product_brand`. Cada
|
|
124
|
+
vídeo se prepara con la voz de una marca; por eso, si el escaparate de un producto importado no
|
|
125
|
+
coincide con ninguna marca existente, el proceso se detiene y pregunta en lugar de adivinar.
|
|
126
|
+
|
|
127
|
+
El propio servidor publica los parámetros exactos de cada herramienta. Este repositorio no los
|
|
128
|
+
repite deliberadamente: ejecuta `python example.py tools`, como se indica abajo, para mostrar los
|
|
129
|
+
esquemas actuales. Así, lo que construyas no puede quedar desfasado respecto a lo que acepta el
|
|
130
|
+
servidor.
|
|
131
|
+
|
|
132
|
+
## Créditos
|
|
133
|
+
|
|
134
|
+
Importar un producto, preparar la dirección creativa y editarla es **gratis**. `generate_video` es
|
|
135
|
+
la única herramienta que consume créditos y requiere tu autorización explícita; las herramientas
|
|
136
|
+
indican antes el coste. Un agente no puede acumular cargos sin avisarte. Consulta los
|
|
137
|
+
[precios](https://instantclips.ai/#pricing).
|
|
138
|
+
|
|
139
|
+
## example.py
|
|
140
|
+
|
|
141
|
+
Un cliente MCP sin dependencias: solo requiere Python 3.9 o posterior y la biblioteca estándar; no
|
|
142
|
+
hace falta ejecutar `pip install`.
|
|
143
|
+
|
|
144
|
+
```bash
|
|
145
|
+
export INSTANTCLIPS_TOKEN="your-token"
|
|
146
|
+
|
|
147
|
+
python example.py tools # todas las herramientas, con su esquema de entrada actual
|
|
148
|
+
python example.py call list_brands '{}' # llama a una herramienta con argumentos JSON
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
Ejecuta primero `tools`: muestra los nombres y tipos de parámetros reales de cada herramienta, que
|
|
152
|
+
es lo que necesitas antes de automatizar el flujo de trabajo descrito arriba.
|
|
153
|
+
|
|
154
|
+
## Enlaces
|
|
155
|
+
|
|
156
|
+
- [instantclips.ai/automate](https://instantclips.ai/automate/) — qué es la automatización y para
|
|
157
|
+
qué sirve. No repite la configuración; esa información está en este archivo y en la página de
|
|
158
|
+
configuración de la aplicación.
|
|
159
|
+
- [app.instantclips.ai/llms.txt](https://app.instantclips.ai/llms.txt) — descripción del producto y
|
|
160
|
+
de la secuencia de herramientas en un formato legible por máquinas.
|
|
161
|
+
- [Términos](https://app.instantclips.ai/terms) · [Privacidad](https://app.instantclips.ai/privacy)
|
|
162
|
+
|
|
163
|
+
## Registro
|
|
164
|
+
|
|
165
|
+
`server.json` es la entrada de este servidor en el
|
|
166
|
+
[registro oficial de MCP](https://registry.modelcontextprotocol.io), del que se alimentan los demás
|
|
167
|
+
directorios. Una sola entrada, `ai.instantclips/instantclips`, contiene tanto el endpoint alojado en
|
|
168
|
+
`remotes` como el adaptador stdio en `packages`. Así, cada cliente puede elegir el transporte que
|
|
169
|
+
admita sin crear dos identidades para el mismo conjunto de herramientas.
|
|
170
|
+
|
|
171
|
+
El valor `mcpName` del paquete npm debe coincidir exactamente con ese nombre del registro. El enlace
|
|
172
|
+
al repositorio apunta al adaptador de código abierto; la implementación alojada del producto no se
|
|
173
|
+
encuentra en este repositorio.
|
|
174
|
+
|
|
175
|
+
El espacio de nombres `ai.instantclips` es el DNS inverso del dominio, por lo que debe publicarse
|
|
176
|
+
mediante autenticación del dominio por DNS o HTTP, no mediante GitHub. Autenticarse con GitHub
|
|
177
|
+
obligaría a usar `io.github.instantstudioai/...` y a renunciar al espacio de nombres de la marca.
|
|
178
|
+
|
|
179
|
+
Publica primero el paquete npm y, después de incrementar `version`, vuelve a publicar esta misma
|
|
180
|
+
entrada del registro con `mcp-publisher publish`. La autenticación del dominio conserva el espacio
|
|
181
|
+
de nombres de marca `ai.instantclips`; no lo sustituyas por un nombre `io.github.*`. La clave de
|
|
182
|
+
firma no se guarda en el repositorio: `.gitignore` cubre `*.pem`, y una clave privada incluida en un
|
|
183
|
+
commit es una clave publicada.
|
|
184
|
+
|
|
185
|
+
`glama.json` es el archivo independiente y específico de Glama que permite reclamar allí la ficha.
|
|
186
|
+
Un servidor perteneciente a una organización, en lugar de una cuenta personal, solo puede
|
|
187
|
+
reclamarse si ese archivo está presente.
|
|
188
|
+
El archivo solo acredita la propiedad: configura `npm ci` como compilación en Glama, ejecuta
|
|
189
|
+
`node bin/instantclips-mcp.js` y proporciona `INSTANTCLIPS_TOKEN` como secreto desde la interfaz de
|
|
190
|
+
administración del servidor.
|
|
191
|
+
|
|
192
|
+
## Licencia
|
|
193
|
+
|
|
194
|
+
MIT — consulta [LICENSE](LICENSE). La licencia cubre el contenido de este repositorio; el uso del
|
|
195
|
+
servicio alojado se rige por los [Términos de servicio](https://app.instantclips.ai/terms).
|
package/README.md
ADDED
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
# InstantClips MCP
|
|
2
|
+
|
|
3
|
+
**English** · [Español](README.es.md) · [简体中文](README.zh-CN.md)
|
|
4
|
+
|
|
5
|
+
[InstantClips](https://instantclips.ai) turns an e-commerce product into short-form vertical
|
|
6
|
+
video for TikTok, Instagram Reels and Stories. It runs a hosted **MCP server**, so Claude Code,
|
|
7
|
+
Codex, Cursor, VS Code, the Claude app, ChatGPT or any other MCP client can do what the web app
|
|
8
|
+
does: import a product, draft the creative direction, and render the video.
|
|
9
|
+
|
|
10
|
+
**The product server stays hosted.** This repository contains its connection guide, registry
|
|
11
|
+
metadata, example HTTP client and a small open-source stdio adapter for clients that cannot connect
|
|
12
|
+
to a remote server directly. The adapter only carries MCP messages to the hosted endpoint; the
|
|
13
|
+
tool definitions and product implementation remain in one place.
|
|
14
|
+
|
|
15
|
+
## Endpoint
|
|
16
|
+
|
|
17
|
+
| | |
|
|
18
|
+
| ---------- | ------------------------------------------ |
|
|
19
|
+
| Endpoint | `https://app.instantclips.ai/mcp` |
|
|
20
|
+
| Transport | Streamable HTTP, stateless |
|
|
21
|
+
| Method | `POST`, JSON-RPC 2.0 |
|
|
22
|
+
| Auth | `Authorization: Bearer <token>` |
|
|
23
|
+
|
|
24
|
+
Mint a token at **[app.instantclips.ai/settings#ai-access](https://app.instantclips.ai/settings#ai-access)**.
|
|
25
|
+
The token is a handle on your own account: same brands, products, credits and plan limits as the
|
|
26
|
+
web app. Signing in creates an account if you do not have one, with free credits to start.
|
|
27
|
+
|
|
28
|
+
Opening the endpoint in a browser returns the setup page rather than a protocol error, with
|
|
29
|
+
one-click install buttons that fill your token in for you.
|
|
30
|
+
|
|
31
|
+
## Install
|
|
32
|
+
|
|
33
|
+
Connect to the hosted endpoint directly whenever your client supports Streamable HTTP. Use the
|
|
34
|
+
stdio adapter below only for clients and automated runners that require a local command.
|
|
35
|
+
|
|
36
|
+
### Claude Code
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
claude mcp add --transport http instantclips https://app.instantclips.ai/mcp --header "Authorization: Bearer YOUR_TOKEN"
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
### Codex
|
|
43
|
+
|
|
44
|
+
Add to `~/.codex/config.toml`, which covers the CLI, the app and the IDE extension together:
|
|
45
|
+
|
|
46
|
+
```toml
|
|
47
|
+
[mcp_servers.instantclips]
|
|
48
|
+
url = "https://app.instantclips.ai/mcp"
|
|
49
|
+
http_headers = { Authorization = "Bearer YOUR_TOKEN" }
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
To keep the token out of the file, swap the header for `bearer_token_env_var = "INSTANTCLIPS_TOKEN"`
|
|
53
|
+
and export it in your shell instead.
|
|
54
|
+
|
|
55
|
+
### Stdio-only clients and headless runners
|
|
56
|
+
|
|
57
|
+
The `instantclips-mcp` npm package is a thin stdio-to-HTTPS adapter. It reads the token from the
|
|
58
|
+
environment, fixes the upstream endpoint to InstantClips and forwards the protocol unchanged:
|
|
59
|
+
|
|
60
|
+
```json
|
|
61
|
+
{
|
|
62
|
+
"mcpServers": {
|
|
63
|
+
"instantclips": {
|
|
64
|
+
"command": "npx",
|
|
65
|
+
"args": ["-y", "instantclips-mcp"],
|
|
66
|
+
"env": {
|
|
67
|
+
"INSTANTCLIPS_TOKEN": "YOUR_TOKEN"
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
For an automated connectivity check, including the live tool names:
|
|
75
|
+
|
|
76
|
+
```bash
|
|
77
|
+
INSTANTCLIPS_TOKEN="your-token" npx -y instantclips-mcp --check --json
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
The token is accepted only through `INSTANTCLIPS_TOKEN`, never as a command-line argument, so it
|
|
81
|
+
does not appear in the process list. Node.js 20 or newer is required.
|
|
82
|
+
|
|
83
|
+
### Cursor and VS Code
|
|
84
|
+
|
|
85
|
+
One-click install buttons are on the [setup page](https://app.instantclips.ai/settings#ai-access).
|
|
86
|
+
They fill in your token once you have minted one.
|
|
87
|
+
|
|
88
|
+
### Claude app and ChatGPT
|
|
89
|
+
|
|
90
|
+
These connect through their own connector settings rather than a file. Point one at
|
|
91
|
+
`https://app.instantclips.ai/mcp` and authenticate with the same token — a request header in
|
|
92
|
+
Claude, an API key in ChatGPT. Claude's request headers are still in beta, and ChatGPT requires
|
|
93
|
+
developer mode; availability there depends on your account and workspace policy.
|
|
94
|
+
|
|
95
|
+
### Anything else
|
|
96
|
+
|
|
97
|
+
OpenClaw, Hermes, or an agent you wrote yourself: point it at the URL over streamable HTTP with an
|
|
98
|
+
`Authorization: Bearer` header. Nothing on the wire is InstantClips-specific, so a client that
|
|
99
|
+
speaks MCP already speaks this.
|
|
100
|
+
|
|
101
|
+
## Tools
|
|
102
|
+
|
|
103
|
+
The workflow, in order:
|
|
104
|
+
|
|
105
|
+
1. **Import** — `import_product_from_url` for a store page, or `create_product_from_images` when
|
|
106
|
+
there is no page to read.
|
|
107
|
+
2. **Wait for the draft** — poll `get_product` until the import and the creative direction have
|
|
108
|
+
finished.
|
|
109
|
+
3. **Read and steer it** — the direction comes back as text: hook, content focus, format,
|
|
110
|
+
execution guidelines, restrictions. `update_video_direction` edits it, `redraft_video_direction`
|
|
111
|
+
asks for another angle.
|
|
112
|
+
4. **Render** — `generate_video`.
|
|
113
|
+
5. **Collect** — poll `get_video` for the finished MP4 and a public share link.
|
|
114
|
+
|
|
115
|
+
Brands work the same way: `list_brands`, `create_brand`, `set_product_brand`. Every video is
|
|
116
|
+
drafted in a brand's voice, so an import whose storefront matches no existing brand stops and asks
|
|
117
|
+
rather than guessing.
|
|
118
|
+
|
|
119
|
+
Each tool's exact parameters are published by the server itself. This repository deliberately does
|
|
120
|
+
not restate them — run `python example.py tools` below to print the live schemas, so what you build
|
|
121
|
+
against cannot drift from what the server accepts.
|
|
122
|
+
|
|
123
|
+
## Credits
|
|
124
|
+
|
|
125
|
+
Importing a product, drafting the creative direction and editing it are all **free**.
|
|
126
|
+
`generate_video` is the only tool that spends credits, and it requires your explicit go-ahead — the
|
|
127
|
+
tools report the cost first. An agent cannot quietly run up a bill. See
|
|
128
|
+
[pricing](https://instantclips.ai/#pricing).
|
|
129
|
+
|
|
130
|
+
## example.py
|
|
131
|
+
|
|
132
|
+
A dependency-free MCP client — Python 3.9+, standard library only, no `pip install`.
|
|
133
|
+
|
|
134
|
+
```bash
|
|
135
|
+
export INSTANTCLIPS_TOKEN="your-token"
|
|
136
|
+
|
|
137
|
+
python example.py tools # every tool, with its live input schema
|
|
138
|
+
python example.py call list_brands '{}' # call one tool with JSON arguments
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
`tools` is the one to run first: it prints the real parameter names and types for every tool, which
|
|
142
|
+
is what you need before scripting the workflow above.
|
|
143
|
+
|
|
144
|
+
## Links
|
|
145
|
+
|
|
146
|
+
- [instantclips.ai/automate](https://instantclips.ai/automate/) — what the automation is and what
|
|
147
|
+
it is for. It does not repeat the setup; this file and the app's setup page are where that lives.
|
|
148
|
+
- [app.instantclips.ai/llms.txt](https://app.instantclips.ai/llms.txt) — machine-readable
|
|
149
|
+
description of the product and the tool sequence
|
|
150
|
+
- [Terms](https://app.instantclips.ai/terms) · [Privacy](https://app.instantclips.ai/privacy)
|
|
151
|
+
|
|
152
|
+
## Registry
|
|
153
|
+
|
|
154
|
+
`server.json` is this server's entry in the [official MCP registry](https://registry.modelcontextprotocol.io),
|
|
155
|
+
which the other directories ingest from. One `ai.instantclips/instantclips` entry carries both the
|
|
156
|
+
hosted endpoint in `remotes` and the stdio adapter in `packages`, so a host can choose the transport
|
|
157
|
+
it supports without creating two identities for the same tool surface.
|
|
158
|
+
|
|
159
|
+
The npm package's `mcpName` must exactly match that registry name. The repository link points to the
|
|
160
|
+
open-source adapter; the hosted product implementation is not in this repository.
|
|
161
|
+
|
|
162
|
+
The `ai.instantclips` namespace is the reverse-DNS of the domain, which requires publishing under
|
|
163
|
+
DNS or HTTP domain auth rather than GitHub auth. Authenticating with GitHub instead would force the
|
|
164
|
+
entry into `io.github.instantstudioai/...` and give up the branded namespace.
|
|
165
|
+
|
|
166
|
+
Publish the npm package first, then re-publish this same registry entry with
|
|
167
|
+
`mcp-publisher publish` after bumping its `version`. Domain authentication keeps the branded
|
|
168
|
+
`ai.instantclips` namespace; do not replace it with an `io.github.*` name. The signing key stays out
|
|
169
|
+
of the repository — `.gitignore` covers `*.pem`, and a committed private key is a published one.
|
|
170
|
+
|
|
171
|
+
`glama.json` is the separate, Glama-specific file that claims the listing there. A server under an
|
|
172
|
+
organisation rather than a personal account can only be claimed with that file present.
|
|
173
|
+
It carries ownership only: configure Glama's build as `npm ci`, run
|
|
174
|
+
`node bin/instantclips-mcp.js`, and supply `INSTANTCLIPS_TOKEN` as a secret in the server admin UI.
|
|
175
|
+
|
|
176
|
+
## License
|
|
177
|
+
|
|
178
|
+
MIT — see [LICENSE](LICENSE). The license covers this repository's contents; use of the hosted
|
|
179
|
+
service is governed by the [Terms of Service](https://app.instantclips.ai/terms).
|
package/README.zh-CN.md
ADDED
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
# InstantClips MCP
|
|
2
|
+
|
|
3
|
+
[English](README.md) · [Español](README.es.md) · **简体中文**
|
|
4
|
+
|
|
5
|
+
[InstantClips](https://instantclips.ai) 可将电商商品转化为适用于 TikTok、Instagram Reels 和
|
|
6
|
+
Stories 的竖屏短视频。它提供托管的 **MCP 服务器**,因此 Claude Code、Codex、Cursor、
|
|
7
|
+
VS Code、Claude 应用、ChatGPT 或其他任何 MCP 客户端都能完成网页应用中的工作:导入商品、
|
|
8
|
+
起草创意方向并渲染视频。
|
|
9
|
+
|
|
10
|
+
**产品服务器仍以托管方式运行。** 本仓库包含连接指南、注册表元数据、示例 HTTP 客户端,以及一个
|
|
11
|
+
面向无法直接连接远程服务器的客户端的小型开源 stdio 适配器。适配器只负责将 MCP 消息转发到托管
|
|
12
|
+
端点;工具定义和产品实现仍然只保留在一个地方。
|
|
13
|
+
|
|
14
|
+
## 端点
|
|
15
|
+
|
|
16
|
+
| | |
|
|
17
|
+
| -------- | ------------------------------------------ |
|
|
18
|
+
| 端点 | `https://app.instantclips.ai/mcp` |
|
|
19
|
+
| 传输方式 | Streamable HTTP,无状态 |
|
|
20
|
+
| 方法 | `POST`,JSON-RPC 2.0 |
|
|
21
|
+
| 身份验证 | `Authorization: Bearer <token>` |
|
|
22
|
+
|
|
23
|
+
前往 **[app.instantclips.ai/settings#ai-access](https://app.instantclips.ai/settings#ai-access)**
|
|
24
|
+
生成令牌。该令牌关联你自己的账户,可访问与网页应用相同的品牌、商品、点数和方案限额。如果你还没有
|
|
25
|
+
账户,登录时会自动创建账户,并赠送可用于开始体验的免费点数。
|
|
26
|
+
|
|
27
|
+
在浏览器中打开端点时会显示设置页面,而不是协议错误;页面上的一键安装按钮会自动为你填入令牌。
|
|
28
|
+
|
|
29
|
+
## 安装
|
|
30
|
+
|
|
31
|
+
如果客户端支持 Streamable HTTP,请优先直接连接托管端点。只有在客户端或自动化运行环境必须执行
|
|
32
|
+
本地命令时,才使用下方的 stdio 适配器。
|
|
33
|
+
|
|
34
|
+
### Claude Code
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
claude mcp add --transport http instantclips https://app.instantclips.ai/mcp --header "Authorization: Bearer YOUR_TOKEN"
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
### Codex
|
|
41
|
+
|
|
42
|
+
将以下配置添加到 `~/.codex/config.toml`。该配置同时适用于 CLI、应用和 IDE 扩展:
|
|
43
|
+
|
|
44
|
+
```toml
|
|
45
|
+
[mcp_servers.instantclips]
|
|
46
|
+
url = "https://app.instantclips.ai/mcp"
|
|
47
|
+
http_headers = { Authorization = "Bearer YOUR_TOKEN" }
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
如果不想将令牌写入文件,请将请求头配置替换为
|
|
51
|
+
`bearer_token_env_var = "INSTANTCLIPS_TOKEN"`,然后在 shell 中导出该环境变量。
|
|
52
|
+
|
|
53
|
+
### 仅支持 stdio 的客户端和无界面自动化
|
|
54
|
+
|
|
55
|
+
`instantclips-mcp` npm 软件包是一个轻量的 stdio 到 HTTPS 适配器。它从环境变量读取令牌,将上游
|
|
56
|
+
端点固定为 InstantClips,并原样转发协议消息:
|
|
57
|
+
|
|
58
|
+
```json
|
|
59
|
+
{
|
|
60
|
+
"mcpServers": {
|
|
61
|
+
"instantclips": {
|
|
62
|
+
"command": "npx",
|
|
63
|
+
"args": ["-y", "instantclips-mcp"],
|
|
64
|
+
"env": {
|
|
65
|
+
"INSTANTCLIPS_TOKEN": "YOUR_TOKEN"
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
如需自动检查连接并获取实时工具名称,请运行:
|
|
73
|
+
|
|
74
|
+
```bash
|
|
75
|
+
INSTANTCLIPS_TOKEN="your-token" npx -y instantclips-mcp --check --json
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
令牌只能通过 `INSTANTCLIPS_TOKEN` 提供,不能作为命令行参数传入,因此不会出现在进程列表中。
|
|
79
|
+
需要 Node.js 20 或更高版本。
|
|
80
|
+
|
|
81
|
+
### Cursor 和 VS Code
|
|
82
|
+
|
|
83
|
+
[设置页面](https://app.instantclips.ai/settings#ai-access)提供一键安装按钮。生成令牌后,按钮会自动
|
|
84
|
+
为你填入令牌。
|
|
85
|
+
|
|
86
|
+
### Claude 应用和 ChatGPT
|
|
87
|
+
|
|
88
|
+
这些客户端通过各自的连接器设置进行连接,而不是读取配置文件。将连接地址设为
|
|
89
|
+
`https://app.instantclips.ai/mcp`,并使用同一个令牌进行身份验证:Claude 使用请求头,ChatGPT
|
|
90
|
+
使用 API 密钥。Claude 的自定义请求头功能仍处于测试阶段,而 ChatGPT 需要开启开发者模式;具体
|
|
91
|
+
是否可用取决于你的账户和工作区政策。
|
|
92
|
+
|
|
93
|
+
### 其他客户端
|
|
94
|
+
|
|
95
|
+
无论是 OpenClaw、Hermes,还是你自己编写的智能体,只需通过 Streamable HTTP 连接该 URL,并
|
|
96
|
+
添加 `Authorization: Bearer` 请求头。传输协议中没有 InstantClips 专用内容,因此任何支持 MCP
|
|
97
|
+
的客户端都能与该服务器通信。
|
|
98
|
+
|
|
99
|
+
## 工具
|
|
100
|
+
|
|
101
|
+
工作流程如下:
|
|
102
|
+
|
|
103
|
+
1. **导入** — 如果有店铺商品页面,使用 `import_product_from_url`;如果没有可读取的页面,则使用
|
|
104
|
+
`create_product_from_images`。
|
|
105
|
+
2. **等待草稿** — 轮询 `get_product`,直到商品导入和创意方向起草完成。
|
|
106
|
+
3. **查看并调整** — 创意方向以文本返回,包含开场钩子、内容重点、形式、执行指南和限制条件。
|
|
107
|
+
使用 `update_video_direction` 进行编辑,或使用 `redraft_video_direction` 获取另一个方向。
|
|
108
|
+
4. **渲染** — 使用 `generate_video`。
|
|
109
|
+
5. **获取结果** — 轮询 `get_video`,获取完成的 MP4 文件和公开分享链接。
|
|
110
|
+
|
|
111
|
+
品牌的操作方式相同:`list_brands`、`create_brand`、`set_product_brand`。每个视频都会采用对应品牌
|
|
112
|
+
的表达风格进行起草。因此,当导入商品的店铺与任何现有品牌都不匹配时,流程会暂停并询问,而不是
|
|
113
|
+
自行猜测。
|
|
114
|
+
|
|
115
|
+
每个工具的确切参数均由服务器自身发布。本仓库有意不重复列出这些参数;请运行下方的
|
|
116
|
+
`python example.py tools` 来输出实时 schema,确保你构建的集成始终与服务器实际接受的参数一致。
|
|
117
|
+
|
|
118
|
+
## 点数
|
|
119
|
+
|
|
120
|
+
导入商品、起草创意方向和编辑方向均为**免费**。只有 `generate_video` 会消耗点数,而且必须获得你
|
|
121
|
+
的明确许可;工具会事先报告费用。智能体无法在你不知情的情况下产生费用。详见
|
|
122
|
+
[价格](https://instantclips.ai/#pricing)。
|
|
123
|
+
|
|
124
|
+
## example.py
|
|
125
|
+
|
|
126
|
+
这是一个无第三方依赖的 MCP 客户端,仅需 Python 3.9 或更高版本和标准库,无需运行
|
|
127
|
+
`pip install`。
|
|
128
|
+
|
|
129
|
+
```bash
|
|
130
|
+
export INSTANTCLIPS_TOKEN="your-token"
|
|
131
|
+
|
|
132
|
+
python example.py tools # 所有工具及其实时输入 schema
|
|
133
|
+
python example.py call list_brands '{}' # 使用 JSON 参数调用一个工具
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
请先运行 `tools`:它会输出每个工具真实的参数名称和类型,这是自动化上述工作流程前所需的信息。
|
|
137
|
+
|
|
138
|
+
## 链接
|
|
139
|
+
|
|
140
|
+
- [instantclips.ai/automate](https://instantclips.ai/automate/) — 介绍自动化功能及其用途。该页面不会
|
|
141
|
+
重复设置说明;设置方法请参阅本文档和应用中的设置页面。
|
|
142
|
+
- [app.instantclips.ai/llms.txt](https://app.instantclips.ai/llms.txt) — 适合机器读取的产品说明和工具
|
|
143
|
+
调用顺序。
|
|
144
|
+
- [服务条款](https://app.instantclips.ai/terms) · [隐私政策](https://app.instantclips.ai/privacy)
|
|
145
|
+
|
|
146
|
+
## 注册表
|
|
147
|
+
|
|
148
|
+
`server.json` 是该服务器在 [MCP 官方注册表](https://registry.modelcontextprotocol.io)中的条目,其他
|
|
149
|
+
目录会从中获取信息。同一个 `ai.instantclips/instantclips` 条目既通过 `remotes` 提供托管端点,
|
|
150
|
+
也通过 `packages` 提供 stdio 适配器。客户端可根据自身支持情况选择传输方式,无需为同一组工具创建
|
|
151
|
+
两个身份。
|
|
152
|
+
|
|
153
|
+
npm 软件包中的 `mcpName` 必须与该注册表名称完全一致。仓库链接指向开源适配器;托管产品的实现
|
|
154
|
+
不在本仓库中。
|
|
155
|
+
|
|
156
|
+
`ai.instantclips` 命名空间是域名的反向 DNS,因此发布时必须使用 DNS 或 HTTP 域名验证,而不能
|
|
157
|
+
使用 GitHub 身份验证。改用 GitHub 身份验证会强制使用 `io.github.instantstudioai/...`,从而失去
|
|
158
|
+
品牌命名空间。
|
|
159
|
+
|
|
160
|
+
请先发布 npm 软件包,再增加 `version`,并运行 `mcp-publisher publish` 重新发布同一个注册表条目。
|
|
161
|
+
域名身份验证会保留品牌命名空间 `ai.instantclips`;请勿将其替换为 `io.github.*` 名称。签名密钥不
|
|
162
|
+
存放在仓库中:`.gitignore` 已忽略 `*.pem`,因为一旦提交私钥,就等于公开了私钥。
|
|
163
|
+
|
|
164
|
+
`glama.json` 是 Glama 专用的独立文件,用于认领该平台上的条目。归属于组织而非个人账户的服务器,
|
|
165
|
+
只有在该文件存在时才能完成认领。
|
|
166
|
+
该文件只用于证明所有权:在 Glama 中将构建命令设置为 `npm ci`,运行
|
|
167
|
+
`node bin/instantclips-mcp.js`,并在服务器管理界面中将 `INSTANTCLIPS_TOKEN` 配置为密钥。
|
|
168
|
+
|
|
169
|
+
## 许可证
|
|
170
|
+
|
|
171
|
+
MIT — 参见 [LICENSE](LICENSE)。该许可证适用于本仓库中的内容;托管服务的使用受
|
|
172
|
+
[服务条款](https://app.instantclips.ai/terms)约束。
|
|
@@ -0,0 +1,318 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import { readFileSync } from "node:fs";
|
|
4
|
+
|
|
5
|
+
import {
|
|
6
|
+
Client,
|
|
7
|
+
StreamableHTTPClientTransport,
|
|
8
|
+
UnauthorizedError,
|
|
9
|
+
} from "@modelcontextprotocol/client";
|
|
10
|
+
import { StdioServerTransport } from "@modelcontextprotocol/server/stdio";
|
|
11
|
+
|
|
12
|
+
const DEFAULT_ENDPOINT = "https://app.instantclips.ai/mcp";
|
|
13
|
+
const SETTINGS_URL = "https://app.instantclips.ai/settings#ai-access";
|
|
14
|
+
const packageJson = JSON.parse(
|
|
15
|
+
readFileSync(new URL("../package.json", import.meta.url), "utf8"),
|
|
16
|
+
);
|
|
17
|
+
const VERSION = packageJson.version;
|
|
18
|
+
|
|
19
|
+
function usage() {
|
|
20
|
+
return `InstantClips MCP ${VERSION}
|
|
21
|
+
|
|
22
|
+
Use the hosted InstantClips MCP server from a client that requires stdio.
|
|
23
|
+
|
|
24
|
+
Usage:
|
|
25
|
+
instantclips-mcp
|
|
26
|
+
instantclips-mcp --check [--json]
|
|
27
|
+
instantclips-mcp --help
|
|
28
|
+
instantclips-mcp --version
|
|
29
|
+
|
|
30
|
+
Environment:
|
|
31
|
+
INSTANTCLIPS_TOKEN Required bearer token. Create one at ${SETTINGS_URL}
|
|
32
|
+
|
|
33
|
+
The upstream endpoint is ${DEFAULT_ENDPOINT}.
|
|
34
|
+
`;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
function configuration(env = process.env) {
|
|
38
|
+
const token = env.INSTANTCLIPS_TOKEN?.trim();
|
|
39
|
+
if (!token) {
|
|
40
|
+
throw new CliError(
|
|
41
|
+
"missing_token",
|
|
42
|
+
`INSTANTCLIPS_TOKEN is required. Create a token at ${SETTINGS_URL}.`,
|
|
43
|
+
78,
|
|
44
|
+
);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
let endpoint;
|
|
48
|
+
try {
|
|
49
|
+
endpoint = new URL(env.INSTANTCLIPS_MCP_URL || DEFAULT_ENDPOINT);
|
|
50
|
+
} catch {
|
|
51
|
+
throw new CliError(
|
|
52
|
+
"invalid_endpoint",
|
|
53
|
+
"The InstantClips MCP endpoint URL is invalid.",
|
|
54
|
+
78,
|
|
55
|
+
);
|
|
56
|
+
}
|
|
57
|
+
const isLoopback = ["localhost", "127.0.0.1", "[::1]"].includes(
|
|
58
|
+
endpoint.hostname,
|
|
59
|
+
);
|
|
60
|
+
if (
|
|
61
|
+
endpoint.protocol !== "https:" &&
|
|
62
|
+
!(endpoint.protocol === "http:" && isLoopback)
|
|
63
|
+
) {
|
|
64
|
+
throw new CliError(
|
|
65
|
+
"insecure_endpoint",
|
|
66
|
+
"The InstantClips MCP endpoint must use HTTPS (HTTP is allowed only for loopback tests).",
|
|
67
|
+
78,
|
|
68
|
+
);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
return { endpoint, token };
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
function remoteTransport({ endpoint, token }) {
|
|
75
|
+
return new StreamableHTTPClientTransport(endpoint, {
|
|
76
|
+
authProvider: { token: async () => token },
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
function isRequest(message) {
|
|
81
|
+
return Boolean(
|
|
82
|
+
message &&
|
|
83
|
+
!Array.isArray(message) &&
|
|
84
|
+
typeof message === "object" &&
|
|
85
|
+
typeof message.method === "string" &&
|
|
86
|
+
Object.hasOwn(message, "id"),
|
|
87
|
+
);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
function isResponse(message) {
|
|
91
|
+
return Boolean(
|
|
92
|
+
message &&
|
|
93
|
+
!Array.isArray(message) &&
|
|
94
|
+
typeof message === "object" &&
|
|
95
|
+
Object.hasOwn(message, "id") &&
|
|
96
|
+
(Object.hasOwn(message, "result") || Object.hasOwn(message, "error")),
|
|
97
|
+
);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
function safeFailure(error, token) {
|
|
101
|
+
const status = error?.data?.status;
|
|
102
|
+
const text = String(error?.message || error || "Unknown error").replaceAll(
|
|
103
|
+
token,
|
|
104
|
+
"[redacted]",
|
|
105
|
+
);
|
|
106
|
+
|
|
107
|
+
if (
|
|
108
|
+
error instanceof UnauthorizedError ||
|
|
109
|
+
status === 401 ||
|
|
110
|
+
/\b401\b/.test(text)
|
|
111
|
+
) {
|
|
112
|
+
return {
|
|
113
|
+
code: "authentication_failed",
|
|
114
|
+
message: `InstantClips authentication failed. Replace INSTANTCLIPS_TOKEN with a token from ${SETTINGS_URL}.`,
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
if (
|
|
119
|
+
/fetch failed|ECONNREFUSED|ENOTFOUND|ETIMEDOUT|network|socket|connect/i.test(text)
|
|
120
|
+
) {
|
|
121
|
+
return {
|
|
122
|
+
code: "upstream_unavailable",
|
|
123
|
+
message: "The hosted InstantClips MCP endpoint is unavailable.",
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
return {
|
|
128
|
+
code: "upstream_error",
|
|
129
|
+
message: `The hosted InstantClips MCP endpoint returned an error: ${text}`,
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
function writeDiagnostic(failure) {
|
|
134
|
+
process.stderr.write(`instantclips-mcp: ${failure.message}\n`);
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
async function startBridge(config) {
|
|
138
|
+
const stdio = new StdioServerTransport();
|
|
139
|
+
const remote = remoteTransport(config);
|
|
140
|
+
const initializeRequestIds = new Set();
|
|
141
|
+
let closing = false;
|
|
142
|
+
|
|
143
|
+
const shutdown = async (exitCode = process.exitCode || 0) => {
|
|
144
|
+
if (closing) return;
|
|
145
|
+
closing = true;
|
|
146
|
+
process.exitCode = exitCode;
|
|
147
|
+
process.stdin.off("end", onStdinEnd);
|
|
148
|
+
process.stdin.off("close", onStdinEnd);
|
|
149
|
+
process.off("SIGINT", onSigint);
|
|
150
|
+
process.off("SIGTERM", onSigterm);
|
|
151
|
+
await Promise.allSettled([remote.close(), stdio.close()]);
|
|
152
|
+
};
|
|
153
|
+
|
|
154
|
+
const onStdinEnd = () => void shutdown();
|
|
155
|
+
const onSigint = () => void shutdown(130);
|
|
156
|
+
const onSigterm = () => void shutdown(143);
|
|
157
|
+
|
|
158
|
+
stdio.onmessage = (message) => {
|
|
159
|
+
if (isRequest(message) && message.method === "initialize") {
|
|
160
|
+
initializeRequestIds.add(message.id);
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
void remote.send(message).catch(async (error) => {
|
|
164
|
+
if (isRequest(message)) {
|
|
165
|
+
initializeRequestIds.delete(message.id);
|
|
166
|
+
const failure = safeFailure(error, config.token);
|
|
167
|
+
await stdio
|
|
168
|
+
.send({
|
|
169
|
+
jsonrpc: "2.0",
|
|
170
|
+
id: message.id,
|
|
171
|
+
error: {
|
|
172
|
+
code: -32000,
|
|
173
|
+
message: failure.message,
|
|
174
|
+
data: { code: failure.code },
|
|
175
|
+
},
|
|
176
|
+
})
|
|
177
|
+
.catch((sendError) => {
|
|
178
|
+
writeDiagnostic(safeFailure(sendError, config.token));
|
|
179
|
+
void shutdown(74);
|
|
180
|
+
});
|
|
181
|
+
}
|
|
182
|
+
});
|
|
183
|
+
};
|
|
184
|
+
|
|
185
|
+
remote.onmessage = (message) => {
|
|
186
|
+
if (isResponse(message) && initializeRequestIds.delete(message.id)) {
|
|
187
|
+
const protocolVersion = message.result?.protocolVersion;
|
|
188
|
+
if (typeof protocolVersion === "string") {
|
|
189
|
+
remote.setProtocolVersion(protocolVersion);
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
void stdio.send(message).catch((error) => {
|
|
193
|
+
writeDiagnostic(safeFailure(error, config.token));
|
|
194
|
+
void shutdown(74);
|
|
195
|
+
});
|
|
196
|
+
};
|
|
197
|
+
|
|
198
|
+
remote.onerror = (error) => writeDiagnostic(safeFailure(error, config.token));
|
|
199
|
+
remote.onclose = () => void shutdown();
|
|
200
|
+
stdio.onerror = (error) => {
|
|
201
|
+
writeDiagnostic(safeFailure(error, config.token));
|
|
202
|
+
void shutdown(74);
|
|
203
|
+
};
|
|
204
|
+
stdio.onclose = () => void shutdown();
|
|
205
|
+
|
|
206
|
+
process.stdin.once("end", onStdinEnd);
|
|
207
|
+
process.stdin.once("close", onStdinEnd);
|
|
208
|
+
process.once("SIGINT", onSigint);
|
|
209
|
+
process.once("SIGTERM", onSigterm);
|
|
210
|
+
|
|
211
|
+
await remote.start();
|
|
212
|
+
await stdio.start();
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
async function checkConnection(config, json) {
|
|
216
|
+
const transport = remoteTransport(config);
|
|
217
|
+
const client = new Client({ name: "instantclips-mcp-check", version: VERSION });
|
|
218
|
+
|
|
219
|
+
try {
|
|
220
|
+
await client.connect(transport);
|
|
221
|
+
const tools = [];
|
|
222
|
+
let cursor;
|
|
223
|
+
do {
|
|
224
|
+
const page = await client.listTools(cursor ? { cursor } : undefined);
|
|
225
|
+
tools.push(...page.tools.map((tool) => tool.name));
|
|
226
|
+
cursor = page.nextCursor;
|
|
227
|
+
} while (cursor);
|
|
228
|
+
|
|
229
|
+
const server = client.getServerVersion();
|
|
230
|
+
const result = {
|
|
231
|
+
ok: true,
|
|
232
|
+
endpoint: config.endpoint.href,
|
|
233
|
+
protocolVersion: client.getNegotiatedProtocolVersion(),
|
|
234
|
+
server,
|
|
235
|
+
toolCount: tools.length,
|
|
236
|
+
tools,
|
|
237
|
+
};
|
|
238
|
+
|
|
239
|
+
if (json) {
|
|
240
|
+
process.stdout.write(`${JSON.stringify(result)}\n`);
|
|
241
|
+
} else {
|
|
242
|
+
process.stdout.write(
|
|
243
|
+
`InstantClips MCP is reachable: ${tools.length} tools from ${server?.name || "the hosted server"}.\n`,
|
|
244
|
+
);
|
|
245
|
+
}
|
|
246
|
+
return 0;
|
|
247
|
+
} catch (error) {
|
|
248
|
+
const failure = safeFailure(error, config.token);
|
|
249
|
+
if (json) {
|
|
250
|
+
process.stdout.write(`${JSON.stringify({ ok: false, ...failure })}\n`);
|
|
251
|
+
} else {
|
|
252
|
+
writeDiagnostic(failure);
|
|
253
|
+
}
|
|
254
|
+
return failure.code === "authentication_failed" ? 77 : 69;
|
|
255
|
+
} finally {
|
|
256
|
+
await client.close().catch(() => {});
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
class CliError extends Error {
|
|
261
|
+
constructor(code, message, exitCode) {
|
|
262
|
+
super(message);
|
|
263
|
+
this.code = code;
|
|
264
|
+
this.exitCode = exitCode;
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
async function main(args) {
|
|
269
|
+
if (args.includes("--help") || args.includes("-h")) {
|
|
270
|
+
if (args.length !== 1) throw new CliError("usage", usage(), 64);
|
|
271
|
+
process.stdout.write(usage());
|
|
272
|
+
return 0;
|
|
273
|
+
}
|
|
274
|
+
if (args.includes("--version") || args.includes("-v")) {
|
|
275
|
+
if (args.length !== 1) throw new CliError("usage", usage(), 64);
|
|
276
|
+
process.stdout.write(`${VERSION}\n`);
|
|
277
|
+
return 0;
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
const check = args.includes("--check");
|
|
281
|
+
const json = args.includes("--json");
|
|
282
|
+
const accepted = new Set(["--check", "--json"]);
|
|
283
|
+
if (args.some((arg) => !accepted.has(arg)) || (json && !check)) {
|
|
284
|
+
throw new CliError("usage", usage(), 64);
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
let config;
|
|
288
|
+
try {
|
|
289
|
+
config = configuration();
|
|
290
|
+
} catch (error) {
|
|
291
|
+
if (check && json && error instanceof CliError) {
|
|
292
|
+
process.stdout.write(
|
|
293
|
+
`${JSON.stringify({ ok: false, code: error.code, message: error.message })}\n`,
|
|
294
|
+
);
|
|
295
|
+
return error.exitCode;
|
|
296
|
+
}
|
|
297
|
+
throw error;
|
|
298
|
+
}
|
|
299
|
+
if (check) return checkConnection(config, json);
|
|
300
|
+
await startBridge(config);
|
|
301
|
+
return 0;
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
try {
|
|
305
|
+
process.exitCode = await main(process.argv.slice(2));
|
|
306
|
+
} catch (error) {
|
|
307
|
+
if (error instanceof CliError) {
|
|
308
|
+
process.stderr.write(
|
|
309
|
+
error.code === "usage"
|
|
310
|
+
? `${error.message}\n`
|
|
311
|
+
: `instantclips-mcp: ${error.message}\n`,
|
|
312
|
+
);
|
|
313
|
+
process.exitCode = error.exitCode;
|
|
314
|
+
} else {
|
|
315
|
+
process.stderr.write(`instantclips-mcp: ${error?.message || error}\n`);
|
|
316
|
+
process.exitCode = 70;
|
|
317
|
+
}
|
|
318
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "instantclips-mcp",
|
|
3
|
+
"mcpName": "ai.instantclips/instantclips",
|
|
4
|
+
"version": "1.1.0",
|
|
5
|
+
"description": "Use the hosted InstantClips MCP server from stdio-only clients.",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"bin": {
|
|
8
|
+
"instantclips-mcp": "bin/instantclips-mcp.js"
|
|
9
|
+
},
|
|
10
|
+
"files": [
|
|
11
|
+
"bin/"
|
|
12
|
+
],
|
|
13
|
+
"scripts": {
|
|
14
|
+
"test": "node --test",
|
|
15
|
+
"check:pack": "npm pack --dry-run",
|
|
16
|
+
"prepublishOnly": "npm test && npm run check:pack"
|
|
17
|
+
},
|
|
18
|
+
"repository": {
|
|
19
|
+
"type": "git",
|
|
20
|
+
"url": "git+https://github.com/InstantStudioAI/instantclips-mcp.git"
|
|
21
|
+
},
|
|
22
|
+
"homepage": "https://instantclips.ai/automate/",
|
|
23
|
+
"bugs": {
|
|
24
|
+
"url": "https://github.com/InstantStudioAI/instantclips-mcp/issues"
|
|
25
|
+
},
|
|
26
|
+
"keywords": [
|
|
27
|
+
"mcp",
|
|
28
|
+
"model-context-protocol",
|
|
29
|
+
"video-generation",
|
|
30
|
+
"video-ads",
|
|
31
|
+
"ecommerce",
|
|
32
|
+
"ai-agents"
|
|
33
|
+
],
|
|
34
|
+
"author": "InstantStudioAI",
|
|
35
|
+
"license": "MIT",
|
|
36
|
+
"engines": {
|
|
37
|
+
"node": ">=20"
|
|
38
|
+
},
|
|
39
|
+
"publishConfig": {
|
|
40
|
+
"access": "public"
|
|
41
|
+
},
|
|
42
|
+
"dependencies": {
|
|
43
|
+
"@modelcontextprotocol/client": "2.0.0",
|
|
44
|
+
"@modelcontextprotocol/server": "2.0.0"
|
|
45
|
+
}
|
|
46
|
+
}
|