跪拜 Guibai
← Back to the summary

MCP Feeds AI Coding Tools Real Component Data, Not Guesswork

Will MCP Become the Standard Interface for Frontend AI Engineering?

Hello everyone! 😃

Let me start with a reality that annoys me.

It's 2026, and AI coding tools are everywhere — Cursor, Claude Code, Codex, all sorts of IDE plugins. But every time I ask one to write a business component, the conversation loops like this👇:

Image

After three or four rounds, it's faster to write it myself.

The real problem isn't that AI isn't smart enough — it's that it knows nothing about your project. It doesn't know which components your component library has, what each component's Props are, that design specs require spacing in multiples of 8px, or that your team mandates Zod for form validation. It can only guess based on public general knowledge, and what it guesses probably won't work in your project🤷‍♂️.

Then I came across MCP. Let's talk about it👇


What exactly is MCP? No hype, no bashing

MCP stands for Model Context Protocol, an open protocol by Anthropic from late 2024. In one sentence: it lets AI models connect to external data sources and tools on their own, instead of relying only on what you feed them in the chat.

Traditional AI coding flow vs. the MCP flow:

Image

What's the difference? AI changes from passively receiving what you feed it to actively going into your project to find information. You no longer need to copy-paste component documentation every time; AI will look it up itself.

The MCP architecture is simple — three roles only👇:

Image


How I plugged it into the component library

Our component library has around 60 components, each with Props type definitions, usage docs, and design specs. Previously this info was scattered across Storybook, README, and TypeScript type files, and AI couldn't reach any of it.

I spent about two days writing an MCP Server to expose this information in a structured way.

The core code isn't complex — using the official SDK @modelcontextprotocol/sdk:

// mcp-server/index.ts
import { McpServer, ResourceTemplate } from '@modelcontextprotocol/sdk/server/mcp.js';
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
import { z } from 'zod';
import { getComponentMeta, getAllComponentNames, getDesignTokens } from './loaders.js';

const server = new McpServer({
  name: 'our-component-library',
  version: '1.0.0',
});

// Resource: expose metadata for all components
server.resource(
  'component-list',
  'components://list',
  async (uri) => ({
    contents: [{
      uri: uri.href,
      mimeType: 'application/json',
      text: JSON.stringify(getAllComponentNames()),
    }],
  })
);

// Resource template: query details by component name
server.resource(
  'component-detail',
  new ResourceTemplate('components://detail/{name}', { list: undefined }),
  async (uri, { name }) => {
    const meta = await getComponentMeta(name as string);
    if (!meta) {
      return { contents: [{ uri: uri.href, text: `Component ${name} does not exist` }] };
    }
    return {
      contents: [{
        uri: uri.href,
        mimeType: 'application/json',
        text: JSON.stringify({
          name: meta.name,
          description: meta.description,
          props: meta.props,        // full Props type definitions
          slots: meta.slots,        // slot definitions
          events: meta.events,      // event definitions
          examples: meta.examples,  // 3-5 real usage examples
          designNotes: meta.designNotes, // design spec notes
        }),
      }],
    };
  }
);

// Resource: design tokens (spacing, colors, font sizes, etc.)
server.resource(
  'design-tokens',
  'design://tokens',
  async (uri) => ({
    contents: [{
      uri: uri.href,
      mimeType: 'application/json',
      text: JSON.stringify(getDesignTokens()),
    }],
  })
);

Then two Tools were added so AI can not only read but act:

// Tool: recommend which components to use based on a requirement description
server.tool(
  'recommend-components',
  'Recommend component combinations based on a natural-language business requirement',
  { requirement: z.string().describe('Natural language description of the business need') },
  async ({ requirement }) => {
    const allComponents = getAllComponentNames();
    // Simple keyword matching based on component descriptions and tags
    // For production, vector search can be integrated
    const recommendations = matchComponents(requirement, allComponents);
    return {
      content: [{
        type: 'text',
        text: JSON.stringify(recommendations, null, 2),
      }],
    };
  }
);

// Tool: validate whether a snippet correctly uses component Props
server.tool(
  'validate-component-usage',
  'Validate whether the Props usage in a code snippet conforms to type definitions',
  { code: z.string().describe('Code snippet containing component calls') },
  async ({ code }) => {
    const issues = validateComponentUsage(code);
    return {
      content: [{
        type: 'text',
        text: issues.length === 0
          ? 'All component usages conform to the specs'
          : `Found ${issues.length} issue(s):\n${issues.map(i => `- ${i}`).join('\n')}`,
      }],
    };
  }
);

// Start
const transport = new StdioServerTransport();
await server.connect(transport);

Finally, register this Server in Claude Code's config file:

{
  "mcpServers": {
    "our-components": {
      "command": "npx",
      "args": ["tsx", "/path/to/mcp-server/index.ts"]
    }
  }
}

Before and after comparison

I tried the same requirement both ways: write a product card component with an image, a title, a price, and an add-to-cart button.

Before MCP

// AI-generated code — all guesses
const ProductCard = ({ product }) => (
  <div className="card" style={{ border: '1px solid #eee', padding: 16 }}>
    <img src={product.image} alt={product.title} style={{ width: '100%' }} />
    <h3>{product.title}</h3>
    <span className="price">¥{product.price}</span>
    <button onClick={() => addToCart(product.id)}>Add to cart</button>
  </div>
);

It used no project components at all — just raw HTML elements with inline styles. Props had no type definitions, addToCart came out of nowhere, and price formatting was hardcoded.

After MCP

Claude automatically called the recommend-components tool before generating code, then queried the detailed Props of the recommended components one by one. The final output:

import { AppCard } from '@/components/AppCard';
import { LazyImage } from '@/components/LazyImage';
import { PriceDisplay } from '@/components/PriceDisplay';
import { ActionButton } from '@/components/ActionButton';
import type { Product } from '@/types/product';

interface ProductCardProps {
  product: Product;
  onAddToCart: (productId: string) => void;
}

export function ProductCard({ product, onAddToCart }: ProductCardProps) {
  return (
    <AppCard variant="outlined" padding="md">
      <LazyImage
        src={product.coverUrl}
        alt={product.title}
        aspectRatio="4:3"
        fallback="/images/product-placeholder.png"
      />
      <AppCard.Body>
        <AppCard.Title level={3}>{product.title}</AppCard.Title>
        <PriceDisplay
          amount={product.price}
          currency={product.currency}
          originalAmount={product.originalPrice}
        />
      </AppCard.Body>
      <AppCard.Footer>
        <ActionButton
          variant="primary"
          size="sm"
          onClick={() => onAddToCart(product.id)}
        >
          Add to cart
        </ActionButton>
      </AppCard.Footer>
    </AppCard>
  );
}

Every component name and every Prop value came from the real definitions in our library. AppCard's variant only uses outlined as we defined it, LazyImage carries fallback and aspectRatio, PriceDisplay handles original price and currency — all of this was discovered through MCP, not guessed.


Some problems with MCP that remain

After two months of use, my verdict on MCP is: it's genuinely useful, but it's still a way off from being a standard interface. A few issues you need to know:

Image

Every Resource and Tool exposed by an MCP Server is accessible to the AI. If you accidentally expose database connection strings, internal API keys, or customer data through MCP, the AI conversation could be logged or transmitted to the cloud.

My rule is: the MCP Server only exposes public development specs and type definitions, never runtime data, keys, or internal interfaces. Treat it as a read-only documentation server — don't give it write capability or sensitive data access.

Maintenance cost of component metadata

The effect of MCP depends entirely on the quality of the metadata you expose. If your component docs are stale, Props descriptions are vague, or usage examples are wrong, the AI-generated code will inherit those errors.

Our current approach is to extract metadata automatically from TypeScript type definitions and JSDoc comments, so we don't manually maintain a separate doc layer:

// loaders.ts — auto-extract component metadata from source
import { Project } from 'ts-morph';

const project = new Project({
  tsConfigFilePath: './tsconfig.json',
});

export function getComponentMeta(name: string) {
  const sourceFile = project.getSourceFile(`src/components/${name}/index.tsx`);
  if (!sourceFile) return null;

  const propsInterface = sourceFile.getInterface(`${name}Props`);
  if (!propsInterface) return null;

  const props = propsInterface.getProperties().map(prop => ({
    name: prop.getName(),
    type: prop.getType().getText(),
    required: !prop.hasQuestionToken(),
    description: prop.getJsDocs().map(d => d.getDescription().trim()).join(' '),
  }));

  return { name, props, /* ... */ };
}

As long as developers keep their TypeScript types and comments up to date, the information MCP exposes is automatically accurate. No extra documentation layer needed.


Is it worth adopting now?

My judgment is straightforward:

If your team has more than 30 self-built components, its own design specs, and uses AI-assisted coding heavily day-to-day — it's worth spending two days to wire up an MCP Server. The investment is small, and it noticeably reduces the back-and-forth when AI-generated code doesn't match your project's actual specs.

If your project directly uses public component libraries like Ant Design / Element Plus, AI already has plenty of training data on them, and the marginal benefit of MCP is low.

As for whether MCP will become the standard interface for frontend AI engineering — it's too early to say. But it points a direction: whoever first structures their engineering knowledge to expose it to AI will be the first to taste the real efficiency gains from AI!

Image


If you like my article, feel free to follow my WeChat official account: 【前端技术官】.

Main topics: Frontend Architecture · AI Programming · Workplace Insights · Developer Growth

前端技术官-ErpanOmer

Scan the QR code to follow 👆

Irregular updates, no spam, only real useful content.

Comments

Top 2 of 4 from juejin.cn, machine-translated. The original thread is authoritative.

汪汪队首席上单

Are Codex and those things considered agents?

ErpanOmer

Definitely counts, yes.

wenps

Why not just add a skill instead? If the company has documentation, wouldn't generating a skill be more convenient?

ErpanOmer

That would work too.