> ## Documentation Index
> Fetch the complete documentation index at: https://docs.so-me.studio/llms.txt
> Use this file to discover all available pages before exploring further.

# Scripting y automatización

> Usa la CLI de Social media studio en scripts, pipelines de CI/CD y flujos de automatización

La CLI está pensada para la automatización: imprime JSON estructurado por defecto, acepta credenciales de
variables de entorno y usa códigos de salida estándar. Cada comando se corresponde 1:1 con un endpoint REST de Social media studio,
así que todo lo que puede hacer la aplicación se puede automatizar con scripts.

> [!NOTE]
>
> El binario es `so-me` (la compilación de desarrollo es `so-me-dev`). Todos los ejemplos siguientes usan `so-me`.
> Los subcomandos usan la sintaxis con dos puntos: `posts:list`, `media:upload`, `agent export-tools`.

## Modos de salida

El formato de salida se controla con opciones globales que se aplican a **todos** los comandos. Deben
colocarse en la línea de comandos junto al resto de tus argumentos (Commander las trata como opciones
globales).

| Opción | Descripción |
| - | - |
| `--json` | Muestra la salida como JSON con formato legible. **Es el valor por defecto**; rara vez necesitas indicarlo de forma explícita. |
| `--table` | Muestra los resultados como una tabla ASCII legible en lugar de JSON. |
| `--verbose` | En caso de fallo, imprime todos los detalles del error (incluida la traza de pila de JS cuando está disponible). |

```bash theme={null}
# JSON is the default
so-me posts:list

# Explicit JSON (same as above)
so-me posts:list --json

# Human-readable table
so-me posts:list --table

# Verbose error output (useful while debugging)
so-me posts:create -c "test" --platform INVALID --verbose
```

> [!WARNING]
>
> Usa `--table` para personas, no para scripts. La vista de tabla trunca los campos largos y selecciona un subconjunto
> de columnas, por lo que **no** se puede analizar automáticamente. En la automatización, encadena siempre el JSON
> por defecto con `jq`.

El formato por defecto también puede guardarse en la configuración de la CLI (`outputFormat`), pero `--table` en la
línea de comandos siempre prevalece en esa ejecución.

## Salida JSON y jq

Encadena cualquier comando con [`jq`](https://jqlang.github.io/jq/) para extraer y transformar datos.

> [!WARNING]
>
> **Los endpoints de listado devuelven un envoltorio paginado**, no un arreglo simple. La estructura es
> `{ "data": [ ... ], "meta": { ... } }`, así que debes indexar `.data[]`. Los comandos de un solo objeto
> (`posts:get`, `posts:create`, `posts:update`, …) devuelven el objeto directamente, por lo que
> campos como `.id` están en el nivel superior.

```bash theme={null}
# Get the text of every scheduled post (note the .data[] — list responses are paginated)
so-me posts:list --status SCHEDULED | jq '.data[].text'

# Grab the first post's ID
so-me posts:list | jq -r '.data[0].id'

# posts:create returns a single object, so .id is top-level
POST_ID=$(so-me posts:create -c "Hello!" --platform TWITTER | jq -r '.id')
echo "Created post: $POST_ID"

# Count posts by platform
so-me posts:list | jq '.data | group_by(.socialMedia)
  | map({platform: .[0].socialMedia, count: length})'

# Read pagination metadata
so-me posts:list --limit 100 | jq '.meta'
```

## Paginación

Los comandos de listado aceptan dos opciones de paginación. **No** hay opción `--cursor` ni `--all` en los comandos
de listado: pagina incrementando `--page`.

| Opción | Por defecto | Notas |
| - | - | - |
| `--page <number>` | `1` | Número de página, empezando en 1. |
| `--limit <number>` | varía según el comando | Elementos por página. `posts:list` tiene un máximo de `100`; los valores por defecto difieren según el comando (p. ej. `posts:list`/`drafts:list` usan `20`, `accounts:list`/`inbox:list`/`teams:list` usan `50`). |

```bash theme={null}
# Second page of 50 posts
so-me posts:list --page 2 --limit 50

# Walk every page until an empty data array comes back
page=1
while :; do
  rows=$(so-me posts:list --page "$page" --limit 100 | jq -c '.data')
  [ "$rows" = "[]" ] && break
  echo "$rows" | jq -r '.[].id'
  page=$((page + 1))
done
```

> [!NOTE]
>
> La opción `--all` existe **solo** en `agent export-tools`, donde significa "emitir todos los formatos de
> herramientas"; no tiene relación con la paginación.

## Scripts de shell

### Crear y programar

```bash theme={null}
#!/bin/bash
set -euo pipefail

# Create a post (publishes immediately when no -s/--date is given), then schedule it
POST_ID=$(so-me posts:create \
  -c "Automated post from CI" \
  --platform LINKEDIN \
  | jq -r '.id')

so-me posts:schedule "$POST_ID" \
  -s "$(date -u -d '+1 hour' +%Y-%m-%dT%H:%M:%SZ)"

echo "Post $POST_ID scheduled"
```

> [!NOTE]
>
> `posts:create` resuelve automáticamente la cuenta social a partir de `--platform` cuando no pasas
> `-a/--accounts`. Si coinciden varias cuentas, el comando pregunta de forma interactiva; por lo tanto, en
> un CI no interactivo, pasa un ID de cuenta explícito con `-a` o asegúrate de tener una sola cuenta
> conectada para esa plataforma.

### Eliminar en masa las publicaciones fallidas

```bash theme={null}
#!/bin/bash
set -euo pipefail

# Collect failed post IDs (remember: .data[] for list responses)
FAILED_IDS=$(so-me posts:list --status FAILED --limit 100 | jq -r '.data[].id')

if [ -z "$FAILED_IDS" ]; then
  echo "No failed posts found"
  exit 0
fi

# posts:delete accepts one or many IDs and -y skips the confirmation prompt
echo "$FAILED_IDS" | xargs so-me posts:delete -y
```

### Convertir todos los borradores

```bash theme={null}
#!/bin/bash
set -euo pipefail

# Convert every draft into a scheduled Twitter post
DRAFT_IDS=$(so-me drafts:list --limit 100 | jq -r '.data[].id')

for id in $DRAFT_IDS; do
  so-me drafts:convert "$id" \
    --platform TWITTER \
    --post-type TEXT \
    -s "$(date -u -d '+2 hours' +%Y-%m-%dT%H:%M:%SZ)"
  echo "Converted draft $id"
done
```

## Autenticación en CI

La CLI busca las credenciales en este orden: la opción `--api-key`, después la variable de entorno
`SOME_API_KEY` y, por último, la clave de API guardada por `auth:login`. Para la automatización, prefiere la
variable de entorno para que no se escriba nada en disco.

| Variable | Opción equivalente | Descripción |
| - | - | - |
| `SOME_API_KEY` | `--api-key <key>` | Clave de API usada para autenticar cada solicitud. |
| `SOME_API_URL` | `--api-url <url>` | URL base de la API. Por defecto `https://api.so-me.studio` (`so-me-dev` usa `http://localhost:8000`). |

```bash theme={null}
# Authenticate purely from the environment — no auth:login needed
export SOME_API_KEY="sk_live_xxx"
so-me auth:whoami        # verify the key and show the authenticated user + org
so-me posts:list

# Or pass per-command (overrides stored credentials and the env var)
so-me posts:list --api-key sk_live_xxx --api-url https://api.so-me.studio
```

### GitHub Actions

```yaml theme={null}
name: Schedule Weekly Post
on:
  schedule:
    - cron: '0 9 * * 1'  # Every Monday at 9 AM UTC

jobs:
  post:
    runs-on: ubuntu-latest
    steps:
      - name: Install CLI
        run: npm install -g @social-media-scheduler/cli

      - name: Create and schedule post
        env:
          SOME_API_KEY: ${{ secrets.SOME_API_KEY }}
        run: |
          so-me posts:create \
            -c "Weekly update: check out what's new!" \
            --platform TWITTER \
            -s "$(date -u -d '+1 hour' +%Y-%m-%dT%H:%M:%SZ)"
```

> [!TIP]
>
> Guarda tu clave de API como secreto del repositorio (`SOME_API_KEY`). La CLI la lee automáticamente del entorno;
> nunca incluyas la clave en un archivo de workflow ni la subas al repositorio.

## Gestión de errores

### Códigos de salida

En caso de fallo, la CLI establece un código de salida distinto de cero (`process.exitCode = 1`), de modo que `&&`, `set -e` y
las guardas `if` se comporten como se espera.

| Código | Significado |
| - | - |
| `0` | Éxito |
| `1` | Error: error de la API, fallo de validación, error de red, credenciales ausentes, etc. |

### Errores detallados

Usa `--verbose` para ver todos los detalles del error, incluida la traza de pila cuando está disponible:

```bash theme={null}
so-me posts:create -c "test" --platform INVALID --verbose
```

Condiciones de error habituales que expone el cliente de la API:

| Estado HTTP | Mensaje de la CLI |
| - | - |
| `401` | `Invalid API key. Run 'so-me auth:login' or set SOME_API_KEY.` (los mensajes específicos del servidor se conservan cuando son más informativos) |
| `403` | `Insufficient permissions. Your plan may not include this feature.` |
| `429` | `Rate limit exceeded. Try again later.` |
| red | `Could not connect to API at <url>. Check your internet connection.` |

### Gestión de límites de solicitudes

Una solicitud limitada por tasa (HTTP 429) termina con el código 1. En los scripts, añade lógica de reintento con espera creciente:

```bash theme={null}
#!/bin/bash
MAX_RETRIES=3
RETRY_DELAY=10

for i in $(seq 1 $MAX_RETRIES); do
  so-me posts:list && break
  echo "Request failed, retrying in ${RETRY_DELAY}s... (attempt $i/$MAX_RETRIES)"
  sleep $RETRY_DELAY
done
```

## Definiciones de herramientas para agentes

La CLI puede exportar el catálogo de herramientas de Social media studio en formatos que pueden consumir los frameworks de agentes de IA.
`agent export-tools` obtiene **en directo** la lista canónica de herramientas del servidor MCP (una llamada JSON-RPC `tools/list`
a `POST /mcp`) y la emite en el formato que elijas. El servidor MCP es la única
fuente de verdad, por lo que las definiciones exportadas siempre coinciden con el catálogo en vivo.

```bash theme={null}
so-me agent export-tools --format <format> [options]
```

**-f, --format \<format>** `string`

Uno de `mcp`, `openai`, `anthropic`, `hermes`, `openclaw`. Obligatorio salvo que se pase `--all`.

**-o, --out \<path>** `string`

Escribe la salida en un archivo (y escribe los archivos complementarios junto a él). Si la ruta parece un
directorio (sin extensión de archivo, o con una barra final), se añade el nombre de archivo por defecto del formato.
Si se omite, la salida principal se escribe en stdout.

**--all** `boolean` (default: false)

Emite **todos** los formatos admitidos. Trata `--out` como un directorio (por defecto `./agent-tools`) y
escribe cada formato en su propio subdirectorio.

### Formatos admitidos

| Formato | Salida principal | Nombre de archivo por defecto | Archivos complementarios |
| - | - | - | - |
| `mcp` | Catálogo MCP sin procesar (`{ "tools": [...] }`) | `tools.mcp.json` | — |
| `openai` | Herramientas de llamada a funciones de OpenAI Chat Completions (`{ "tools": [{ "type": "function", "function": { ... } }] }`) | `tools.openai.json` | — |
| `anthropic` | Herramientas de la API Messages de Anthropic (estructura plana con `input_schema`) | `tools.anthropic.json` | — |
| `hermes` | JSON de herramientas compatible con OpenAI (Nous Hermes 4) | `tools.json` | `system_prompt.md`, `tools.md` |
| `openclaw` | Referencia de skill en Markdown (tablas de herramientas agrupadas + apéndice completo de JSON Schema) | `tools.md` | — |

### Ejemplos

```bash MCP (stdout) theme={null}
# Print the raw MCP tool catalog to stdout
so-me agent export-tools --format mcp
```

```bash OpenAI theme={null}
# Write OpenAI-style function definitions to a file
so-me agent export-tools --format openai --out tools.openai.json
```

```bash Anthropic theme={null}
# Write the Anthropic tool-use format
so-me agent export-tools --format anthropic --out tools.anthropic.json
```

```bash Hermes theme={null}
# Hermes kit — writes tools.json plus companion system_prompt.md and tools.md
so-me agent export-tools --format hermes --out ./hermes/
```

```bash OpenClaw theme={null}
# OpenClaw skill reference (markdown). Writes tools.md when --out is a directory
so-me agent export-tools --format openclaw --out tools.md
```

```bash Todos los formatos theme={null}
# Emit every format. Each lands in its own subdirectory under ./agent-tools,
# e.g. ./agent-tools/mcp/tools.mcp.json, ./agent-tools/hermes/tools.json, etc.
so-me agent export-tools --all --out ./agent-tools
```

> [!NOTE]
>
> Todos los formatos se derivan de la misma respuesta de `tools/list`, por lo que las definiciones exportadas se mantienen sincronizadas
> con el catálogo de herramientas en vivo. Los nombres de las herramientas están en snake\_case (p. ej. `create_post`) y reflejan los
> comandos `resource:verb` de la CLI. En el transporte MCP, las mismas herramientas se registran como
> `mcp_so-me-studio_<tool_name>` (p. ej. `mcp_so-me-studio_create_post`).

## Instancias autoalojadas

Apunta la CLI a una URL de API personalizada mediante la opción o la variable de entorno:

```bash theme={null}
# Via flag (per command)
so-me posts:list --api-url https://api.yourdomain.com

# Via environment variable (whole session)
export SOME_API_URL=https://api.yourdomain.com
so-me posts:list
```


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.