Skip to content
Cowliss is in beta: features and pricing may change.

For agents: CLI and MCP

Agents are first-class operators of a Cowliss org. Everything the dashboard can do, an agent can do: through the cow CLI, through the MCP server, or directly against the typed REST API. All three are the same surface: the CLI and MCP server are thin clients of the API, so parity is structural rather than maintained.

Terminal window
cow login # browser flow; tick the organizations, cached per API at ~/.cow/credentials.json
cow apps list # every command prints the response envelope as JSON

Non-interactive and agent-friendly by design:

  • --json forces compact single-line output; piping (non-TTY) does the same automatically.
  • Commands that take JSON arguments accept - to read the document from stdin.
  • --api <url> overrides the API base URL; cow login --no-open prints the login URL instead of opening a browser, for headless environments.
  • --org <id> (or COW_ORG_ID) names the organization to act in when the login covers several and the directory has no cow.json; a repository’s cow.json names it by itself.
  • Errors exit non-zero with the API’s error envelope on stderr.

The full surface (auth, apps and their sources, event names per app, segments, webhooks, sending domains, suppressions, billing, automations with their stats and dry run, templates with preview and test send, pushes, versions, executions, deliveries, and users, plus the repo commands init, add blueprint, test, plan, push, status, enable, disable, and pull) is in the CLI reference, generated from the command definitions themselves.

The repo commands are what an agent uses to write an automation: cow init, then edit automations/ and emails/, then cow test to run the scenarios on a virtual clock, cow plan to read the diff a push would apply, cow push, and cow enable <key> to run it for real. All of it is files and exit codes, no browser involved. See Your repo.

An agent with no repo writes the same thing through automations.create and automations.update (CLI or MCP), and a template, Liquid HTML or a doc, through templates.create and templates.update. Each is a write like a push, and a later push that would change it names it as a conflict first; cow pull brings it into a repo as a file.

An automation is a JSON definition: a trigger and a closed list of seven step types, with JSONLogic rules in a branch’s if and in the values a send passes. Give the agent its JSON Schema, /schemas/automation.json, generated from the schema the CLI and the API validate with, so whatever passes it is a definition Cowliss accepts. Automations explains each step and has four complete examples to copy from; Automation API reference lists every field.

The same admin API exposed as native tools. Tool names are the API’s operation ids with underscores (apps_list, apps_sources_add, segments_create, automations_dryRun, …) and are stable per major. Role gates apply identically: an agent with a member’s access gets exactly what a member clicking the dashboard gets.

https://api.cowliss.com/mcp

Add that URL to any MCP client. Connecting signs you in and asks which organization to use; to work in another organization, connect again and choose it. The URL is also on Settings > Credentials in the dashboard.

  • Claude Code: Run in your terminal, then /mcp in Claude Code to sign in.

    Terminal window
    claude mcp add --transport http cow https://api.cowliss.com/mcp
  • Cursor: Add to .cursor/mcp.json in the project, or ~/.cursor/mcp.json for every project.

    {
    "mcpServers": {
    "cow": {
    "url": "https://api.cowliss.com/mcp"
    }
    }
    }
  • Codex: Run in your terminal. The second line signs you in.

    Terminal window
    codex mcp add cow --url https://api.cowliss.com/mcp
    codex mcp login cow
  • OpenCode: Add to opencode.json in the project, then run opencode mcp auth cow to sign in.

    {
    "$schema": "https://opencode.ai/config.json",
    "mcp": {
    "cow": {
    "type": "remote",
    "url": "https://api.cowliss.com/mcp"
    }
    }
    }
  • Local (cow mcp): Add to any client’s MCP config to run the server on your machine with every tool, signed in through cow login.

    {
    "mcpServers": {
    "cow": {
    "command": "npx",
    "args": [
    "-y",
    "@cowliss/cli",
    "mcp"
    ]
    }
    }
    }
  • Claude.ai: Settings > Connectors > Add custom connector, paste the URL.
  • Other clients: wherever the client takes a remote MCP server URL. No command, no token to paste.

Settings > Credentials in the dashboard shows the same snippets with your API’s URL filled in.

The URL carries the 27 everyday tools: health and counts (overview, apps_list, apps_get, apps_health, app_health, status, the *_stats and events_statsByName tools, billing_summary), broadcasts (list, read, create and update from markdown, preview, audience, test send) and lookups (search, users_find, users_get, users_timeline, events_get, automations_list, lists_list). Tool names match cow mcp, so a prompt written for one works on the other.

cow mcp runs the same server over stdio, with the whole tool table plus one tool that reads the project on disk: events_prompt answers the project’s event prompt, and stores nothing. To read the diff a push would apply before making it, an agent runs cow plan (or cow plan --json) in the repo. The client config is the “Local” entry above.

cow mcp talks to https://api.cowliss.com unless COW_API_URL says otherwise. It is the same binary as the CLI: it reads the CLI’s cached login for the API it talks to (~/.cow/credentials.json keeps one per API URL, with a token per organization), re-reading on every call so a fresh cow login is picked up without restarting the editor session. When that login covers several organizations, run it from the repository whose cow.json names one, or set COW_ORG_ID. Set COW_TOKEN or COW_PIPELINE_KEY to pass a credential explicitly instead.

These docs are published machine-readable alongside the human pages:

  • /llms.txt: the site map, every page with a one-line summary and a link to its markdown.
  • Per-page markdown: append index.md to any page URL, e.g. /automations/index.md. A request for the page itself with Accept: text/markdown gets the same markdown back, and every page links to it with <link rel="alternate" type="text/markdown">.
  • /llms-full.txt: the entire docs site as one markdown document, for stuffing a context window.
  • /openapi.json: the OpenAPI 3.1 document for the whole API, generated from the same zod schemas the server validates with. Prefer it over scraping HTML when calling the API directly.
  • /schemas/automation.json: the JSON Schema of an automation definition, and /schemas/cow.json, the project file’s.

Two surfaces matter most when an agent iterates on automations: cow test runs a scenario file in seconds (the scenario JSON schema is deliberately small, being a user, the trigger’s properties, later events at offsets, and expected side effects, so it is meant to be written by hand or by an agent), and cow automations dryRun validates against real state with sends disabled. Both are covered in Testing automations.