<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: yang7206</title>
    <description>The latest articles on DEV Community by yang7206 (@yang7206).</description>
    <link>https://dev.to/yang7206</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4200626%2F96519eb9-8bdc-441c-a681-eb581bb150d2.png</url>
      <title>DEV Community: yang7206</title>
      <link>https://dev.to/yang7206</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/yang7206"/>
    <language>en</language>
    <item>
      <title>I gave my coding agent a color palette library, and stopped pasting hex codes</title>
      <dc:creator>yang7206</dc:creator>
      <pubDate>Thu, 22 Oct 2026 14:05:41 +0000</pubDate>
      <link>https://dev.to/yang7206/i-gave-my-coding-agent-a-color-palette-library-and-stopped-pasting-hex-codes-2c83</link>
      <guid>https://dev.to/yang7206/i-gave-my-coding-agent-a-color-palette-library-and-stopped-pasting-hex-codes-2c83</guid>
      <description>&lt;p&gt;I asked Claude for a color palette for a finance app last month. It gave me six hex codes. They looked right in the chat window. In the actual UI, the body text sat on a primary color at about 2.8:1 contrast, which is unreadable for anyone who isn't 20/20, and the "dark mode" surface was a greenish gray that made every card look sick.&lt;/p&gt;

&lt;p&gt;The model wasn't being lazy. It has no ruler. It can produce a hex value that "looks like" a dark teal, but it cannot compute that white text on that teal lands at 2.8:1, because nothing in the conversation tells it what the number is. Ask a better question and you get a nicer-looking guess. That's the ceiling.&lt;/p&gt;

&lt;p&gt;So I built the ruler.&lt;/p&gt;

&lt;h2&gt;
  
  
  What PaletteGet is
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://paletteget.com/" rel="noopener noreferrer"&gt;PaletteGet&lt;/a&gt; is a small site with about 90 hand-picked palettes for three surfaces: mobile apps, web, and mini programs (the WeChat-style mini app format). Each palette ships with role colors, measured WCAG contrast for the pairs that matter, and a short editor note about when to use it.&lt;/p&gt;

&lt;p&gt;The part that matters here is that it's also an MCP server, so an agent can read it directly:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"mcpServers"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"paletteget"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"url"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://paletteget-mcp.y7206062.workers.dev/mcp"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Drop that into Cursor, Claude Desktop, or any client that speaks Streamable HTTP. No API key, no sign-up, no local process.&lt;/p&gt;

&lt;h2&gt;
  
  
  Four tools, on purpose
&lt;/h2&gt;

&lt;p&gt;I kept the surface small because tool sprawl makes agents worse, not better:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;list_palettes&lt;/code&gt; filters by platform and tag&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;get_palette&lt;/code&gt; returns one palette's role colors, contrast, and the editor note&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;suggest_palette&lt;/code&gt; takes a plain-language query ("dark finance app")&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;get_css_variables&lt;/code&gt; returns paste-ready custom properties&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That's it. Four tools, read-only.&lt;/p&gt;

&lt;h2&gt;
  
  
  The conversation that convinced me
&lt;/h2&gt;

&lt;p&gt;Here is the exchange, trimmed:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Me:&lt;/strong&gt; I need a palette for a dark-mode finance app. Numbers need to be legible.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Agent:&lt;/strong&gt; &lt;em&gt;(calls &lt;code&gt;suggest_palette&lt;/code&gt; with "dark finance app")&lt;/em&gt; &lt;a href="https://paletteget.com/palette-list/app/mo-lan-ye/" rel="noopener noreferrer"&gt;Ink Blue Night&lt;/a&gt; is the closest fit, tagged for finance and analytics apps in dark mode. Background &lt;code&gt;#12161f&lt;/code&gt;. Body text &lt;code&gt;#e8ecf4&lt;/code&gt; reads at 15.29:1, AAA. The primary &lt;code&gt;#4c8df6&lt;/code&gt; sits at 5.56:1 against the background: AA for body copy, AAA for large text, so primary-colored links and icons hold up on the page. The amber accent &lt;code&gt;#f2b33d&lt;/code&gt; lands at 9.73:1, safe for prices and deltas. One catch: white on the primary measures 3.26:1, enough for large text only, so keep the button fill for big bold labels.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Read that last sentence again. The agent didn't just hand me colors, it told me &lt;em&gt;where each one is allowed&lt;/em&gt;. That distinction is what a contrast number buys you: the model stops asserting and starts measuring.&lt;/p&gt;

&lt;p&gt;Before, I'd get "here's a nice palette" and find out it was wrong after wiring it up. Now the constraint arrives with the proposal.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why not just prompt better
&lt;/h2&gt;

&lt;p&gt;Two reasons.&lt;/p&gt;

&lt;p&gt;First, arithmetic is not what LLMs are good at, and contrast is arithmetic with a specific formula (relative luminance, then a ratio). A model can approximate it and be wrong exactly often enough to hurt.&lt;/p&gt;

&lt;p&gt;Second, the failure is silent. A palette that fails contrast still looks fine to the person choosing it, because contrast failure is a property of &lt;em&gt;use&lt;/em&gt; (text on a surface at a size), not of the color swatch. You only discover it when a real paragraph lands on it.&lt;/p&gt;

&lt;h2&gt;
  
  
  The CSS shortcut
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;get_css_variables&lt;/code&gt; is the tool I use most, because it collapses two steps into one:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="c"&gt;/* Ink Blue Night */&lt;/span&gt;
&lt;span class="nd"&gt;:root&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="py"&gt;--color-primary&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#4c8df6&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="py"&gt;--color-primary-dark&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#2f6bd4&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="py"&gt;--color-primary-light&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#1e3a63&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="py"&gt;--color-secondary&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#8b7cf6&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="py"&gt;--color-accent&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#f2b33d&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="py"&gt;--color-success&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#3fbf7f&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="py"&gt;--color-warning&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#e8b341&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="py"&gt;--color-danger&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#f2685e&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="py"&gt;--color-bg&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#12161f&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="py"&gt;--color-text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#e8ecf4&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Semantic names, not &lt;code&gt;--blue-500&lt;/code&gt;. If I later swap palettes, the components don't change.&lt;/p&gt;

&lt;h2&gt;
  
  
  What this is not
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Not a generator. Roughly 90 palettes, curated, and it grows by one or two a day at most. If you want infinite procedural color, this is the wrong tool.&lt;/li&gt;
&lt;li&gt;Not a design system. It gives you color roles and contrast, not spacing, type scales, or components.&lt;/li&gt;
&lt;li&gt;Not a hosted service with an SLA. It's a read-only endpoint on a Worker.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Try it
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Endpoint: &lt;code&gt;https://paletteget-mcp.y7206062.workers.dev/mcp&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Docs: &lt;a href="https://paletteget.com/docs/" rel="noopener noreferrer"&gt;https://paletteget.com/docs/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Source: &lt;a href="https://github.com/yang7206/paletteget-mcp" rel="noopener noreferrer"&gt;https://github.com/yang7206/paletteget-mcp&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Registry: &lt;code&gt;io.github.yang7206/paletteget&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If your agent keeps inventing hex values that fall apart in the browser, give it the ruler and see what changes. Feedback welcome, especially palettes you want that aren't there.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>mcp</category>
      <category>design</category>
      <category>css</category>
    </item>
  </channel>
</rss>
