Skill: jonah-saltzman/monday-direct (version 1.0.7)

--- name: monday description: Interact directly with the monday.com GraphQL API — no third-party gateway required. Read and create boards, items, columns, updates, and users. Use when asked to check tasks, add items, update statuses, query boards, or do anything with a user's monday.com workspace. homepage: https://github.com/mondaycom/monday-graphql-api metadata: { "openclaw": { "emoji": "📋", "requires": { "env": ["MONDAY_API_TOKEN"], "optionalEnv": ["MONDAY_API_ENDPOINT", "PLATFORM_API"] }, "primaryEnv": "MONDAY_API_TOKEN", }, } --- # monday.com GraphQL API skill via the official `@mondaydotcomorg/api` client. ## Setup 1. **Install dependencies** — `node_modules` is not included in the published skill. After installing, run: ```bash npm install --prefix ~/.agents/skills/monday/scripts ``` 2. **API token** — set `MONDAY_API_TOKEN` in your environment, or store it in `openclaw.json` under `skills.entries.monday.apiKey` and add `"primaryEnv": "MONDAY_API_TOKEN"` to your agent config so OpenClaw injects it automatically. Optional env vars (endpoint overrides, rarely needed): - `MONDAY_API_ENDPOINT` — override the API base URL - `PLATFORM_API` — JSON secret map containing `PLATFORM_API_ENDPOINT` (monday.com platform apps only) ## Running queries All API calls go through `scripts/monday.js`: ```bash node ~/.agents/skills/monday/scripts/monday.js query '<graphql>' [--variables '<json>'] [--version '2026-01'] ``` - Prints JSON to stdout on success. - Prints `{ "error": "...", "graphqlErrors": [...] }` to stderr and exits non-zero on failure. - Default API version: `2026-01`. ### Example — who am I? ```bash node ~/.agents/skills/monday/scripts/monday.js query '{ me { id name email } }' ``` ### Example — list boards ```bash node ~/.agents/skills/monday/scripts/monday.js query '{ boards(limit: 20) { id name description } }' ``` ### Example — items on a board (paginated) ```bash node ~/.agents/skills/monday/scripts/monday.js query ' query($id: [ID!]) { boards(ids: $id) { items_page(limit: 50) { cursor items { id name state column_values { id text } } } } } ' --variables '{"id": ["BOARD_ID"]}' ``` ### Example — create an item ```bash node ~/.agents/skills/monday/scripts/monday.js query ' mutation($board: ID!, $name: String!) { create_item(board_id: $board, item_name: $name) { id name } } ' --variables '{"board": "BOARD_ID", "name": "New task"}' ``` ## Key API rules - Use `items_page` (not `items`) for fetching items from a board — it is paginated and performant. - Use `next_items_page(cursor: $cursor)` to fetch subsequent pages. - Use `users(limit: 50, page: N)` for paginating users. - Request only the fields you actually need. - Board IDs and item IDs are strings in variables (`ID!` type). ## LLM context rules Official monday.com guidance files are in `references/`: - `references/graphql-api-best-practices.md` — pagination patterns and correct query structure - `references/api-client-best-practices.md` — client setup, error handling, env var usage - `references/backend-usage-rules.md` — Node.js mutation/query examples with full error handling - `references/frontend-usage-rules.md` — browser/React examples (reference only; this skill is server-side) When writing a new or unfamiliar query, read the relevant rules file first.

path: references/api-client-best-practices.md
content: ---
description: Use these rules when making API calls to the monday.com GraphQL API. Best practices for using the monday API client, making requests and handling errors. 
globs: 
alwaysApply: false
---
# Using monday.com API Client Libraries

## Overview
This guide explains how to use the official monday.com API client libraries to make GraphQL API calls. The client libraries provide type-safe, reliable methods for interacting with the monday.com API.

## Using monday client libraries to make GraphQL API calls

- Use the `@mondaydotcomorg/api` package to call the monday API
- Read the client documentation at @https://www.npmjs.com/package/@mondaydotcomorg/api
- Prefer the `@mondaydotcomorg/api` package over the "monday-sdk-js" package for making API calls

### Installing the API client
- If `@mondaydotcomorg/api` is not in the project dependencies, install it:
```bash
npm install @mondaydotcomorg/api
```

### Using the API client
- Use the `ApiClient` class to make API calls from the server-side, such as Node.js environments. 
- Use the `SeamlessApiClient` class to make API calls from the client-side, such as in React environments. 

## Installation and Setup

### Installing the API Client
```bash
npm install @mondaydotcomorg/api
```

### Required Imports
```typescript
import { ApiClient, SeamlessApiClient } from "@mondaydotcomorg/api";
```

## Type Definitions

```typescript
// Base response type for all API calls
type APIResponse<T> = {
    loading: boolean;                 // Top-level loading state
    error: APIError | null;          // Top-level errors
    data: {
        loading: boolean;            // Query-specific loading state
        error: APIError | null;      // Query-specific errors
        data: T;                     // Your query results
    };
}

// Structured error type
type APIError = {
    message: string;
    status: number;
    errors?: Array<{
        message: string;
        path?: string[];
    }>;
}
```


## Error Handling Best Practices

1. **Always check both levels of errors**
```typescript
if (error instanceof ClientError) {
    console.error(error.response.errors);
} else {
    console.error(error);
}
```

2. **Use try-catch blocks**
```typescript
try {
    const response = await client.request(query);
    // Handle success
} catch (error) {
    // Handle network errors, parsing errors, etc.
}
```

## Important Notes

1. **API Token Security**
   - Never hardcode API tokens in your code
   - Use environment variables for API tokens
   - Backend: Use `process.env.MONDAY_API_TOKEN`
   - Frontend: The SeamlessApiClient handles authentication automatically
2. **API Version Compatibility**
   - Always pass an API version
   - Check monday API release notes for updates: @https://developer.monday.com/api-reference/docs/release-notes

3. **Rate Limiting**
   - Implement appropriate error handling for rate limit responses
   - Consider implementing retry logic with exponential backoff

4. **Performance Tips**
   - Request only the fields you need
   - Use pagination for large datasets
   - Cache responses when appropriate

path: references/backend-usage-rules.md
content: ---
description: Backend code examples for the official monday.com API client library. Use these rules when making GraphQL queries in a server-side environment. 
globs: 
alwaysApply: false
---
## Backend Usage (Node.js Environment)

The following examples show correct usage of the monday API client in a backend environment, such as NodeJS or in server-side code for NextJS or React. 

### Basic Mutation Example
```typescript
import { ApiClient } from "@mondaydotcomorg/api";

// Define your mutation types
type CreateItemResponse = {
    create_item: {
        id: string;
        name: string;
    };
}

// Define your GraphQL mutation
const CREATE_ITEM = `
    mutation($boardId: ID!, $itemName: String!) {
        create_item(
            board_id: $boardId,
            item_name: $itemName
        ) {
            id
            name
        }
    }
`;

// Make the API call
async function createNewItem(boardId: string, itemName: string) {
    // Get your API token from environment variables
    const API_TOKEN = process.env.MONDAY_API_TOKEN;
    if (!API_TOKEN) {
        throw new Error('API token not found in environment variables');
    }

    const client = new ApiClient({ [REDACTED_SECRET], apiVersion: "2025-04"});
    
    try {
        const response = await client.request<APIResponse<CreateItemResponse>>(
            CREATE_ITEM,
            {
                variables: {
                    boardId,
                    itemName
                }
            }
        );

        if (response.error || response.data.error) {
            throw new Error(response.error?.message || response.data.error?.message);
        }

        return response.data.data;
    } catch (error) {
        console.error('Failed to create item:', error);
        throw error;
    }
}
```

## Correct error handling example

```typescript
import { ApiClient, ClientError } from "@mondaydotcomorg/api";
import { GetBoardsQuery, GetBoardsQueryVariables } from "./generated/graphql";
import { exampleQuery } from "./queries.graphql";

async function getBoardDetails(): Promise<void> {
  try {
    const [REDACTED_SECRET]";
    const client = new ApiClient({ token });
    const queryVariables: GetBoardsQueryVariables = { ids: ["5901934630"] };
    const queryData = await client.request<GetBoardsQuery>(
      exampleQuery,
      queryVariables
    );

    console.log(queryData.boards);
  } catch (error) {
    if (error instanceof ClientError) {
      console.error(error.response.errors);
    } else {
      console.error(error);
    }
  }
}

getBoardDetails();
```


path: references/frontend-usage-rules.md
content: ---
description: Use these rules when making GraphQL queries in a client-side or browser environment. Frontend code examples for the official monday.com API client library. 
globs: 
alwaysApply: false
---
## Frontend Usage (Browser Environment)

The following examples show correct usage of the monday API client in a frontend browser environment. 

### Basic Query Example
```typescript
import { SeamlessApiClient } from "@mondaydotcomorg/api";

// Define your query types
type UserData = {
    me: {
        name: string;
        email: string;
    };
}

// Define your GraphQL query
const GET_USER_INFO = `
    query {
        me {
            name
            email
        }
    }
`;

// Make the API call
async function getUserInfo() {
    const client = new SeamlessApiClient();
    try {
        const response = await client.request<APIResponse<UserData>>(GET_USER_INFO);
        
        if (response.error || response.data.error) {
            throw new Error(response.error?.message || response.data.error?.message);
        }
        
        return response.data.data;
    } catch (error) {
        console.error('API call failed:', error);
        throw error;
    }
}
```

path: references/graphql-api-best-practices.md
content: ---
description: Use these rules when developing GraphQL queries to the monday.com API. Best practices for apps that interact with the monday GraphQL API
globs: 
alwaysApply: false
---
# monday GraphQL API Best Practices

You are an expert at developing apps for the monday.com platform, and GraphQL query writing. 

## GraphQL Query Best Practices
- Use the `items_page` object when querying items from a board. 
- Use pagination when querying large datasets

### Pagination: Users query
```graphql
{
    users (limit:50, page: 1) {
        id
        name
        email
    }
}
```

### Pagination: Items on a board (React environment)
```javascript
async function getItemsWithPagination() {
    const boardIds = currentBoard;

    // get first page of items
    var items_page = await SeamlApiClient.request(`
        query ($boardIds:[ID!]){
        boards (ids:$boardIds) { 
            items_page (limit:1) {
            cursor
            items {
                name
                id
            }
            } 
        } 
        }`, { boardIds });

    // dispatch changes to items state
    handleGetItems(items_page.data.boards[0].items_page.items);

    // set cursor & increment page
    var cursor = items_page.data.boards[0].items_page.cursor;

    // if cursor exists, retrieve next page
    while (cursor) {
        items_page = await SeamlApiClient.request(`
        query ($cursor:String!){
            next_items_page (limit:1, cursor:$cursor) {
                cursor
                items {
                name
                id
                }
            } 
        }`, { cursor });
        handleGetItems(items_page.data.next_items_page.items);
        cursor = items_page.data.next_items_page.cursor;
    }
}
```

path: scripts/monday.js
content: #!/usr/bin/env node
/**
 * monday.js — CLI wrapper for the monday.com GraphQL API
 *
 * Usage:
 *   node monday.js query '<graphql>'
 *   node monday.js query '<graphql>' --variables '{"boardId": "123"}'
 *   node monday.js query '<graphql>' --version '2026-01'
 *
 * Reads API token from MONDAY_API_TOKEN env var.
 * Prints JSON result to stdout. Exits non-zero on error.
 */

'use strict';

const { ApiClient, ClientError } = require('@mondaydotcomorg/api');

function usage() {
  console.error('Usage: node monday.js query <graphql> [--variables <json>] [--version <yyyy-mm>]');
  process.exit(1);
}

function parseArgs(argv) {
  const args = argv.slice(2);
  if (args[0] !== 'query' || !args[1]) usage();

  const graphql = args[1];
  let variables = undefined;
  let version = undefined;

  for (let i = 2; i < args.length; i++) {
    if (args[i] === '--variables' && args[i + 1]) {
      try {
        variables = JSON.parse(args[++i]);
      } catch {
        console.error('Error: --variables must be valid JSON');
        process.exit(1);
      }
    } else if (args[i] === '--version' && args[i + 1]) {
      version = args[++i];
    }
  }

  return { graphql, variables, version };
}

async function main() {
  const [REDACTED_SECRET];
  if (!token) {
    console.error('Error: MONDAY_API_TOKEN environment variable is not set');
    process.exit(1);
  }

  const { graphql, variables, version } = parseArgs(process.argv);

  const clientConfig = { token };
  if (version) clientConfig.apiVersion = version;

  const client = new ApiClient(clientConfig);

  try {
    const data = await client.request(graphql, variables);
    console.log(JSON.stringify(data, null, 2));
  } catch (err) {
    if (err instanceof ClientError) {
      console.error(JSON.stringify({ error: err.message, graphqlErrors: err.response?.errors ?? [] }, null, 2));
    } else {
      console.error(JSON.stringify({ error: String(err) }, null, 2));
    }
    process.exit(1);
  }
}

main();


path: scripts/package.json
content: {
  "name": "monday-skill-scripts",
  "version": "1.0.0",
  "private": true,
  "description": "CLI wrapper for monday.com API skill",
  "main": "monday.js",
  "type": "commonjs",
  "engines": {
    "node": ">= 18.0.0"
  },
  "dependencies": {
    "@mondaydotcomorg/api": "^14.0.0"
  }
}


Security scan verdicts — ClawScan: suspicious | static analysis: clean | VirusTotal: clean | SkillSpector: suspicious (MEDIUM)