@mondaydotcomorg/monday-api-mcp 1.11.3 โ 1.12.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +48 -2
- package/dist/domains/atp/atp.consts.js +87 -0
- package/dist/domains/atp/atp.service.js +112 -0
- package/dist/domains/atp/atp.types.js +2 -0
- package/dist/domains/atp/index.js +21 -0
- package/dist/index.js +17 -8
- package/dist/utils/args/args.config.js +1 -1
- package/package.json +6 -2
package/README.md
CHANGED
|
@@ -8,7 +8,7 @@ A server implementation for the [Model Context Protocol (MCP)](https://modelcont
|
|
|
8
8
|
|
|
9
9
|
## ๐ป Claude Desktop Demo
|
|
10
10
|
|
|
11
|
-
https://github.com/user-attachments/assets/ed8d24e1-256b-4f6b-9d84-38e54a8703fd
|
|
11
|
+
<https://github.com/user-attachments/assets/ed8d24e1-256b-4f6b-9d84-38e54a8703fd>
|
|
12
12
|
|
|
13
13
|
## Prerequisites
|
|
14
14
|
|
|
@@ -33,9 +33,55 @@ The monday.com API token can also be provided via the `monday_token` environment
|
|
|
33
33
|
| monday.com API Token | `--token`, `-t` | monday.com API token (can also be provided via `monday_token` environment variable) | Yes | - |
|
|
34
34
|
| API Version | `--version`, `-v` | monday.com API version | No | `current` |
|
|
35
35
|
| Read Only Mode | `--read-only`, `-ro` | Enable read-only mode | No | `false` |
|
|
36
|
-
|
|
|
36
|
+
| Mode | `--mode`, `-m` | Set the mode for tool selection: "api" - API tools only, "apps" - (Beta) Monday Apps tools only, "atp" - (Alpha) ATP server mode | No | `api` |
|
|
37
37
|
| Dynamic API Tools | `--enable-dynamic-api-tools`, `-edat` | (Beta) Enable dynamic API tools (Mode that includes the whole API schema, not supported when using read-only mode) | No | `false` |
|
|
38
38
|
|
|
39
|
+
## ๐งช ATP Mode (Alpha)
|
|
40
|
+
|
|
41
|
+
ATP (Agent Tool Protocol) mode provides an alternative integration that enables GraphQL API exploration and code execution capabilities. This mode exposes two powerful tools:
|
|
42
|
+
|
|
43
|
+
- **explore_api**: Navigate and discover the monday.com GraphQL API structure
|
|
44
|
+
- **execute_code**: Execute JavaScript code to call monday.com APIs dynamically
|
|
45
|
+
|
|
46
|
+
> โ ๏ธ **Alpha Feature**: ATP mode is currently in alpha. APIs and behavior may change.
|
|
47
|
+
|
|
48
|
+
### Usage
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
npx @mondaydotcomorg/monday-api-mcp@latest -t abcd123 -m atp
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
### Configuration
|
|
55
|
+
|
|
56
|
+
| Environment Variable | Description | Required |
|
|
57
|
+
|---------------------|-------------|----------|
|
|
58
|
+
| `MONDAY_ATP_PORT` | Specify a fixed port for the ATP server (1-65535). If not set, a random available port will be used. | No |
|
|
59
|
+
| `NODE_OPTIONS` | Node.js runtime options. Set to `--no-node-snapshot` for compatibility. | Yes |
|
|
60
|
+
| `ATP_JWT_SECRET` | JWT secret for ATP authentication. Must be set but currently not used (e.g., `ignore`). | Yes |
|
|
61
|
+
|
|
62
|
+
### Cursor Integration (ATP Mode)
|
|
63
|
+
|
|
64
|
+
```json
|
|
65
|
+
{
|
|
66
|
+
"mcpServers": {
|
|
67
|
+
"monday-api-mcp": {
|
|
68
|
+
"command": "npx",
|
|
69
|
+
"args": [
|
|
70
|
+
"@mondaydotcomorg/monday-api-mcp@latest",
|
|
71
|
+
"-t",
|
|
72
|
+
"abcd123",
|
|
73
|
+
"-m",
|
|
74
|
+
"atp"
|
|
75
|
+
],
|
|
76
|
+
"env": {
|
|
77
|
+
"NODE_OPTIONS": "--no-node-snapshot",
|
|
78
|
+
"ATP_JWT_SECRET": "ignore"
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
```
|
|
84
|
+
|
|
39
85
|
## ๐ป Claude Desktop Integration
|
|
40
86
|
|
|
41
87
|
```json
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.TOOL_DESCRIPTIONS = exports.getMondaySchemaUrl = exports.QUERY_DEPTH_LIMIT = exports.DEFAULT_API_VERSION = exports.MONDAY_API_NAME = exports.MONDAY_API_BASE_URL = exports.ATP_SERVER_VERSION = exports.ATP_SERVER_NAME = void 0;
|
|
4
|
+
exports.ATP_SERVER_NAME = 'monday.com';
|
|
5
|
+
exports.ATP_SERVER_VERSION = '1.0.0';
|
|
6
|
+
exports.MONDAY_API_BASE_URL = 'https://api.monday.com/v2';
|
|
7
|
+
exports.MONDAY_API_NAME = 'monday';
|
|
8
|
+
exports.DEFAULT_API_VERSION = '2025-10';
|
|
9
|
+
exports.QUERY_DEPTH_LIMIT = 2;
|
|
10
|
+
const getMondaySchemaUrl = (version = exports.DEFAULT_API_VERSION) => `https://api.monday.com/v2/get_schema?version=${version}&format=sdl`;
|
|
11
|
+
exports.getMondaySchemaUrl = getMondaySchemaUrl;
|
|
12
|
+
exports.TOOL_DESCRIPTIONS = {
|
|
13
|
+
execute_code: `Execute Javascript code to call Monday.com APIs. MUST use 'return' to see results.
|
|
14
|
+
|
|
15
|
+
**API Pattern:** api.monday.query_xxx() for reads, api.monday.mutation_xxx() for writes.
|
|
16
|
+
|
|
17
|
+
**Critical Rules:**
|
|
18
|
+
- Use _fields parameter for nested data: 'id,name,columns{id,title,type},items_page{cursor}'
|
|
19
|
+
- ColumnValue has: id, type, text, value (NOT "title")
|
|
20
|
+
- items_page returns ~25 items - use pagination for more
|
|
21
|
+
- When searching/filtering, use the FULL value provided by the user (e.g., full name, not partial)
|
|
22
|
+
|
|
23
|
+
**When Unsure - ASK THE USER:**
|
|
24
|
+
- If you're not 100% sure about the user's intent, ASK before executing
|
|
25
|
+
- If multiple results match a search, ASK which one they mean
|
|
26
|
+
- If you're missing required information - ASK, don't guess
|
|
27
|
+
|
|
28
|
+
**Multi-line Example:**
|
|
29
|
+
\`\`\`typescript
|
|
30
|
+
// 1. Get board with columns and cursor
|
|
31
|
+
const boards = await api.monday.query_boards({
|
|
32
|
+
ids: ['BOARD_ID'],
|
|
33
|
+
_fields: 'id,columns{id,title,type},items_page{cursor}'
|
|
34
|
+
});
|
|
35
|
+
const board = boards[0];
|
|
36
|
+
|
|
37
|
+
// 2. Find column by title
|
|
38
|
+
const statusCol = board.columns.find(c => c.title === 'Status')?.id;
|
|
39
|
+
|
|
40
|
+
// 3. Paginate items
|
|
41
|
+
let cursor = board.items_page.cursor;
|
|
42
|
+
const allItems = [];
|
|
43
|
+
for (let page = 0; page < 20; page++) {
|
|
44
|
+
if (!cursor) break;
|
|
45
|
+
const result = await api.monday.query_next_items_page({
|
|
46
|
+
cursor, limit: 100,
|
|
47
|
+
_fields: 'cursor,items{id,name,group{title},column_values{id,text}}'
|
|
48
|
+
});
|
|
49
|
+
allItems.push(...result.items);
|
|
50
|
+
cursor = result.cursor;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
// 4. Analyze and return
|
|
54
|
+
return { total: allItems.length, items: allItems.slice(0, 5) };
|
|
55
|
+
\`\`\`
|
|
56
|
+
|
|
57
|
+
Use AFTER exploring the API to understand available operations.`,
|
|
58
|
+
explore_api: `Explore Monday.com API structure using filesystem-like navigation. ALWAYS use this BEFORE writing code to discover available operations and parameters.
|
|
59
|
+
|
|
60
|
+
**Navigation Paths:**
|
|
61
|
+
- "/monday/query" - List all query operations (read data)
|
|
62
|
+
- "/monday/mutation" - List all mutation operations (write data)
|
|
63
|
+
- "/monday/query/boards" - See parameters for boards query
|
|
64
|
+
- "/monday/query/items" - See parameters for items query
|
|
65
|
+
|
|
66
|
+
**Valid Exploration Pattern:**
|
|
67
|
+
2. Then: path="/monday/query" to see query operations
|
|
68
|
+
3. Then: path="/monday/query/<operation_name>" to see parameters
|
|
69
|
+
|
|
70
|
+
**DO NOT explore nested paths like:**
|
|
71
|
+
- /monday/query/boards/items_page (doesn't exist)
|
|
72
|
+
- /monday/query/boards/fields (doesn't exist)
|
|
73
|
+
|
|
74
|
+
Only explore: /monday/query, /monday/mutation, or /monday/query/<operation_name>
|
|
75
|
+
|
|
76
|
+
**Example Workflow:**
|
|
77
|
+
1. explore_api path="/monday/query" โ discover "boards", "items", "users" operations
|
|
78
|
+
2. explore_api path="/monday/query/boards" โ see ids, _fields parameters
|
|
79
|
+
3. YOU MUST USE THE EXPLORE_API TOOL TO DISCOVER THE OPERATIONS AND PARAMETERS BEFORE USING THE EXECUTE_CODE TOOL
|
|
80
|
+
4. NOW write code using execute_code with discovered operations
|
|
81
|
+
5. TRY TO MAKE ALL CODE EXECUTION IN ONE SCRIPT INSTEAD OF MULTIPLE ONES (IF POSSIBLE)
|
|
82
|
+
|
|
83
|
+
**IMPORTANT - When Unsure, ASK:**
|
|
84
|
+
- If you don't understand what the user wants - ASK
|
|
85
|
+
- If you're missing required information - ASK
|
|
86
|
+
- Don't guess or assume - it's better to ask than to make mistakes`,
|
|
87
|
+
};
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.runAtpMcpServer = runAtpMcpServer;
|
|
4
|
+
const stdio_js_1 = require("@modelcontextprotocol/sdk/server/stdio.js");
|
|
5
|
+
const mcp_js_1 = require("@modelcontextprotocol/sdk/server/mcp.js");
|
|
6
|
+
const net_1 = require("net");
|
|
7
|
+
const atp_consts_js_1 = require("./atp.consts.js");
|
|
8
|
+
// Dynamic imports required: ATP packages are ESM, this package is CJS
|
|
9
|
+
async function loadAtpDependencies() {
|
|
10
|
+
const { createServer } = await import('@mondaydotcomorg/atp-server');
|
|
11
|
+
const { AgentToolProtocolClient, ToolNames } = await import('@mondaydotcomorg/atp-client');
|
|
12
|
+
const { registerToolsWithMCP } = await import('@mondaydotcomorg/atp-mcp-adapter');
|
|
13
|
+
return { createServer, AgentToolProtocolClient, ToolNames, registerToolsWithMCP };
|
|
14
|
+
}
|
|
15
|
+
function getToolDescriptions(ToolNames) {
|
|
16
|
+
return {
|
|
17
|
+
[String(ToolNames.EXECUTE_CODE)]: atp_consts_js_1.TOOL_DESCRIPTIONS.execute_code,
|
|
18
|
+
[String(ToolNames.EXPLORE_API)]: atp_consts_js_1.TOOL_DESCRIPTIONS.explore_api,
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
function filterAndEnhanceTools(tools, toolDescriptions) {
|
|
22
|
+
return tools
|
|
23
|
+
.filter((tool) => tool.name in toolDescriptions)
|
|
24
|
+
.map((tool) => ({
|
|
25
|
+
...tool,
|
|
26
|
+
description: toolDescriptions[tool.name],
|
|
27
|
+
}));
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Gets the ATP port from environment variable, or returns undefined to use dynamic port allocation.
|
|
31
|
+
* Set MONDAY_ATP_PORT environment variable to use a specific port.
|
|
32
|
+
*/
|
|
33
|
+
function getAtpPort() {
|
|
34
|
+
const envPort = process.env.MONDAY_ATP_PORT;
|
|
35
|
+
if (envPort) {
|
|
36
|
+
const port = parseInt(envPort, 10);
|
|
37
|
+
if (!isNaN(port) && port > 0 && port <= 65535) {
|
|
38
|
+
return port;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
return undefined; // Will use dynamic port allocation
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Finds an available port by binding to port 0 and letting the OS assign one.
|
|
45
|
+
*/
|
|
46
|
+
async function findAvailablePort() {
|
|
47
|
+
return new Promise((resolve, reject) => {
|
|
48
|
+
const server = (0, net_1.createServer)();
|
|
49
|
+
server.listen(0, () => {
|
|
50
|
+
const address = server.address();
|
|
51
|
+
if (address && typeof address === 'object') {
|
|
52
|
+
const port = address.port;
|
|
53
|
+
server.close(() => resolve(port));
|
|
54
|
+
}
|
|
55
|
+
else {
|
|
56
|
+
server.close(() => reject(new Error('Failed to get port from server address')));
|
|
57
|
+
}
|
|
58
|
+
});
|
|
59
|
+
server.on('error', reject);
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
async function initAtpServer(createServer) {
|
|
63
|
+
const server = createServer({ logger: 'none' });
|
|
64
|
+
// Use configured port or find an available one
|
|
65
|
+
const configuredPort = getAtpPort();
|
|
66
|
+
const port = configuredPort ?? (await findAvailablePort());
|
|
67
|
+
await server.listen(port);
|
|
68
|
+
return { server, port };
|
|
69
|
+
}
|
|
70
|
+
async function loadMondaySchema(server, token, version) {
|
|
71
|
+
const apiVersion = version ?? atp_consts_js_1.DEFAULT_API_VERSION;
|
|
72
|
+
await server.loadGraphQL((0, atp_consts_js_1.getMondaySchemaUrl)(apiVersion), {
|
|
73
|
+
name: atp_consts_js_1.MONDAY_API_NAME,
|
|
74
|
+
url: atp_consts_js_1.MONDAY_API_BASE_URL,
|
|
75
|
+
headers: {
|
|
76
|
+
Authorization: token,
|
|
77
|
+
'API-Version': apiVersion,
|
|
78
|
+
},
|
|
79
|
+
queryDepthLimit: atp_consts_js_1.QUERY_DEPTH_LIMIT,
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
async function initAtpClient(AgentToolProtocolClient, port) {
|
|
83
|
+
const client = new AgentToolProtocolClient({
|
|
84
|
+
baseUrl: `http://localhost:${port}`,
|
|
85
|
+
});
|
|
86
|
+
await client.init({ name: 'monday-api-mcp', version: '1.0.0' });
|
|
87
|
+
await client.connect();
|
|
88
|
+
return client;
|
|
89
|
+
}
|
|
90
|
+
function createMcpServer() {
|
|
91
|
+
return new mcp_js_1.McpServer({
|
|
92
|
+
name: atp_consts_js_1.ATP_SERVER_NAME,
|
|
93
|
+
version: atp_consts_js_1.ATP_SERVER_VERSION,
|
|
94
|
+
}, {
|
|
95
|
+
capabilities: {
|
|
96
|
+
tools: {},
|
|
97
|
+
},
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
async function runAtpMcpServer(config) {
|
|
101
|
+
const { token, version } = config;
|
|
102
|
+
const { createServer, AgentToolProtocolClient, ToolNames, registerToolsWithMCP } = await loadAtpDependencies();
|
|
103
|
+
const { server, port } = await initAtpServer(createServer);
|
|
104
|
+
await loadMondaySchema(server, token, version);
|
|
105
|
+
const client = await initAtpClient(AgentToolProtocolClient, port);
|
|
106
|
+
const mcpServer = createMcpServer();
|
|
107
|
+
const toolDescriptions = getToolDescriptions(ToolNames);
|
|
108
|
+
const atpTools = filterAndEnhanceTools(client.getATPTools(), toolDescriptions);
|
|
109
|
+
registerToolsWithMCP(atpTools, mcpServer);
|
|
110
|
+
const transport = new stdio_js_1.StdioServerTransport();
|
|
111
|
+
await mcpServer.connect(transport);
|
|
112
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
exports.runAtpMcpServer = void 0;
|
|
18
|
+
var atp_service_js_1 = require("./atp.service.js");
|
|
19
|
+
Object.defineProperty(exports, "runAtpMcpServer", { enumerable: true, get: function () { return atp_service_js_1.runAtpMcpServer; } });
|
|
20
|
+
__exportStar(require("./atp.consts.js"), exports);
|
|
21
|
+
__exportStar(require("./atp.types.js"), exports);
|
package/dist/index.js
CHANGED
|
@@ -6,17 +6,12 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
6
6
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
7
|
const stdio_js_1 = require("@modelcontextprotocol/sdk/server/stdio.js");
|
|
8
8
|
const mcp_1 = require("@mondaydotcomorg/agent-toolkit/mcp");
|
|
9
|
+
const core_1 = require("@mondaydotcomorg/agent-toolkit/core");
|
|
9
10
|
const args_service_js_1 = require("./utils/args/args.service.js");
|
|
11
|
+
const index_js_1 = require("./domains/atp/index.js");
|
|
10
12
|
const dotenv_1 = __importDefault(require("dotenv"));
|
|
11
13
|
dotenv_1.default.config();
|
|
12
|
-
|
|
13
|
-
* Initializes and starts the MCP server with the Monday Agent Toolkit
|
|
14
|
-
* Uses stdio for transport
|
|
15
|
-
*/
|
|
16
|
-
async function runServer() {
|
|
17
|
-
const args = process.argv.slice(2);
|
|
18
|
-
const parsedArgs = (0, args_service_js_1.parseArgs)(args);
|
|
19
|
-
const validatedArgs = (0, args_service_js_1.validateArgs)(parsedArgs);
|
|
14
|
+
async function runMcpServer(validatedArgs) {
|
|
20
15
|
const toolkit = new mcp_1.MondayAgentToolkit({
|
|
21
16
|
mondayApiToken: validatedArgs.token,
|
|
22
17
|
mondayApiVersion: validatedArgs.version,
|
|
@@ -31,6 +26,20 @@ async function runServer() {
|
|
|
31
26
|
const transport = new stdio_js_1.StdioServerTransport();
|
|
32
27
|
await toolkit.connect(transport);
|
|
33
28
|
}
|
|
29
|
+
async function runServer() {
|
|
30
|
+
const args = process.argv.slice(2);
|
|
31
|
+
const parsedArgs = (0, args_service_js_1.parseArgs)(args);
|
|
32
|
+
const validatedArgs = (0, args_service_js_1.validateArgs)(parsedArgs);
|
|
33
|
+
if (validatedArgs.mode === core_1.ToolMode.ATP) {
|
|
34
|
+
await (0, index_js_1.runAtpMcpServer)({
|
|
35
|
+
token: validatedArgs.token,
|
|
36
|
+
version: validatedArgs.version,
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
else {
|
|
40
|
+
await runMcpServer(validatedArgs);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
34
43
|
runServer().catch((error) => {
|
|
35
44
|
console.error('Fatal error in main():', error);
|
|
36
45
|
process.exit(1);
|
|
@@ -25,7 +25,7 @@ exports.ARG_CONFIGS = [
|
|
|
25
25
|
{
|
|
26
26
|
name: 'mode',
|
|
27
27
|
flags: ['--mode', '-m'],
|
|
28
|
-
description: 'Set the mode for tool selection: "api" - API tools only, "apps" - (Beta) Monday Apps tools only',
|
|
28
|
+
description: 'Set the mode for tool selection: "api" - API tools only, "apps" - (Beta) Monday Apps tools only, "atp" - ATP server mode with GraphQL exploration',
|
|
29
29
|
required: false,
|
|
30
30
|
defaultValue: 'api',
|
|
31
31
|
},
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mondaydotcomorg/monday-api-mcp",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.12.2",
|
|
4
4
|
"description": "MCP server for using the monday.com API",
|
|
5
5
|
"mcpName": "com.monday/monday.com",
|
|
6
6
|
"license": "MIT",
|
|
@@ -25,7 +25,11 @@
|
|
|
25
25
|
"dependencies": {
|
|
26
26
|
"@modelcontextprotocol/sdk": "^1.13.2",
|
|
27
27
|
"@mondaydotcomorg/agent-toolkit": "*",
|
|
28
|
-
"
|
|
28
|
+
"@mondaydotcomorg/atp-client": "^0.19.6",
|
|
29
|
+
"@mondaydotcomorg/atp-mcp-adapter": "^0.19.7",
|
|
30
|
+
"@mondaydotcomorg/atp-server": "^0.19.7",
|
|
31
|
+
"dotenv": "^16.4.7",
|
|
32
|
+
"zod": "^3.25.0"
|
|
29
33
|
},
|
|
30
34
|
"devDependencies": {
|
|
31
35
|
"@types/jest": "^29.5.12",
|