checkbox-mcp-server 1.1.0

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.
@@ -0,0 +1,18 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Checkbox MCP Server
4
+ *
5
+ * Exposes the Checkbox capability API as MCP tools so AI assistants
6
+ * (Claude, etc.) can interact with a Checkbox workspace through the
7
+ * standard Model Context Protocol.
8
+ *
9
+ * Environment variables:
10
+ * CHECKBOX_API_URL — Base URL of the Checkbox instance (e.g. https://checkbox.my)
11
+ * CHECKBOX_API_TOKEN — API key (ck_live_...) or Supabase JWT
12
+ *
13
+ * Get your API key:
14
+ * 1. Log in to checkbox.my
15
+ * 2. Go to Developer Hub (sidebar)
16
+ * 3. Create an API key — it never expires unless you configure an expiry
17
+ */
18
+ export {};
package/dist/index.js ADDED
@@ -0,0 +1,146 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Checkbox MCP Server
4
+ *
5
+ * Exposes the Checkbox capability API as MCP tools so AI assistants
6
+ * (Claude, etc.) can interact with a Checkbox workspace through the
7
+ * standard Model Context Protocol.
8
+ *
9
+ * Environment variables:
10
+ * CHECKBOX_API_URL — Base URL of the Checkbox instance (e.g. https://checkbox.my)
11
+ * CHECKBOX_API_TOKEN — API key (ck_live_...) or Supabase JWT
12
+ *
13
+ * Get your API key:
14
+ * 1. Log in to checkbox.my
15
+ * 2. Go to Developer Hub (sidebar)
16
+ * 3. Create an API key — it never expires unless you configure an expiry
17
+ */
18
+ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
19
+ import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
20
+ import { z } from 'zod';
21
+ // ── Config ──────────────────────────────────────────────────────────
22
+ const API_URL = process.env.CHECKBOX_API_URL ?? 'https://checkbox.my';
23
+ const API_TOKEN = process.env.CHECKBOX_API_TOKEN ?? '';
24
+ function getHeaders() {
25
+ return {
26
+ 'Content-Type': 'application/json',
27
+ ...(API_TOKEN ? { Authorization: `Bearer ${API_TOKEN}` } : {}),
28
+ };
29
+ }
30
+ // ── HTTP helpers ────────────────────────────────────────────────────
31
+ async function apiGet(path) {
32
+ const res = await fetch(`${API_URL}${path}`, {
33
+ method: 'GET',
34
+ headers: getHeaders(),
35
+ });
36
+ return res.json();
37
+ }
38
+ async function apiPost(path, body) {
39
+ const res = await fetch(`${API_URL}${path}`, {
40
+ method: 'POST',
41
+ headers: getHeaders(),
42
+ body: JSON.stringify(body),
43
+ });
44
+ return res.json();
45
+ }
46
+ function resultText(data) {
47
+ return JSON.stringify(data, null, 2);
48
+ }
49
+ // ── MCP Server ──────────────────────────────────────────────────────
50
+ const server = new McpServer({
51
+ name: 'checkbox',
52
+ version: '1.1.0',
53
+ });
54
+ // 1. List capabilities ───────────────────────────────────────────────
55
+ server.tool('list_capabilities', 'List all available Checkbox commands and queries with their descriptions, required roles, and domains. Call this first to understand what actions are available.', {}, async () => {
56
+ const data = await apiGet('/api/v2/introspection/capabilities');
57
+ return { content: [{ type: 'text', text: resultText(data) }] };
58
+ });
59
+ // 2. Execute command ─────────────────────────────────────────────────
60
+ server.tool('execute_command', 'Execute a Checkbox capability command. Use list_capabilities to see available command types and get_schema to understand the payload shape for each entity type.', {
61
+ type: z.string().describe('The command type (e.g. "create_task", "complete_task", "update_plan")'),
62
+ organization_id: z.string().optional().describe('Organization ID. Required for org-scoped commands; omit for authenticated-scope commands like create_organization.'),
63
+ payload: z.record(z.unknown()).describe('Command payload — structure depends on the command type. Use get_schema to discover the expected fields.'),
64
+ }, async ({ type, organization_id, payload }) => {
65
+ const body = { type, payload };
66
+ if (organization_id)
67
+ body.organization_id = organization_id;
68
+ const data = await apiPost('/api/v2/commands', body);
69
+ return { content: [{ type: 'text', text: resultText(data) }] };
70
+ });
71
+ // 3. Execute query ───────────────────────────────────────────────────
72
+ server.tool('execute_query', 'Execute a Checkbox capability query. Use list_capabilities to see available query types.', {
73
+ type: z.string().describe('The query type (e.g. "get_task_states", "workspace_graph", "list_entities", "get_entity")'),
74
+ organization_id: z.string().describe('Organization ID'),
75
+ payload: z.record(z.unknown()).describe('Query payload — structure depends on the query type. Use get_schema to discover the expected fields.'),
76
+ }, async ({ type, organization_id, payload }) => {
77
+ const data = await apiPost('/api/v2/query', {
78
+ type,
79
+ organization_id,
80
+ payload: { ...payload, organization_id },
81
+ });
82
+ return { content: [{ type: 'text', text: resultText(data) }] };
83
+ });
84
+ // 4. Get workspace graph ─────────────────────────────────────────────
85
+ server.tool('get_workspace', 'Get the full workspace graph — all entities (tasks, plans, goals, rules, requirements, tables, documents, etc.) and their relationships. Useful for understanding the structure of an organization before taking actions.', {
86
+ organization_id: z.string().describe('Organization ID'),
87
+ }, async ({ organization_id }) => {
88
+ const data = await apiPost('/api/v2/introspection/workspace', { organization_id });
89
+ return { content: [{ type: 'text', text: resultText(data) }] };
90
+ });
91
+ // 5. Find entities ───────────────────────────────────────────────────
92
+ server.tool('find_entities', 'Search for entities in the workspace by type and/or text search. Returns matching entities with their IDs, names, and metadata.', {
93
+ organization_id: z.string().describe('Organization ID'),
94
+ entity_type: z.string().optional().describe('Filter by entity type (e.g. "task", "plan", "table", "document")'),
95
+ search: z.string().optional().describe('Text search across entity names'),
96
+ limit: z.number().optional().describe('Max results to return (default varies by type)'),
97
+ }, async ({ organization_id, entity_type, search, limit }) => {
98
+ const data = await apiPost('/api/v2/introspection/entities', {
99
+ organization_id,
100
+ entity_type,
101
+ search,
102
+ limit,
103
+ });
104
+ return { content: [{ type: 'text', text: resultText(data) }] };
105
+ });
106
+ // 6. Get schema ──────────────────────────────────────────────────────
107
+ server.tool('get_schema', 'Get the schema for entity types — describes fields, writable fields, and filterable fields. Use this to understand what parameters to pass when creating or updating entities.', {
108
+ organization_id: z.string().describe('Organization ID'),
109
+ entity_type: z.string().optional().describe('Specific entity type to get schema for (e.g. "task", "plan", "table")'),
110
+ entity_id: z.string().optional().describe('Specific entity ID to get schema for (useful for table records whose schema is defined per-table)'),
111
+ }, async ({ organization_id, entity_type, entity_id }) => {
112
+ const data = await apiPost('/api/v2/introspection/schema', {
113
+ organization_id,
114
+ entity_type,
115
+ entity_id,
116
+ });
117
+ return { content: [{ type: 'text', text: resultText(data) }] };
118
+ });
119
+ // 7. Check permissions ───────────────────────────────────────────────
120
+ server.tool('check_permissions', 'Check which capabilities the current user has in an organization. Returns the user role and a list of all commands/queries with allowed/denied status.', {
121
+ organization_id: z.string().describe('Organization ID'),
122
+ }, async ({ organization_id }) => {
123
+ const data = await apiPost('/api/v2/introspection/permissions', { organization_id });
124
+ return { content: [{ type: 'text', text: resultText(data) }] };
125
+ });
126
+ // 8. List my organizations ──────────────────────────────────────────
127
+ server.tool('list_my_organizations', 'List all organizations the authenticated user belongs to, with their role in each. Call this first to discover which organization_id to use for subsequent commands and queries.', {}, async () => {
128
+ const data = await apiPost('/api/v2/query', {
129
+ type: 'list_my_organizations',
130
+ payload: {},
131
+ });
132
+ return { content: [{ type: 'text', text: resultText(data) }] };
133
+ });
134
+ // ── Start ───────────────────────────────────────────────────────────
135
+ async function main() {
136
+ if (!API_TOKEN) {
137
+ console.error('Warning: CHECKBOX_API_TOKEN is not set. Authenticated requests will fail.\n' +
138
+ 'Get an API key: log in to checkbox.my → Developer Hub → Create Key');
139
+ }
140
+ const transport = new StdioServerTransport();
141
+ await server.connect(transport);
142
+ }
143
+ main().catch((err) => {
144
+ console.error('Fatal:', err);
145
+ process.exit(1);
146
+ });
package/package.json ADDED
@@ -0,0 +1,49 @@
1
+ {
2
+ "name": "checkbox-mcp-server",
3
+ "version": "1.1.0",
4
+ "description": "MCP server for the Checkbox capability API — lets AI assistants (Claude, Cursor, etc.) manage compliance plans, tasks, documents, and more through the Model Context Protocol.",
5
+ "type": "module",
6
+ "main": "dist/index.js",
7
+ "bin": {
8
+ "checkbox-mcp": "dist/index.js"
9
+ },
10
+ "files": [
11
+ "dist"
12
+ ],
13
+ "scripts": {
14
+ "build": "tsc",
15
+ "prepublishOnly": "tsc",
16
+ "start": "node dist/index.js",
17
+ "dev": "tsx src/index.ts"
18
+ },
19
+ "keywords": [
20
+ "mcp",
21
+ "model-context-protocol",
22
+ "checkbox",
23
+ "compliance",
24
+ "ai-agent",
25
+ "claude",
26
+ "cursor",
27
+ "automation"
28
+ ],
29
+ "author": "Checkbox <hello@checkbox.my>",
30
+ "license": "MIT",
31
+ "repository": {
32
+ "type": "git",
33
+ "url": "https://github.com/fadhelcarlos/checkbox.git",
34
+ "directory": "mcp-server"
35
+ },
36
+ "homepage": "https://checkbox.my",
37
+ "engines": {
38
+ "node": ">=18.0.0"
39
+ },
40
+ "dependencies": {
41
+ "@modelcontextprotocol/sdk": "^1.12.1",
42
+ "zod": "^3.23.8"
43
+ },
44
+ "devDependencies": {
45
+ "typescript": "^5.7.0",
46
+ "tsx": "^4.19.0",
47
+ "@types/node": "^22.0.0"
48
+ }
49
+ }