Zero to Hundred
Búsqueda y comparación de software público. Acceso con alcance a la cuenta para borradores propios; revisar y publicar en el sitio web de Zero to Hundred.
Servidor MCP alojado
npx add-mcp 'https://zerotohundred.ai/api/mcp'Se instala en Claude Code, Codex, Cursor y más
Documentación
Hay 4 formas de enviar un borrador de listado a Zero to Hundred. Una URL de precarga para plataformas web, una API REST estable para backends personalizados, OAuth 2.1 + PKCE para aplicaciones de socios, y un servidor MCP oficial para herramientas de codificación con IA. Los llamadores del conector crean borradores; el Builder los revisa y publica en el asistente.
Descripción general
La plataforma del conector tiene tres capas. Elige la que se ajuste a cómo funciona tu plataforma. Todas llegan al mismo lugar: un listado status="draft" que el Builder termina en el asistente de Zero to Hundred.
URL de precarga
Plataformas web (sin backend)
Crea un enlace y colócalo en tu menú Compartir. Sin SDK, sin claves. El Builder inicia sesión en Zero to Hundred a mitad del flujo y el asistente se abre precargado.
API REST
Backends personalizados
Envía un borrador con un token de portador. Tokens de acceso personal para Builders individuales, OAuth 2.1 + PKCE para aplicaciones de socios que actúan en nombre de un Builder.
Servidor MCP
Herramientas de codificación con IA
El servidor local publicado puede crear un borrador de software desde un cliente MCP compatible. El Builder lo revisa y publica en el sitio web.
Descubrimiento público
Busca software público en vivo sin iniciar sesión ni enviar un token. Usa el endpoint REST directamente o llama a z2h_search_marketplace a través de cualquiera de los dos servidores MCP.
curl --get https://zerotohundred.ai/api/v1/discover \
--data-urlencode "search=invoicing" \
--data-urlencode "type=tool" \
--data-urlencode "limit=5"
La respuesta JSON contiene items, nextCursor y hasMore. Los resultados contienen metadatos públicos del listado, no archivos fuente. La búsqueda coincide con palabras en el texto del listado. Un resultado vacío no prueba que no exista software adecuado.
REST acepta limit de 1 a 50 y el valor predeterminado es 20. Repite las claves de filtro para seleccionar múltiples valores. Con una búsqueda, la ordenación predeterminada es relevance. Si hasMore es verdadero y nextCursor es nulo, reduce la búsqueda. Otras ordenaciones admiten el cursor devuelto. Las solicitudes tienen límite de velocidad por IP; en 429, espera el intervalo de Retry-After.
URL de precarga
La integración más ligera: un solo enlace. Sin autenticación, sin SDK. Agrega ?prefill=connector a la URL del asistente y pasa los campos que conozcas como parámetros de consulta. El Builder llega allí, inicia sesión (Clerk conserva la cadena de consulta) y el asistente se abre precargado. Atribuye el embudo con source=<your-platform>. Cada borrador creado de esta manera llega con created_via configurado con tu nombre.
https://zerotohundred.ai/listings/new?prefill=connector
&source=your-platform
&title=My%20Cool%20App
&shortDescription=Drop-in%20analytics%20for%20indie%20apps
&demoUrl=https%3A%2F%2Fmycoolapp.example.com
&repoUrl=https%3A%2F%2Fgithub.com%2Falice%2Fmycoolapp
&techStack=nextjs,supabase,tailwind
&type=tool
&operatingStatus=ready_to_launch
&domains=analytics,productivity
| Campo | Tipo | Notas |
|---|---|---|
| prefill | obligatorio | Debe ser "connector" para activar el flujo precargado. |
| source | string | Atribución del embudo → created_via. Limitado a 40 caracteres. |
| title | string | Título del listado. Truncado a 200 caracteres. |
| shortDescription | string | Descripción de una línea. Truncada a 160 caracteres. |
| longDescription | string | Descripción completa. |
| demoUrl | url | Aceptado solo si tiene forma http(s). |
| repoUrl | url | Repositorio de GitHub → sourceRepoUrl. Nota: el parámetro es repoUrl, no sourceRepoUrl. |
| techStack | csv | Separado por comas, máximo 10. |
| askingPrice | number | Dígitos con hasta 2 decimales. |
| type | enum | Uno de los 9 tipos de listado (ver Valores de campo). |
| operatingStatus | enum | Uno de los 3 estados operativos. |
| domains | csv | Separado por comas, máximo 5. |
Todo se vuelve a validar en el servidor. La precarga solo siembra el formulario; el Builder confirma antes de que se escriba cualquier cosa. Un botón de React listo para colocar en un menú Compartir está en el kit de socios.
Autenticación
La API REST acepta un token de portador en el encabezado Authorization. Las cookies nunca se aceptan en rutas de listado autenticadas. El descubrimiento público no necesita cuenta ni token. Hay dos tipos de token:
Authorization: Bearer z2h_pat_<prefix>_<secret> # Personal Access Token
Authorization: Bearer z2h_oat_<secret> # OAuth access token (1h TTL)
- Token de acceso personal. Un Builder crea una cuenta o inicia sesión en el sitio web, luego genera uno en /account/developers. Mejor para Builders individuales y uso con CLI/agentes.
- Token de acceso OAuth. Una aplicación de socio lo obtiene mediante el flujo OAuth 2.1 + PKCE para actuar en nombre de un Builder.
Solicita solo los alcances que usa tu integración. Las lecturas de propiedad necesitan listings:read; la creación de borradores, ediciones y cargas de fuente necesitan listings:write. Solicita ambos cuando necesites ambos flujos de trabajo. La creación de cuentas y el inicio de sesión ocurren en el sitio web. Las herramientas MCP no recopilan contraseñas ni crean cuentas.
Alcances: listings:write, listings:read y listings:publish. El alcance de publicación está reservado. Requiere el escaneo de fuente asíncrono y no se puede otorgar en v1.
Semántica de fallos: un token faltante o no resoluble devuelve un 401 { "error": "Unauthorized" } uniforme (con WWW-Authenticate: Bearer). Es la misma respuesta para faltante/inválido/expirado/revocado, por lo que un token no se puede sondear. Un token válido que carece del alcance requerido devuelve 403 { "error": "Forbidden", "reason": "missing_scope:..." }.
API REST
Ruta base https://zerotohundred.ai/api/v1. Cada respuesta lleva encabezados CORS (Access-Control-Allow-Origin: *, métodos GET, POST, PATCH, OPTIONS y Expose-Headers: Retry-After para que los clientes de origen cruzado puedan leer el retroceso del límite de velocidad). La verificación previa de OPTIONS devuelve 204. Los llamadores del conector solo crean filas draft. Las lecturas públicas nunca las ven.
POST/api/v1/listings
Crea un borrador de listado. Alcance listings:write. Límite de velocidad 10 solicitudes / 60s, clave por token.
Aviso de compatibilidad: valor predeterminado del código fuente
La creación de borradores ahora establece sourceCodeIncluded en false cuando lo omites. Anteriormente, omitirlo establecía true. Actualiza tu cliente para enviar sourceCodeIncluded: true solo después de que el Builder confirme que el listado incluye código fuente. Una URL de repositorio por sí sola no hace esa elección. Esto se aplica a nuevos borradores REST autenticados con un token de acceso personal o un token de acceso OAuth. Los listados existentes conservan su elección guardada.
curl -X POST https://zerotohundred.ai/api/v1/listings \
-H "Authorization: Bearer z2h_pat_..." \
-H "Content-Type: application/json" \
-d '{
"title": "My SaaS",
"shortDescription": "One-line pitch",
"longDescription": "What it does, in ~100 words.",
"type": "micro_saas",
"operatingStatus": "ready_to_launch",
"domains": ["analytics", "productivity"],
"askingPrice": 199,
"demoUrl": "https://example.com",
"sourceRepoUrl": "https://github.com/me/myapp",
"techStack": ["nextjs", "tailwind"],
"source": "api"
}'
Cuerpo
| Campo | Tipo | Notas |
|---|---|---|
| title | string · obligatorio | De 1 a 200 caracteres. |
| shortDescription | string · obligatorio | ≤ 160 caracteres. |
| longDescription | string · obligatorio | ≥ 20 caracteres. |
| type | enum · obligatorio | Ver Valores de campo. |
| operatingStatus | enum · obligatorio | Ver Valores de campo. |
| domains | string[] | Predeterminado []. |
| askingPrice | number | No negativo. |
| demoUrl | url | Solo http/https. |
| thumbnailUrl | url | Solo http/https. |
| imageUrls | url[] | Máximo 5, cada uno http/https. |
| techStack | string[] | Predeterminado []. |
| testEnvUrl / testEnvInstructions | string | Entorno de prueba opcional para el revisor. |
| testEnvCredentials | string | Cifrado en reposo; nunca se devuelve. |
| sourceCodeIncluded | boolean | Los borradores REST tienen como predeterminado false. Establécelo en true solo cuando el Builder confirme que el código fuente está incluido. |
| sourceRepoUrl | url | github.com/<owner>/<repo>; el propietario debe coincidir con tu identificador de GitHub conectado. |
| source | string | Aceptado por compatibilidad pero ignorado. El servidor registra las creaciones de PAT como api y las creaciones de OAuth bajo el ID de cliente registrado. |
201 Creado
{
"id": "...", "slug": "...", "status": "draft",
"createdAt": "<ISO8601>",
"editUrl": "https://zerotohundred.ai/listings/<slug>/edit",
"publishUrl": "https://zerotohundred.ai/listings/<slug>/edit?step=review"
}
Errores: 400 (JSON inválido, validación de Zod con issues[], URL incorrecta o discrepancia de propiedad de GitHub), 401 / 403, 429, 500.
Lista tus propios listados, del más reciente al más antiguo. Alcance listings:read. Sin límite de velocidad. Paginación por conjunto de claves: pasa limit (predeterminado 25, máximo 100) y el cursor opaco de la página anterior.
GET https://zerotohundred.ai/api/v1/listings?limit=25&cursor=<opaque>
200 OK
{
"items": [
{ "id","slug","title","status","type","operatingStatus",
"askingPrice","demoUrl","thumbnailUrl","createdVia",
"createdAt","updatedAt","editUrl","publishUrl" }
],
"nextCursor": "<opaque>|null"
}
nextCursor no es nulo solo cuando hay más filas más allá de esta página. Detente cuando sea null.
GET/api/v1/listings/{slug}
Lee un listado que posees. Alcance listings:read. Un slug que no posees devuelve 404 (anti-sondeo, nunca 403). Devuelve el objeto completo; testEnvCredentials nunca se incluye.
Actualiza un borrador. Alcance listings:write. Límite de velocidad 10 / 60s por token. Solo borradores. Un listado que no es borrador devuelve 409. Todos los campos del cuerpo son opcionales; las claves desconocidas se rechazan. Envía un campo como null para limpiarlo solo para askingPrice, demoUrl, videoUploadUrl, thumbnailUrl o sourceRepoUrl. Los campos heredados testEnvUrl, testEnvCredentials y testEnvInstructions también aceptan null. Los campos omitidos permanecen sin cambios. Envía un arreglo vacío para limpiar un campo de arreglo.
PATCH https://zerotohundred.ai/api/v1/listings/<slug>
{ "askingPrice": 149, "techStack": ["nextjs","trpc"] }
200 OK
{ "id","slug","status":"draft","editUrl","publishUrl" }
Cargas de archivos fuente
Adjunta la fuente a un borrador que posees con listings:write. Los endpoints REST a continuación aceptan un PAT o una concesión REST de OAuth. MCP alojado expone la misma secuencia a través de z2h_request_source_upload y z2h_confirm_source_upload.
Selecciona el archivo primero. Muestra al Builder esta declaración exacta y requiere su aceptación explícita para ese archivo antes de solicitar o confirmar una carga:
I own or have the rights to sell the codebase I am about to upload.
El ownershipVersion actual es 2026-09-27. Conectar una cuenta o crear un borrador no establece aceptación. Si el archivo cambia, pide al Builder que acepte la declaración para el archivo de reemplazo.
| Campo | Tipo | Notas |
|---|---|---|
| contentType | string | application/zip, application/x-zip-compressed, application/gzip, application/x-gzip o application/x-tar. |
| sizeBytes | entero positivo | Tamaño del archivo en bytes, como máximo 104857600 bytes, o 100 MiB. El servidor también verifica el tamaño real del archivo almacenado y la firma del archivo. |
| ownershipAccepted | true | Envía solo después de que el Builder acepte explícitamente la declaración para el archivo seleccionado. |
| ownershipVersion | string | 2026-09-27 |
Solicita una URL de carga firmada. Reemplaza el slug con el slug de tu borrador y 1048576 con el tamaño de tu archivo en bytes. Los cuerpos de solicitud JSON están limitados a 8 KiB.
curl --fail-with-body --request POST "https://zerotohundred.ai/api/v1/listings/<slug>/source-bundle" \
--header "Authorization: Bearer z2h_pat_..." \
--header "Content-Type: application/json" \
--data '{
"contentType": "application/zip",
"sizeBytes": 1048576,
"ownershipAccepted": true,
"ownershipVersion": "2026-09-27"
}'
200 OK
{
"signedUrl": "<private signed upload URL>",
"objectKey": "<returned object key>",
"contentType": "application/zip"
}
Carga los bytes del archivo
Mantén signedUrl y objectKey privados. Configura SIGNED_URL localmente con la URL exacta devuelta y haz PUT del archivo seleccionado antes de que expire la URL. Usa el contentType devuelto. El ejemplo ZIP envía solo los bytes del archivo y su tipo de contenido al almacenamiento. No envíes tu token de portador de cuenta a la URL firmada.
curl --fail-with-body --request PUT "$SIGNED_URL" \
--header "Content-Type: application/zip" \
--data-binary @./source.zip
Después de que el PUT tenga éxito, confirma usando la clave de objeto devuelta y los mismos metadatos del archivo y la versión de declaración aceptada.
curl --fail-with-body --request POST "https://zerotohundred.ai/api/v1/listings/<slug>/source-bundle/confirm" \
--header "Authorization: Bearer z2h_pat_..." \
--header "Content-Type: application/json" \
--data '{
"objectKey": "<returned object key>",
"contentType": "application/zip",
"sizeBytes": 1048576,
"ownershipAccepted": true,
"ownershipVersion": "2026-09-27"
}'
200 OK
{ "ok": true }
La confirmación verifica el archivo almacenado, lo adjunta al borrador y registra el texto aceptado. Establece sourceCodeIncluded en true y reemplaza cualquier adjunto de fuente de repositorio. Confirmar el mismo objeto adjunto nuevamente devuelve ok: true sin otro cambio.
Los errores incluyen 400 para JSON inválido, metadatos o bytes de archivo, 401 para autenticación inválida, 403 para un alcance faltante, 404 para un listado faltante o no propiedad, y 409 cuando la elegibilidad del borrador o la fuente cambia. En 429, espera antes de reintentar. Un PUT exitoso por sí solo no adjunta la fuente; la confirmación debe tener éxito.
Estas operaciones de API aceptan solo borradores. Si tu host MCP no puede leer el archivo seleccionado y hacer PUT de sus bytes, abre el editUrl del listado y carga en el asistente web. El Builder termina la revisión de la fuente y la publicación allí después de que pasen las compuertas requeridas.
OAuth 2.1 + PKCE
Para aplicaciones de socios que actúan en nombre de un Builder. Solo código de autorización + PKCE. Sin flujo implícito, sin concesión de contraseña. Registra una aplicación para obtener un client_id; elige público (solo PKCE, sin secreto, para clientes de navegador/CLI/nativos) o confidencial (un client_secret que mantienes en el servidor).
El siguiente flujo crea una concesión de API REST y omite resource. MCP alojado requiere una concesión separada vinculada a recursos, descrita a continuación. Registra tu cliente y su URI de redirección exacta antes de comenzar cualquier flujo. El servidor de autorización no anuncia registro automático de clientes.
1 · Autorizar
Envía al Builder a la pantalla de consentimiento. Esta es una ruta de página en /oauth/authorize (no bajo /api/v1). PKCE es obligatorio. Una solicitud sin code_challenge se rechaza.
GET https://zerotohundred.ai/oauth/authorize
?client_id=<your-client-id>
&redirect_uri=<exact-registered-uri>
&response_type=code
&scope=listings:write%20listings:read
&state=<csrf-token>
&code_challenge=<base64url(sha256(verifier))>
&code_challenge_method=S256
→ redirects to: <redirect_uri>?code=<code>&state=<state>
(or ?error=access_denied&state=<state> on deny)
redirect_uri debe coincidir exactamente con una URI registrada (sin comodines). El código de autorización es de un solo uso y expira en 10 minutos.
2 · Intercambia el código por tokens
POST /api/v1/oauth/token (acepta formulario o JSON; límite de velocidad 10 / 60s por cliente).
POST https://zerotohundred.ai/api/v1/oauth/token
grant_type=authorization_code
&client_id=<your-client-id>
&code=<code>
&redirect_uri=<same-as-authorize>
&code_verifier=<pkce-verifier>
# confidential clients ALSO send &client_secret=...
# public clients MUST omit client_secret
200 OK
{ "access_token": "z2h_oat_...", "refresh_token": "...",
"token_type": "Bearer", "expires_in": 3600,
"scope": "listings:read listings:write" }
Un cliente público que envía un client_secret es rechazado (sin degradación silenciosa); un cliente confidencial que lo omite es rechazado. Los errores usan el formato RFC 6749: invalid_request, invalid_client (401), invalid_grant, unsupported_grant_type.
3 · Renovación y revocación
Renueva con grant_type=refresh_token. Los tokens de renovación rotan: el anterior se revoca y se emite un nuevo par. Reutilizar un token de renovación revocado revoca todas las concesiones activas para ese Builder + aplicación (detección de compromiso de cadena). Revoca cualquier token (de acceso o de renovación) mediante POST /api/v1/oauth/revoke con token=.... Devuelve 200 { "ok": true } incondicionalmente (RFC 7009).
Autorización MCP alojada
El endpoint alojado es https://zerotohundred.ai/api/mcp. Los clientes pueden descubrir su recurso protegido y servidor de autorización en estas URLs públicas:
GET https://zerotohundred.ai/.well-known/oauth-protected-resource/api/mcp
GET https://zerotohundred.ai/.well-known/oauth-authorization-server
Para una concesión OAuth de MCP, envía el resource=https://zerotohundred.ai/api/mcp canónico en la autorización, el intercambio de código y cada renovación. Mantén exactamente el mismo valor en cada paso. Por ejemplo, un cliente público registrado usa:
GET https://zerotohundred.ai/oauth/authorize
?client_id=<your-client-id>
&redirect_uri=<exact-registered-uri>
&response_type=code
&scope=listings:read%20listings:write
&state=<csrf-token>
&code_challenge=<base64url(sha256(verifier))>
&code_challenge_method=S256
&resource=https%3A%2F%2Fzerotohundred.ai%2Fapi%2Fmcp
POST https://zerotohundred.ai/api/v1/oauth/token
grant_type=authorization_code
&client_id=<your-client-id>
&code=<code>
&redirect_uri=<same-as-authorize>
&code_verifier=<pkce-verifier>
&resource=https%3A%2F%2Fzerotohundred.ai%2Fapi%2Fmcp
POST https://zerotohundred.ai/api/v1/oauth/token
grant_type=refresh_token
&client_id=<your-client-id>
&refresh_token=<current-refresh-token>
&resource=https%3A%2F%2Fzerotohundred.ai%2Fapi%2Fmcp
Envía las solicitudes de token como datos de formulario o JSON. Un cliente confidencial también envía su client_secret en el intercambio de código y la renovación. Usa el token de acceso resultante para autenticar llamadas a /api/mcp. Los tokens OAuth vinculados a MCP no pueden autenticar llamadas directas de listado REST, y las concesiones OAuth REST no pueden autenticar herramientas de Builder MCP alojadas. Los PAT con ámbito admiten ambas interfaces.
Servidor MCP
Agrega https://zerotohundred.ai/api/mcp como una conexión HTTP Streamable alojada en un host que lo admita. La búsqueda, la comparación y el panel de marketplace no necesitan token. Las herramientas de Builder necesitan un PAT con ámbito o la conexión OAuth MCP descrita anteriormente. Una conexión de host privada o personalizada es independiente de un listado de directorio público o de la aprobación del proveedor.
El paquete MCP, @zerotohundred/mcp-server, conecta herramientas de codificación locales a Zero to Hundred. Sus herramientas de Builder leen un Personal Access Token de Z2H_API_KEY. Sin ese token, esas herramientas devuelven un enlace de configuración en lugar de llamar a la API. El servidor registra los listados creados por PAT como api; las etiquetas de origen proporcionadas por el cliente no establecen atribución de integración.
El servidor local ofrece búsqueda pública de marketplace y herramientas de Builder para borradores propios. Puede solicitar una carga de archivo fuente firmado y confirmar el archivo después de que tu cliente MCP lo cargue. El endpoint alojado /api/mcp ofrece las mismas herramientas de listado con una concesión OAuth o un Personal Access Token con ámbito. Ninguna herramienta MCP publica un listado; el Builder lo revisa y publica en el asistente web.
Claude Code, búsqueda pública
claude mcp add z2h -- npx -y @zerotohundred/mcp-server
Claude Code, acceso de Builder
Para usar las herramientas de Builder, configura el PAT en el entorno del servidor y reinícialo. Para una configuración local nueva:
claude mcp add z2h \
--env Z2H_API_KEY=YOUR_TOKEN \
-- npx -y @zerotohundred/mcp-server
Configuración local de stdio
Usa el formato y la ubicación de configuración MCP de tu host. Este servidor se ejecuta con command, args y un env opcional que contiene el PAT. Omite env solo para búsqueda pública.
{
"mcpServers": {
"z2h": {
"command": "npx",
"args": ["-y", "@zerotohundred/mcp-server"],
"env": { "Z2H_API_KEY": "YOUR_TOKEN" }
}
}
}
Herramientas
El paquete local expone 7 herramientas. El MCP alojado expone las 9 herramientas siguientes. El panel alojado depende del soporte de MCP Apps en el host; los clientes sin él pueden usar la búsqueda de texto y los resultados de comparación.
| Herramienta | Función | Llamadas | Disponible a través de |
|---|---|---|---|
| z2h_search_marketplace | Busca listados públicos en vivo sin token | GET /api/v1/discover | Local y alojado |
| z2h_compare_marketplace_listings | Renueva y compara de 2 a 4 slugs públicos sin token | Descubrimiento público | Alojado |
| z2h_show_marketplace | Muestra tarjetas públicas de hasta 20 slugs sin token | Recurso público de MCP App | Alojado |
| z2h_create_draft_listing | Crea un borrador | POST /api/v1/listings | Local y alojado |
| z2h_list_my_listings | Lista tus listados | GET /api/v1/listings | Local y alojado |
| z2h_get_listing | Lee uno que poseas por slug | GET /api/v1/listings/{slug} | Local y alojado |
| z2h_update_draft_listing | Actualiza un borrador | PATCH /api/v1/listings/{slug} | Local y alojado |
| z2h_request_source_upload | Obtiene una URL de carga firmada para un borrador propio | POST /api/v1/listings/{slug}/source-bundle | Local y alojado |
| z2h_confirm_source_upload | Verifica y adjunta el archivo cargado | POST /api/v1/listings/{slug}/source-bundle/confirm | Local y alojado |
No existe una herramienta publish. La publicación ejecuta un escaneo de fuente asíncrono y permanece en el asistente, donde el Builder revisa el borrador primero.
Valores de campo
type (10 valores)
full_product · micro_saas · tool · template · ai_agent
component · bot · extension · automation · design_system
operatingStatus (3 valores)
ready_to_launch · live · live_with_revenue
domains (34 valores, kebab-case)
ai · analytics · art-design · conference · developer-tools
e-commerce-marketplace · education · entertainment · environmental
fashion · finance · food · gaming · graphic-design · health
interior-design · marketing · membership · non-profit · political
productivity · real-estate · religious · services · social
technology · travel · wedding · other
mode es siempre license (paga una vez, posee para siempre), y los listados creados por conectores siempre comienzan como draft.
Construye una integración
Genera un Personal Access Token para llamar a la API REST o conectar el servidor MCP, o coloca un botón de URL de relleno previo en tu menú Compartir. No se necesitan claves.