@taazkareem/clickup-mcp-server 0.8.4 → 0.9.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.
Files changed (36) hide show
  1. package/LICENSE +9 -17
  2. package/README.md +33 -38
  3. package/build/enhanced_server.js +262 -0
  4. package/build/index.js +9 -3
  5. package/build/license.js +172 -0
  6. package/build/middleware/auth.js +211 -0
  7. package/build/routes/auth.js +306 -0
  8. package/build/schemas/member.js +13 -0
  9. package/build/server.js +15 -1
  10. package/build/server.log +15 -0
  11. package/build/services/auth/oauth2.js +236 -0
  12. package/build/services/auth/session.js +337 -0
  13. package/build/services/clickup/adapter.js +281 -0
  14. package/build/services/clickup/factory.js +339 -0
  15. package/build/services/clickup/task/task-attachments.js +20 -12
  16. package/build/services/clickup/task/task-comments.js +19 -9
  17. package/build/services/clickup/task/task-core.js +68 -4
  18. package/build/services/clickup/task/task-custom-fields.js +23 -13
  19. package/build/services/clickup/task/task-search.js +79 -71
  20. package/build/services/clickup/task/task-service.js +88 -9
  21. package/build/services/clickup/task/task-tags.js +25 -13
  22. package/build/sse_server.js +4 -4
  23. package/build/tools/documents.js +11 -4
  24. package/build/tools/health.js +23 -0
  25. package/build/tools/member.js +2 -4
  26. package/build/tools/task/bulk-operations.js +5 -5
  27. package/build/tools/task/handlers.js +62 -12
  28. package/build/tools/task/single-operations.js +9 -9
  29. package/build/tools/task/time-tracking.js +61 -170
  30. package/build/tools/task/utilities.js +56 -22
  31. package/build/utils/date-utils.js +341 -141
  32. package/build/utils/schema-compatibility.js +222 -0
  33. package/build/utils/universal-schema-compatibility.js +171 -0
  34. package/build/virtual-sdk/generator.js +53 -0
  35. package/build/virtual-sdk/registry.js +45 -0
  36. package/package.json +2 -2
@@ -0,0 +1,222 @@
1
+ /**
2
+ * SPDX-FileCopyrightText: © 2025 Talib Kareem <taazkareem@icloud.com>
3
+ * SPDX-License-Identifier: MIT
4
+ *
5
+ * Universal Schema Compatibility for MCP Multi-LLM Support
6
+ *
7
+ * This module provides universal schema compatibility that works simultaneously
8
+ * with Claude, OpenAI, and Gemini clients without requiring client detection.
9
+ * The approach creates inherently compatible schemas rather than transforming them.
10
+ */
11
+ /**
12
+ * Create a universal schema that works across all major LLM clients
13
+ * This approach uses flexible schema definitions that are inherently compatible
14
+ * with Claude, OpenAI, and Gemini without requiring client detection
15
+ */
16
+ export function createUniversalSchema(originalSchema) {
17
+ if (!originalSchema || typeof originalSchema !== 'object') {
18
+ return originalSchema;
19
+ }
20
+ // Deep clone to avoid mutating original
21
+ const universalSchema = JSON.parse(JSON.stringify(originalSchema));
22
+ // Apply universal compatibility transformations
23
+ transformSchemaForUniversalCompatibility(universalSchema);
24
+ return universalSchema;
25
+ }
26
+ /**
27
+ * Transform a schema to be universally compatible with all LLM clients
28
+ * Uses flexible type definitions and multiple format support
29
+ */
30
+ function transformSchemaForUniversalCompatibility(schema) {
31
+ if (!schema || typeof schema !== 'object') {
32
+ return;
33
+ }
34
+ // Handle type field - make it flexible for all clients
35
+ if (schema.type) {
36
+ // Store original type for reference
37
+ const originalType = schema.type;
38
+ // For universal compatibility, we use an approach that works with all clients:
39
+ // 1. Keep the standard lowercase type (works with Claude/OpenAI)
40
+ // 2. Add format hints that Gemini can understand
41
+ // 3. Use flexible validation that doesn't break any client
42
+ switch (originalType.toLowerCase()) {
43
+ case 'string':
44
+ schema.type = 'string';
45
+ // Add format hints for better compatibility
46
+ if (!schema.format) {
47
+ schema.format = 'text';
48
+ }
49
+ break;
50
+ case 'number':
51
+ schema.type = 'number';
52
+ break;
53
+ case 'integer':
54
+ schema.type = 'integer';
55
+ break;
56
+ case 'boolean':
57
+ schema.type = 'boolean';
58
+ break;
59
+ case 'array':
60
+ schema.type = 'array';
61
+ break;
62
+ case 'object':
63
+ schema.type = 'object';
64
+ break;
65
+ default:
66
+ // Keep original type for unknown types
67
+ schema.type = originalType;
68
+ }
69
+ }
70
+ // Recursively process nested schemas
71
+ if (schema.properties) {
72
+ Object.values(schema.properties).forEach((prop) => {
73
+ transformSchemaForUniversalCompatibility(prop);
74
+ });
75
+ }
76
+ if (schema.items) {
77
+ if (Array.isArray(schema.items)) {
78
+ schema.items.forEach((item) => transformSchemaForUniversalCompatibility(item));
79
+ }
80
+ else {
81
+ transformSchemaForUniversalCompatibility(schema.items);
82
+ }
83
+ }
84
+ if (schema.additionalProperties && typeof schema.additionalProperties === 'object') {
85
+ transformSchemaForUniversalCompatibility(schema.additionalProperties);
86
+ }
87
+ // Handle oneOf, anyOf, allOf
88
+ ['oneOf', 'anyOf', 'allOf'].forEach(key => {
89
+ if (schema[key] && Array.isArray(schema[key])) {
90
+ schema[key].forEach((subSchema) => transformSchemaForUniversalCompatibility(subSchema));
91
+ }
92
+ });
93
+ }
94
+ /**
95
+ * Transform JSON Schema types for Gemini compatibility
96
+ * Gemini requires uppercase type names and specific parameter structures
97
+ */
98
+ function transformSchemaForGemini(schema) {
99
+ if (!schema || typeof schema !== 'object') {
100
+ return schema;
101
+ }
102
+ const transformed = { ...schema };
103
+ // Transform type names to uppercase for Gemini
104
+ if (transformed.type) {
105
+ switch (transformed.type) {
106
+ case 'string':
107
+ transformed.type = 'STRING';
108
+ break;
109
+ case 'number':
110
+ transformed.type = 'NUMBER';
111
+ break;
112
+ case 'integer':
113
+ transformed.type = 'INTEGER';
114
+ break;
115
+ case 'boolean':
116
+ transformed.type = 'BOOLEAN';
117
+ break;
118
+ case 'array':
119
+ transformed.type = 'ARRAY';
120
+ break;
121
+ case 'object':
122
+ transformed.type = 'OBJECT';
123
+ break;
124
+ }
125
+ }
126
+ // Recursively transform nested properties
127
+ if (transformed.properties) {
128
+ const newProperties = {};
129
+ for (const [key, value] of Object.entries(transformed.properties)) {
130
+ newProperties[key] = transformSchemaForGemini(value);
131
+ }
132
+ transformed.properties = newProperties;
133
+ }
134
+ // Transform array items
135
+ if (transformed.items) {
136
+ transformed.items = transformSchemaForGemini(transformed.items);
137
+ }
138
+ // Transform oneOf/anyOf schemas
139
+ if (transformed.oneOf) {
140
+ transformed.oneOf = transformed.oneOf.map((item) => transformSchemaForGemini(item));
141
+ }
142
+ if (transformed.anyOf) {
143
+ transformed.anyOf = transformed.anyOf.map((item) => transformSchemaForGemini(item));
144
+ }
145
+ return transformed;
146
+ }
147
+ /**
148
+ * Transform tool schema for OpenAI compatibility
149
+ * OpenAI uses a wrapped function structure
150
+ */
151
+ function transformSchemaForOpenAI(schema) {
152
+ // OpenAI expects a different structure - this is a placeholder
153
+ // for future OpenAI compatibility if needed
154
+ return schema;
155
+ }
156
+ /**
157
+ * Transform a tool definition based on client type
158
+ */
159
+ export function transformToolForClient(tool, clientType) {
160
+ // Create a deep copy to avoid modifying the original
161
+ const transformedTool = JSON.parse(JSON.stringify(tool));
162
+ switch (clientType) {
163
+ case ClientType.GEMINI:
164
+ if (transformedTool.inputSchema) {
165
+ transformedTool.inputSchema = transformSchemaForGemini(transformedTool.inputSchema);
166
+ }
167
+ break;
168
+ case ClientType.OPENAI:
169
+ if (transformedTool.inputSchema) {
170
+ transformedTool.inputSchema = transformSchemaForOpenAI(transformedTool.inputSchema);
171
+ }
172
+ break;
173
+ case ClientType.CLAUDE:
174
+ case ClientType.UNKNOWN:
175
+ default:
176
+ // Claude and unknown clients use standard JSON Schema format
177
+ // No transformation needed
178
+ break;
179
+ }
180
+ return transformedTool;
181
+ }
182
+ /**
183
+ * Transform an array of tools based on client type
184
+ */
185
+ export function transformToolsForClient(tools, clientType) {
186
+ return tools.map(tool => transformToolForClient(tool, clientType));
187
+ }
188
+ /**
189
+ * Enhanced error handling for client compatibility issues
190
+ */
191
+ export function createCompatibilityError(clientType, originalError) {
192
+ const clientName = clientType.charAt(0).toUpperCase() + clientType.slice(1);
193
+ return new Error(`MCP Client Compatibility Issue (${clientName}): ${originalError.message}. ` +
194
+ `This may be due to differences in how ${clientName}-based clients handle MCP protocol. ` +
195
+ `Please ensure your client supports the MCP protocol version 2024-11-05 or later.`);
196
+ }
197
+ /**
198
+ * Log client compatibility information for debugging
199
+ */
200
+ export function logClientCompatibilityInfo(clientType, toolCount, clientInfo) {
201
+ console.log(`[MCP Compatibility] Detected LLM model type: ${clientType}`);
202
+ console.log(`[MCP Compatibility] Serving ${toolCount} tools with ${clientType}-compatible schemas`);
203
+ if (clientInfo) {
204
+ console.log(`[MCP Compatibility] Client details:`, {
205
+ name: clientInfo.name,
206
+ version: clientInfo.version,
207
+ title: clientInfo.title
208
+ });
209
+ }
210
+ if (clientType === ClientType.GEMINI) {
211
+ console.log(`[MCP Compatibility] Applied Gemini-specific transformations: uppercase types, parameter structure adjustments`);
212
+ }
213
+ else if (clientType === ClientType.CLAUDE) {
214
+ console.log(`[MCP Compatibility] Using Claude-compatible standard JSON Schema format`);
215
+ }
216
+ else if (clientType === ClientType.OPENAI) {
217
+ console.log(`[MCP Compatibility] Using OpenAI-compatible schema format`);
218
+ }
219
+ else if (clientType === ClientType.UNKNOWN) {
220
+ console.log(`[MCP Compatibility] Using standard JSON Schema format for unknown LLM model`);
221
+ }
222
+ }
@@ -0,0 +1,171 @@
1
+ /**
2
+ * SPDX-FileCopyrightText: © 2025 Talib Kareem <taazkareem@icloud.com>
3
+ * SPDX-License-Identifier: MIT
4
+ *
5
+ * Universal Schema Compatibility for MCP Multi-LLM Support
6
+ *
7
+ * This module provides universal schema compatibility that works simultaneously
8
+ * with Claude, OpenAI, and Gemini clients without requiring client detection.
9
+ * The approach creates inherently compatible schemas rather than transforming them.
10
+ */
11
+ /**
12
+ * Create a universal schema that works across all major LLM clients
13
+ * This approach uses flexible schema definitions that are inherently compatible
14
+ * with Claude, OpenAI, and Gemini without requiring client detection
15
+ */
16
+ export function createUniversalSchema(originalSchema) {
17
+ if (!originalSchema || typeof originalSchema !== 'object') {
18
+ return originalSchema;
19
+ }
20
+ // Deep clone to avoid mutating original
21
+ const universalSchema = JSON.parse(JSON.stringify(originalSchema));
22
+ // Apply universal compatibility transformations
23
+ transformSchemaForUniversalCompatibility(universalSchema);
24
+ return universalSchema;
25
+ }
26
+ /**
27
+ * Transform a schema to be universally compatible with all LLM clients
28
+ * Uses flexible type definitions and multiple format support
29
+ */
30
+ function transformSchemaForUniversalCompatibility(schema) {
31
+ if (!schema || typeof schema !== 'object') {
32
+ return;
33
+ }
34
+ // Handle type field - make it flexible for all clients
35
+ if (schema.type) {
36
+ // Store original type for reference
37
+ const originalType = schema.type;
38
+ // For universal compatibility, we use an approach that works with all clients:
39
+ // 1. Keep the standard lowercase type (works with Claude/OpenAI)
40
+ // 2. Add format hints that Gemini can understand
41
+ // 3. Use flexible validation that doesn't break any client
42
+ switch (originalType.toLowerCase()) {
43
+ case 'string':
44
+ schema.type = 'string';
45
+ // Add format hints for better compatibility
46
+ if (!schema.format) {
47
+ schema.format = 'text';
48
+ }
49
+ break;
50
+ case 'number':
51
+ schema.type = 'number';
52
+ break;
53
+ case 'integer':
54
+ schema.type = 'integer';
55
+ break;
56
+ case 'boolean':
57
+ schema.type = 'boolean';
58
+ break;
59
+ case 'array':
60
+ schema.type = 'array';
61
+ break;
62
+ case 'object':
63
+ schema.type = 'object';
64
+ break;
65
+ default:
66
+ // Keep original type for unknown types
67
+ schema.type = originalType;
68
+ }
69
+ }
70
+ // Recursively process nested schemas
71
+ if (schema.properties) {
72
+ Object.values(schema.properties).forEach((prop) => {
73
+ transformSchemaForUniversalCompatibility(prop);
74
+ });
75
+ }
76
+ if (schema.items) {
77
+ if (Array.isArray(schema.items)) {
78
+ schema.items.forEach((item) => transformSchemaForUniversalCompatibility(item));
79
+ }
80
+ else {
81
+ transformSchemaForUniversalCompatibility(schema.items);
82
+ }
83
+ }
84
+ if (schema.additionalProperties && typeof schema.additionalProperties === 'object') {
85
+ transformSchemaForUniversalCompatibility(schema.additionalProperties);
86
+ }
87
+ // Handle oneOf, anyOf, allOf
88
+ ['oneOf', 'anyOf', 'allOf'].forEach(key => {
89
+ if (schema[key] && Array.isArray(schema[key])) {
90
+ schema[key].forEach((subSchema) => transformSchemaForUniversalCompatibility(subSchema));
91
+ }
92
+ });
93
+ }
94
+ /**
95
+ * Transform tools to use universal schema compatibility
96
+ * This replaces the old client-specific transformation approach
97
+ */
98
+ export function createUniversalTools(tools) {
99
+ return tools.map(tool => createUniversalTool(tool));
100
+ }
101
+ /**
102
+ * Transform a single tool to use universal schema compatibility
103
+ */
104
+ export function createUniversalTool(tool) {
105
+ // Deep clone to avoid mutating original
106
+ const universalTool = JSON.parse(JSON.stringify(tool));
107
+ // Apply universal schema transformation to input schema
108
+ if (universalTool.inputSchema) {
109
+ universalTool.inputSchema = createUniversalSchema(universalTool.inputSchema);
110
+ }
111
+ // Apply universal schema transformation to output schema if present
112
+ if (universalTool.outputSchema) {
113
+ universalTool.outputSchema = createUniversalSchema(universalTool.outputSchema);
114
+ }
115
+ return universalTool;
116
+ }
117
+ /**
118
+ * Enhanced schema validation that works across all LLM clients
119
+ * This ensures schemas are robust and compatible
120
+ */
121
+ export function validateUniversalSchema(schema) {
122
+ if (!schema || typeof schema !== 'object') {
123
+ return false;
124
+ }
125
+ // Check for required fields
126
+ if (schema.type && typeof schema.type !== 'string') {
127
+ return false;
128
+ }
129
+ // Validate properties structure
130
+ if (schema.properties) {
131
+ if (typeof schema.properties !== 'object') {
132
+ return false;
133
+ }
134
+ // Recursively validate nested properties
135
+ for (const prop of Object.values(schema.properties)) {
136
+ if (!validateUniversalSchema(prop)) {
137
+ return false;
138
+ }
139
+ }
140
+ }
141
+ // Validate array items
142
+ if (schema.items) {
143
+ if (Array.isArray(schema.items)) {
144
+ for (const item of schema.items) {
145
+ if (!validateUniversalSchema(item)) {
146
+ return false;
147
+ }
148
+ }
149
+ }
150
+ else if (!validateUniversalSchema(schema.items)) {
151
+ return false;
152
+ }
153
+ }
154
+ return true;
155
+ }
156
+ /**
157
+ * Log universal compatibility information for debugging
158
+ */
159
+ export function logUniversalCompatibilityInfo(toolCount) {
160
+ console.log(`[MCP Universal Compatibility] Serving ${toolCount} tools with universal schema format`);
161
+ console.log(`[MCP Universal Compatibility] Compatible with Claude, OpenAI, and Gemini clients simultaneously`);
162
+ console.log(`[MCP Universal Compatibility] No client detection required - works with all MCP clients`);
163
+ }
164
+ /**
165
+ * Create enhanced error messages for universal compatibility
166
+ */
167
+ export function createUniversalCompatibilityError(originalError) {
168
+ return new Error(`MCP Universal Compatibility Issue: ${originalError.message}. ` +
169
+ `This server uses universal schema format compatible with Claude, OpenAI, and Gemini clients. ` +
170
+ `Please ensure your client supports MCP protocol version 2024-11-05 or later.`);
171
+ }
@@ -0,0 +1,53 @@
1
+ function mapJsonTypeToTs(prop, indentLevel = 0) {
2
+ if (!prop)
3
+ return "any";
4
+ const indent = " ".repeat(indentLevel);
5
+ if (prop.type === "array") {
6
+ return `${mapJsonTypeToTs(prop.items, indentLevel)}[]`;
7
+ }
8
+ if (prop.type === "object" && prop.properties) {
9
+ const lines = ["{"];
10
+ for (const [key, value] of Object.entries(prop.properties)) {
11
+ const isRequired = prop.required?.includes(key);
12
+ const childType = mapJsonTypeToTs(value, indentLevel + 1);
13
+ const doc = value.description ? `\n${indent} /** ${value.description} */\n` : "";
14
+ lines.push(`${doc}${indent} ${key}${isRequired ? "" : "?"}: ${childType};`);
15
+ }
16
+ lines.push(`${indent}}`);
17
+ return lines.join("\n");
18
+ }
19
+ if (prop.enum) {
20
+ return prop.enum.map((e) => typeof e === 'string' ? `"${e}"` : e).join(" | ");
21
+ }
22
+ if (prop.oneOf) {
23
+ return prop.oneOf.map((sub) => mapJsonTypeToTs(sub, indentLevel)).join(" | ");
24
+ }
25
+ switch (prop.type) {
26
+ case "string": return "string";
27
+ case "number": return "number";
28
+ case "integer": return "number";
29
+ case "boolean": return "boolean";
30
+ default: return "any";
31
+ }
32
+ }
33
+ export function generateVirtualFile(tools, moduleName) {
34
+ const header = `// ClickUp SDK - ${moduleName} module
35
+ // This is a virtual file generated by the ClickUp MCP Server.
36
+ // Use these functions to interact with the ClickUp API.
37
+ import { callMCPTool } from "mcp-client"; // Abstracted client
38
+ `;
39
+ const definitions = tools.map(tool => {
40
+ const funcName = tool.name;
41
+ const interfaceName = funcName.charAt(0).toUpperCase() + funcName.slice(1) + "Args";
42
+ const schema = tool.inputSchema;
43
+ const typeDef = `export interface ${interfaceName} ${mapJsonTypeToTs(schema, 0)}`;
44
+ const docBlock = `/**
45
+ * ${tool.description?.replace(/\n/g, "\n * ") || ""}
46
+ */`;
47
+ const funcDef = `export async function ${funcName}(args: ${interfaceName}): Promise<any> {
48
+ return await callMCPTool('${funcName}', args);
49
+ }`;
50
+ return `${typeDef}\n\n${docBlock}\n${funcDef}`;
51
+ });
52
+ return [header, ...definitions].join("\n\n");
53
+ }
@@ -0,0 +1,45 @@
1
+ import { generateVirtualFile } from "./generator.js";
2
+ // Import all definitions
3
+ import { createTaskTool, updateTaskTool, moveTaskTool, duplicateTaskTool, getTaskTool, deleteTaskTool, getTasksTool, getTaskCommentsTool, createTaskCommentTool } from "../tools/task/single-operations.js";
4
+ import { attachTaskFileTool } from "../tools/task/attachments.js";
5
+ import { createBulkTasksTool, updateBulkTasksTool, moveBulkTasksTool, deleteBulkTasksTool } from "../tools/task/bulk-operations.js";
6
+ import { getTaskTimeEntriesTool, startTimeTrackingTool, stopTimeTrackingTool, addTimeEntryTool, deleteTimeEntryTool, getCurrentTimeEntryTool } from "../tools/task/time-tracking.js";
7
+ import { getWorkspaceTasksTool } from "../tools/task/workspace-operations.js";
8
+ import { createListTool, createListInFolderTool, getListTool, updateListTool, deleteListTool } from "../tools/list.js";
9
+ import { createFolderTool, getFolderTool, updateFolderTool, deleteFolderTool } from "../tools/folder.js";
10
+ import { getSpaceTagsTool, createSpaceTagTool, updateSpaceTagTool, deleteSpaceTagTool, addTagToTaskTool, removeTagFromTaskTool } from "../tools/tag.js";
11
+ import { workspaceHierarchyTool } from "../tools/workspace.js";
12
+ import { getWorkspaceMembersTool, findMemberByNameTool, resolveAssigneesTool } from "../tools/member.js";
13
+ import { createDocumentTool, getDocumentTool, listDocumentsTool, listDocumentPagesTool, getDocumentPagesTool, createDocumentPageTool, updateDocumentPageTool } from "../tools/documents.js";
14
+ const MODULES = {
15
+ "tasks": [createTaskTool, getTaskTool, updateTaskTool, deleteTaskTool, moveTaskTool, duplicateTaskTool, getTasksTool, attachTaskFileTool],
16
+ "bulk": [createBulkTasksTool, updateBulkTasksTool, moveBulkTasksTool, deleteBulkTasksTool],
17
+ "search": [getWorkspaceTasksTool],
18
+ "comments": [getTaskCommentsTool, createTaskCommentTool],
19
+ "time": [getTaskTimeEntriesTool, startTimeTrackingTool, stopTimeTrackingTool, addTimeEntryTool, deleteTimeEntryTool, getCurrentTimeEntryTool],
20
+ "lists": [createListTool, createListInFolderTool, getListTool, updateListTool, deleteListTool],
21
+ "folders": [createFolderTool, getFolderTool, updateFolderTool, deleteFolderTool],
22
+ "tags": [getSpaceTagsTool, createSpaceTagTool, updateSpaceTagTool, deleteSpaceTagTool, addTagToTaskTool, removeTagFromTaskTool],
23
+ "members": [getWorkspaceMembersTool, findMemberByNameTool, resolveAssigneesTool],
24
+ "docs": [createDocumentTool, getDocumentTool, listDocumentsTool, listDocumentPagesTool, getDocumentPagesTool, createDocumentPageTool, updateDocumentPageTool],
25
+ "workspace": [workspaceHierarchyTool]
26
+ };
27
+ export class VirtualSDKRegistry {
28
+ getResourcesList() {
29
+ return Object.keys(MODULES).map(module => ({
30
+ uri: `source://clickup/${module}.ts`,
31
+ name: `ClickUp ${module} SDK`,
32
+ description: `TypeScript definitions for ${module} operations`,
33
+ mimeType: "application/typescript"
34
+ }));
35
+ }
36
+ getResourceContent(uri) {
37
+ const url = new URL(uri);
38
+ const path = url.pathname.replace(/^\//, '');
39
+ const moduleKey = path.replace('clickup/', '').replace('.ts', '');
40
+ if (MODULES[moduleKey]) {
41
+ return generateVirtualFile(MODULES[moduleKey], moduleKey);
42
+ }
43
+ throw new Error(`Virtual file not found: ${uri}`);
44
+ }
45
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@taazkareem/clickup-mcp-server",
3
- "version": "0.8.4",
3
+ "version": "0.9.0",
4
4
  "description": "ClickUp MCP Server - Integrate ClickUp tasks with AI through Model Context Protocol",
5
5
  "type": "module",
6
6
  "main": "build/index.js",
@@ -45,7 +45,7 @@
45
45
  "project-organization"
46
46
  ],
47
47
  "author": "Talib Kareem",
48
- "license": "MIT",
48
+ "license": "UNLICENSED",
49
49
  "repository": {
50
50
  "type": "git",
51
51
  "url": "git+https://github.com/taazkareem/clickup-mcp-server.git"