@trishchuk/coolors-mcp 1.0.1 → 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.
Files changed (105) hide show
  1. package/.github/workflows/ci.yml +23 -20
  2. package/.github/workflows/deploy-docs.yml +6 -3
  3. package/.github/workflows/release.yml +11 -9
  4. package/README.md +123 -14
  5. package/dist/bin/server.js +997 -256
  6. package/dist/bin/server.js.map +1 -1
  7. package/dist/{chunk-P3ARRKLS.js → chunk-HOMDMKUY.js} +3 -1
  8. package/dist/{chunk-P3ARRKLS.js.map → chunk-HOMDMKUY.js.map} +1 -1
  9. package/dist/{chunk-IQ7NN26V.js → chunk-LHW2ZTOU.js} +14 -2
  10. package/dist/chunk-LHW2ZTOU.js.map +1 -0
  11. package/dist/color/index.js +1 -1
  12. package/dist/coolors-mcp.d.ts +4 -4
  13. package/dist/coolors-mcp.js +1 -1
  14. package/eslint.config.ts +13 -0
  15. package/jsr.json +1 -1
  16. package/package.json +16 -12
  17. package/src/bin/server.ts +13 -1
  18. package/src/color/__tests__/extract-colors.test.ts +20 -30
  19. package/src/color/apca.ts +105 -0
  20. package/src/color/color-blindness.ts +109 -0
  21. package/src/coolors-mcp.ts +1 -1
  22. package/src/session.ts +10 -2
  23. package/src/theme/matcher.ts +1 -1
  24. package/src/theme/refactor.ts +1 -1
  25. package/src/theme/types.ts +3 -0
  26. package/src/tools/__tests__/cohesion.test.ts +97 -0
  27. package/src/tools/__tests__/color-blindness.test.ts +45 -0
  28. package/src/tools/__tests__/color-conversion.test.ts +38 -0
  29. package/src/tools/__tests__/contrast-checker.test.ts +56 -0
  30. package/src/tools/__tests__/palette-export.test.ts +54 -0
  31. package/src/tools/adjust-color.tool.ts +80 -0
  32. package/src/tools/cohesion.tools.ts +380 -0
  33. package/src/tools/color-blindness.tool.ts +168 -0
  34. package/src/tools/color-conversion.tool.ts +1 -1
  35. package/src/tools/contrast-checker.tool.ts +53 -14
  36. package/src/tools/dislike-analyzer.tool.ts +41 -54
  37. package/src/tools/image-extraction.tools.ts +62 -115
  38. package/src/tools/index.ts +15 -2
  39. package/src/tools/palette-export.tool.ts +174 -0
  40. package/src/tools/palette-with-locks.tool.ts +8 -6
  41. package/src/types.ts +2 -3
  42. package/tsconfig.json +12 -2
  43. package/vitest.config.js +1 -3
  44. package/.claude/settings.local.json +0 -35
  45. package/.env +0 -2
  46. package/.mcp.json +0 -12
  47. package/CLAUDE.md +0 -201
  48. package/DOCUMENTATION.md +0 -274
  49. package/GEMINI.md +0 -54
  50. package/TOOLS_UK.md +0 -233
  51. package/demo/content_based_color.png +0 -0
  52. package/demo/music-player.html +0 -621
  53. package/demo/podcast-player.html +0 -903
  54. package/dist/chunk-IQ7NN26V.js.map +0 -1
  55. package/docs/.vitepress/cache/deps/@braintree_sanitize-url.js +0 -111
  56. package/docs/.vitepress/cache/deps/@braintree_sanitize-url.js.map +0 -7
  57. package/docs/.vitepress/cache/deps/_metadata.json +0 -127
  58. package/docs/.vitepress/cache/deps/chunk-BUSYA2B4.js +0 -12
  59. package/docs/.vitepress/cache/deps/chunk-BUSYA2B4.js.map +0 -7
  60. package/docs/.vitepress/cache/deps/chunk-JD3CXNQ6.js +0 -13614
  61. package/docs/.vitepress/cache/deps/chunk-JD3CXNQ6.js.map +0 -7
  62. package/docs/.vitepress/cache/deps/chunk-SYPOPCWC.js +0 -10698
  63. package/docs/.vitepress/cache/deps/chunk-SYPOPCWC.js.map +0 -7
  64. package/docs/.vitepress/cache/deps/cytoscape-cose-bilkent.js +0 -5609
  65. package/docs/.vitepress/cache/deps/cytoscape-cose-bilkent.js.map +0 -7
  66. package/docs/.vitepress/cache/deps/cytoscape.js +0 -36234
  67. package/docs/.vitepress/cache/deps/cytoscape.js.map +0 -7
  68. package/docs/.vitepress/cache/deps/dayjs.js +0 -507
  69. package/docs/.vitepress/cache/deps/dayjs.js.map +0 -7
  70. package/docs/.vitepress/cache/deps/debug.js +0 -512
  71. package/docs/.vitepress/cache/deps/debug.js.map +0 -7
  72. package/docs/.vitepress/cache/deps/package.json +0 -3
  73. package/docs/.vitepress/cache/deps/prismjs.js +0 -1638
  74. package/docs/.vitepress/cache/deps/prismjs.js.map +0 -7
  75. package/docs/.vitepress/cache/deps/prismjs_components_prism-bash.js +0 -235
  76. package/docs/.vitepress/cache/deps/prismjs_components_prism-bash.js.map +0 -7
  77. package/docs/.vitepress/cache/deps/prismjs_components_prism-javascript.js +0 -173
  78. package/docs/.vitepress/cache/deps/prismjs_components_prism-javascript.js.map +0 -7
  79. package/docs/.vitepress/cache/deps/prismjs_components_prism-json.js +0 -27
  80. package/docs/.vitepress/cache/deps/prismjs_components_prism-json.js.map +0 -7
  81. package/docs/.vitepress/cache/deps/prismjs_components_prism-python.js +0 -72
  82. package/docs/.vitepress/cache/deps/prismjs_components_prism-python.js.map +0 -7
  83. package/docs/.vitepress/cache/deps/prismjs_components_prism-typescript.js +0 -56
  84. package/docs/.vitepress/cache/deps/prismjs_components_prism-typescript.js.map +0 -7
  85. package/docs/.vitepress/cache/deps/prismjs_components_prism-yaml.js +0 -107
  86. package/docs/.vitepress/cache/deps/prismjs_components_prism-yaml.js.map +0 -7
  87. package/docs/.vitepress/cache/deps/vitepress___@vue_devtools-api.js +0 -5074
  88. package/docs/.vitepress/cache/deps/vitepress___@vue_devtools-api.js.map +0 -7
  89. package/docs/.vitepress/cache/deps/vitepress___@vueuse_core.js +0 -584
  90. package/docs/.vitepress/cache/deps/vitepress___@vueuse_core.js.map +0 -7
  91. package/docs/.vitepress/cache/deps/vitepress___@vueuse_integrations_useFocusTrap.js +0 -1483
  92. package/docs/.vitepress/cache/deps/vitepress___@vueuse_integrations_useFocusTrap.js.map +0 -7
  93. package/docs/.vitepress/cache/deps/vitepress___mark__js_src_vanilla__js.js +0 -1779
  94. package/docs/.vitepress/cache/deps/vitepress___mark__js_src_vanilla__js.js.map +0 -7
  95. package/docs/.vitepress/cache/deps/vitepress___minisearch.js +0 -2023
  96. package/docs/.vitepress/cache/deps/vitepress___minisearch.js.map +0 -7
  97. package/docs/.vitepress/cache/deps/vue.js +0 -344
  98. package/docs/.vitepress/cache/deps/vue.js.map +0 -7
  99. package/examples/theme-matching.md +0 -113
  100. package/mcp-config.json +0 -8
  101. package/note.md +0 -34
  102. package/research_results.md +0 -53
  103. package/src/tools/colors.ts +0 -31
  104. package/src/tools/registry.ts +0 -142
  105. package/src/tools/simple-tools.ts +0 -37
@@ -1,113 +0,0 @@
1
- # Theme Color Matching Examples
2
-
3
- ## Generate Theme CSS from Source Color
4
-
5
- Generate a complete Material Design 3 theme with CSS variables:
6
-
7
- ```bash
8
- # Using the MCP tool
9
- generate_theme_css --sourceColor "#6750a4"
10
- ```
11
-
12
- This generates:
13
-
14
- - Primary, secondary, tertiary palettes (tones 0-100)
15
- - Error, neutral, and neutral variant palettes
16
- - Semantic color mappings for light theme
17
-
18
- ## Match Legacy Colors to Theme Variables
19
-
20
- Find the closest theme variable for a legacy color:
21
-
22
- ```bash
23
- # Match a single color
24
- match_theme_color --color "#6850a0" --themeCSS ":root { --color-primary-40: #6750a4; }"
25
-
26
- # Result:
27
- # Variable: --color-primary-40
28
- # Confidence: 95%
29
- # Distance: 2.3
30
- ```
31
-
32
- ## Refactor CSS with Theme Variables
33
-
34
- Automatically replace hardcoded colors with theme variables:
35
-
36
- ### Input CSS:
37
-
38
- ```css
39
- .button {
40
- background-color: #6750a4;
41
- color: #fffbfe;
42
- border: 1px solid #79747e;
43
- }
44
- ```
45
-
46
- ### Theme CSS:
47
-
48
- ```css
49
- :root {
50
- --color-primary-40: #6750a4;
51
- --color-surface-99: #fffbfe;
52
- --color-outline-50: #79747e;
53
- }
54
- ```
55
-
56
- ### Refactored Output:
57
-
58
- ```css
59
- .button {
60
- background-color: var(--color-primary-40);
61
- color: var(--color-surface-99);
62
- border: 1px solid var(--color-outline-50);
63
- }
64
- ```
65
-
66
- ## Context-Aware Matching
67
-
68
- The matcher considers usage context for better results:
69
-
70
- - **text**: Prefers high-contrast colors
71
- - **background**: Prefers surface colors
72
- - **border**: Prefers outline colors
73
- - **shadow**: Prefers shadow colors
74
- - **accent**: Prefers primary/secondary colors
75
-
76
- ## Batch Color Matching
77
-
78
- Match multiple colors at once:
79
-
80
- ```bash
81
- match_theme_colors_batch --colors ["#6750a4", "#ba1a1a", "#ffffff"] --themeCSS "..."
82
-
83
- # Result:
84
- # #6750a4 → --color-primary-40 (100%)
85
- # #ba1a1a → --color-error-40 (100%)
86
- # #ffffff → --color-surface-100 (100%)
87
- ```
88
-
89
- ## Key Features
90
-
91
- ### HCT Color Space
92
-
93
- - Uses Google's HCT (Hue, Chroma, Tone) for perceptually uniform color matching
94
- - Better than LAB for UI applications
95
- - Tone differences guarantee specific contrast ratios
96
-
97
- ### Multi-Factor Scoring
98
-
99
- - **Perceptual Distance (60%)**: How visually similar the colors are
100
- - **Semantic Context (20%)**: Whether the color role matches the usage
101
- - **Accessibility (20%)**: Contrast ratio considerations
102
-
103
- ### Accessibility Validation
104
-
105
- - Automatic WCAG contrast checking
106
- - Warns about potential accessibility issues
107
- - Suggests alternatives when contrast is insufficient
108
-
109
- ### Material Design Integration
110
-
111
- - Generates Material Design 3 compliant themes
112
- - Supports all Material color roles
113
- - Includes tonal palettes with standard Material tones
package/mcp-config.json DELETED
@@ -1,8 +0,0 @@
1
- {
2
- "mcpServers": {
3
- "coolors-mcp": {
4
- "command": "node",
5
- "args": ["/Users/taras/www/MCP/coolors-mcp/dist/bin/server.js"]
6
- }
7
- }
8
- }
package/note.md DELETED
@@ -1,34 +0,0 @@
1
- Phase 1: Core Infrastructure
2
-
3
- - Integrate Material Color Utilities HCT system into existing codebase
4
- - Build theme variable parser for CSS custom properties
5
- - Implement HCT-based color distance calculations
6
-
7
- Phase 2: Matching Engine
8
-
9
- - Create efficient color lookup using spatial indexing (k-d tree)
10
- - Implement multi-factor scoring algorithm (perceptual + semantic +
11
- accessibility)
12
- - Add context-aware matching for different UI elements
13
-
14
- Phase 3: CSS Refactoring
15
-
16
- - Build CSS parser to extract legacy colors
17
- - Generate refactored CSS with theme variable replacements
18
- - Include confidence scores and alternative suggestions
19
-
20
- Phase 4: MCP Integration
21
-
22
- - Add new MCP tools: match_theme_color, refactor_css_colors,
23
- analyze_theme_quality
24
- - Extend existing tools to support HCT color space
25
-
26
- This approach leverages Material Color Utilities for sophisticated color
27
- science while integrating with your existing infrastructure for maximum utility
28
- in UI development.
29
-
30
- ---
31
-
32
- [material-color-utilities](researcher/material-color-utilities)
33
-
34
- https://github.com/material-foundation/material-color-utilities#readme
@@ -1,53 +0,0 @@
1
- # Research Results
2
-
3
- ## chromaticity-color-utilities
4
-
5
- Based on the search results, "chromaticity-color-utilities" seems to be a general term for libraries that provide color science calculations. There are many libraries available for different languages.
6
-
7
- For JavaScript/Node.js, some popular libraries are:
8
-
9
- - **Culori**: A comprehensive color library that supports a wide range of color spaces and difference calculations.
10
- - **Color.js**: A library for color conversion and manipulation.
11
- - **Chroma.js**: A small library for color conversions and scales.
12
-
13
- For Python, some popular libraries are:
14
-
15
- - **Colour**: A powerful color science library with a wide range of features.
16
- - **ColorPy**: A library for color calculations and visualization.
17
- - **ColorAide**: A modern color library with a focus on ease of use.
18
-
19
- The user should specify the programming language and the specific functionality they need to get a more specific recommendation.
20
-
21
- ## encodable
22
-
23
- "Encodable" is a general term in software engineering that refers to the ability of data or an object to be converted into a specific format for storage, transmission, or processing.
24
-
25
- Common types of encoding include:
26
-
27
- - **Data Serialization**: Converting data structures or object states into a format that can be stored or transmitted and reconstructed later (e.g., JSON, XML, Protocol Buffers).
28
- - **Character Encoding**: Representing text characters in a digital format (e.g., UTF-8, ASCII).
29
- - **Binary-to-Text Encoding**: Converting binary data into a text-based format (e.g., Base64, Hexadecimal).
30
- - **URL Encoding**: Converting characters in a URL into a format that can be safely transmitted.
31
-
32
- The user should provide more context on what they mean by "encodable" to get a more specific answer.
33
-
34
- ## material-color-utilities
35
-
36
- "Material Color Utilities" (MCU) is a set of color libraries developed by Material Design. It provides algorithms and utilities for generating dynamic color themes and schemes, particularly for Material You.
37
-
38
- MCU is available for various programming languages, including:
39
-
40
- - **TypeScript** (via npm): `@material/material-color-utilities`
41
- - **Dart** (via Pub.dev): `material_color_utilities`
42
- - **Rust**: `material-color-utilities`
43
-
44
- The core concepts of MCU include:
45
-
46
- - **Dynamic Color**: Generating a color palette from a single seed color, often extracted from a user's wallpaper.
47
- - **Tonal Palettes**: A set of 13 tones for each color in the palette, which provides a range of shades for different UI elements.
48
-
49
- MCU can be used to:
50
-
51
- - Create personalized color themes for applications.
52
- - Ensure color harmony and accessibility in UIs.
53
- - Implement Material You features in an application.
@@ -1,31 +0,0 @@
1
- import { formatHex, formatHsl, formatRgb, parse } from "culori";
2
- import { z } from "zod";
3
-
4
- import { ColorFormat } from "../constants.js";
5
-
6
- export const convertColor = {
7
- description: "Convert a color from one format to another",
8
- execute: async (args: { color: string; to?: ColorFormat }) => {
9
- const { color, to = ColorFormat.HEX } = args;
10
- const parsed = parse(color);
11
- if (!parsed) {
12
- throw new Error(`Invalid color: ${color}`);
13
- }
14
-
15
- switch (to) {
16
- case ColorFormat.HEX:
17
- return formatHex(parsed);
18
- case ColorFormat.HSL:
19
- return formatHsl(parsed);
20
- case ColorFormat.RGB:
21
- return formatRgb(parsed);
22
- default:
23
- throw new Error(`Invalid output format: ${to}`);
24
- }
25
- },
26
- name: "convertColor",
27
- parameters: z.object({
28
- color: z.string().describe("The color to convert"),
29
- to: z.nativeEnum(ColorFormat).optional().describe("The output format"),
30
- }),
31
- };
@@ -1,142 +0,0 @@
1
- import { Prompt, Tool } from "@modelcontextprotocol/sdk/types.js"; // Each tool definition includes its metadata, schema, prompt, and execution logic in one place.
2
- import { ZodError, ZodTypeAny } from "zod";
3
- import { zodToJsonSchema } from "zod-to-json-schema";
4
-
5
- export interface UnifiedTool {
6
- category?: "codex" | "simple" | "utility";
7
- description: string;
8
- execute: (
9
- args: Record<string, unknown>,
10
- onProgress?: (newOutput: string) => void,
11
- ) => Promise<string>;
12
-
13
- name: string;
14
-
15
- prompt?: {
16
- arguments?: Array<{
17
- description: string;
18
- name: string;
19
- required: boolean;
20
- }>;
21
- description: string;
22
- };
23
- zodSchema: ZodTypeAny;
24
- }
25
-
26
- export const toolRegistry: UnifiedTool[] = [];
27
-
28
- export async function executeTool(
29
- toolName: string,
30
- args: Record<string, unknown>,
31
- onProgress?: (newOutput: string) => void,
32
- ): Promise<string> {
33
- const tool = toolRegistry.find((t) => t.name === toolName);
34
- if (!tool) {
35
- throw new Error(`Unknown tool: ${toolName}`);
36
- }
37
- try {
38
- const validatedArgs = tool.zodSchema.parse(args);
39
- return tool.execute(validatedArgs, onProgress);
40
- } catch (error) {
41
- if (error instanceof ZodError) {
42
- const issues = error.issues
43
- .map((issue) => `${issue.path.join(".")}: ${issue.message}`)
44
- .join(", ");
45
- throw new Error(`Invalid arguments for ${toolName}: ${issues}`);
46
- }
47
- throw error;
48
- }
49
- }
50
-
51
- export function getPromptDefinitions(): Prompt[] {
52
- // Helper to get MCP Prompt definitions from registry
53
- return toolRegistry
54
- .filter((tool) => tool.prompt)
55
- .map((tool) => ({
56
- arguments:
57
- tool.prompt!.arguments || extractPromptArguments(tool.zodSchema),
58
- description: tool.prompt!.description,
59
- name: tool.name,
60
- }));
61
- }
62
-
63
- export function getPromptMessage(
64
- toolName: string,
65
- args: Record<string, unknown>,
66
- ): string {
67
- const tool = toolRegistry.find((t) => t.name === toolName);
68
- if (!tool?.prompt) {
69
- throw new Error(`No prompt defined for tool: ${toolName}`);
70
- }
71
- const paramStrings: string[] = [];
72
-
73
- if (args.prompt) {
74
- paramStrings.push(args.prompt as string);
75
- }
76
-
77
- Object.entries(args).forEach(([key, value]) => {
78
- if (
79
- key !== "prompt" &&
80
- value !== undefined &&
81
- value !== null &&
82
- value !== false
83
- ) {
84
- if (typeof value === "boolean" && value) {
85
- paramStrings.push(`[${key}]`);
86
- } else if (typeof value !== "boolean") {
87
- paramStrings.push(`(${key}: ${value})`);
88
- }
89
- }
90
- });
91
-
92
- return `Use the ${toolName} tool${paramStrings.length > 0 ? ": " + paramStrings.join(" ") : ""}`;
93
- }
94
-
95
- export function getToolDefinitions(): Tool[] {
96
- // get Tool definitions from registry
97
- return toolRegistry.map((tool) => {
98
- const raw = zodToJsonSchema(tool.zodSchema, tool.name) as {
99
- definitions?: Record<string, unknown>;
100
- properties?: Record<string, unknown>;
101
- required?: string[];
102
- };
103
- const def = (raw.definitions?.[tool.name] ?? raw) as {
104
- properties?: Record<string, unknown>;
105
- required?: string[];
106
- };
107
- const inputSchema: Tool["inputSchema"] = {
108
- properties: def.properties || {},
109
- required: def.required || [],
110
- type: "object",
111
- };
112
-
113
- return {
114
- description: tool.description,
115
- inputSchema,
116
- name: tool.name,
117
- };
118
- });
119
- }
120
-
121
- export function toolExists(toolName: string): boolean {
122
- return toolRegistry.some((t) => t.name === toolName);
123
- }
124
-
125
- function extractPromptArguments(zodSchema: ZodTypeAny): Array<{
126
- description: string;
127
- name: string;
128
- required: boolean;
129
- }> {
130
- const jsonSchema = zodToJsonSchema(zodSchema) as {
131
- properties?: Record<string, { description?: string }>;
132
- required?: string[];
133
- };
134
- const properties = jsonSchema.properties || {};
135
- const required = jsonSchema.required || [];
136
-
137
- return Object.entries(properties).map(([name, prop]) => ({
138
- description: prop.description || `${name} parameter`,
139
- name,
140
- required: required.includes(name),
141
- }));
142
- }
@@ -1,37 +0,0 @@
1
- import { z } from "zod";
2
-
3
- import { UnifiedTool } from "./registry.js";
4
-
5
- const pingArgsSchema = z.object({
6
- prompt: z.string().default("").describe("Message to echo "),
7
- });
8
-
9
- export const pingTool: UnifiedTool = {
10
- category: "simple",
11
- description: "Echo",
12
- execute: async (args) => {
13
- const message = args.prompt || args.message || "Pong!";
14
- // Return message directly to avoid cross-platform issues with echo command
15
- return message as string;
16
- },
17
- name: "ping",
18
- prompt: {
19
- description: "Echo test message with structured response.",
20
- },
21
- zodSchema: pingArgsSchema,
22
- };
23
-
24
- const helpArgsSchema = z.object({});
25
-
26
- export const helpTool: UnifiedTool = {
27
- category: "simple",
28
- description: "receive help information",
29
- execute: async () => {
30
- return "Help information for Coolors MCP:\n\nAvailable tools for color manipulation, theme generation, and CSS refactoring.\nSee documentation for details.";
31
- },
32
- name: "Help",
33
- prompt: {
34
- description: "receive help information",
35
- },
36
- zodSchema: helpArgsSchema,
37
- };