@rog0x/mcp-color-tools 1.0.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.
package/README.md ADDED
@@ -0,0 +1,96 @@
1
+ # mcp-color-tools
2
+
3
+ MCP server providing color manipulation and design tools for AI agents.
4
+
5
+ ## Tools
6
+
7
+ ### color_convert
8
+
9
+ Convert a color between HEX, RGB, HSL, HSV, and CMYK. Accepts any format as input and returns all formats.
10
+
11
+ ```json
12
+ { "color": "#ff6b35" }
13
+ { "color": "rgb(255, 107, 53)" }
14
+ { "color": "hsl(16, 100%, 60%)" }
15
+ { "color": "hsv(16, 79%, 100%)" }
16
+ { "color": "cmyk(0, 58, 79, 0)" }
17
+ ```
18
+
19
+ ### palette_generate
20
+
21
+ Generate a color palette from a base color.
22
+
23
+ **Types:** complementary, analogous, triadic, split-complementary, monochromatic
24
+
25
+ ```json
26
+ { "color": "#ff6b35", "type": "triadic" }
27
+ ```
28
+
29
+ ### contrast_check
30
+
31
+ Check WCAG contrast ratio between two colors. Reports AA/AAA compliance for normal text, large text, and UI components.
32
+
33
+ ```json
34
+ { "color1": "#ffffff", "color2": "#333333" }
35
+ ```
36
+
37
+ ### color_mix
38
+
39
+ Mix, blend, lighten, darken, saturate, or desaturate colors.
40
+
41
+ ```json
42
+ { "operation": "mix", "colors": ["#ff0000", "#0000ff"], "weights": [2, 1] }
43
+ { "operation": "blend", "colors": ["#ff0000", "#0000ff"], "ratio": 0.3 }
44
+ { "operation": "lighten", "colors": ["#ff6b35"], "amount": 20 }
45
+ { "operation": "darken", "colors": ["#ff6b35"], "amount": 15 }
46
+ { "operation": "saturate", "colors": ["#888888"], "amount": 30 }
47
+ { "operation": "desaturate", "colors": ["#ff6b35"], "amount": 25 }
48
+ ```
49
+
50
+ ### css_gradient
51
+
52
+ Generate CSS gradient code with direction, stops, and browser prefixes.
53
+
54
+ ```json
55
+ {
56
+ "type": "linear",
57
+ "colors": ["#ff6b35", "#ffd700", "#00bcd4"],
58
+ "direction": "135deg"
59
+ }
60
+ ```
61
+
62
+ ```json
63
+ {
64
+ "type": "radial",
65
+ "colors": [
66
+ { "color": "#ff6b35", "position": 0 },
67
+ { "color": "#ffd700", "position": 50 },
68
+ { "color": "#00bcd4", "position": 100 }
69
+ ],
70
+ "direction": "circle at center"
71
+ }
72
+ ```
73
+
74
+ ## Setup
75
+
76
+ ```bash
77
+ npm install
78
+ npm run build
79
+ ```
80
+
81
+ ## Claude Desktop Configuration
82
+
83
+ ```json
84
+ {
85
+ "mcpServers": {
86
+ "color-tools": {
87
+ "command": "node",
88
+ "args": ["path/to/mcp-color-tools/dist/index.js"]
89
+ }
90
+ }
91
+ }
92
+ ```
93
+
94
+ ## License
95
+
96
+ MIT
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ export {};
package/dist/index.js ADDED
@@ -0,0 +1,229 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ const index_js_1 = require("@modelcontextprotocol/sdk/server/index.js");
5
+ const stdio_js_1 = require("@modelcontextprotocol/sdk/server/stdio.js");
6
+ const types_js_1 = require("@modelcontextprotocol/sdk/types.js");
7
+ const color_converter_js_1 = require("./tools/color-converter.js");
8
+ const palette_generator_js_1 = require("./tools/palette-generator.js");
9
+ const contrast_checker_js_1 = require("./tools/contrast-checker.js");
10
+ const color_mixer_js_1 = require("./tools/color-mixer.js");
11
+ const css_gradient_js_1 = require("./tools/css-gradient.js");
12
+ const server = new index_js_1.Server({
13
+ name: "mcp-color-tools",
14
+ version: "1.0.0",
15
+ }, {
16
+ capabilities: {
17
+ tools: {},
18
+ },
19
+ });
20
+ // List available tools
21
+ server.setRequestHandler(types_js_1.ListToolsRequestSchema, async () => ({
22
+ tools: [
23
+ {
24
+ name: "color_convert",
25
+ description: "Convert a color between formats: HEX, RGB, HSL, HSV, CMYK. Accepts any format as input and returns all formats.",
26
+ inputSchema: {
27
+ type: "object",
28
+ properties: {
29
+ color: {
30
+ type: "string",
31
+ description: "Color in any format: HEX (#ff0000), RGB (rgb(255,0,0)), HSL (hsl(0,100%,50%)), HSV (hsv(0,100%,100%)), CMYK (cmyk(0,100,100,0))",
32
+ },
33
+ },
34
+ required: ["color"],
35
+ },
36
+ },
37
+ {
38
+ name: "palette_generate",
39
+ description: "Generate a color palette from a base color. Types: complementary, analogous, triadic, split-complementary, monochromatic.",
40
+ inputSchema: {
41
+ type: "object",
42
+ properties: {
43
+ color: {
44
+ type: "string",
45
+ description: "Base color in any supported format",
46
+ },
47
+ type: {
48
+ type: "string",
49
+ description: "Palette type: complementary, analogous, triadic, split-complementary, monochromatic",
50
+ enum: [
51
+ "complementary",
52
+ "analogous",
53
+ "triadic",
54
+ "split-complementary",
55
+ "monochromatic",
56
+ ],
57
+ },
58
+ },
59
+ required: ["color", "type"],
60
+ },
61
+ },
62
+ {
63
+ name: "contrast_check",
64
+ description: "Check WCAG contrast ratio between two colors. Reports AA/AAA compliance for normal text, large text, and UI components.",
65
+ inputSchema: {
66
+ type: "object",
67
+ properties: {
68
+ color1: {
69
+ type: "string",
70
+ description: "First color (foreground) in any supported format",
71
+ },
72
+ color2: {
73
+ type: "string",
74
+ description: "Second color (background) in any supported format",
75
+ },
76
+ },
77
+ required: ["color1", "color2"],
78
+ },
79
+ },
80
+ {
81
+ name: "color_mix",
82
+ description: "Mix, blend, lighten, darken, saturate, or desaturate colors. For mix/blend provide 2+ colors; for lighten/darken/saturate/desaturate provide 1 color and an amount.",
83
+ inputSchema: {
84
+ type: "object",
85
+ properties: {
86
+ operation: {
87
+ type: "string",
88
+ description: "Operation: mix, blend, lighten, darken, saturate, desaturate",
89
+ enum: [
90
+ "mix",
91
+ "blend",
92
+ "lighten",
93
+ "darken",
94
+ "saturate",
95
+ "desaturate",
96
+ ],
97
+ },
98
+ colors: {
99
+ type: "array",
100
+ items: { type: "string" },
101
+ description: "Array of colors in any supported format",
102
+ },
103
+ weights: {
104
+ type: "array",
105
+ items: { type: "number" },
106
+ description: "Optional weights for mixing (same length as colors). Default: equal weights.",
107
+ },
108
+ ratio: {
109
+ type: "number",
110
+ description: "Blend ratio from 0 (first color) to 1 (second color). Default: 0.5.",
111
+ },
112
+ amount: {
113
+ type: "number",
114
+ description: "Amount for lighten/darken/saturate/desaturate (0-100). Default: 10.",
115
+ },
116
+ },
117
+ required: ["operation", "colors"],
118
+ },
119
+ },
120
+ {
121
+ name: "css_gradient",
122
+ description: "Generate CSS gradient code. Supports linear, radial, and conic gradients with direction, stops, and browser prefixes.",
123
+ inputSchema: {
124
+ type: "object",
125
+ properties: {
126
+ type: {
127
+ type: "string",
128
+ description: "Gradient type: linear, radial, conic",
129
+ enum: ["linear", "radial", "conic"],
130
+ },
131
+ colors: {
132
+ type: "array",
133
+ items: {
134
+ oneOf: [
135
+ { type: "string" },
136
+ {
137
+ type: "object",
138
+ properties: {
139
+ color: { type: "string" },
140
+ position: {
141
+ type: "number",
142
+ description: "Stop position as percentage (0-100)",
143
+ },
144
+ },
145
+ required: ["color"],
146
+ },
147
+ ],
148
+ },
149
+ description: "Array of colors (strings) or color stops ({color, position}). Minimum 2.",
150
+ },
151
+ direction: {
152
+ type: "string",
153
+ description: "Direction/shape. Linear: 'to right', '45deg'. Radial: 'circle at center', 'ellipse at top'. Conic: 'from 0deg at center'.",
154
+ },
155
+ includePrefix: {
156
+ type: "boolean",
157
+ description: "Include -webkit- browser prefix. Default: true.",
158
+ },
159
+ },
160
+ required: ["type", "colors"],
161
+ },
162
+ },
163
+ ],
164
+ }));
165
+ // Handle tool calls
166
+ server.setRequestHandler(types_js_1.CallToolRequestSchema, async (request) => {
167
+ const { name, arguments: args } = request.params;
168
+ try {
169
+ switch (name) {
170
+ case "color_convert": {
171
+ const result = (0, color_converter_js_1.convertColor)(args?.color);
172
+ return {
173
+ content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
174
+ };
175
+ }
176
+ case "palette_generate": {
177
+ const result = (0, palette_generator_js_1.generatePalette)(args?.color, args?.type);
178
+ return {
179
+ content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
180
+ };
181
+ }
182
+ case "contrast_check": {
183
+ const result = (0, contrast_checker_js_1.checkContrast)(args?.color1, args?.color2);
184
+ return {
185
+ content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
186
+ };
187
+ }
188
+ case "color_mix": {
189
+ const result = (0, color_mixer_js_1.colorMix)({
190
+ operation: args?.operation,
191
+ colors: args?.colors,
192
+ weights: args?.weights,
193
+ ratio: args?.ratio,
194
+ amount: args?.amount,
195
+ });
196
+ return {
197
+ content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
198
+ };
199
+ }
200
+ case "css_gradient": {
201
+ const result = (0, css_gradient_js_1.generateGradient)({
202
+ type: args?.type,
203
+ colors: args?.colors,
204
+ direction: args?.direction,
205
+ includePrefix: args?.includePrefix,
206
+ });
207
+ return {
208
+ content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
209
+ };
210
+ }
211
+ default:
212
+ throw new Error(`Unknown tool: ${name}`);
213
+ }
214
+ }
215
+ catch (error) {
216
+ const message = error instanceof Error ? error.message : String(error);
217
+ return {
218
+ content: [{ type: "text", text: `Error: ${message}` }],
219
+ isError: true,
220
+ };
221
+ }
222
+ });
223
+ // Start server
224
+ async function main() {
225
+ const transport = new stdio_js_1.StdioServerTransport();
226
+ await server.connect(transport);
227
+ console.error("MCP Color Tools server running on stdio");
228
+ }
229
+ main().catch(console.error);
@@ -0,0 +1,56 @@
1
+ export interface RGB {
2
+ r: number;
3
+ g: number;
4
+ b: number;
5
+ }
6
+ export interface HSL {
7
+ h: number;
8
+ s: number;
9
+ l: number;
10
+ }
11
+ export interface HSV {
12
+ h: number;
13
+ s: number;
14
+ v: number;
15
+ }
16
+ export interface CMYK {
17
+ c: number;
18
+ m: number;
19
+ y: number;
20
+ k: number;
21
+ }
22
+ export declare function rgbToHex(rgb: RGB): string;
23
+ export declare function rgbToHsl(rgb: RGB): HSL;
24
+ export declare function hslToRgb(hsl: HSL): RGB;
25
+ export declare function rgbToHsv(rgb: RGB): HSV;
26
+ export declare function hsvToRgb(hsv: HSV): RGB;
27
+ export declare function rgbToCmyk(rgb: RGB): CMYK;
28
+ export declare function cmykToRgb(cmyk: CMYK): RGB;
29
+ export declare function parseColor(input: string): RGB;
30
+ export interface ConvertResult {
31
+ hex: string;
32
+ rgb: {
33
+ r: number;
34
+ g: number;
35
+ b: number;
36
+ css: string;
37
+ };
38
+ hsl: {
39
+ h: number;
40
+ s: number;
41
+ l: number;
42
+ css: string;
43
+ };
44
+ hsv: {
45
+ h: number;
46
+ s: number;
47
+ v: number;
48
+ };
49
+ cmyk: {
50
+ c: number;
51
+ m: number;
52
+ y: number;
53
+ k: number;
54
+ };
55
+ }
56
+ export declare function convertColor(input: string): ConvertResult;
@@ -0,0 +1,269 @@
1
+ "use strict";
2
+ // Color Converter — convert between HEX, RGB, HSL, HSV, and CMYK formats.
3
+ // All color math is implemented manually without external libraries.
4
+ Object.defineProperty(exports, "__esModule", { value: true });
5
+ exports.rgbToHex = rgbToHex;
6
+ exports.rgbToHsl = rgbToHsl;
7
+ exports.hslToRgb = hslToRgb;
8
+ exports.rgbToHsv = rgbToHsv;
9
+ exports.hsvToRgb = hsvToRgb;
10
+ exports.rgbToCmyk = rgbToCmyk;
11
+ exports.cmykToRgb = cmykToRgb;
12
+ exports.parseColor = parseColor;
13
+ exports.convertColor = convertColor;
14
+ // --- Parsing ---
15
+ function parseHex(hex) {
16
+ let h = hex.replace(/^#/, "").trim();
17
+ if (h.length === 3) {
18
+ h = h[0] + h[0] + h[1] + h[1] + h[2] + h[2];
19
+ }
20
+ if (!/^[0-9a-fA-F]{6}$/.test(h)) {
21
+ throw new Error(`Invalid HEX color: ${hex}`);
22
+ }
23
+ return {
24
+ r: parseInt(h.substring(0, 2), 16),
25
+ g: parseInt(h.substring(2, 4), 16),
26
+ b: parseInt(h.substring(4, 6), 16),
27
+ };
28
+ }
29
+ function parseRgbString(str) {
30
+ const match = str.match(/rgba?\s*\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*(?:,\s*[\d.]+\s*)?\)/i);
31
+ if (!match)
32
+ throw new Error(`Invalid RGB string: ${str}`);
33
+ return {
34
+ r: clamp(parseInt(match[1]), 0, 255),
35
+ g: clamp(parseInt(match[2]), 0, 255),
36
+ b: clamp(parseInt(match[3]), 0, 255),
37
+ };
38
+ }
39
+ function parseHslString(str) {
40
+ const match = str.match(/hsla?\s*\(\s*([\d.]+)\s*,\s*([\d.]+)%?\s*,\s*([\d.]+)%?\s*(?:,\s*[\d.]+\s*)?\)/i);
41
+ if (!match)
42
+ throw new Error(`Invalid HSL string: ${str}`);
43
+ return {
44
+ h: parseFloat(match[1]) % 360,
45
+ s: clamp(parseFloat(match[2]), 0, 100),
46
+ l: clamp(parseFloat(match[3]), 0, 100),
47
+ };
48
+ }
49
+ function parseHsvString(str) {
50
+ const match = str.match(/hsv\s*\(\s*([\d.]+)\s*,\s*([\d.]+)%?\s*,\s*([\d.]+)%?\s*\)/i);
51
+ if (!match)
52
+ throw new Error(`Invalid HSV string: ${str}`);
53
+ return {
54
+ h: parseFloat(match[1]) % 360,
55
+ s: clamp(parseFloat(match[2]), 0, 100),
56
+ v: clamp(parseFloat(match[3]), 0, 100),
57
+ };
58
+ }
59
+ function parseCmykString(str) {
60
+ const match = str.match(/cmyk\s*\(\s*([\d.]+)%?\s*,\s*([\d.]+)%?\s*,\s*([\d.]+)%?\s*,\s*([\d.]+)%?\s*\)/i);
61
+ if (!match)
62
+ throw new Error(`Invalid CMYK string: ${str}`);
63
+ return {
64
+ c: clamp(parseFloat(match[1]), 0, 100),
65
+ m: clamp(parseFloat(match[2]), 0, 100),
66
+ y: clamp(parseFloat(match[3]), 0, 100),
67
+ k: clamp(parseFloat(match[4]), 0, 100),
68
+ };
69
+ }
70
+ function clamp(val, min, max) {
71
+ return Math.max(min, Math.min(max, val));
72
+ }
73
+ // --- Conversion core ---
74
+ function rgbToHex(rgb) {
75
+ const toHex = (n) => clamp(Math.round(n), 0, 255).toString(16).padStart(2, "0");
76
+ return `#${toHex(rgb.r)}${toHex(rgb.g)}${toHex(rgb.b)}`;
77
+ }
78
+ function rgbToHsl(rgb) {
79
+ const r = rgb.r / 255;
80
+ const g = rgb.g / 255;
81
+ const b = rgb.b / 255;
82
+ const max = Math.max(r, g, b);
83
+ const min = Math.min(r, g, b);
84
+ const delta = max - min;
85
+ let h = 0;
86
+ let s = 0;
87
+ const l = (max + min) / 2;
88
+ if (delta !== 0) {
89
+ s = l > 0.5 ? delta / (2 - max - min) : delta / (max + min);
90
+ if (max === r) {
91
+ h = ((g - b) / delta + (g < b ? 6 : 0)) * 60;
92
+ }
93
+ else if (max === g) {
94
+ h = ((b - r) / delta + 2) * 60;
95
+ }
96
+ else {
97
+ h = ((r - g) / delta + 4) * 60;
98
+ }
99
+ }
100
+ return {
101
+ h: round2(h),
102
+ s: round2(s * 100),
103
+ l: round2(l * 100),
104
+ };
105
+ }
106
+ function hslToRgb(hsl) {
107
+ const h = hsl.h;
108
+ const s = hsl.s / 100;
109
+ const l = hsl.l / 100;
110
+ if (s === 0) {
111
+ const v = Math.round(l * 255);
112
+ return { r: v, g: v, b: v };
113
+ }
114
+ const hueToRgb = (p, q, t) => {
115
+ if (t < 0)
116
+ t += 1;
117
+ if (t > 1)
118
+ t -= 1;
119
+ if (t < 1 / 6)
120
+ return p + (q - p) * 6 * t;
121
+ if (t < 1 / 2)
122
+ return q;
123
+ if (t < 2 / 3)
124
+ return p + (q - p) * (2 / 3 - t) * 6;
125
+ return p;
126
+ };
127
+ const q = l < 0.5 ? l * (1 + s) : l + s - l * s;
128
+ const p = 2 * l - q;
129
+ const hNorm = h / 360;
130
+ return {
131
+ r: Math.round(hueToRgb(p, q, hNorm + 1 / 3) * 255),
132
+ g: Math.round(hueToRgb(p, q, hNorm) * 255),
133
+ b: Math.round(hueToRgb(p, q, hNorm - 1 / 3) * 255),
134
+ };
135
+ }
136
+ function rgbToHsv(rgb) {
137
+ const r = rgb.r / 255;
138
+ const g = rgb.g / 255;
139
+ const b = rgb.b / 255;
140
+ const max = Math.max(r, g, b);
141
+ const min = Math.min(r, g, b);
142
+ const delta = max - min;
143
+ let h = 0;
144
+ const s = max === 0 ? 0 : delta / max;
145
+ const v = max;
146
+ if (delta !== 0) {
147
+ if (max === r) {
148
+ h = ((g - b) / delta + (g < b ? 6 : 0)) * 60;
149
+ }
150
+ else if (max === g) {
151
+ h = ((b - r) / delta + 2) * 60;
152
+ }
153
+ else {
154
+ h = ((r - g) / delta + 4) * 60;
155
+ }
156
+ }
157
+ return {
158
+ h: round2(h),
159
+ s: round2(s * 100),
160
+ v: round2(v * 100),
161
+ };
162
+ }
163
+ function hsvToRgb(hsv) {
164
+ const h = hsv.h;
165
+ const s = hsv.s / 100;
166
+ const v = hsv.v / 100;
167
+ const c = v * s;
168
+ const x = c * (1 - Math.abs(((h / 60) % 2) - 1));
169
+ const m = v - c;
170
+ let r1 = 0, g1 = 0, b1 = 0;
171
+ if (h < 60) {
172
+ r1 = c;
173
+ g1 = x;
174
+ b1 = 0;
175
+ }
176
+ else if (h < 120) {
177
+ r1 = x;
178
+ g1 = c;
179
+ b1 = 0;
180
+ }
181
+ else if (h < 180) {
182
+ r1 = 0;
183
+ g1 = c;
184
+ b1 = x;
185
+ }
186
+ else if (h < 240) {
187
+ r1 = 0;
188
+ g1 = x;
189
+ b1 = c;
190
+ }
191
+ else if (h < 300) {
192
+ r1 = x;
193
+ g1 = 0;
194
+ b1 = c;
195
+ }
196
+ else {
197
+ r1 = c;
198
+ g1 = 0;
199
+ b1 = x;
200
+ }
201
+ return {
202
+ r: Math.round((r1 + m) * 255),
203
+ g: Math.round((g1 + m) * 255),
204
+ b: Math.round((b1 + m) * 255),
205
+ };
206
+ }
207
+ function rgbToCmyk(rgb) {
208
+ const r = rgb.r / 255;
209
+ const g = rgb.g / 255;
210
+ const b = rgb.b / 255;
211
+ const k = 1 - Math.max(r, g, b);
212
+ if (k === 1) {
213
+ return { c: 0, m: 0, y: 0, k: 100 };
214
+ }
215
+ return {
216
+ c: round2(((1 - r - k) / (1 - k)) * 100),
217
+ m: round2(((1 - g - k) / (1 - k)) * 100),
218
+ y: round2(((1 - b - k) / (1 - k)) * 100),
219
+ k: round2(k * 100),
220
+ };
221
+ }
222
+ function cmykToRgb(cmyk) {
223
+ const c = cmyk.c / 100;
224
+ const m = cmyk.m / 100;
225
+ const y = cmyk.y / 100;
226
+ const k = cmyk.k / 100;
227
+ return {
228
+ r: Math.round(255 * (1 - c) * (1 - k)),
229
+ g: Math.round(255 * (1 - m) * (1 - k)),
230
+ b: Math.round(255 * (1 - y) * (1 - k)),
231
+ };
232
+ }
233
+ function round2(n) {
234
+ return Math.round(n * 100) / 100;
235
+ }
236
+ // --- Auto-detect and parse any color format ---
237
+ function parseColor(input) {
238
+ const trimmed = input.trim();
239
+ if (/^#?[0-9a-fA-F]{3}([0-9a-fA-F]{3})?$/.test(trimmed)) {
240
+ return parseHex(trimmed);
241
+ }
242
+ if (/^rgba?\s*\(/i.test(trimmed)) {
243
+ return parseRgbString(trimmed);
244
+ }
245
+ if (/^hsla?\s*\(/i.test(trimmed)) {
246
+ return hslToRgb(parseHslString(trimmed));
247
+ }
248
+ if (/^hsv\s*\(/i.test(trimmed)) {
249
+ return hsvToRgb(parseHsvString(trimmed));
250
+ }
251
+ if (/^cmyk\s*\(/i.test(trimmed)) {
252
+ return cmykToRgb(parseCmykString(trimmed));
253
+ }
254
+ throw new Error(`Cannot parse color: "${input}". Supported formats: HEX (#ff0000), RGB (rgb(255,0,0)), HSL (hsl(0,100%,50%)), HSV (hsv(0,100%,100%)), CMYK (cmyk(0,100,100,0))`);
255
+ }
256
+ function convertColor(input) {
257
+ const rgb = parseColor(input);
258
+ const hsl = rgbToHsl(rgb);
259
+ const hsv = rgbToHsv(rgb);
260
+ const cmyk = rgbToCmyk(rgb);
261
+ const hex = rgbToHex(rgb);
262
+ return {
263
+ hex,
264
+ rgb: { ...rgb, css: `rgb(${rgb.r}, ${rgb.g}, ${rgb.b})` },
265
+ hsl: { ...hsl, css: `hsl(${hsl.h}, ${hsl.s}%, ${hsl.l}%)` },
266
+ hsv,
267
+ cmyk,
268
+ };
269
+ }
@@ -0,0 +1,22 @@
1
+ import { type RGB, type HSL } from "./color-converter.js";
2
+ interface MixedColor {
3
+ hex: string;
4
+ rgb: RGB;
5
+ hsl: HSL;
6
+ }
7
+ export declare function mixColors(colors: string[], weights?: number[]): MixedColor;
8
+ export declare function blendColors(color1: string, color2: string, ratio?: number): MixedColor;
9
+ export declare function lightenColor(color: string, amount?: number): MixedColor;
10
+ export declare function darkenColor(color: string, amount?: number): MixedColor;
11
+ export declare function saturateColor(color: string, amount?: number): MixedColor;
12
+ export declare function desaturateColor(color: string, amount?: number): MixedColor;
13
+ export type MixOperation = "mix" | "blend" | "lighten" | "darken" | "saturate" | "desaturate";
14
+ export interface MixRequest {
15
+ operation: MixOperation;
16
+ colors: string[];
17
+ weights?: number[];
18
+ ratio?: number;
19
+ amount?: number;
20
+ }
21
+ export declare function colorMix(req: MixRequest): MixedColor;
22
+ export {};