mcli - monday.com GraphQL CLI
A command-line interface for monday.com's GraphQL API with JSON output, LLM-native design, and semantic business-layer operations
MCLI is a command-line interface to monday.com's GraphQL API. It's a single static binary with no dependencies, designed for both human operators and LLM agents.
Key capabilities
- JSON by default - all output is structured JSON (use
--prettyfor human-readable formatting) - Single binary - no runtime dependencies; build once, deploy anywhere
- LLM-native - no interactive prompts on the read path; self-describing via
mcli skill - Semantic layer - save domain-named queries/mutations to create a business-level API over boards
- Escape hatch - raw
mcli query/mcli mutationaccess for anything not covered by CLI commands - Webhooks & daemon - background process to receive and poll webhook events
- Authentication - token stored securely in OS keychain (macOS Keychain, Linux Secret Service)
Installation
# From source (requires Go 1.26+)
go install github.com/arnon/mcli/cmd/mcli@latest
# Or build locally
git clone [email protected]:DaPulse/mcli.git
cd mcli
make build # → bin/mcliQuick start
# Authenticate (one-time, stores in OS keychain)
mcli auth login --token <your-monday-api-token>
# Verify
mcli me
# List your boards
mcli board list
# Get board structure
mcli board get 9832181507
# List items with decoded column values
mcli item list --board 9832181507
# Create an item with column values
mcli item create --board 9832181507 --name "Ship feature" \
--col 'status={"label":"Working on it"}' \
--col 'due_date={"date":"2026-06-01"}'
# Run a raw GraphQL query
mcli query 'query { me { id name } }'Command reference
Authentication:
mcli auth login/logout/status
User:
mcli me- current user info
Workspaces & organization:
mcli workspace list/get/create/update/deletemcli folder list/create/rename/delete
Boards:
mcli board list/get/create/rename/archive/deletemcli board group list/create/rename/archive/deletemcli board column list/create/rename/describe/delete
Items:
mcli item list/get/create/update/move/archive/delete
GraphQL (escape hatch):
mcli query '<graphql>'- run raw queries (inline, from file, or stdin)mcli mutation '<graphql>'- run raw mutationsmcli query save/list/run/delete- manage saved queriesmcli mutation save/list/run/delete- manage saved mutations
Webhooks & events:
mcli daemon start/stop/status- background webhook receivermcli webhook create/list/delete/events- webhook registrationmcli notification list/count/ack- poll for webhook events
Utility:
mcli skill- print LLM skill documentmcli version- print version
Run mcli <command> --help for flags and detailed usage on any command.
Semantic layer for LLM agents
Save reusable queries and mutations as domain-named operations. LLMs then operate in business terms instead of board IDs and column IDs.
Pattern
- Set up boards and columns (one-time)
- Save domain-named queries/mutations that encode the board structure
- Agents call
mcli query run <name>/mcli mutation run <name>with business-level variables
Example
Save a query that lists products from a specific board:
mcli query save list_products --query 'query($boardId: ID!) {
boards(ids: [$boardId]) {
items_page(limit: 100) {
items { id name column_values { id text } }
}
}
}'Run it with variables:
mcli query run list_products --var boardId=9832181507Agents never need to know board IDs or column IDs — they call domain operations:
mcli query run list_products --var boardId=products_board
mcli mutation run create_order --var board=orders_board --var name="ORD-99" \
--var cols='{"customer":"Acme Corp","status":{"label":"Draft"}}'
mcli mutation run update_order_status --var board=orders_board --var item=789 \
--var cols='{"status":{"label":"Ordered"}}'E-Commerce demo: products, inventory & orders
This demo shows how an LLM agent (or human) can use mcli's generic commands to:
- Create boards with typed columns
- Define a semantic layer of saved queries/mutations with business-domain names
- Seed data using the structured item commands
- Place an order using only the semantic layer (no board IDs in the "business logic")
Prerequisites
mcli auth login(orMONDAY_API_TOKENset)jqin PATH- Run the full demo:
./examples/ecommerce-demo.sh
Phase 1: Create boards
mcli board create --name "Products" --kind public --empty # → {"id":"..."}
mcli board create --name "Inventory" --kind public --empty
mcli board create --name "Orders" --kind public --emptyEach board starts empty (no default columns/items).
Phase 2: Define columns
Products — item name is the product name; add SKU, Description, Price:
mcli board column create --board $PRODUCTS_BOARD --title "SKU" --type text
mcli board column create --board $PRODUCTS_BOARD --title "Description" --type long_text
mcli board column create --board $PRODUCTS_BOARD --title "Price" --type numbersInventory — item name is the SKU for quick lookup:
mcli board column create --board $INVENTORY_BOARD --title "SKU" --type text
mcli board column create --board $INVENTORY_BOARD --title "Quantity" --type numbersOrders — item name is the order ID; subitems are order lines:
mcli board column create --board $ORDERS_BOARD --title "Customer" --type text
mcli board column create --board $ORDERS_BOARD --title "Status" --type status \
--defaults '{"labels":{"0":"Draft","1":"Ordered","2":"Shipped","3":"Delivered"}}'Phase 3: Semantic layer
Saved queries and mutations give business-level names to operations. An LLM can call mcli mutation run create_order --var ... without knowing GraphQL:
Queries
| Name | Purpose |
|---|---|
list_products | All products with column values |
get_inventory | Full inventory snapshot |
list_orders | Orders with their line-item subitems |
get_order | Single order detail by item ID |
mcli query save list_products --query \
'query($boardId: ID!) { boards(ids: [$boardId]) { items_page(limit:100) { items { id name column_values { id text value } } } } }'Mutations
| Name | Purpose |
|---|---|
create_product | Add a product to the catalog |
update_inventory | Adjust stock quantity |
create_order | Create a new order (starts as Draft) |
add_order_line | Add a line-item subitem to an order |
update_order_status | Transition order status |
mcli mutation save create_order --query \
'mutation($board: ID!, $name: String!, $cols: JSON!) { create_item(board_id: $board, item_name: $name, column_values: $cols) { id } }'Phase 4: Seed data
Using the structured item create command (more ergonomic for setup):
mcli item create --board $PRODUCTS_BOARD --name "Widget Pro" \
--col "$PROD_SKU"='"WGT-001"' \
--col "$PROD_PRICE"='"29.99"'Or using the semantic layer:
mcli mutation run create_product \
--var board=$PRODUCTS_BOARD \
--var name="Widget Pro" \
--var cols='{"sku":"WGT-001","price":"29.99"}'Phase 5: Place an order
This is where the semantic layer shines - the agent writes natural JSON in --var and mcli handles the encoding automatically. monday.com's JSON scalar expects a stringified JSON value on the wire, but mcli detects variables declared as JSON in the query and re-encodes them transparently. No double-escaping needed.
# 1. Create order in Draft status
mcli mutation run create_order \
--var board=$ORDERS_BOARD \
--var name="ORD-1001" \
--var cols='{"customer":"Acme Corp","status":{"label":"Draft"}}'
# 2. Add line items
mcli mutation run add_order_line \
--var parent=$ORDER_ID \
--var name="Widget Pro x2" \
--var cols='{}'
mcli mutation run add_order_line \
--var parent=$ORDER_ID \
--var name="Doohickey x5" \
--var cols='{}'
# 3. Confirm the order
mcli mutation run update_order_status \
--var board=$ORDERS_BOARD \
--var item=$ORDER_ID \
--var cols='{"status":{"label":"Ordered"}}'Phase 6: Verify
mcli query run list_products --var boardId=$PRODUCTS_BOARD --pretty
mcli query run get_order --var itemId="[$ORDER_ID]" --prettyKey takeaways
- Generic commands (
board create,item create) handle setup - Saved queries/mutations create a domain-specific API layer
- JSON coercion - variables declared as JSON in the query are auto-stringified, so
--var cols='{"key":"val"}'just works without double-encoding - LLM agents can operate entirely through
mcli mutation run <name>/mcli query run <name>without understanding monday.com internals or wire-format quirks - The semantic layer is project-local (
.mcli/directory) and version-controllable
Column values
Reading
Column values are automatically decoded to human-readable form (status labels become strings, dates become ISO format, etc.).
Writing
Pass monday's raw column-value JSON via --col <id>=<json>:
mcli item create --board 123 --name "Task" \
--col 'status={"label":"Done"}' \
--col 'date={"date":"2026-05-10"}' \
--col 'priority={"label":"High"}'Use mcli board column list --board <id> to discover column IDs, types, and settings.
Webhooks and daemon
mcli includes a background daemon that receives monday.com webhooks and stores them as an inbox for agents to poll.
Start the daemon
# Foreground — opens a Cloudflare Quick Tunnel for a public URL
mcli daemon start
# Or supply your own public URL
mcli daemon start --url https://your-server.example.comThe daemon:
- Listens for webhook payloads on HTTP port (default 6780)
- Exposes a Unix socket IPC for CLI commands
- Opens a Cloudflare Quick Tunnel automatically (requires
cloudflaredin PATH) - Re-registers webhooks when the tunnel URL changes
Register webhooks
# Register for item creation events on a board
mcli webhook create --board 9832181507 --event create_item
# List registered webhooks
mcli webhook list
# List supported event types
mcli webhook events
# Remove a webhook
mcli webhook delete <webhook-id>Poll notifications
# Check if there are unread events
mcli notification count
# List unread events
mcli notification list --unread
# Filter by board or event type
mcli notification list --board 9832181507 --event change_column_value
# Acknowledge (mark read)
mcli notification ack <event-id>
mcli notification ack --allAll notification/webhook commands require the daemon to be running.
LLM integration
mcli is purpose-built for LLM agents.
# Load the skill document into your LLM context
mcli skillThis outputs a concise, goal-oriented guide. The LLM discovers exact flags via mcli <command> --help as needed.
Authentication
Token resolution (first match wins):
--token <t>flagMONDAY_API_TOKENenvironment variable- Stored credential in OS keychain (
mcli auth login)
Credentials are stored securely in the OS keychain (macOS Keychain, Linux Secret Service) or an age-encrypted file. Never stored plaintext.
License
MIT
Updated 4 days ago
