mcp-avatar-builder 0.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 (119) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +163 -0
  3. package/build/composer.d.ts +4 -0
  4. package/build/composer.d.ts.map +1 -0
  5. package/build/composer.js +65 -0
  6. package/build/composer.js.map +1 -0
  7. package/build/index.d.ts +3 -0
  8. package/build/index.d.ts.map +1 -0
  9. package/build/index.js +7 -0
  10. package/build/index.js.map +1 -0
  11. package/build/rasterizer.d.ts +2 -0
  12. package/build/rasterizer.d.ts.map +1 -0
  13. package/build/rasterizer.js +12 -0
  14. package/build/rasterizer.js.map +1 -0
  15. package/build/server.d.ts +3 -0
  16. package/build/server.d.ts.map +1 -0
  17. package/build/server.js +118 -0
  18. package/build/server.js.map +1 -0
  19. package/build/styles/chibi/index.d.ts +3 -0
  20. package/build/styles/chibi/index.d.ts.map +1 -0
  21. package/build/styles/chibi/index.js +57 -0
  22. package/build/styles/chibi/index.js.map +1 -0
  23. package/build/styles/chibi/palettes.d.ts +3 -0
  24. package/build/styles/chibi/palettes.d.ts.map +1 -0
  25. package/build/styles/chibi/palettes.js +29 -0
  26. package/build/styles/chibi/palettes.js.map +1 -0
  27. package/build/styles/chibi/parts/accessories.d.ts +3 -0
  28. package/build/styles/chibi/parts/accessories.d.ts.map +1 -0
  29. package/build/styles/chibi/parts/accessories.js +18 -0
  30. package/build/styles/chibi/parts/accessories.js.map +1 -0
  31. package/build/styles/chibi/parts/clothing.d.ts +3 -0
  32. package/build/styles/chibi/parts/clothing.d.ts.map +1 -0
  33. package/build/styles/chibi/parts/clothing.js +21 -0
  34. package/build/styles/chibi/parts/clothing.js.map +1 -0
  35. package/build/styles/chibi/parts/eyebrows.d.ts +3 -0
  36. package/build/styles/chibi/parts/eyebrows.d.ts.map +1 -0
  37. package/build/styles/chibi/parts/eyebrows.js +15 -0
  38. package/build/styles/chibi/parts/eyebrows.js.map +1 -0
  39. package/build/styles/chibi/parts/eyes.d.ts +3 -0
  40. package/build/styles/chibi/parts/eyes.d.ts.map +1 -0
  41. package/build/styles/chibi/parts/eyes.js +29 -0
  42. package/build/styles/chibi/parts/eyes.js.map +1 -0
  43. package/build/styles/chibi/parts/hair.d.ts +4 -0
  44. package/build/styles/chibi/parts/hair.d.ts.map +1 -0
  45. package/build/styles/chibi/parts/hair.js +29 -0
  46. package/build/styles/chibi/parts/hair.js.map +1 -0
  47. package/build/styles/chibi/parts/head.d.ts +3 -0
  48. package/build/styles/chibi/parts/head.d.ts.map +1 -0
  49. package/build/styles/chibi/parts/head.js +15 -0
  50. package/build/styles/chibi/parts/head.js.map +1 -0
  51. package/build/styles/chibi/parts/mouth.d.ts +3 -0
  52. package/build/styles/chibi/parts/mouth.d.ts.map +1 -0
  53. package/build/styles/chibi/parts/mouth.js +12 -0
  54. package/build/styles/chibi/parts/mouth.js.map +1 -0
  55. package/build/styles/cyberpunk/defs.d.ts +3 -0
  56. package/build/styles/cyberpunk/defs.d.ts.map +1 -0
  57. package/build/styles/cyberpunk/defs.js +74 -0
  58. package/build/styles/cyberpunk/defs.js.map +1 -0
  59. package/build/styles/cyberpunk/index.d.ts +3 -0
  60. package/build/styles/cyberpunk/index.d.ts.map +1 -0
  61. package/build/styles/cyberpunk/index.js +81 -0
  62. package/build/styles/cyberpunk/index.js.map +1 -0
  63. package/build/styles/cyberpunk/palettes.d.ts +3 -0
  64. package/build/styles/cyberpunk/palettes.d.ts.map +1 -0
  65. package/build/styles/cyberpunk/palettes.js +43 -0
  66. package/build/styles/cyberpunk/palettes.js.map +1 -0
  67. package/build/styles/cyberpunk/parts/accessories.d.ts +3 -0
  68. package/build/styles/cyberpunk/parts/accessories.d.ts.map +1 -0
  69. package/build/styles/cyberpunk/parts/accessories.js +77 -0
  70. package/build/styles/cyberpunk/parts/accessories.js.map +1 -0
  71. package/build/styles/cyberpunk/parts/background.d.ts +3 -0
  72. package/build/styles/cyberpunk/parts/background.d.ts.map +1 -0
  73. package/build/styles/cyberpunk/parts/background.js +132 -0
  74. package/build/styles/cyberpunk/parts/background.js.map +1 -0
  75. package/build/styles/cyberpunk/parts/clothing.d.ts +3 -0
  76. package/build/styles/cyberpunk/parts/clothing.d.ts.map +1 -0
  77. package/build/styles/cyberpunk/parts/clothing.js +137 -0
  78. package/build/styles/cyberpunk/parts/clothing.js.map +1 -0
  79. package/build/styles/cyberpunk/parts/effects.d.ts +3 -0
  80. package/build/styles/cyberpunk/parts/effects.d.ts.map +1 -0
  81. package/build/styles/cyberpunk/parts/effects.js +33 -0
  82. package/build/styles/cyberpunk/parts/effects.js.map +1 -0
  83. package/build/styles/cyberpunk/parts/eyebrows.d.ts +3 -0
  84. package/build/styles/cyberpunk/parts/eyebrows.d.ts.map +1 -0
  85. package/build/styles/cyberpunk/parts/eyebrows.js +15 -0
  86. package/build/styles/cyberpunk/parts/eyebrows.js.map +1 -0
  87. package/build/styles/cyberpunk/parts/eyes.d.ts +3 -0
  88. package/build/styles/cyberpunk/parts/eyes.d.ts.map +1 -0
  89. package/build/styles/cyberpunk/parts/eyes.js +110 -0
  90. package/build/styles/cyberpunk/parts/eyes.js.map +1 -0
  91. package/build/styles/cyberpunk/parts/face_mods.d.ts +3 -0
  92. package/build/styles/cyberpunk/parts/face_mods.d.ts.map +1 -0
  93. package/build/styles/cyberpunk/parts/face_mods.js +105 -0
  94. package/build/styles/cyberpunk/parts/face_mods.js.map +1 -0
  95. package/build/styles/cyberpunk/parts/hair.d.ts +4 -0
  96. package/build/styles/cyberpunk/parts/hair.d.ts.map +1 -0
  97. package/build/styles/cyberpunk/parts/hair.js +175 -0
  98. package/build/styles/cyberpunk/parts/hair.js.map +1 -0
  99. package/build/styles/cyberpunk/parts/head.d.ts +3 -0
  100. package/build/styles/cyberpunk/parts/head.d.ts.map +1 -0
  101. package/build/styles/cyberpunk/parts/head.js +158 -0
  102. package/build/styles/cyberpunk/parts/head.js.map +1 -0
  103. package/build/styles/cyberpunk/parts/mouth.d.ts +3 -0
  104. package/build/styles/cyberpunk/parts/mouth.d.ts.map +1 -0
  105. package/build/styles/cyberpunk/parts/mouth.js +71 -0
  106. package/build/styles/cyberpunk/parts/mouth.js.map +1 -0
  107. package/build/styles/index.d.ts +4 -0
  108. package/build/styles/index.d.ts.map +1 -0
  109. package/build/styles/index.js +15 -0
  110. package/build/styles/index.js.map +1 -0
  111. package/build/styles/style.d.ts +15 -0
  112. package/build/styles/style.d.ts.map +1 -0
  113. package/build/styles/style.js +2 -0
  114. package/build/styles/style.js.map +1 -0
  115. package/build/types.d.ts +37 -0
  116. package/build/types.d.ts.map +1 -0
  117. package/build/types.js +2 -0
  118. package/build/types.js.map +1 -0
  119. package/package.json +40 -0
@@ -0,0 +1,175 @@
1
+ // hair_back renders behind the head
2
+ export const backVariants = {
3
+ mohawk: (c) => `
4
+ <!-- Mohawk back — tall swept ridge -->
5
+ <path d="
6
+ M185,85 Q190,40 200,25 Q210,40 215,85
7
+ Q220,80 218,95
8
+ L200,90
9
+ L182,95
10
+ Q180,80 185,85Z
11
+ " fill="${c.hair}" />
12
+ <path d="
13
+ M185,85 Q190,40 200,25 Q210,40 215,85
14
+ Q220,80 218,95 L200,90 L182,95 Q180,80 185,85Z
15
+ " fill="url(#gradient-hair-sheen)" />
16
+ `,
17
+ undercut: (c) => `
18
+ <!-- Undercut back — short sides, volume on top -->
19
+ <path d="
20
+ M145,140 Q142,120 148,105 Q160,90 200,85 Q240,90 252,105
21
+ Q258,120 255,140 L260,170 Q260,180 255,185
22
+ L145,185 Q140,180 140,170Z
23
+ " fill="${c.hair}" />
24
+ <!-- Shaved side texture (left) -->
25
+ <g stroke="${c.hair}" stroke-width="0.5" opacity="0.3">
26
+ <line x1="143" y1="145" x2="155" y2="142" />
27
+ <line x1="142" y1="152" x2="154" y2="149" />
28
+ <line x1="142" y1="159" x2="153" y2="156" />
29
+ <line x1="141" y1="166" x2="153" y2="163" />
30
+ </g>
31
+ <!-- Shaved side texture (right) -->
32
+ <g stroke="${c.hair}" stroke-width="0.5" opacity="0.3">
33
+ <line x1="245" y1="142" x2="257" y2="145" />
34
+ <line x1="246" y1="149" x2="258" y2="152" />
35
+ <line x1="247" y1="156" x2="258" y2="159" />
36
+ <line x1="247" y1="163" x2="259" y2="166" />
37
+ </g>
38
+ <path d="
39
+ M145,140 Q142,120 148,105 Q160,90 200,85 Q240,90 252,105
40
+ Q258,120 255,140 L260,170 Q260,180 255,185
41
+ L145,185 Q140,180 140,170Z
42
+ " fill="url(#gradient-hair-sheen)" />
43
+ `,
44
+ wired: (c) => {
45
+ const neon = c.neon ?? "#00E5FF";
46
+ return `
47
+ <!-- Wired hair back — cables and strands -->
48
+ <path d="
49
+ M148,120 Q145,100 155,90 Q175,78 200,75 Q225,78 245,90
50
+ Q255,100 252,120
51
+ L258,160 Q260,175 255,185
52
+ L145,185 Q140,175 142,160Z
53
+ " fill="${c.hair}" />
54
+ <path d="
55
+ M148,120 Q145,100 155,90 Q175,78 200,75 Q225,78 245,90
56
+ Q255,100 252,120
57
+ L258,160 Q260,175 255,185
58
+ L145,185 Q140,175 142,160Z
59
+ " fill="url(#gradient-hair-sheen)" />
60
+ <!-- Neon wire strands -->
61
+ <g stroke="${neon}" stroke-width="1" fill="none" opacity="0.4">
62
+ <path d="M160,90 Q155,120 150,170 Q148,190 140,210" />
63
+ <path d="M240,90 Q245,120 250,170 Q252,190 260,210" />
64
+ <path d="M170,82 Q162,130 155,185 Q150,200 145,220" />
65
+ </g>
66
+ <!-- Wire glow -->
67
+ <g stroke="${neon}" stroke-width="3" fill="none" opacity="0.08">
68
+ <path d="M160,90 Q155,120 150,170 Q148,190 140,210" />
69
+ <path d="M240,90 Q245,120 250,170 Q252,190 260,210" />
70
+ </g>
71
+ `;
72
+ },
73
+ shaved: (c) => `
74
+ <!-- Shaved/buzz cut back — minimal, shows scalp -->
75
+ <path d="
76
+ M142,170 Q140,125 150,100 Q165,85 200,82 Q235,85 250,100
77
+ Q260,125 258,170
78
+ L260,175 Q260,180 255,182
79
+ L145,182 Q140,180 140,175Z
80
+ " fill="${c.hair}" opacity="0.4" />
81
+ <!-- Stubble texture -->
82
+ <g fill="${c.hair}" opacity="0.15">
83
+ <circle cx="160" cy="110" r="0.8" />
84
+ <circle cx="170" cy="105" r="0.8" />
85
+ <circle cx="180" cy="100" r="0.8" />
86
+ <circle cx="190" cy="98" r="0.8" />
87
+ <circle cx="200" cy="97" r="0.8" />
88
+ <circle cx="210" cy="98" r="0.8" />
89
+ <circle cx="220" cy="100" r="0.8" />
90
+ <circle cx="230" cy="105" r="0.8" />
91
+ <circle cx="240" cy="110" r="0.8" />
92
+ <circle cx="165" cy="120" r="0.8" />
93
+ <circle cx="185" cy="115" r="0.8" />
94
+ <circle cx="215" cy="115" r="0.8" />
95
+ <circle cx="235" cy="120" r="0.8" />
96
+ </g>
97
+ `,
98
+ };
99
+ // hair_front renders on top of everything
100
+ export const frontVariants = {
101
+ mohawk: (c) => {
102
+ const neon = c.neon ?? "#00E5FF";
103
+ return `
104
+ <!-- Mohawk front — dramatic ridge -->
105
+ <path d="
106
+ M180,100 Q185,55 190,35 Q195,20 200,15
107
+ Q205,20 210,35 Q215,55 220,100
108
+ L218,105 Q200,98 182,105Z
109
+ " fill="${c.hair}" />
110
+ <!-- Hair strand detail -->
111
+ <path d="M192,35 Q197,50 195,80" stroke="${c.hair}" stroke-width="2" fill="none" opacity="0.3" />
112
+ <path d="M208,35 Q203,50 205,80" stroke="${c.hair}" stroke-width="2" fill="none" opacity="0.3" />
113
+ <!-- Neon tip highlight -->
114
+ <path d="M195,20 Q200,12 205,20" stroke="${neon}" stroke-width="1" fill="none" opacity="0.3" />
115
+ <!-- Sheen -->
116
+ <path d="
117
+ M180,100 Q185,55 190,35 Q195,20 200,15
118
+ Q205,20 210,35 Q215,55 220,100
119
+ L218,105 Q200,98 182,105Z
120
+ " fill="url(#gradient-hair-sheen)" />
121
+ `;
122
+ },
123
+ undercut: (c) => `
124
+ <!-- Undercut front — swept volume -->
125
+ <path d="
126
+ M150,140 Q148,115 155,100 Q168,88 200,84 Q232,88 245,100
127
+ Q252,115 250,140
128
+ L248,138 Q240,120 220,112 Q200,108 180,112 Q160,120 152,138Z
129
+ " fill="${c.hair}" />
130
+ <!-- Swept fringe -->
131
+ <path d="
132
+ M155,135 Q160,105 175,95 Q190,88 200,87
133
+ Q210,88 225,95 Q240,105 245,135
134
+ L240,130 Q232,108 215,100 Q200,96 185,100 Q168,108 160,130Z
135
+ " fill="${c.hair}" />
136
+ <path d="
137
+ M155,135 Q160,105 175,95 Q190,88 200,87
138
+ Q210,88 225,95 Q240,105 245,135
139
+ L240,130 Q232,108 215,100 Q200,96 185,100 Q168,108 160,130Z
140
+ " fill="url(#gradient-hair-sheen)" />
141
+ <!-- Parting line -->
142
+ <path d="M200,87 Q198,100 195,120" stroke="#00000015" stroke-width="0.8" fill="none" />
143
+ `,
144
+ wired: (c) => {
145
+ const neon = c.neon ?? "#00E5FF";
146
+ return `
147
+ <!-- Wired front — cable-like strands -->
148
+ <path d="
149
+ M155,120 Q152,100 160,90 Q175,78 200,75
150
+ Q225,78 240,90 Q248,100 245,120
151
+ L242,115 Q235,95 215,88 Q200,84 185,88 Q165,95 158,115Z
152
+ " fill="${c.hair}" />
153
+ <path d="
154
+ M155,120 Q152,100 160,90 Q175,78 200,75
155
+ Q225,78 240,90 Q248,100 245,120
156
+ L242,115 Q235,95 215,88 Q200,84 185,88 Q165,95 158,115Z
157
+ " fill="url(#gradient-hair-sheen)" />
158
+ <!-- Front wire strands falling over forehead -->
159
+ <g stroke="${c.hair}" stroke-width="2.5" fill="none" stroke-linecap="round">
160
+ <path d="M175,85 Q168,110 165,140 Q162,160 158,175" />
161
+ <path d="M185,82 Q180,105 178,130" />
162
+ </g>
163
+ <!-- Neon wire accents -->
164
+ <g stroke="${neon}" stroke-width="0.8" fill="none" opacity="0.5">
165
+ <path d="M175,85 Q168,110 165,140 Q162,160 158,175" />
166
+ </g>
167
+ `;
168
+ },
169
+ shaved: () => `
170
+ <!-- Shaved front — minimal, just hairline definition -->
171
+ <path d="M150,130 Q155,100 170,92 Q185,86 200,84 Q215,86 230,92 Q245,100 250,130"
172
+ stroke="#00000008" stroke-width="1" fill="none" />
173
+ `,
174
+ };
175
+ //# sourceMappingURL=hair.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hair.js","sourceRoot":"","sources":["../../../../src/styles/cyberpunk/parts/hair.ts"],"names":[],"mappings":"AAEA,oCAAoC;AACpC,MAAM,CAAC,MAAM,YAAY,GAAiC;IACxD,MAAM,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC;;;;;;;;cAQH,CAAC,CAAC,IAAI;;;;;GAKjB;IAED,QAAQ,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC;;;;;;cAML,CAAC,CAAC,IAAI;;iBAEH,CAAC,CAAC,IAAI;;;;;;;iBAON,CAAC,CAAC,IAAI;;;;;;;;;;;GAWpB;IAED,KAAK,EAAE,CAAC,CAAC,EAAE,EAAE;QACX,MAAM,IAAI,GAAG,CAAC,CAAC,IAAI,IAAI,SAAS,CAAC;QACjC,OAAO;;;;;;;cAOG,CAAC,CAAC,IAAI;;;;;;;;iBAQH,IAAI;;;;;;iBAMJ,IAAI;;;;KAIhB,CAAC;IACJ,CAAC;IAED,MAAM,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC;;;;;;;cAOH,CAAC,CAAC,IAAI;;eAEL,CAAC,CAAC,IAAI;;;;;;;;;;;;;;;GAelB;CACF,CAAC;AAEF,0CAA0C;AAC1C,MAAM,CAAC,MAAM,aAAa,GAAiC;IACzD,MAAM,EAAE,CAAC,CAAC,EAAE,EAAE;QACZ,MAAM,IAAI,GAAG,CAAC,CAAC,IAAI,IAAI,SAAS,CAAC;QACjC,OAAO;;;;;;cAMG,CAAC,CAAC,IAAI;;+CAE2B,CAAC,CAAC,IAAI;+CACN,CAAC,CAAC,IAAI;;+CAEN,IAAI;;;;;;;KAO9C,CAAC;IACJ,CAAC;IAED,QAAQ,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC;;;;;;cAML,CAAC,CAAC,IAAI;;;;;;cAMN,CAAC,CAAC,IAAI;;;;;;;;GAQjB;IAED,KAAK,EAAE,CAAC,CAAC,EAAE,EAAE;QACX,MAAM,IAAI,GAAG,CAAC,CAAC,IAAI,IAAI,SAAS,CAAC;QACjC,OAAO;;;;;;cAMG,CAAC,CAAC,IAAI;;;;;;;iBAOH,CAAC,CAAC,IAAI;;;;;iBAKN,IAAI;;;KAGhB,CAAC;IACJ,CAAC;IAED,MAAM,EAAE,GAAG,EAAE,CAAC;;;;GAIb;CACF,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { PartRenderer } from "../../../types.js";
2
+ export declare const variants: Record<string, PartRenderer>;
3
+ //# sourceMappingURL=head.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"head.d.ts","sourceRoot":"","sources":["../../../../src/styles/cyberpunk/parts/head.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAEtD,eAAO,MAAM,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,YAAY,CA8JjD,CAAC"}
@@ -0,0 +1,158 @@
1
+ export const variants = {
2
+ angular: (c) => `
3
+ <!-- Neck -->
4
+ <path d="M178,300 L178,330 Q178,340 185,345 L215,345 Q222,340 222,330 L222,300"
5
+ fill="${c.skin}" />
6
+ <path d="M178,300 L178,330 Q178,340 185,345 L215,345 Q222,340 222,330 L222,300"
7
+ fill="none" stroke="#00000015" stroke-width="0.8" />
8
+ <!-- Neck shadow -->
9
+ <path d="M178,300 Q195,310 222,300 L222,308 Q195,318 178,308Z"
10
+ fill="black" opacity="0.08" />
11
+ <!-- Head base — angular jaw, sharp cheekbones -->
12
+ <path d="
13
+ M140,170
14
+ C140,115 155,90 200,85
15
+ C245,90 260,115 260,170
16
+ C260,210 258,240 250,260
17
+ C242,278 230,292 218,298
18
+ Q200,305 182,298
19
+ C170,292 158,278 150,260
20
+ C142,240 140,210 140,170Z
21
+ " fill="${c.skin}" />
22
+ <!-- Subtle skin highlight -->
23
+ <path d="
24
+ M140,170
25
+ C140,115 155,90 200,85
26
+ C245,90 260,115 260,170
27
+ C260,210 258,240 250,260
28
+ C242,278 230,292 218,298
29
+ Q200,305 182,298
30
+ C170,292 158,278 150,260
31
+ C142,240 140,210 140,170Z
32
+ " fill="url(#gradient-skin-highlight)" />
33
+ <!-- Edge stroke -->
34
+ <path d="
35
+ M140,170
36
+ C140,115 155,90 200,85
37
+ C245,90 260,115 260,170
38
+ C260,210 258,240 250,260
39
+ C242,278 230,292 218,298
40
+ Q200,305 182,298
41
+ C170,292 158,278 150,260
42
+ C142,240 140,210 140,170Z
43
+ " fill="none" stroke="#00000012" stroke-width="0.8" />
44
+ <!-- Cheekbone highlight left -->
45
+ <path d="M148,200 Q155,190 160,200 Q155,205 148,200Z" fill="white" opacity="0.06" />
46
+ <!-- Cheekbone highlight right -->
47
+ <path d="M252,200 Q245,190 240,200 Q245,205 252,200Z" fill="white" opacity="0.06" />
48
+ <!-- Nose bridge -->
49
+ <path d="M196,215 L198,240 L200,245 L202,240 L204,215" stroke="#00000015" stroke-width="0.6" fill="none" />
50
+ <!-- Nose tip -->
51
+ <ellipse cx="200" cy="245" rx="8" ry="4" fill="#00000008" />
52
+ `,
53
+ scarred: (c) => `
54
+ <!-- Neck -->
55
+ <path d="M178,300 L178,330 Q178,340 185,345 L215,345 Q222,340 222,330 L222,300"
56
+ fill="${c.skin}" />
57
+ <path d="M178,300 Q195,310 222,300 L222,308 Q195,318 178,308Z"
58
+ fill="black" opacity="0.08" />
59
+ <!-- Head base — broad and angular -->
60
+ <path d="
61
+ M138,175
62
+ C138,118 154,88 200,82
63
+ C246,88 262,118 262,175
64
+ C262,212 260,242 252,262
65
+ C244,280 232,294 220,300
66
+ Q200,308 180,300
67
+ C168,294 156,280 148,262
68
+ C140,242 138,212 138,175Z
69
+ " fill="${c.skin}" />
70
+ <path d="
71
+ M138,175
72
+ C138,118 154,88 200,82
73
+ C246,88 262,118 262,175
74
+ C262,212 260,242 252,262
75
+ C244,280 232,294 220,300
76
+ Q200,308 180,300
77
+ C168,294 156,280 148,262
78
+ C140,242 138,212 138,175Z
79
+ " fill="url(#gradient-skin-highlight)" />
80
+ <path d="
81
+ M138,175
82
+ C138,118 154,88 200,82
83
+ C246,88 262,118 262,175
84
+ C262,212 260,242 252,262
85
+ C244,280 232,294 220,300
86
+ Q200,308 180,300
87
+ C168,294 156,280 148,262
88
+ C140,242 138,212 138,175Z
89
+ " fill="none" stroke="#00000012" stroke-width="0.8" />
90
+ <!-- Scar across left eye area -->
91
+ <path d="M155,165 L165,185 L158,210 L162,225"
92
+ stroke="#00000025" stroke-width="1.5" fill="none" stroke-linecap="round" />
93
+ <path d="M155,165 L165,185 L158,210 L162,225"
94
+ stroke="${c.skin}" stroke-width="0.6" fill="none" stroke-linecap="round" opacity="0.5" />
95
+ <!-- Nose -->
96
+ <path d="M196,215 L198,240 L200,245 L202,240 L204,215" stroke="#00000015" stroke-width="0.6" fill="none" />
97
+ <ellipse cx="200" cy="245" rx="8" ry="4" fill="#00000008" />
98
+ `,
99
+ implanted: (c) => {
100
+ const accent = c.accent ?? "#4A4A5A";
101
+ return `
102
+ <!-- Neck -->
103
+ <path d="M178,300 L178,330 Q178,340 185,345 L215,345 Q222,340 222,330 L222,300"
104
+ fill="${c.skin}" />
105
+ <path d="M178,300 Q195,310 222,300 L222,308 Q195,318 178,308Z"
106
+ fill="black" opacity="0.08" />
107
+ <!-- Head base -->
108
+ <path d="
109
+ M140,172
110
+ C140,116 156,88 200,83
111
+ C244,88 260,116 260,172
112
+ C260,210 258,240 250,260
113
+ C242,278 230,292 218,298
114
+ Q200,305 182,298
115
+ C170,292 158,278 150,260
116
+ C142,240 140,210 140,172Z
117
+ " fill="${c.skin}" />
118
+ <path d="
119
+ M140,172
120
+ C140,116 156,88 200,83
121
+ C244,88 260,116 260,172
122
+ C260,210 258,240 250,260
123
+ C242,278 230,292 218,298
124
+ Q200,305 182,298
125
+ C170,292 158,278 150,260
126
+ C142,240 140,210 140,172Z
127
+ " fill="url(#gradient-skin-highlight)" />
128
+ <path d="
129
+ M140,172
130
+ C140,116 156,88 200,83
131
+ C244,88 260,116 260,172
132
+ C260,210 258,240 250,260
133
+ C242,278 230,292 218,298
134
+ Q200,305 182,298
135
+ C170,292 158,278 150,260
136
+ C142,240 140,210 140,172Z
137
+ " fill="none" stroke="#00000012" stroke-width="0.8" />
138
+ <!-- Metal plate on right temple -->
139
+ <path d="
140
+ M248,150 L258,160 L260,180 L256,200 L248,195 L245,175 L248,150Z
141
+ " fill="${accent}" />
142
+ <path d="
143
+ M248,150 L258,160 L260,180 L256,200 L248,195 L245,175 L248,150Z
144
+ " fill="url(#gradient-metal)" opacity="0.5" />
145
+ <path d="
146
+ M248,150 L258,160 L260,180 L256,200 L248,195 L245,175 L248,150Z
147
+ " fill="none" stroke="${accent}" stroke-width="0.5" opacity="0.6" />
148
+ <!-- Rivets on plate -->
149
+ <circle cx="252" cy="162" r="1.5" fill="#888898" />
150
+ <circle cx="254" cy="180" r="1.5" fill="#888898" />
151
+ <circle cx="252" cy="195" r="1.5" fill="#888898" />
152
+ <!-- Nose -->
153
+ <path d="M196,215 L198,240 L200,245 L202,240 L204,215" stroke="#00000015" stroke-width="0.6" fill="none" />
154
+ <ellipse cx="200" cy="245" rx="8" ry="4" fill="#00000008" />
155
+ `;
156
+ },
157
+ };
158
+ //# sourceMappingURL=head.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"head.js","sourceRoot":"","sources":["../../../../src/styles/cyberpunk/parts/head.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,QAAQ,GAAiC;IACpD,OAAO,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC;;;cAGJ,CAAC,CAAC,IAAI;;;;;;;;;;;;;;;;cAgBN,CAAC,CAAC,IAAI;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BjB;IAED,OAAO,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC;;;cAGJ,CAAC,CAAC,IAAI;;;;;;;;;;;;;cAaN,CAAC,CAAC,IAAI;;;;;;;;;;;;;;;;;;;;;;;;;gBAyBJ,CAAC,CAAC,IAAI;;;;GAInB;IAED,SAAS,EAAE,CAAC,CAAC,EAAE,EAAE;QACf,MAAM,MAAM,GAAG,CAAC,CAAC,MAAM,IAAI,SAAS,CAAC;QACrC,OAAO;;;cAGG,CAAC,CAAC,IAAI;;;;;;;;;;;;;cAaN,CAAC,CAAC,IAAI;;;;;;;;;;;;;;;;;;;;;;;;cAwBN,MAAM;;;;;;4BAMQ,MAAM;;;;;;;;KAQ7B,CAAC;IACJ,CAAC;CACF,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { PartRenderer } from "../../../types.js";
2
+ export declare const variants: Record<string, PartRenderer>;
3
+ //# sourceMappingURL=mouth.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mouth.d.ts","sourceRoot":"","sources":["../../../../src/styles/cyberpunk/parts/mouth.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAEtD,eAAO,MAAM,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,YAAY,CAuEjD,CAAC"}
@@ -0,0 +1,71 @@
1
+ export const variants = {
2
+ neutral: (c) => `
3
+ <!-- Lips — closed, neutral expression -->
4
+ <path d="M182,264 Q191,260 200,262 Q209,260 218,264"
5
+ stroke="#00000020" stroke-width="1.2" fill="none" stroke-linecap="round" />
6
+ <!-- Upper lip definition -->
7
+ <path d="M185,263 Q193,259 200,261 Q207,259 215,263"
8
+ fill="#00000010" />
9
+ <!-- Lower lip highlight -->
10
+ <path d="M186,265 Q200,272 214,265"
11
+ fill="white" opacity="0.04" />
12
+ <!-- Lip color tint -->
13
+ <path d="M184,264 Q200,268 216,264 Q200,270 184,264Z"
14
+ fill="${c.skin}" opacity="0.3" />
15
+ `,
16
+ respirator: (c) => {
17
+ const accent = c.accent ?? "#4A4A5A";
18
+ const neon = c.neon ?? "#00E5FF";
19
+ return `
20
+ <!-- Respirator mask covering lower face -->
21
+ <path d="
22
+ M155,245 Q158,238 175,235 Q200,230 225,235 Q242,238 245,245
23
+ L248,270 Q248,295 235,300
24
+ Q200,310 165,300
25
+ Q152,295 152,270Z
26
+ " fill="${accent}" />
27
+ <!-- Mask surface detail — gradient overlay -->
28
+ <path d="
29
+ M155,245 Q158,238 175,235 Q200,230 225,235 Q242,238 245,245
30
+ L248,270 Q248,295 235,300
31
+ Q200,310 165,300
32
+ Q152,295 152,270Z
33
+ " fill="url(#gradient-metal)" opacity="0.4" />
34
+ <!-- Ventilation grille -->
35
+ <g stroke="${accent}" stroke-width="0.8" opacity="0.6">
36
+ <line x1="185" y1="268" x2="215" y2="268" />
37
+ <line x1="183" y1="273" x2="217" y2="273" />
38
+ <line x1="185" y1="278" x2="215" y2="278" />
39
+ <line x1="183" y1="283" x2="217" y2="283" />
40
+ <line x1="185" y1="288" x2="215" y2="288" />
41
+ </g>
42
+ <!-- Filter canister left -->
43
+ <ellipse cx="158" cy="268" rx="8" ry="12" fill="${accent}" />
44
+ <ellipse cx="158" cy="268" rx="6" ry="10" fill="#333345" />
45
+ <circle cx="158" cy="268" r="3" fill="#222235" />
46
+ <!-- Filter canister right -->
47
+ <ellipse cx="242" cy="268" rx="8" ry="12" fill="${accent}" />
48
+ <ellipse cx="242" cy="268" rx="6" ry="10" fill="#333345" />
49
+ <circle cx="242" cy="268" r="3" fill="#222235" />
50
+ <!-- LED indicator -->
51
+ <circle cx="200" cy="258" r="2" fill="${neon}" opacity="0.7" />
52
+ <!-- Edge seam lines -->
53
+ <path d="M155,245 Q200,240 245,245" stroke="#00000020" stroke-width="0.5" fill="none" />
54
+ <path d="M155,260 Q200,255 245,260" stroke="#FFFFFF08" stroke-width="0.5" fill="none" />
55
+ `;
56
+ },
57
+ smirk: (c) => `
58
+ <!-- Asymmetric smirk -->
59
+ <path d="M182,264 Q193,260 200,262 Q210,261 220,258"
60
+ stroke="#00000025" stroke-width="1.4" fill="none" stroke-linecap="round" />
61
+ <!-- Lip fill -->
62
+ <path d="M184,264 Q200,267 218,260 Q200,272 184,264Z"
63
+ fill="${c.skin}" opacity="0.25" />
64
+ <!-- Lower lip -->
65
+ <path d="M186,265 Q198,272 212,266"
66
+ fill="white" opacity="0.04" />
67
+ <!-- Corner shadow (smirk side) -->
68
+ <circle cx="220" cy="259" r="1.5" fill="#00000012" />
69
+ `,
70
+ };
71
+ //# sourceMappingURL=mouth.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mouth.js","sourceRoot":"","sources":["../../../../src/styles/cyberpunk/parts/mouth.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,QAAQ,GAAiC;IACpD,OAAO,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC;;;;;;;;;;;;cAYJ,CAAC,CAAC,IAAI;GACjB;IAED,UAAU,EAAE,CAAC,CAAC,EAAE,EAAE;QAChB,MAAM,MAAM,GAAG,CAAC,CAAC,MAAM,IAAI,SAAS,CAAC;QACrC,MAAM,IAAI,GAAG,CAAC,CAAC,IAAI,IAAI,SAAS,CAAC;QACjC,OAAO;;;;;;;cAOG,MAAM;;;;;;;;;iBASH,MAAM;;;;;;;;sDAQ+B,MAAM;;;;sDAIN,MAAM;;;;4CAIhB,IAAI;;;;KAI3C,CAAC;IACJ,CAAC;IAED,KAAK,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC;;;;;;cAMF,CAAC,CAAC,IAAI;;;;;;GAMjB;CACF,CAAC"}
@@ -0,0 +1,4 @@
1
+ import type { AvatarStyle } from "./style.js";
2
+ export declare function getStyle(name: string): AvatarStyle | undefined;
3
+ export declare function listStyles(): AvatarStyle[];
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/styles/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAa9C,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW,GAAG,SAAS,CAE9D;AAED,wBAAgB,UAAU,IAAI,WAAW,EAAE,CAE1C"}
@@ -0,0 +1,15 @@
1
+ import { chibiStyle } from "./chibi/index.js";
2
+ import { cyberpunkStyle } from "./cyberpunk/index.js";
3
+ const registry = new Map();
4
+ function register(style) {
5
+ registry.set(style.name, style);
6
+ }
7
+ register(chibiStyle);
8
+ register(cyberpunkStyle);
9
+ export function getStyle(name) {
10
+ return registry.get(name);
11
+ }
12
+ export function listStyles() {
13
+ return Array.from(registry.values());
14
+ }
15
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/styles/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAEtD,MAAM,QAAQ,GAAG,IAAI,GAAG,EAAuB,CAAC;AAEhD,SAAS,QAAQ,CAAC,KAAkB;IAClC,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;AAClC,CAAC;AAED,QAAQ,CAAC,UAAU,CAAC,CAAC;AACrB,QAAQ,CAAC,cAAc,CAAC,CAAC;AAEzB,MAAM,UAAU,QAAQ,CAAC,IAAY;IACnC,OAAO,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;AAC5B,CAAC;AAED,MAAM,UAAU,UAAU;IACxB,OAAO,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC;AACvC,CAAC"}
@@ -0,0 +1,15 @@
1
+ import type { AvatarOptions, CategoryDef, PaletteDef, ResolvedColors } from "../types.js";
2
+ export interface AvatarStyle {
3
+ name: string;
4
+ meta: {
5
+ title: string;
6
+ author: string;
7
+ license: string;
8
+ };
9
+ categories: CategoryDef[];
10
+ palettes: PaletteDef;
11
+ layerOrder: string[];
12
+ viewBox: string;
13
+ render(options: AvatarOptions, colors: ResolvedColors): string;
14
+ }
15
+ //# sourceMappingURL=style.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"style.d.ts","sourceRoot":"","sources":["../../src/styles/style.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,WAAW,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAE1F,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE;QACJ,KAAK,EAAE,MAAM,CAAC;QACd,MAAM,EAAE,MAAM,CAAC;QACf,OAAO,EAAE,MAAM,CAAC;KACjB,CAAC;IACF,UAAU,EAAE,WAAW,EAAE,CAAC;IAC1B,QAAQ,EAAE,UAAU,CAAC;IACrB,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,OAAO,EAAE,aAAa,EAAE,MAAM,EAAE,cAAc,GAAG,MAAM,CAAC;CAChE"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=style.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"style.js","sourceRoot":"","sources":["../../src/styles/style.ts"],"names":[],"mappings":""}
@@ -0,0 +1,37 @@
1
+ export interface AvatarOptions {
2
+ parts?: Record<string, string>;
3
+ colors?: AvatarColors;
4
+ }
5
+ export interface AvatarColors {
6
+ skin?: string;
7
+ hair?: string;
8
+ eyes?: string;
9
+ clothing?: string;
10
+ [key: string]: string | undefined;
11
+ }
12
+ export interface CategoryDef {
13
+ name: string;
14
+ variants: string[];
15
+ default: number;
16
+ optional?: boolean;
17
+ }
18
+ export interface PaletteDef {
19
+ skin: PaletteEntry[];
20
+ hair: PaletteEntry[];
21
+ eyes: PaletteEntry[];
22
+ [key: string]: PaletteEntry[];
23
+ }
24
+ export interface PaletteEntry {
25
+ name: string;
26
+ value: string;
27
+ }
28
+ export type PartRenderer = (colors: ResolvedColors) => string;
29
+ export interface ResolvedColors {
30
+ skin: string;
31
+ hair: string;
32
+ eyes: string;
33
+ clothing: string;
34
+ [key: string]: string;
35
+ }
36
+ export type OutputFormat = "svg" | "png";
37
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,aAAa;IAC5B,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC/B,MAAM,CAAC,EAAE,YAAY,CAAC;CACvB;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAC;CACnC;AAED,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,YAAY,EAAE,CAAC;IACrB,IAAI,EAAE,YAAY,EAAE,CAAC;IACrB,IAAI,EAAE,YAAY,EAAE,CAAC;IACrB,CAAC,GAAG,EAAE,MAAM,GAAG,YAAY,EAAE,CAAC;CAC/B;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,MAAM,YAAY,GAAG,CAAC,MAAM,EAAE,cAAc,KAAK,MAAM,CAAC;AAE9D,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAC;CACvB;AAED,MAAM,MAAM,YAAY,GAAG,KAAK,GAAG,KAAK,CAAC"}
package/build/types.js ADDED
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
package/package.json ADDED
@@ -0,0 +1,40 @@
1
+ {
2
+ "name": "mcp-avatar-builder",
3
+ "version": "0.1.0",
4
+ "description": "MCP server that generates composable avatars via SVG layer composition",
5
+ "type": "module",
6
+ "bin": {
7
+ "mcp-avatar-builder": "./build/index.js"
8
+ },
9
+ "files": [
10
+ "build",
11
+ "README.md",
12
+ "LICENSE"
13
+ ],
14
+ "scripts": {
15
+ "build": "tsc",
16
+ "dev": "tsc --watch",
17
+ "start": "node build/index.js",
18
+ "lint": "tsc --noEmit",
19
+ "test": "vitest run",
20
+ "test:watch": "vitest",
21
+ "prepublishOnly": "npm run build"
22
+ },
23
+ "keywords": ["mcp", "avatar", "svg", "generator", "cyberpunk", "chibi", "profile-picture"],
24
+ "repository": {
25
+ "type": "git",
26
+ "url": "git+https://github.com/Desperado/mcp-avatar-builder.git"
27
+ },
28
+ "homepage": "https://github.com/Desperado/mcp-avatar-builder#readme",
29
+ "license": "MIT",
30
+ "dependencies": {
31
+ "@modelcontextprotocol/sdk": "^1.26.0",
32
+ "@resvg/resvg-js": "^2.6.2",
33
+ "zod": "^3.25.0"
34
+ },
35
+ "devDependencies": {
36
+ "@types/node": "^22.0.0",
37
+ "typescript": "^5.7.0",
38
+ "vitest": "^3.0.0"
39
+ }
40
+ }