> ## Content Index
> Fetch the complete content index at: https://www.azurebrasil.cloud/llms.txt
> Use this file to discover other available public pages before exploring further.

# Modelo de contexto para design: como o GitHub Copilot usa o Figma MCP para não inventar pixel - Parte 2
- URL: https://www.azurebrasil.cloud/blog/modelo-de-contexto-para-design-como-o-github-copilot-usa-o-figma-mcp-para-nao-inventar-pixel-parte-2/
- Published: 2026-09-10T12:51:44.000Z
- Updated: 2026-09-10T13:12:21.000Z
- Author: Felipe Faria

O [Model Context Protocol](https://modelcontextprotocol.io/?ref=azurebrasil.cloud) é o padrão aberto que permite a uma ferramenta de IA como o GitHub Copilot se conectar a fontes externas de dados através de servidores dedicados, em vez de depender só do que está escrito no código ou do que o modelo já sabe de treinamento. No projeto BookStore, dois desses servidores MCP foram plugados ao GitHub Copilot: um para o [PrimeVue](https://primevue.dev/mcp/?ref=azurebrasil.cloud), que expõe a documentação de cada componente diretamente no chat, e um para o [Figma](https://www.figma.com/?ref=azurebrasil.cloud), que permite ler um frame real de design e extrair medidas, cores e textos exatos. Este artigo é a Parte 2 da série sobre a modernização do front-end do BookStore, e o foco aqui é justamente esse segundo servidor: como o GitHub Copilot usa o Figma MCP para implementar um componente Vue sem chutar um valor sequer.  
  
Tela Home: 

![](https://storage.ghost.io/c/00/52/0052dced-0017-4d07-b190-1f5c48e0ab59/content/images/2026/08/image-24.png)

Tela Books:

![](https://storage.ghost.io/c/00/52/0052dced-0017-4d07-b190-1f5c48e0ab59/content/images/2026/08/image-25.png)

Tela Authors:

![](https://storage.ghost.io/c/00/52/0052dced-0017-4d07-b190-1f5c48e0ab59/content/images/2026/08/image-26.png)

  
O motivo de isso importar é simples. Numa tarefa de UI, é fácil pedir para uma IA "fazer parecido com essa imagem" e receber de volta um componente com espaçamento aproximado, cor levemente errada e tipografia no tamanho padrão do framework. Isso funciona para um protótipo, mas não para um sistema de design real, onde 21px de border-radius e 67px de altura de cabeçalho são valores deliberados, não arredondamentos. Por isso o repositório tem uma skill dedicada só para essa etapa: a [figma-discovery](https://github.com/AzureBrasil-cloud/webinar-gh-copilot/tree/feature/module4/.github/skills/figma-discovery?ref=azurebrasil.cloud), que roda antes de qualquer linha de componente ser escrita.

Skill: figma-discovery

```javascript
---
name: figma-discovery
description: "Discovers and extracts design specs from Figma for a Vue/PrimeVue front-end. Use when: the user gives a Figma URL or node reference, asks to implement/match a design, refactor existing UI to align with the design system, or a new/changed component needs accurate spacing, color, typography or assets from Figma before coding. Parses Figma URLs, calls the Figma MCP tools, and maps raw values to the codebase's existing PrimeVue/Tailwind design-token conventions instead of raw hex/pixel values."
argument-hint: "A Figma URL or node reference, and what component/page it's for"
---

# Figma Discovery

Extracts an implementable spec from a Figma design BEFORE any component code is written or changed. Never
guess colors, spacing, or structure from a screenshot alone - always pull the real node data through the
Figma MCP server, then translate it into the codebase's existing PrimeVue + Tailwind conventions.

Output of this skill is a **discovery report**, not code. Hand it to `/primevue-component-build`.

## Required setup

- `.vscode/mcp.json` must contain the `figma-mcp` server entry:
  ```json
  "figma-mcp": { "type": "http", "url": "https://mcp.figma.com/mcp" }
  ```
  If it is missing or malformed, stop and say this is Frontend-Tooling-Specialist's responsibility - do not add it from this skill.
- The remote server requires the user to be signed into Figma and to approve the OAuth prompt in the IDE. If tool calls return an auth/permission error, ask the user to re-authenticate; never fall back to inventing values.
- Figma MCP tools used: `get_metadata`, `get_screenshot`, `get_design_context`, `get_variable_defs`, plus whatever design-system search the server exposes. Tool names are prefixed per workspace (here: `mcp_figma_mcp_ser_*`) - list the available tools rather than assuming an exact name.

## Vault touchpoints

- Run `/vault-search` for the component/page name and for prior Figma token mappings before starting, so you reuse decisions already made.
- After the implementation lands, the calling agent records the node -> component mapping and any NEW token mapping through `/vault-write`. If this skill discovers a token mapping not in the table below, say so explicitly in the report so it gets persisted.

## Procedure

1. **Parse the reference.** From `figma.com/design/:fileKey/:fileName?node-id=:nodeId`, extract `fileKey` and `nodeId`, converting `-` to `:` in the node id (`39-21141` -> `39:21141`). If only a node id was given with no file link, ask for the URL - never reuse a `fileKey` from a previous, unrelated task.
2. **Confirm the target.** Call `get_metadata` and/or `get_screenshot` for the node first, to check it is the right frame/component before pulling the full context (cheaper, catches a wrong node id early).
3. **Pull the real spec.** Call `get_design_context` for the node. Treat its output as a REFERENCE to adapt, not as final code - it knows nothing about this codebase's components, composables or token conventions.
4. **Resolve ambiguous raw values.** If a color/spacing value is not obviously a token, call `get_variable_defs` to resolve it to a named Figma variable, then map it with the table below.
5. **Check for an existing match first.** Search `ClientApp/src/components/common/` for an analogous piece (a Dialog shell, a button style, a paginator, a form field, a table). If the app already has a pattern for this UI, prefer reusing/extending the existing convention over the raw Figma pixel value. Introduce a new value only where there is a deliberate visual difference.
6. **Identify assets.** Note any image/icon that must be exported. Icons: prefer an equivalent PrimeIcon (`pi pi-*`). Real images: export and place under `Src/BookStore.Web/wwwroot/images/<page>/`, referenced by absolute URL (`/images/home/books.jpg`) - not imported through Vite.
7. **Map interaction and data.** Say which parts are static design and which are data-bound (rows, empty state, loading, error, pagination) - the data always comes from the `/api/*` endpoints via the composables, never from Figma sample content.
8. **Report the discovery** (hand-off to `/primevue-component-build`): node id + name, mapped color tokens, spacing/sizing (flagging which need Tailwind arbitrary values vs. the default scale), typography, icons/assets, which existing component(s) to mirror or extend, and which PrimeVue component + `pt` sections will carry the styling.

## Token mapping table (extend as new values appear - never leave a raw hex/px in code when a row below applies)

| Figma value observed | Use this Tailwind/PrimeVue token |
|---|---|
| `#334155` (dark slate) | `surface-700` (`bg-surface-700`, `border-surface-700`, `text-surface-700`) |
| `#1e293b` (darker slate, hover) | `surface-800` |
| `#cbd5e1` / light gray borders | `border-surface-300` |
| `#f8fafc` / very light row hover | `surface-50` / `surface-100` |
| `#ffffff` panel background | `bg-surface-0` |
| `#64748b` muted gray text | `text-muted-color` |
| primary body text (near-black slate) | `text-color` |
| Brand/primary action fill | `bg-primary` + `text-primary-contrast` (or `primaryButtonClass` from `styles/buttonStyles.ts`) |
| Icon glyphs | PrimeIcons `pi pi-*` - never inline SVG or Bootstrap Icons (`bi-*`) when an equivalent `pi-*` exists |

Recurring component-level mappings already derived from Figma (reuse, do not re-derive):

- Modal shell (rounded 21px white panel, 67px header, 3-gap footer) -> `dialogShellPt(width)` / `detailsDialogPt(width)` in `components/common/dialog/dialogStyles.ts`.
- Primary/secondary/danger action buttons -> `primaryButtonClass` / `secondaryButtonClass` / `dangerButtonClass` in `styles/buttonStyles.ts`.
- Row-action popup menu and the flat borderless paginator -> the `menuPt` / `paginatorPt` objects in `components/common/table/DataTableCommon.vue`.

## Rules

- Never fabricate Figma content - always call the MCP tools; if a call fails, say so rather than guessing values.
- Never hardcode a raw hex when a `surface-*`/`*-color` token is an exact or near match.
- Arbitrary Tailwind values (`rounded-[21px]`, `gap-1.75`, `w-[765px]`) are acceptable and already used throughout this codebase when the Figma value does not land on Tailwind's default scale - do not force a bad approximation to avoid one.
- Never copy Figma's generated code verbatim into a component - it ignores the existing composables, `pt` conventions and token utilities.
- Delete any temporary screenshot/reference asset after the implementation is verified against it.
- Always re-derive `fileKey`/`nodeId` from what the user provided in THIS task.
- In a new project, replace the token table above with that project's design-system mapping before using this skill in anger, and record it in that project's vault.

```

O servidor do Figma é declarado em `mcp.json`, junto do servidor do PrimeVue:

![](https://storage.ghost.io/c/00/52/0052dced-0017-4d07-b190-1f5c48e0ab59/content/images/2026/09/image.png)

Autenticação do MCP do lado do Figma (Perfil/Settings/Security):

![](https://storage.ghost.io/c/00/52/0052dced-0017-4d07-b190-1f5c48e0ab59/content/images/2026/09/Group-2.png)

  
Esse arquivo é só a porta de entrada. O `primevue` roda localmente via `npx`, já o `figma-mcp` é remoto, então o GitHub Copilot precisa que o usuário esteja autenticado no Figma dentro do próprio VS Code para conseguir chamar as ferramentas do servidor. Sem essa configuração, a skill de descoberta é instruída a parar e avisar que a configuração do MCP é responsabilidade do agente de tooling, em vez de tentar contornar o problema.

A skill [figma-discovery](https://github.com/AzureBrasil-cloud/webinar-gh-copilot/tree/feature/module4/.github/skills/figma-discovery?ref=azurebrasil.cloud) segue um roteiro fixo: primeiro interpreta a URL do Figma, extraindo o identificador do arquivo e o id do nó de design, depois confirma que pegou o frame certo com uma chamada mais barata (metadados ou uma captura de tela), e só então pede o contexto completo de design. Um exemplo real desse fluxo no BookStore foi a modal de confirmação de exclusão de um livro, implementada a partir do nó `58:25679` do Figma. Depois de confirmar o frame certo, o próximo passo do roteiro busca o spec completo:

1. Parse da URL do Figma (fileKey + nodeId, convertendo "-" em ":")
2. get\_metadata / get\_screenshot para confirmar o frame certo
3. get\_design\_context para extrair cor, espaçamento, tipografia
4. get\_variable\_defs para resolver variáveis nomeadas do Figma
5. Busca por um componente equivalente já existente em common/
6. Identificação de ícones/imagens a exportar
7. Mapeamento do que é estático (design) vs dinâmico (dados da API)

get\_metadata()

- Confirma rapidamente se o nó apontado é realmente o frame certo antes de gastar uma chamada mais cara.

get\_design\_context()

- Retorna a especificação completa do nó: cores, espaçamentos, tipografia e estrutura, tratada como referência a adaptar, não como código final.

get\_variable\_defs()

- Resolve um valor bruto de cor ou espaçamento para a variável nomeada correspondente no arquivo Figma, quando o valor não bate obviamente com um token já conhecido.

Imagem: Frame da modal de confirmação de exclusão de livro aberto no Figma, nó 58:25679, mostrando o painel arredondado com o ícone de aviso e os botões Cancel/Delete  
  
1 Passo: Copy link to selection

![](https://storage.ghost.io/c/00/52/0052dced-0017-4d07-b190-1f5c48e0ab59/content/images/2026/09/image-1.png)

2 Passo: Colar o link no GitHub Copilot e selecionar o agente especializado em Front-End chamado [Frontend-Specialist](https://github.com/AzureBrasil-cloud/webinar-gh-copilot/blob/feature/module4/.github/agents/frontend-specialist.agent.md?ref=azurebrasil.cloud)

![](https://storage.ghost.io/c/00/52/0052dced-0017-4d07-b190-1f5c48e0ab59/content/images/2026/09/image-3.png)

3 Passo: O Agent [Frontedn-Specialist](https://github.com/AzureBrasil-cloud/webinar-gh-copilot/blob/feature/module4/.github/agents/frontend-specialist.agent.md?ref=azurebrasil.cloud), chama as Skills ([figma-discovery](https://github.com/AzureBrasil-cloud/webinar-gh-copilot/tree/feature/module4/.github/skills/figma-discovery?ref=azurebrasil.cloud) e [primevue-component-build](https://github.com/AzureBrasil-cloud/webinar-gh-copilot/tree/feature/module4/.github/skills/primevue-component-build?ref=azurebrasil.cloud)) e verifica se já existe o componente criado dentro da pasta /common se não ele cria do zero, para que não haja duplicidade.

![](https://storage.ghost.io/c/00/52/0052dced-0017-4d07-b190-1f5c48e0ab59/content/images/2026/09/image-2.png)

O passo mais importante desse roteiro não é técnico, é de disciplina: antes de aceitar qualquer valor extraído do Figma como definitivo, a skill manda procurar primeiro por um componente equivalente já existente em `components/common/`. Isso evitou reinventar a modal do zero, porque o BookStore já tinha estabelecido, num componente de exclusão anterior, um formato de `Dialog` reutilizável. Esse padrão foi extraído para um arquivo só de estilos:

```javascript
const FORM_CONTENT_CLASS = "flex flex-col gap-[21px] px-6 py-2";
const DETAILS_CONTENT_CLASS = "flex flex-col gap-1.75 px-[21px] py-[17.5px]";

export function dialogShellPt(width: string, contentClass: string = FORM_CONTENT_CLASS) {
  return {
    root: { class: `${width} max-w-[92vw] rounded-[21px] border border-surface-300 bg-surface-0 p-0 overflow-hidden` },
    header: { class: "h-[67px] items-center justify-between pt-5 pb-4 pl-6 pr-4" },
    content: { class: contentClass },
    footer: { class: "gap-3 justify-end pb-5 pt-4 px-6" },
  };
}
```

dialogShellPt()

- Monta o objeto de passthrough (`pt`) do Dialog do PrimeVue a partir de dois valores que variam por tela, a largura do modal e a classe de conteúdo, mantendo fixos os números extraídos do Figma para o cabeçalho de 67px e o arredondamento de 21px.

Repare que nenhum desses números é arbitrário. `rounded-[21px]`, `h-[67px]` e `gap-[21px]` vieram diretamente do `get_design_context` do nó 58:25679, e como o [Tailwind CSS](https://tailwindcss.com/?ref=azurebrasil.cloud) padrão não tem uma escala que bata exatamente com 21px ou 67px, a convenção do projeto é usar valores arbitrários entre colchetes em vez de forçar uma aproximação para o valor de escala mais próximo. Essa mesma função é reaproveitada pelos diálogos de criação e edição de Livro e Autor, cada um só passando sua própria largura.

Com o shell de estilo pronto, o componente da modal de exclusão ficou assim:

```javascript
<script setup lang="ts">
import Dialog from "primevue/dialog";
import Button from "primevue/button";
import Message from "primevue/message";
import { dialogShellPt, dialogSecondaryButtonClass, dialogDangerButtonClass } from "./dialogStyles";

const props = defineProps<{
  visible: boolean;
  title: string;
  message: string;
  details: { label: string; value: string }[];
  loading?: boolean;
  error?: string | null;
}>();

const dialogPt = dialogShellPt("w-[765px]");
</script>
```

defineProps()

- Declara o contrato do componente: título, mensagem de aviso, uma lista de detalhes label/valor do registro a ser excluído, e os estados de carregamento e erro vindos da chamada à API.

dialogShellPt("w-\[765px\]")

- Aplica a largura de 765px definida no Figma para esse modal específico, reaproveitando o mesmo objeto de passthrough usado pelos outros diálogos.

O `pt` (passthrough) é o mecanismo do [PrimeVue](https://primevue.dev/?ref=azurebrasil.cloud) que permite injetar classes do Tailwind diretamente nas seções internas de um componente, como `root`, `header`, `content` e `footer`, em vez de depender de uma única classe genérica no elemento raiz. É esse recurso que torna possível reproduzir com fidelidade um espaçamento de 67px de altura de cabeçalho sem escrever CSS customizado por fora do componente.

Depois que o componente está implementado, a segunda skill entra em ação, a [primevue-component-build](https://github.com/AzureBrasil-cloud/webinar-gh-copilot/tree/feature/module4/.github/skills/primevue-component-build?ref=azurebrasil.cloud), que cuida da parte de verificação: rodar `npx vue-tsc --noEmit` para checar os tipos, depois `npm run build` para gerar o bundle final, e só então comparar o resultado renderizado contra o frame do Figma no navegador.

```javascript
npx vue-tsc --noEmit
npm run build
```

O primeiro comando roda o compilador do Vue em modo de checagem, sem gerar arquivos, pegando erros de tipo nas props e nos emits do componente. O segundo executa o build de produção do Vite, que regenera `wwwroot/dist/main.js` e `wwwroot/dist/main.css`, os únicos artefatos que o ASP.NET Core efetivamente serve.

Imagem: Navegador mostrando a modal de confirmação de exclusão de um livro já implementada, lado a lado com o frame original do Figma para comparação  
  
Imagem do figma:

![](https://storage.ghost.io/c/00/52/0052dced-0017-4d07-b190-1f5c48e0ab59/content/images/2026/09/image-6.png)

Imagem: http://localhost:5045/Books

![](https://storage.ghost.io/c/00/52/0052dced-0017-4d07-b190-1f5c48e0ab59/content/images/2026/09/image-8.png)

O resultado prático desse processo é que a modal de exclusão do BookStore não é uma aproximação visual, ela reproduz o painel de 21px de arredondamento, o cabeçalho de 67px e o rodapé com os botões Cancel e Delete exatamente como especificado no nó 58:25679, porque cada valor foi extraído do Figma via MCP e não digitado de memória. O mesmo padrão de `dialogShellPt` depois foi reaproveitado para os modais de criação de Livro e Autor, que só trocam a largura do painel (765px para Livro, 480px para Autor), mostrando como uma descoberta de design bem documentada vira um investimento que se paga em componentes futuros.

Na Parte 3 dessa série, a ideia é sair do design e entrar na memória de longo prazo do próprio GitHub Copilot, mostrando como o projeto usa um vault de documentação em Markdown para que decisões como essa (o formato do `dialogShellPt`, os nós do Figma já mapeados) não se percam entre uma sessão de chat e outra.

O código completo deste projeto está disponível no meu repositório no [GitHub](https://github.com/AzureBrasil-cloud/webinar-gh-copilot/tree/feature/module4?ref=azurebrasil.cloud).

Links e Docks:

[What is the Model Context Protocol (MCP)? - Model Context Protocol![](https://storage.ghost.io/c/00/52/0052dced-0017-4d07-b190-1f5c48e0ab59/content/images/icon/android-chrome-192x192-a21c0663-e46b-4edd-bc4c-4bd4ddf25570.png)Model Context Protocol![](https://storage.ghost.io/c/00/52/0052dced-0017-4d07-b190-1f5c48e0ab59/content/images/thumbnail/og-image-b37cd438-edee-4ef5-84de-b9f7c4b0a83e.png)](https://modelcontextprotocol.io/docs/2026-07-28/getting-started/intro?ref=azurebrasil.cloud)

[PrimeVue | Vue UI Component LibraryThe ultimate collection of design-agnostic, flexible and accessible Vue UI Components.![](https://storage.ghost.io/c/00/52/0052dced-0017-4d07-b190-1f5c48e0ab59/content/images/icon/favicon-4173dbc9-806c-4b67-9419-5e09714e2f51.png)PrimeVue![](https://storage.ghost.io/c/00/52/0052dced-0017-4d07-b190-1f5c48e0ab59/content/images/thumbnail/primevue-meta-5de5e318-730b-49e1-996e-98a6fe002403.png)](https://primevue.dev/mcp/?ref=azurebrasil.cloud)

[Figma: The collaborative canvas for design, code, and AIFigma is the canvas where design, code, and AI come together. From first idea to shipped product — go from concept to production with your whole team, in one place.![](https://storage.ghost.io/c/00/52/0052dced-0017-4d07-b190-1f5c48e0ab59/content/images/icon/favicon-4425a0d3-0e4a-4616-9ec9-e0683e85b82e.png)Figma![](https://storage.ghost.io/c/00/52/0052dced-0017-4d07-b190-1f5c48e0ab59/content/images/thumbnail/b08d37520f7d5ad8d6562975b5932dd2d9a862bb-1200x630-4200a652-fc61-4310-898c-e1adb6e9c2d7.gif)](https://www.figma.com/?ref=azurebrasil.cloud)

Não esqueça de me seguir no [LinkedIn](https://www.linkedin.com/in/flpfaria/?ref=azurebrasil.cloud) para mais conteúdos.  
Até a próxima!!!