<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Ramon Domingos Blog</title>
	<atom:link href="https://ramondomingos.com.br/feed/" rel="self" type="application/rss+xml" />
	<link>https://ramondomingos.com.br/</link>
	<description>Conteúdo sobre tecnologia e engenharia de software.</description>
	<lastBuildDate>Wed, 06 May 2026 19:13:37 +0000</lastBuildDate>
	<language>pt-BR</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=7.0</generator>

<image>
	<url>https://ramondomingos.com.br/wp-content/uploads/2023/09/cropped-Logotipo_bold_minimalista_amarelo_para_blog__1_-removebg-preview-32x32.png</url>
	<title>Ramon Domingos Blog</title>
	<link>https://ramondomingos.com.br/</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>Do Risco à Inovação: Como Transformamos a Conformidade à LGPD em Propriedade Intelectual Patenteada</title>
		<link>https://ramondomingos.com.br/do-risco-a-inovacao-como-transformamos-a-conformidade-a-lgpd-em-propriedade-intelectual-patenteada/</link>
					<comments>https://ramondomingos.com.br/do-risco-a-inovacao-como-transformamos-a-conformidade-a-lgpd-em-propriedade-intelectual-patenteada/#respond</comments>
		
		<dc:creator><![CDATA[Ramon Domingos]]></dc:creator>
		<pubDate>Wed, 06 May 2026 19:13:30 +0000</pubDate>
				<category><![CDATA[Sem categoria]]></category>
		<guid isPermaLink="false">https://ramondomingos.com.br/?p=335</guid>

					<description><![CDATA[<p>A adequação à Lei Geral de Proteção de Dados (LGPD) e ao GDPR frequentemente é vista pelas empresas como um centro de custo — um checklist regulatório complexo que consome recursos e impõe freios ao desenvolvimento de novas funcionalidades. Mas e se a busca pela conformidade for, na verdade, um dos maiores catalisadores de inovação&#8230;</p>
<p>O post <a href="https://ramondomingos.com.br/do-risco-a-inovacao-como-transformamos-a-conformidade-a-lgpd-em-propriedade-intelectual-patenteada/">Do Risco à Inovação: Como Transformamos a Conformidade à LGPD em Propriedade Intelectual Patenteada</a> apareceu primeiro em <a href="https://ramondomingos.com.br">Ramon Domingos Blog</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">A adequação à Lei Geral de Proteção de Dados (LGPD) e ao GDPR frequentemente é vista pelas empresas como um centro de custo — um checklist regulatório complexo que consome recursos e impõe freios ao desenvolvimento de novas funcionalidades. Mas e se a busca pela conformidade for, na verdade, um dos maiores catalisadores de inovação técnica e diferencial competitivo para o negócio?</p>



<p class="wp-block-paragraph">Recentemente, concluí meu mestrado em Engenharia de Software na <strong>Universidade Federal do Rio Grande do Norte (UFRN)</strong>, focado exatamente nessa interseção entre privacidade, conformidade e arquitetura de sistemas distribuídos. O resultado dessa jornada foi muito além da academia: desenvolvemos uma solução tão disruptiva para o mercado que o <strong>componente central da pesquisa foi oficialmente patenteado</strong>.</p>



<p class="wp-block-paragraph">Neste post, quero compartilhar a visão de mercado por trás desse projeto e como resolvemos um dos gargalos mais caros da governança de dados moderna.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">O Gargalo: O Direito ao Esquecimento em Larga Escala</h2>



<p class="wp-block-paragraph">Para empresas que operam com sistemas legados ou arquiteturas modernas baseadas em microsserviços, o cumprimento do <strong>Direito ao Esquecimento</strong> (a exclusão definitiva dos dados a pedido do titular) é um pesadelo operacional.</p>



<p class="wp-block-paragraph">Em estruturas complexas, os dados de um único cliente não estão centralizados. Eles estão espalhados por dezenas de bancos de dados relacionais e não-relacionais, filas de mensageria, data lakes e caches. Quando um usuário solicita a exclusão:</p>



<ul class="wp-block-list">
<li><strong>O risco operacional aumenta:</strong> Como garantir, de forma auditável, que o dado foi apagado em <em>todos</em> os pontos sem causar inconsistências no sistema?</li>



<li><strong>O custo financeiro dispara:</strong> Interromper times de engenharia para criar soluções customizadas e manuais de exclusão a cada nova API é financeiramente insustentável.</li>



<li><strong>A segurança jurídica fica fragilizada:</strong> Sem uma orquestração automatizada, o risco de falha humana e sanções administrativas pesadas (como as multas da LGPD) permanece alto.</li>
</ul>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">A Solução: Governança Nativa por Meio de Middleware</h2>



<p class="wp-block-paragraph">A tese central da pesquisa desenvolvida na UFRN, que agora se tornou propriedade intelectual protegida, parte do princípio do <em>Privacy by Design</em>. Em vez de forçar cada microsserviço ou equipe de desenvolvimento a criar sua própria lógica de exclusão e conformidade, centralizamos essa inteligência em uma camada agnóstica: um <strong>middleware de orquestração</strong>.</p>



<p class="wp-block-paragraph">O componente patenteado funciona como um maestro invisível em sistemas distribuídos. Ele intercepta de forma segura as requisições de privacidade, mapeia as dependências de dados e garante que o fluxo de exclusão ocorra de forma resiliente, assíncrona e totalmente auditável — sem comprometer a performance, a escalabilidade ou a disponibilidade do ecossistema de software da empresa.</p>



<figure class="wp-block-image size-large"><img fetchpriority="high" decoding="async" width="1024" height="926" src="https://ramondomingos.com.br/wp-content/uploads/2026/05/image-1024x926.png" alt="" class="wp-image-336" srcset="https://ramondomingos.com.br/wp-content/uploads/2026/05/image-1024x926.png 1024w, https://ramondomingos.com.br/wp-content/uploads/2026/05/image-300x271.png 300w, https://ramondomingos.com.br/wp-content/uploads/2026/05/image-768x695.png 768w, https://ramondomingos.com.br/wp-content/uploads/2026/05/image-1536x1389.png 1536w, https://ramondomingos.com.br/wp-content/uploads/2026/05/image.png 1694w" sizes="(max-width: 1024px) 100vw, 1024px" /><figcaption class="wp-element-caption">Registro oficial do componente de arquitetura distribuída voltado para conformidade nativa à LGPD.</figcaption></figure>



<p class="wp-block-paragraph">Para o negócio, isso significa:</p>



<ol start="1" class="wp-block-list">
<li><strong>Mitigação Absoluta de Risco:</strong> Processos automatizados e à prova de falhas, gerando relatórios de conformidade prontos para auditorias.</li>



<li><strong>Eficiência de Engenharia:</strong> Os times de desenvolvimento voltam a focar nas regras de negócio e no produto, pois a governança de dados passa a ser uma engrenagem nativa da infraestrutura.</li>



<li><strong>Valor de Mercado:</strong> Empresas que protegem a privacidade dos clientes com tecnologia proprietária e escalável aumentam drasticamente seu valuation e sua confiabilidade no mercado B2B e B2C.</li>
</ol>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">O Próximo Capítulo: Ciência de Ponta com Impacto no Mercado</h2>



<p class="wp-block-paragraph">A conquista da patente e a conclusão do mestrado coroam um ciclo de validação rigorosa. Ela prova que a pesquisa científica de ponta realizada no Brasil, quando alinhada às dores reais do mercado corporativo, é capaz de gerar ativos de altíssimo valor.</p>



<p class="wp-block-paragraph">Garantir a privacidade não precisa ser um freio para a inovação; pode ser o motor que posiciona sua infraestrutura tecnológica anos à frente da concorrência.</p>



<p class="wp-block-paragraph"><em>Gostaria de expressar meu profundo agradecimento à <strong>UFRN</strong> por toda a infraestrutura e suporte, e em especial ao meu orientador, <strong>Prof. Dr. Eiji Adachi Medeiros Barbosa</strong>, cuja orientação brilhante e visão estratégica foram fundamentais para transformar uma inquietação acadêmica em um componente tecnológico patenteado de impacto real. O futuro da engenharia de software é, obrigatoriamente, privado e seguro — e estamos prontos para ele.</em></p>
<p>O post <a href="https://ramondomingos.com.br/do-risco-a-inovacao-como-transformamos-a-conformidade-a-lgpd-em-propriedade-intelectual-patenteada/">Do Risco à Inovação: Como Transformamos a Conformidade à LGPD em Propriedade Intelectual Patenteada</a> apareceu primeiro em <a href="https://ramondomingos.com.br">Ramon Domingos Blog</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://ramondomingos.com.br/do-risco-a-inovacao-como-transformamos-a-conformidade-a-lgpd-em-propriedade-intelectual-patenteada/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Criando seu primeiro servidor FastMCP do zero</title>
		<link>https://ramondomingos.com.br/criando-seu-primeiro-servidor-fastmcp-do-zero/</link>
					<comments>https://ramondomingos.com.br/criando-seu-primeiro-servidor-fastmcp-do-zero/#comments</comments>
		
		<dc:creator><![CDATA[Ramon Domingos]]></dc:creator>
		<pubDate>Wed, 22 Apr 2026 21:12:07 +0000</pubDate>
				<category><![CDATA[FastMCP]]></category>
		<category><![CDATA[fastmcp]]></category>
		<category><![CDATA[mcp]]></category>
		<guid isPermaLink="false">https://ramondomingos.com.br/?p=313</guid>

					<description><![CDATA[<p>Nos dois posts anteriores entendemos o que é o Model Context Protocol e conhecemos o FastMCP, a biblioteca que simplifica a criação de servidores MCP em Python. Agora é hora de colocar a mão na massa. Post 1: O que é MCP e por que ele importa para o futuro dos agentes de IA?Post 2:&#8230;</p>
<p>O post <a href="https://ramondomingos.com.br/criando-seu-primeiro-servidor-fastmcp-do-zero/">Criando seu primeiro servidor FastMCP do zero</a> apareceu primeiro em <a href="https://ramondomingos.com.br">Ramon Domingos Blog</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">Nos dois posts anteriores entendemos o que é o <strong>Model Context Protocol</strong> e conhecemos o <strong>FastMCP</strong>, a biblioteca que simplifica a criação de servidores MCP em Python. Agora é hora de colocar a mão na massa.</p>



<blockquote class="wp-block-quote has-cyan-bluish-gray-background-color has-background is-layout-flow wp-block-quote-is-layout-flow">
<p class="has-small-font-size wp-block-paragraph">Post 1: <a href="https://ramondomingos.com.br/o-que-e-mcp-e-por-que-ele-importa-para-o-futuro-dos-agentes-de-ia/">O que é MCP e por que ele importa para o futuro dos agentes de IA?</a><br>Post 2: <a href="https://ramondomingos.com.br/fastmcp-a-forma-mais-rapida-de-criar-servidores-mcp-em-python/">FastMCP: a forma mais rápida de criar servidores MCP em Python</a></p>
</blockquote>



<p class="wp-block-paragraph">Neste post vamos construir um servidor FastMCP real, do zero, que consulta endereços a partir de um CEP usando a API pública <strong>ViaCEP</strong> — sem chave de API, sem autenticação, pronto para usar.</p>



<p class="wp-block-paragraph">Ao final, você vai conectar esse servidor ao <strong>Claude Desktop</strong> e perguntar diretamente ao Claude: <em>&#8220;Qual o endereço do CEP 01310-100?&#8221;</em> — e ele vai responder usando a sua tool.</p>



<h2 class="wp-block-heading">Pré-requisitos</h2>



<p class="wp-block-paragraph">Antes de começar, certifique-se de ter:</p>



<ul class="wp-block-list">
<li><strong>Python 3.10+</strong> instalado</li>



<li><strong>pip</strong> atualizado</li>



<li><strong>Claude Desktop</strong> instalado (<a href="https://claude.ai/download" target="_blank" rel="noreferrer noopener">download aqui</a>)</li>



<li>Terminal (usaremos o Terminal do Mac)</li>
</ul>



<p class="wp-block-paragraph">Para verificar sua versão do Python:</p>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:1.125rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#d8dee9ff;--cbp-line-number-width:calc(1 * 0.6 * 1.125rem);line-height:1.625rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>python3 --version</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #88C0D0">python3</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">--version</span></span></code></pre></div>



<h2 class="wp-block-heading">1. Criando o ambiente do projeto</h2>



<p class="wp-block-paragraph">Abra o Terminal e crie uma pasta para o projeto:</p>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:1.125rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#d8dee9ff;--cbp-line-number-width:calc(1 * 0.6 * 1.125rem);line-height:1.625rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>mkdir mcp-cep-server
cd mcp-cep-server</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #88C0D0">mkdir</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">mcp-cep-server</span></span>
<span class="line"><span style="color: #88C0D0">cd</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">mcp-cep-server</span></span></code></pre></div>



<p class="wp-block-paragraph">Crie e ative um ambiente virtual:</p>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:1.125rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#d8dee9ff;--cbp-line-number-width:calc(1 * 0.6 * 1.125rem);line-height:1.625rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>python3 -m venv .venv
source .venv/bin/activate</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #88C0D0">python3</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">-m</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">venv</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">.venv</span></span>
<span class="line"><span style="color: #88C0D0">source</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">.venv/bin/activate</span></span></code></pre></div>



<p class="wp-block-paragraph">Você verá o prefixo <code>(.venv)</code> no terminal — isso confirma que o ambiente está ativo.</p>



<p class="wp-block-paragraph">Instale as dependências:</p>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:1.125rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#d8dee9ff;--cbp-line-number-width:calc(1 * 0.6 * 1.125rem);line-height:1.625rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>pip install fastmcp httpx</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #88C0D0">pip</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">install</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">fastmcp</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">httpx</span></span></code></pre></div>



<ul class="wp-block-list">
<li><strong>fastmcp</strong> — o framework do servidor </li>



<li><strong>httpx</strong> — cliente HTTP moderno para consumir a API ViaCEP</li>
</ul>



<p class="wp-block-paragraph">Você irá ver os logs, com o sucesso da instalação.</p>



<h2 class="wp-block-heading">2. Criando o servidor</h2>



<p class="wp-block-paragraph">Crie o arquivo principal do servidor:</p>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:1.125rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#d8dee9ff;--cbp-line-number-width:calc(1 * 0.6 * 1.125rem);line-height:1.625rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>touch server.py
# ou voce pode criar direto no vscode mesmo...</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #88C0D0">touch</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">server.py</span></span>
<span class="line"><span style="color: #616E88"># ou voce pode criar direto no vscode mesmo...</span></span></code></pre></div>



<p class="wp-block-paragraph">Abra seu editor de código favorito e escreva o código:</p>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:1.125rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#d8dee9ff;--cbp-line-number-width:calc(2 * 0.6 * 1.125rem);line-height:1.625rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>import httpx
from fastmcp import FastMCP

mcp = FastMCP("servidor-cep")

@mcp.tool()
async def consultar_cep(cep: str) -> str:
    """
    Consulta o endereço completo a partir de um CEP brasileiro.
    Retorna rua, bairro, cidade e estado.
    """
    cep_limpo = cep.replace("-", "").replace(" ", "")

    if len(cep_limpo) != 8 or not cep_limpo.isdigit():
        return "CEP inválido. Informe um CEP com 8 dígitos numéricos."

    async with httpx.AsyncClient() as client:
        response = await client.get(
            f"https://viacep.com.br/ws/{cep_limpo}/json/"
        )

    if response.status_code != 200:
        return "Erro ao consultar o CEP. Tente novamente."

    dados = response.json()

    if "erro" in dados:
        return f"CEP {cep} não encontrado."

    return (
        f"CEP: {dados.get('cep', '-')}\n"
        f"Rua: {dados.get('logradouro', '-')}\n"
        f"Bairro: {dados.get('bairro', '-')}\n"
        f"Cidade: {dados.get('localidade', '-')}\n"
        f"Estado: {dados.get('uf', '-')}"
    )

if __name__ == "__main__":
    mcp.run()</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #81A1C1">import</span><span style="color: #D8DEE9FF"> httpx</span></span>
<span class="line"><span style="color: #81A1C1">from</span><span style="color: #D8DEE9FF"> fastmcp </span><span style="color: #81A1C1">import</span><span style="color: #D8DEE9FF"> FastMCP</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF">mcp </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">FastMCP</span><span style="color: #ECEFF4">(</span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">servidor-cep</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">)</span></span>
<span class="line"></span>
<span class="line"><span style="color: #ECEFF4">@</span><span style="color: #D08770">mcp</span><span style="color: #ECEFF4">.</span><span style="color: #D08770">tool</span><span style="color: #ECEFF4">()</span></span>
<span class="line"><span style="color: #81A1C1">async</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">def</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">consultar_cep</span><span style="color: #ECEFF4">(</span><span style="color: #D8DEE9">cep</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">str</span><span style="color: #ECEFF4">)</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">-&gt;</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">str</span><span style="color: #ECEFF4">:</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #ECEFF4">&quot;&quot;&quot;</span></span>
<span class="line"><span style="color: #A3BE8C">    Consulta o endereço completo a partir de um CEP brasileiro.</span></span>
<span class="line"><span style="color: #A3BE8C">    Retorna rua, bairro, cidade e estado.</span></span>
<span class="line"><span style="color: #A3BE8C">    </span><span style="color: #ECEFF4">&quot;&quot;&quot;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    cep_limpo </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> cep</span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">replace</span><span style="color: #ECEFF4">(</span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">-</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;&quot;</span><span style="color: #ECEFF4">).</span><span style="color: #88C0D0">replace</span><span style="color: #ECEFF4">(</span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;&quot;</span><span style="color: #ECEFF4">)</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #81A1C1">if</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">len</span><span style="color: #ECEFF4">(</span><span style="color: #D8DEE9FF">cep_limpo</span><span style="color: #ECEFF4">)</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">!=</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">8</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">or</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">not</span><span style="color: #D8DEE9FF"> cep_limpo</span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">isdigit</span><span style="color: #ECEFF4">():</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #81A1C1">return</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">CEP inválido. Informe um CEP com 8 dígitos numéricos.</span><span style="color: #ECEFF4">&quot;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #81A1C1">async</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">with</span><span style="color: #D8DEE9FF"> httpx</span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">AsyncClient</span><span style="color: #ECEFF4">()</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">as</span><span style="color: #D8DEE9FF"> client</span><span style="color: #ECEFF4">:</span></span>
<span class="line"><span style="color: #D8DEE9FF">        response </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">await</span><span style="color: #D8DEE9FF"> client</span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">get</span><span style="color: #ECEFF4">(</span></span>
<span class="line"><span style="color: #D8DEE9FF">            </span><span style="color: #81A1C1">f</span><span style="color: #A3BE8C">&quot;https://viacep.com.br/ws/</span><span style="color: #EBCB8B">{</span><span style="color: #D8DEE9FF">cep_limpo</span><span style="color: #EBCB8B">}</span><span style="color: #A3BE8C">/json/&quot;</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #ECEFF4">)</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #81A1C1">if</span><span style="color: #D8DEE9FF"> response</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9FF">status_code </span><span style="color: #81A1C1">!=</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">200</span><span style="color: #ECEFF4">:</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #81A1C1">return</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">Erro ao consultar o CEP. Tente novamente.</span><span style="color: #ECEFF4">&quot;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF">    dados </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> response</span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">json</span><span style="color: #ECEFF4">()</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #81A1C1">if</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">erro</span><span style="color: #ECEFF4">&quot;</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">in</span><span style="color: #D8DEE9FF"> dados</span><span style="color: #ECEFF4">:</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #81A1C1">return</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">f</span><span style="color: #A3BE8C">&quot;CEP </span><span style="color: #EBCB8B">{</span><span style="color: #D8DEE9FF">cep</span><span style="color: #EBCB8B">}</span><span style="color: #A3BE8C"> não encontrado.&quot;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #81A1C1">return</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">(</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #81A1C1">f</span><span style="color: #A3BE8C">&quot;CEP: </span><span style="color: #EBCB8B">{</span><span style="color: #D8DEE9FF">dados</span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">get</span><span style="color: #ECEFF4">(</span><span style="color: #ECEFF4">&#39;</span><span style="color: #A3BE8C">cep</span><span style="color: #ECEFF4">&#39;</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&#39;</span><span style="color: #A3BE8C">-</span><span style="color: #ECEFF4">&#39;</span><span style="color: #ECEFF4">)</span><span style="color: #EBCB8B">}\n</span><span style="color: #A3BE8C">&quot;</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #81A1C1">f</span><span style="color: #A3BE8C">&quot;Rua: </span><span style="color: #EBCB8B">{</span><span style="color: #D8DEE9FF">dados</span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">get</span><span style="color: #ECEFF4">(</span><span style="color: #ECEFF4">&#39;</span><span style="color: #A3BE8C">logradouro</span><span style="color: #ECEFF4">&#39;</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&#39;</span><span style="color: #A3BE8C">-</span><span style="color: #ECEFF4">&#39;</span><span style="color: #ECEFF4">)</span><span style="color: #EBCB8B">}\n</span><span style="color: #A3BE8C">&quot;</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #81A1C1">f</span><span style="color: #A3BE8C">&quot;Bairro: </span><span style="color: #EBCB8B">{</span><span style="color: #D8DEE9FF">dados</span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">get</span><span style="color: #ECEFF4">(</span><span style="color: #ECEFF4">&#39;</span><span style="color: #A3BE8C">bairro</span><span style="color: #ECEFF4">&#39;</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&#39;</span><span style="color: #A3BE8C">-</span><span style="color: #ECEFF4">&#39;</span><span style="color: #ECEFF4">)</span><span style="color: #EBCB8B">}\n</span><span style="color: #A3BE8C">&quot;</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #81A1C1">f</span><span style="color: #A3BE8C">&quot;Cidade: </span><span style="color: #EBCB8B">{</span><span style="color: #D8DEE9FF">dados</span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">get</span><span style="color: #ECEFF4">(</span><span style="color: #ECEFF4">&#39;</span><span style="color: #A3BE8C">localidade</span><span style="color: #ECEFF4">&#39;</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&#39;</span><span style="color: #A3BE8C">-</span><span style="color: #ECEFF4">&#39;</span><span style="color: #ECEFF4">)</span><span style="color: #EBCB8B">}\n</span><span style="color: #A3BE8C">&quot;</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #81A1C1">f</span><span style="color: #A3BE8C">&quot;Estado: </span><span style="color: #EBCB8B">{</span><span style="color: #D8DEE9FF">dados</span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">get</span><span style="color: #ECEFF4">(</span><span style="color: #ECEFF4">&#39;</span><span style="color: #A3BE8C">uf</span><span style="color: #ECEFF4">&#39;</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&#39;</span><span style="color: #A3BE8C">-</span><span style="color: #ECEFF4">&#39;</span><span style="color: #ECEFF4">)</span><span style="color: #EBCB8B">}</span><span style="color: #A3BE8C">&quot;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #ECEFF4">)</span></span>
<span class="line"></span>
<span class="line"><span style="color: #81A1C1">if</span><span style="color: #D8DEE9FF"> __name__ </span><span style="color: #81A1C1">==</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">__main__</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">:</span></span>
<span class="line"><span style="color: #D8DEE9FF">    mcp</span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">run</span><span style="color: #ECEFF4">()</span></span></code></pre></div>



<h3 class="wp-block-heading">O que esse código faz?</h3>



<ul class="wp-block-list">
<li><strong>Linha 4:</strong> instancia o servidor FastMCP com o nome <code>"servidor-cep"</code></li>



<li><strong>Linha 6:</strong> decora a função com <code>@mcp.tool()</code> — o FastMCP registra automaticamente a tool no protocolo</li>



<li><strong>Linhas 7-10:</strong> a docstring vira a descrição da tool que o LLM vai ler para decidir quando usá-la</li>



<li><strong>Linhas 12-14:</strong> limpa o CEP removendo traços e espaços, e valida o formato</li>



<li><strong>Linhas 16-20:</strong> faz a requisição HTTP para a API ViaCEP de forma assíncrona</li>



<li><strong>Linhas 22-30:</strong> trata erros e formata a resposta</li>
</ul>



<h2 class="wp-block-heading">3. Testando o servidor localmente</h2>



<p class="wp-block-paragraph">Antes de conectar ao Claude Desktop, vamos garantir que o servidor está funcionando. O FastMCP tem um modo de inspeção embutido:</p>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:1.125rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#d8dee9ff;--cbp-line-number-width:calc(1 * 0.6 * 1.125rem);line-height:1.625rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>fastmcp dev inspector  server.py</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #88C0D0">fastmcp</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">dev</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">inspector</span><span style="color: #D8DEE9FF">  </span><span style="color: #A3BE8C">server.py</span></span></code></pre></div>



<p class="wp-block-paragraph">Esse comando sobe o servidor e abre o <strong>MCP Inspector</strong> no navegador, uma interface visual onde você pode chamar suas tools manualmente.</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<figure class="wp-block-image size-large"><img decoding="async" width="1024" height="718" src="https://ramondomingos.com.br/wp-content/uploads/2026/04/image-1024x718.png" alt="" class="wp-image-316" srcset="https://ramondomingos.com.br/wp-content/uploads/2026/04/image-1024x718.png 1024w, https://ramondomingos.com.br/wp-content/uploads/2026/04/image-300x210.png 300w, https://ramondomingos.com.br/wp-content/uploads/2026/04/image-768x539.png 768w, https://ramondomingos.com.br/wp-content/uploads/2026/04/image-1536x1078.png 1536w, https://ramondomingos.com.br/wp-content/uploads/2026/04/image-2048x1437.png 2048w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>
</blockquote>



<p class="wp-block-paragraph">No Inspector:</p>



<ol class="wp-block-list">
<li>Clique em <strong>&#8220;Tools&#8221;</strong> no menu lateral</li>



<li>Selecione <strong>&#8220;consultar_cep&#8221;</strong></li>



<li>Preencha o campo <code>cep</code> com <code>01310-100</code></li>



<li>Clique em <strong>&#8220;Run&#8221;</strong></li>
</ol>



<p class="wp-block-paragraph">Você deve ver a resposta:</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<figure class="wp-block-image size-large"><img decoding="async" width="1024" height="637" src="https://ramondomingos.com.br/wp-content/uploads/2026/04/image-1-1024x637.png" alt="" class="wp-image-317" srcset="https://ramondomingos.com.br/wp-content/uploads/2026/04/image-1-1024x637.png 1024w, https://ramondomingos.com.br/wp-content/uploads/2026/04/image-1-300x187.png 300w, https://ramondomingos.com.br/wp-content/uploads/2026/04/image-1-768x478.png 768w, https://ramondomingos.com.br/wp-content/uploads/2026/04/image-1.png 1384w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>
</blockquote>



<h2 class="wp-block-heading">4. Conectando ao Claude Desktop</h2>



<p class="wp-block-paragraph">Agora vamos conectar o servidor ao Claude Desktop para que o Claude possa usar a tool diretamente nas conversas.</p>



<h3 class="wp-block-heading">4.1 Localize o arquivo de configuração</h3>



<p class="wp-block-paragraph">O Claude Desktop usa um arquivo JSON para registrar servidores MCP. No Mac, ele fica em:</p>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:1.125rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#d8dee9ff;--cbp-line-number-width:calc(1 * 0.6 * 1.125rem);line-height:1.625rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>~/Library/Application Support/Claude/claude_desktop_config.json  </textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #81A1C1">~/</span><span style="color: #D8DEE9FF">Library</span><span style="color: #81A1C1">/</span><span style="color: #D8DEE9FF">Application Support</span><span style="color: #81A1C1">/</span><span style="color: #D8DEE9FF">Claude</span><span style="color: #81A1C1">/</span><span style="color: #D8DEE9FF">claude_desktop_config</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9FF">json  </span></span></code></pre></div>



<pre class="wp-block-code"><code></code></pre>



<p class="wp-block-paragraph">Abra o Terminal e edite o arquivo:</p>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:1.125rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#d8dee9ff;--cbp-line-number-width:calc(1 * 0.6 * 1.125rem);line-height:1.625rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>open -a TextEdit ~/Library/Application\ Support/Claude/claude_desktop_config.json</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #88C0D0">open</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">-</span><span style="color: #D8DEE9FF">a TextEdit </span><span style="color: #81A1C1">~/</span><span style="color: #D8DEE9FF">Library</span><span style="color: #81A1C1">/</span><span style="color: #D8DEE9FF">Application</span><span style="color: #ECEFF4">\</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">Support/Claude/claude_desktop_config.json</span></span></code></pre></div>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p class="wp-block-paragraph">Se o arquivo não existir, crie-o com o comando:</p>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:1.125rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#d8dee9ff;--cbp-line-number-width:calc(1 * 0.6 * 1.125rem);line-height:1.625rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>mkdir -p ~/Library/Application\ Support/Claude
touch ~/Library/Application\ Support/Claude/claude_desktop_config.json</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #D8DEE9FF">mkdir </span><span style="color: #81A1C1">-</span><span style="color: #D8DEE9FF">p </span><span style="color: #81A1C1">~/</span><span style="color: #D8DEE9FF">Library</span><span style="color: #81A1C1">/</span><span style="color: #D8DEE9FF">Application</span><span style="color: #ECEFF4">\</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">Support/Claude</span></span>
<span class="line"><span style="color: #D8DEE9FF">touch </span><span style="color: #81A1C1">~/</span><span style="color: #D8DEE9FF">Library</span><span style="color: #81A1C1">/</span><span style="color: #D8DEE9FF">Application</span><span style="color: #ECEFF4">\</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">Support/Claude/claude_desktop_config.json</span></span></code></pre></div>
</blockquote>



<h3 class="wp-block-heading">4.2 Adicione o servidor</h3>



<p class="wp-block-paragraph">Cole o seguinte conteúdo no arquivo, ajustando o caminho para o seu projeto:</p>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:1.125rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#d8dee9ff;--cbp-line-number-width:calc(2 * 0.6 * 1.125rem);line-height:1.625rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>{
  "mcpServers": {
    "servidor-cep": {
      "command": "/caminho/para/seu/projeto/mcp-cep-server/.venv/bin/python",
      "args": &#91;
        "/caminho/para/seu/projeto/mcp-cep-server/server.py"
      &#93;
    }
  }
}</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #ECEFF4">&quot;</span><span style="color: #8FBCBB">mcpServers</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #ECEFF4">&quot;</span><span style="color: #8FBCBB">servidor-cep</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">      </span><span style="color: #ECEFF4">&quot;</span><span style="color: #8FBCBB">command</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">/caminho/para/seu/projeto/mcp-cep-server/.venv/bin/python</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">,</span></span>
<span class="line"><span style="color: #D8DEE9FF">      </span><span style="color: #ECEFF4">&quot;</span><span style="color: #8FBCBB">args</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&#91;</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">/caminho/para/seu/projeto/mcp-cep-server/server.py</span><span style="color: #ECEFF4">&quot;</span></span>
<span class="line"><span style="color: #D8DEE9FF">      </span><span style="color: #ECEFF4">&#93;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #ECEFF4">}</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #ECEFF4">}</span></span>
<span class="line"><span style="color: #ECEFF4">}</span></span></code></pre></div>



<p class="wp-block-paragraph">Para descobrir o caminho correto do Python no seu ambiente virtual, rode:</p>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:1.125rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#d8dee9ff;--cbp-line-number-width:calc(1 * 0.6 * 1.125rem);line-height:1.625rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>which python</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #88C0D0">which</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">python</span></span></code></pre></div>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p class="wp-block-paragraph"></p>
</blockquote>



<h3 class="wp-block-heading">4.3 Reinicie o Claude Desktop</h3>



<p class="wp-block-paragraph">Feche e abra o Claude Desktop novamente. Após reiniciar, você verá um ícone de <strong>conectore </strong> na interface de chat — isso indica que tools MCP estão disponíveis.</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="897" height="612" src="https://ramondomingos.com.br/wp-content/uploads/2026/04/image-2.png" alt="" class="wp-image-320" srcset="https://ramondomingos.com.br/wp-content/uploads/2026/04/image-2.png 897w, https://ramondomingos.com.br/wp-content/uploads/2026/04/image-2-300x205.png 300w, https://ramondomingos.com.br/wp-content/uploads/2026/04/image-2-768x524.png 768w" sizes="(max-width: 897px) 100vw, 897px" /></figure>
</blockquote>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">5. Testando no Claude Desktop</h2>



<p class="wp-block-paragraph">Com tudo configurado, abra uma nova conversa no Claude Desktop e pergunte:</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p class="wp-block-paragraph"><em>&#8220;Qual o endereço do CEP 01310-100?&#8221;</em></p>
</blockquote>



<p class="wp-block-paragraph">O Claude vai identificar que tem uma tool disponível para isso, vai chamá-la automaticamente e retornar a resposta formatada.</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p class="wp-block-paragraph"></p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="522" src="https://ramondomingos.com.br/wp-content/uploads/2026/04/image-3-1024x522.png" alt="" class="wp-image-321" srcset="https://ramondomingos.com.br/wp-content/uploads/2026/04/image-3-1024x522.png 1024w, https://ramondomingos.com.br/wp-content/uploads/2026/04/image-3-300x153.png 300w, https://ramondomingos.com.br/wp-content/uploads/2026/04/image-3-768x392.png 768w, https://ramondomingos.com.br/wp-content/uploads/2026/04/image-3-1536x783.png 1536w, https://ramondomingos.com.br/wp-content/uploads/2026/04/image-3.png 1898w" sizes="(max-width: 1024px) 100vw, 1024px" /><figcaption class="wp-element-caption"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f4f8.png" alt="📸" class="wp-smiley" style="height: 1em; max-height: 1em;" /> <em>Print da conversa no Claude Desktop com a resposta como cep da Avenida Paulista</em></figcaption></figure>
</blockquote>



<p class="wp-block-paragraph">Você também pode testar casos de erro:</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p class="wp-block-paragraph"><em>&#8220;Consulta o CEP 00000-000 pra mim&#8221;</em></p>
</blockquote>



<p class="wp-block-paragraph">E o Claude vai retornar a mensagem de CEP não encontrado — exatamente como programamos.</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="698" src="https://ramondomingos.com.br/wp-content/uploads/2026/04/image-5-1024x698.png" alt="" class="wp-image-323" srcset="https://ramondomingos.com.br/wp-content/uploads/2026/04/image-5-1024x698.png 1024w, https://ramondomingos.com.br/wp-content/uploads/2026/04/image-5-300x204.png 300w, https://ramondomingos.com.br/wp-content/uploads/2026/04/image-5-768x524.png 768w, https://ramondomingos.com.br/wp-content/uploads/2026/04/image-5-1536x1047.png 1536w, https://ramondomingos.com.br/wp-content/uploads/2026/04/image-5.png 1558w" sizes="(max-width: 1024px) 100vw, 1024px" /><figcaption class="wp-element-caption">Retorno no Claude desktop, de um cep inválido.</figcaption></figure>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">Conclusão</h2>



<p class="wp-block-paragraph">Em menos de 40 linhas de Python, criamos um servidor MCP real que:</p>



<ul class="wp-block-list">
<li><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2705.png" alt="✅" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Expõe uma tool funcional via protocolo MCP</li>



<li><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2705.png" alt="✅" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Consome uma API externa de forma assíncrona</li>



<li><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2705.png" alt="✅" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Valida entradas e trata erros</li>



<li><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2705.png" alt="✅" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Está conectado ao Claude Desktop e pronto para uso</li>
</ul>



<p class="wp-block-paragraph">Isso é o poder do MCP na prática: você escreve a lógica, o protocolo cuida da comunicação, e o LLM sabe exatamente quando e como usar sua tool.</p>



<h3 class="wp-block-heading">Próximos passos</h3>



<p class="wp-block-paragraph">A partir daqui, as possibilidades são muitas:</p>



<ul class="wp-block-list">
<li>Adicionar mais tools ao mesmo servidor (ex: consulta de CNPJ, cotação de moeda)</li>



<li>Criar <strong>Resources</strong> para expor dados estáticos ou dinâmicos</li>



<li>Fazer deploy do servidor em modo <strong>SSE</strong> para acesso remoto</li>



<li>Publicar seu servidor no ecossistema MCP para que outros usem</li>
</ul>



<p class="wp-block-paragraph">A série não para por aqui — fique ligado nos próximos posts.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<p class="wp-block-paragraph"><em>Conseguiu rodar? Compartilha um print nos comentários! Tem alguma dúvida? Me chama.</em></p>



<p class="wp-block-paragraph"></p>
<p>O post <a href="https://ramondomingos.com.br/criando-seu-primeiro-servidor-fastmcp-do-zero/">Criando seu primeiro servidor FastMCP do zero</a> apareceu primeiro em <a href="https://ramondomingos.com.br">Ramon Domingos Blog</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://ramondomingos.com.br/criando-seu-primeiro-servidor-fastmcp-do-zero/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
			</item>
		<item>
		<title>FastMCP: a forma mais rápida de criar servidores MCP em Python</title>
		<link>https://ramondomingos.com.br/fastmcp-a-forma-mais-rapida-de-criar-servidores-mcp-em-python/</link>
					<comments>https://ramondomingos.com.br/fastmcp-a-forma-mais-rapida-de-criar-servidores-mcp-em-python/#comments</comments>
		
		<dc:creator><![CDATA[Ramon Domingos]]></dc:creator>
		<pubDate>Wed, 22 Apr 2026 16:26:31 +0000</pubDate>
				<category><![CDATA[FastMCP]]></category>
		<category><![CDATA[fastmcp]]></category>
		<category><![CDATA[mcp]]></category>
		<guid isPermaLink="false">https://ramondomingos.com.br/?p=303</guid>

					<description><![CDATA[<p>No post anterior, entendemos o que é o Model Context Protocol e por que ele está se tornando o padrão da indústria para conectar LLMs ao mundo real. Se você ainda não leu, recomendo começar por lá. Agora vamos dar um passo à frente: conhecer o FastMCP, a biblioteca Python que torna a criação de&#8230;</p>
<p>O post <a href="https://ramondomingos.com.br/fastmcp-a-forma-mais-rapida-de-criar-servidores-mcp-em-python/">FastMCP: a forma mais rápida de criar servidores MCP em Python</a> apareceu primeiro em <a href="https://ramondomingos.com.br">Ramon Domingos Blog</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">No <a href="https://ramondomingos.com.br/o-que-e-mcp-e-por-que-ele-importa-para-o-futuro-dos-agentes-de-ia/">post anterior</a>, entendemos o que é o <strong>Model Context Protocol</strong> e por que ele está se tornando o padrão da indústria para conectar LLMs ao mundo real. Se você ainda não leu, recomendo começar por lá.</p>



<p class="wp-block-paragraph">Agora vamos dar um passo à frente: conhecer o <strong>FastMCP</strong>, a biblioteca Python que torna a criação de servidores MCP algo surpreendentemente simples — e entender por que ela existe.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">O SDK oficial do MCP</h2>



<p class="wp-block-paragraph">A Anthropic disponibilizou um SDK oficial em Python para criar servidores MCP. Ele funciona, é completo e segue o protocolo à risca. Mas tem um problema: é <strong>verboso</strong>.</p>



<p class="wp-block-paragraph">Para criar um servidor com uma única tool usando o SDK oficial, você escreve algo assim:</p>



<div class="wp-block-kevinbatdorf-code-block-pro cbp-has-line-numbers" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:1.125rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;--cbp-line-number-color:#d8dee9ff;--cbp-line-number-width:calc(2 * 0.6 * 1.125rem);line-height:1.625rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>from mcp.server import Server
from mcp.server.stdio import stdio_server
from mcp import types
import asyncio

server = Server("meu-servidor")

@server.list_tools()
async def list_tools() -> list&#91;types.Tool&#93;:
    return [
        types.Tool(
            name="somar",
            description="Soma dois números",
            inputSchema={
                "type": "object",
                "properties": {
                    "a": {"type": "number"},
                    "b": {"type": "number"}
                },
                "required": &#91;"a", "b"&#93;
            }
        )
    ]

@server.call_tool()
async def call_tool(name: str, arguments: dict):
    if name == "somar":
        return [types.TextContent(
            type="text",
            text=str(arguments&#91;"a"&#93; + arguments&#91;"b"&#93;)
        )]

async def main():
    async with stdio_server() as (read, write):
        await server.run(read, write, server.create_initialization_options())

asyncio.run(main())</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #D8DEE9">from</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">mcp</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9">server</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">import</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">Server</span></span>
<span class="line"><span style="color: #81A1C1">from</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">mcp</span><span style="color: #D8DEE9FF">.</span><span style="color: #8FBCBB">server</span><span style="color: #D8DEE9FF">.</span><span style="color: #8FBCBB">stdio</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">import</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">stdio_server</span></span>
<span class="line"><span style="color: #81A1C1">from</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">mcp</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">import</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">types</span></span>
<span class="line"><span style="color: #8FBCBB">import</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">asyncio</span></span>
<span class="line"></span>
<span class="line"><span style="color: #8FBCBB">server</span><span style="color: #D8DEE9FF"> = </span><span style="color: #8FBCBB">Server</span><span style="color: #D8DEE9FF">(</span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">meu-servidor</span><span style="color: #ECEFF4">&quot;</span><span style="color: #D8DEE9FF">)</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF">@</span><span style="color: #8FBCBB">server</span><span style="color: #D8DEE9FF">.</span><span style="color: #8FBCBB">list_tools</span><span style="color: #D8DEE9FF">()</span></span>
<span class="line"><span style="color: #8FBCBB">async</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">def</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">list_tools</span><span style="color: #D8DEE9FF">() -&gt; </span><span style="color: #8FBCBB">list</span><span style="color: #D8DEE9FF">&#91;</span><span style="color: #8FBCBB">types</span><span style="color: #D8DEE9FF">.</span><span style="color: #8FBCBB">Tool</span><span style="color: #D8DEE9FF">&#93;:</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #8FBCBB">return</span><span style="color: #D8DEE9FF"> [</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #8FBCBB">types</span><span style="color: #D8DEE9FF">.</span><span style="color: #8FBCBB">Tool</span><span style="color: #D8DEE9FF">(</span></span>
<span class="line"><span style="color: #D8DEE9FF">            </span><span style="color: #8FBCBB">name</span><span style="color: #D8DEE9FF">=</span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">somar</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">,</span></span>
<span class="line"><span style="color: #D8DEE9FF">            </span><span style="color: #8FBCBB">description</span><span style="color: #D8DEE9FF">=</span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">Soma dois números</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">,</span></span>
<span class="line"><span style="color: #D8DEE9FF">            </span><span style="color: #8FBCBB">inputSchema</span><span style="color: #D8DEE9FF">=</span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">                &quot;</span><span style="color: #8FBCBB">type</span><span style="color: #D8DEE9FF">&quot;: &quot;</span><span style="color: #8FBCBB">object</span><span style="color: #D8DEE9FF">&quot;</span><span style="color: #ECEFF4">,</span></span>
<span class="line"><span style="color: #D8DEE9FF">                &quot;</span><span style="color: #8FBCBB">properties</span><span style="color: #D8DEE9FF">&quot;: {</span></span>
<span class="line"><span style="color: #D8DEE9FF">                    &quot;</span><span style="color: #8FBCBB">a</span><span style="color: #D8DEE9FF">&quot;: {&quot;</span><span style="color: #8FBCBB">type</span><span style="color: #D8DEE9FF">&quot;: &quot;</span><span style="color: #8FBCBB">number</span><span style="color: #D8DEE9FF">&quot;</span><span style="color: #ECEFF4">},</span></span>
<span class="line"><span style="color: #D8DEE9FF">                    </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">b</span><span style="color: #ECEFF4">&quot;</span><span style="color: #D8DEE9FF">: </span><span style="color: #ECEFF4">{</span><span style="color: #D8DEE9FF">&quot;</span><span style="color: #8FBCBB">type</span><span style="color: #D8DEE9FF">&quot;: &quot;</span><span style="color: #8FBCBB">number</span><span style="color: #D8DEE9FF">&quot;</span><span style="color: #ECEFF4">}</span></span>
<span class="line"><span style="color: #D8DEE9FF">                }</span><span style="color: #ECEFF4">,</span></span>
<span class="line"><span style="color: #D8DEE9FF">                </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">required</span><span style="color: #ECEFF4">&quot;</span><span style="color: #D8DEE9FF">: &#91;</span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">a</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">b</span><span style="color: #ECEFF4">&quot;</span><span style="color: #D8DEE9FF">&#93;</span></span>
<span class="line"><span style="color: #D8DEE9FF">            }</span></span>
<span class="line"><span style="color: #D8DEE9FF">        )</span></span>
<span class="line"><span style="color: #D8DEE9FF">    ]</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF">@</span><span style="color: #8FBCBB">server</span><span style="color: #D8DEE9FF">.</span><span style="color: #8FBCBB">call_tool</span><span style="color: #D8DEE9FF">()</span></span>
<span class="line"><span style="color: #8FBCBB">async</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">def</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">call_tool</span><span style="color: #D8DEE9FF">(</span><span style="color: #8FBCBB">name</span><span style="color: #D8DEE9FF">: </span><span style="color: #8FBCBB">str</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">arguments</span><span style="color: #D8DEE9FF">: </span><span style="color: #8FBCBB">dict</span><span style="color: #D8DEE9FF">):</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #8FBCBB">if</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">name</span><span style="color: #D8DEE9FF"> == </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">somar</span><span style="color: #ECEFF4">&quot;</span><span style="color: #D8DEE9FF">:</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #8FBCBB">return</span><span style="color: #D8DEE9FF"> [</span><span style="color: #8FBCBB">types</span><span style="color: #D8DEE9FF">.</span><span style="color: #8FBCBB">TextContent</span><span style="color: #D8DEE9FF">(</span></span>
<span class="line"><span style="color: #D8DEE9FF">            </span><span style="color: #8FBCBB">type</span><span style="color: #D8DEE9FF">=</span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">text</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">,</span></span>
<span class="line"><span style="color: #D8DEE9FF">            </span><span style="color: #8FBCBB">text</span><span style="color: #D8DEE9FF">=</span><span style="color: #8FBCBB">str</span><span style="color: #D8DEE9FF">(</span><span style="color: #8FBCBB">arguments</span><span style="color: #D8DEE9FF">&#91;</span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">a</span><span style="color: #ECEFF4">&quot;</span><span style="color: #D8DEE9FF">&#93; + </span><span style="color: #8FBCBB">arguments</span><span style="color: #D8DEE9FF">&#91;</span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">b</span><span style="color: #ECEFF4">&quot;</span><span style="color: #D8DEE9FF">&#93;)</span></span>
<span class="line"><span style="color: #D8DEE9FF">        )]</span></span>
<span class="line"></span>
<span class="line"><span style="color: #8FBCBB">async</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">def</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">main</span><span style="color: #D8DEE9FF">():</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #8FBCBB">async</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">with</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">stdio_server</span><span style="color: #D8DEE9FF">() </span><span style="color: #8FBCBB">as</span><span style="color: #D8DEE9FF"> (</span><span style="color: #8FBCBB">read</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">write</span><span style="color: #D8DEE9FF">):</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #8FBCBB">await</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">server</span><span style="color: #D8DEE9FF">.</span><span style="color: #8FBCBB">run</span><span style="color: #D8DEE9FF">(</span><span style="color: #8FBCBB">read</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">write</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">server</span><span style="color: #D8DEE9FF">.</span><span style="color: #8FBCBB">create_initialization_options</span><span style="color: #D8DEE9FF">())</span></span>
<span class="line"></span>
<span class="line"><span style="color: #8FBCBB">asyncio</span><span style="color: #D8DEE9FF">.</span><span style="color: #8FBCBB">run</span><span style="color: #D8DEE9FF">(</span><span style="color: #8FBCBB">main</span><span style="color: #D8DEE9FF">())</span></span></code></pre></div>



<pre class="wp-block-code"><code><code>
</code></code></pre>



<p class="wp-block-paragraph">Funciona. Mas são mais de 30 linhas para uma operação trivial. Imagine isso escalando para 10, 20 tools.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">O que é o FastMCP?</h2>



<p class="wp-block-paragraph">O <strong>FastMCP</strong> é uma biblioteca Python de alto nível construída <strong>sobre</strong> o SDK oficial do MCP. A inspiração é clara no nome: assim como o <strong>FastAPI</strong> simplificou a criação de APIs REST em Python, o FastMCP simplifica a criação de servidores MCP.</p>



<p class="wp-block-paragraph">O mesmo servidor acima, com FastMCP:</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:1.125rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.625rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>from fastmcp import FastMCP

mcp = FastMCP("meu-servidor")

@mcp.tool()
def somar(a: float, b: float) -> float:
    """Soma dois números"""
    return a + b</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #D8DEE9">from</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">fastmcp</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">import</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">FastMCP</span></span>
<span class="line"></span>
<span class="line"><span style="color: #8FBCBB">mcp</span><span style="color: #D8DEE9FF"> = </span><span style="color: #8FBCBB">FastMCP</span><span style="color: #D8DEE9FF">(</span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">meu-servidor</span><span style="color: #ECEFF4">&quot;</span><span style="color: #D8DEE9FF">)</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF">@</span><span style="color: #8FBCBB">mcp</span><span style="color: #D8DEE9FF">.</span><span style="color: #8FBCBB">tool</span><span style="color: #D8DEE9FF">()</span></span>
<span class="line"><span style="color: #8FBCBB">def</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">somar</span><span style="color: #D8DEE9FF">(</span><span style="color: #8FBCBB">a</span><span style="color: #D8DEE9FF">: </span><span style="color: #8FBCBB">float</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">b</span><span style="color: #D8DEE9FF">: </span><span style="color: #8FBCBB">float</span><span style="color: #D8DEE9FF">) -&gt; </span><span style="color: #8FBCBB">float</span><span style="color: #D8DEE9FF">:</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #ECEFF4">&quot;&quot;&quot;</span><span style="color: #A3BE8C">Soma dois números</span><span style="color: #ECEFF4">&quot;&quot;&quot;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #8FBCBB">return</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">a</span><span style="color: #D8DEE9FF"> + </span><span style="color: #8FBCBB">b</span></span></code></pre></div>



<p class="wp-block-paragraph"><br><strong>4 linhas.</strong> Mesmo resultado. Mesmo protocolo. Mesma compatibilidade.</p>



<p class="wp-block-paragraph">O FastMCP cuida de toda a camada de serialização, validação de schema, registro de tools e comunicação via JSON-RPC — você foca apenas na lógica.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">Por que FastMCP e não o SDK puro?</h2>



<figure class="wp-block-table"><table class="has-fixed-layout"><thead><tr><th></th><th>SDK Oficial</th><th>FastMCP</th></tr></thead><tbody><tr><td>Linhas para 1 tool</td><td>~30</td><td>~4</td></tr><tr><td>Tipagem automática</td><td><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/274c.png" alt="❌" class="wp-smiley" style="height: 1em; max-height: 1em;" /></td><td><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2705.png" alt="✅" class="wp-smiley" style="height: 1em; max-height: 1em;" /> via type hints</td></tr><tr><td>Validação de schema</td><td>Manual</td><td>Automática</td></tr><tr><td>Curva de aprendizado</td><td>Alta</td><td>Baixa</td></tr><tr><td>Compatibilidade MCP</td><td><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2705.png" alt="✅" class="wp-smiley" style="height: 1em; max-height: 1em;" /></td><td><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2705.png" alt="✅" class="wp-smiley" style="height: 1em; max-height: 1em;" /></td></tr><tr><td>Ideal para</td><td>Controle total</td><td>Produtividade</td></tr></tbody></table></figure>



<p class="wp-block-paragraph">A escolha não é binária — para casos que exigem controle fino do protocolo, o SDK oficial ainda faz sentido. Mas para a grande maioria dos projetos, o FastMCP é a escolha certa.</p>



<svg width="100%" viewBox="0 0 680 560" font-family="var(--font-sans)">
  <defs>
    <marker id="arr" markerWidth="8" markerHeight="8" refX="6" refY="3" orient="auto">
      <path d="M0,0 L0,6 L8,3 z" fill="#aaa"/>
    </marker>
    <marker id="arr-teal" markerWidth="8" markerHeight="8" refX="6" refY="3" orient="auto">
      <path d="M0,0 L0,6 L8,3 z" fill="#2ABFBF"/>
    </marker>
    <marker id="arr-green" markerWidth="8" markerHeight="8" refX="6" refY="3" orient="auto">
      <path d="M0,0 L0,6 L8,3 z" fill="#4CAF50"/>
    </marker>
  </defs>

  <text x="340" y="26" text-anchor="middle" font-size="15" font-weight="500" fill="var(--color-text-primary)">SDK Oficial vs FastMCP — Como se relacionam</text>

  <!-- SDK OFICIAL - lado esquerdo -->
  <rect x="20" y="44" width="290" height="230" rx="14" fill="none" stroke="#E07B54" stroke-width="1.2"/>
  <text x="165" y="66" text-anchor="middle" font-size="12" font-weight="500" fill="#E07B54">SDK OFICIAL MCP</text>
  <text x="165" y="82" text-anchor="middle" font-size="10" fill="var(--color-text-tertiary)">Controle total · Verboso</text>

  <rect x="36" y="92" width="258" height="36" rx="6" fill="#E07B54" fill-opacity="0.1" stroke="#E07B54" stroke-width="0.6"/>
  <text x="165" y="106" text-anchor="middle" font-size="11" font-weight="500" fill="var(--color-text-primary)">list_tools() manual</text>
  <text x="165" y="120" text-anchor="middle" font-size="10" fill="var(--color-text-secondary)">Schema JSON escrito à mão</text>

  <rect x="36" y="138" width="258" height="36" rx="6" fill="#E07B54" fill-opacity="0.1" stroke="#E07B54" stroke-width="0.6"/>
  <text x="165" y="152" text-anchor="middle" font-size="11" font-weight="500" fill="var(--color-text-primary)">call_tool() manual</text>
  <text x="165" y="166" text-anchor="middle" font-size="10" fill="var(--color-text-secondary)">Serialização e tipos manuais</text>

  <rect x="36" y="184" width="258" height="36" rx="6" fill="#E07B54" fill-opacity="0.1" stroke="#E07B54" stroke-width="0.6"/>
  <text x="165" y="198" text-anchor="middle" font-size="11" font-weight="500" fill="var(--color-text-primary)">stdio_server() + asyncio</text>
  <text x="165" y="212" text-anchor="middle" font-size="10" fill="var(--color-text-secondary)">Boilerplate de inicialização</text>

  <rect x="36" y="230" width="258" height="32" rx="6" fill="#E07B54" fill-opacity="0.06" stroke="#E07B54" stroke-width="0.5" stroke-dasharray="4,3"/>
  <text x="165" y="250" text-anchor="middle" font-size="10" fill="var(--color-text-tertiary)">~30 linhas para 1 tool simples</text>

  <!-- Seta SDK -> FastMCP -->
  <path d="M310 159 L370 159" fill="none" stroke="#aaa" stroke-width="1.2" marker-end="url(#arr)"/>
  <text x="340" y="152" text-anchor="middle" font-size="10" fill="var(--color-text-tertiary)">abstrai</text>

  <!-- FASTMCP - lado direito -->
  <rect x="370" y="44" width="290" height="230" rx="14" fill="none" stroke="#2ABFBF" stroke-width="1.5"/>
  <text x="515" y="66" text-anchor="middle" font-size="12" font-weight="500" fill="#2ABFBF">FASTMCP</text>
  <text x="515" y="82" text-anchor="middle" font-size="10" fill="var(--color-text-tertiary)">Alto nível · Produtivo</text>

  <rect x="386" y="92" width="258" height="36" rx="6" fill="#2ABFBF" fill-opacity="0.12" stroke="#2ABFBF" stroke-width="0.8"/>
  <text x="515" y="106" text-anchor="middle" font-size="11" font-weight="500" fill="var(--color-text-primary)">@mcp.tool()</text>
  <text x="515" y="120" text-anchor="middle" font-size="10" fill="var(--color-text-secondary)">Schema gerado via type hints</text>

  <rect x="386" y="138" width="258" height="36" rx="6" fill="#2ABFBF" fill-opacity="0.12" stroke="#2ABFBF" stroke-width="0.8"/>
  <text x="515" y="152" text-anchor="middle" font-size="11" font-weight="500" fill="var(--color-text-primary)">@mcp.resource()</text>
  <text x="515" y="166" text-anchor="middle" font-size="10" fill="var(--color-text-secondary)">Fontes de dados via URI</text>

  <rect x="386" y="184" width="258" height="36" rx="6" fill="#2ABFBF" fill-opacity="0.12" stroke="#2ABFBF" stroke-width="0.8"/>
  <text x="515" y="198" text-anchor="middle" font-size="11" font-weight="500" fill="var(--color-text-primary)">@mcp.prompt()</text>
  <text x="515" y="212" text-anchor="middle" font-size="10" fill="var(--color-text-secondary)">Templates reutilizáveis</text>

  <rect x="386" y="230" width="258" height="32" rx="6" fill="#2ABFBF" fill-opacity="0.06" stroke="#2ABFBF" stroke-width="0.5" stroke-dasharray="4,3"/>
  <text x="515" y="250" text-anchor="middle" font-size="10" fill="var(--color-text-tertiary)">~4 linhas para 1 tool simples</text>

  <!-- CAMADAS INTERNAS FASTMCP -->
  <rect x="20" y="294" width="640" height="200" rx="14" fill="none" stroke="#2ABFBF" stroke-width="1"/>
  <text x="340" y="316" text-anchor="middle" font-size="12" font-weight="500" fill="#2ABFBF">O que o FastMCP faz por baixo dos panos</text>

  <!-- Camada 1: seu código -->
  <rect x="36" y="326" width="608" height="44" rx="8" fill="#4A90D9" fill-opacity="0.12" stroke="#4A90D9" stroke-width="0.8"/>
  <text x="340" y="344" text-anchor="middle" font-size="12" font-weight="500" fill="var(--color-text-primary)">Seu código Python</text>
  <text x="340" y="360" text-anchor="middle" font-size="10" fill="var(--color-text-secondary)">def somar(a: float, b: float) -> float — type hints + docstring</text>

  <path d="M340 370 L340 382" fill="none" stroke="#aaa" stroke-width="1" marker-end="url(#arr)"/>

  <!-- Camada 2: FastMCP -->
  <rect x="36" y="382" width="608" height="44" rx="8" fill="#2ABFBF" fill-opacity="0.12" stroke="#2ABFBF" stroke-width="0.8"/>
  <text x="340" y="400" text-anchor="middle" font-size="12" font-weight="500" fill="var(--color-text-primary)">FastMCP</text>
  <text x="340" y="416" text-anchor="middle" font-size="10" fill="var(--color-text-secondary)">Valida tipos · Gera schema JSON · Registra tool · Gerencia erros</text>

  <path d="M340 426 L340 438" fill="none" stroke="#aaa" stroke-width="1" marker-end="url(#arr)"/>

  <!-- Camada 3: SDK / Protocolo -->
  <rect x="36" y="438" width="608" height="44" rx="8" fill="#888" fill-opacity="0.1" stroke="#888" stroke-width="0.6"/>
  <text x="340" y="456" text-anchor="middle" font-size="12" font-weight="500" fill="var(--color-text-primary)">SDK Oficial MCP · JSON-RPC 2.0</text>
  <text x="340" y="472" text-anchor="middle" font-size="10" fill="var(--color-text-secondary)">Serialização · Transporte (stdio / SSE) · Protocolo</text>

  <text x="340" y="516" text-anchor="middle" font-size="11" fill="var(--color-text-tertiary)">FastMCP não substitui o SDK — ele senta em cima dele e remove o boilerplate.</text>
<text x="340" y="536" text-anchor="middle" font-size="11" fill="var(--color-text-tertiary)">Imagem gerada com auxilio de IA.</text>
</svg>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">Arquitetura de um servidor FastMCP</h2>



<p class="wp-block-paragraph">Um servidor FastMCP é composto pelos mesmos três conceitos do protocolo MCP:</p>



<h3 class="wp-block-heading"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f527.png" alt="🔧" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Tools</h3>



<p class="wp-block-paragraph">Funções Python decoradas com <code>@mcp.tool()</code>. O FastMCP lê os <strong>type hints</strong> e a <strong>docstring</strong> automaticamente para gerar o schema JSON da tool.</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:1.125rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.625rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>@mcp.tool()
def buscar_usuario(user_id: int) -> str:
    """Busca um usuário pelo ID"""
    # sua lógica aqui
    return f"Usuário {user_id}"</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #D08770">@</span><span style="color: #D8DEE9">mcp</span><span style="color: #ECEFF4">.</span><span style="color: #D08770">tool</span><span style="color: #D8DEE9FF">()</span></span>
<span class="line"><span style="color: #D8DEE9">def</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">buscar_usuario</span><span style="color: #D8DEE9FF">(</span><span style="color: #D8DEE9">user_id</span><span style="color: #D8DEE9FF">: </span><span style="color: #D8DEE9">int</span><span style="color: #D8DEE9FF">) </span><span style="color: #81A1C1">-&gt;</span><span style="color: #D8DEE9FF"> str</span><span style="color: #ECEFF4">:</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #ECEFF4">&quot;&quot;&quot;</span><span style="color: #A3BE8C">Busca um usuário pelo ID</span><span style="color: #ECEFF4">&quot;&quot;&quot;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    # </span><span style="color: #D8DEE9">sua</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">lógica</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">aqui</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #81A1C1">return</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">f</span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">Usuário {user_id}</span><span style="color: #ECEFF4">&quot;</span></span></code></pre></div>



<pre class="wp-block-code"><code></code></pre>



<h3 class="wp-block-heading"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f4e6.png" alt="📦" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Resources</h3>



<p class="wp-block-paragraph">Fontes de dados expostas via URI, decoradas com <code>@mcp.resource()</code>.</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:1.125rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.625rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>@mcp.resource("dados://config")
def get_config() -> str:
    """Retorna a configuração atual"""
    return "versão: 1.0"</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #D08770">@</span><span style="color: #D8DEE9">mcp</span><span style="color: #ECEFF4">.</span><span style="color: #D08770">resource</span><span style="color: #D8DEE9FF">(</span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">dados://config</span><span style="color: #ECEFF4">&quot;</span><span style="color: #D8DEE9FF">)</span></span>
<span class="line"><span style="color: #D8DEE9">def</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">get_config</span><span style="color: #D8DEE9FF">() </span><span style="color: #81A1C1">-&gt;</span><span style="color: #D8DEE9FF"> str</span><span style="color: #ECEFF4">:</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #ECEFF4">&quot;&quot;&quot;</span><span style="color: #A3BE8C">Retorna a configuração atual</span><span style="color: #ECEFF4">&quot;&quot;&quot;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #81A1C1">return</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">versão: 1.0</span><span style="color: #ECEFF4">&quot;</span></span></code></pre></div>



<pre class="wp-block-code"><code>
</code></pre>



<h3 class="wp-block-heading"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f4ac.png" alt="💬" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Prompts</h3>



<p class="wp-block-paragraph">Templates reutilizáveis decorados com <code>@mcp.prompt()</code>.</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:1.125rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.625rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>@mcp.prompt()
def resumir(texto: str) -> str:
    """Prompt para resumir um texto"""
    return f"Resuma o seguinte texto em 3 bullets:\n\n{texto}"</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #ECEFF4">@</span><span style="color: #D08770">mcp</span><span style="color: #ECEFF4">.</span><span style="color: #D08770">prompt</span><span style="color: #ECEFF4">()</span></span>
<span class="line"><span style="color: #81A1C1">def</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">resumir</span><span style="color: #ECEFF4">(</span><span style="color: #D8DEE9">texto</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">str</span><span style="color: #ECEFF4">)</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">-&gt;</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">str</span><span style="color: #ECEFF4">:</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #ECEFF4">&quot;&quot;&quot;</span><span style="color: #A3BE8C">Prompt para resumir um texto</span><span style="color: #ECEFF4">&quot;&quot;&quot;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #81A1C1">return</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">f</span><span style="color: #A3BE8C">&quot;Resuma o seguinte texto em 3 bullets:</span><span style="color: #EBCB8B">\n\n{</span><span style="color: #D8DEE9FF">texto</span><span style="color: #EBCB8B">}</span><span style="color: #A3BE8C">&quot;</span></span></code></pre></div>



<pre class="wp-block-code"><code></code></pre>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">Instalação e configuração do ambiente</h2>



<p class="wp-block-paragraph">O FastMCP requer <strong>Python 3.10+</strong>. A instalação é simples:</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:1.125rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.625rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly># Com pip
pip install fastmcp

# Com uv (recomendado)
uv add fastmcp</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #616E88"># Com pip</span></span>
<span class="line"><span style="color: #88C0D0">pip</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">install</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">fastmcp</span></span>
<span class="line"></span>
<span class="line"><span style="color: #616E88"># Com uv (recomendado)</span></span>
<span class="line"><span style="color: #88C0D0">uv</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">add</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">fastmcp</span></span></code></pre></div>



<pre class="wp-block-code"><code>
</code></pre>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p class="wp-block-paragraph"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f4a1.png" alt="💡" class="wp-smiley" style="height: 1em; max-height: 1em;" /> <strong>Por que <code>uv</code>?</strong> O <code>uv</code> é um gerenciador de pacotes e ambientes Python extremamente rápido, escrito em Rust. É a ferramenta recomendada pelo ecossistema MCP para gerenciar dependências. Se ainda não usa, vale a pena conhecer.</p>
</blockquote>



<p class="wp-block-paragraph">Para verificar a instalação:</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:1.125rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.625rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>python -c "import fastmcp; print(fastmcp.__version__)"
</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #88C0D0">python</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">-c</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">import fastmcp; print(fastmcp.__version__)</span><span style="color: #ECEFF4">&quot;</span></span>
<span class="line"></span></code></pre></div>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">A estrutura mínima de um servidor FastMCP</h2>



<p class="wp-block-paragraph">Todo servidor FastMCP segue esta estrutura base:</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:1.125rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.625rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><pre class="code-block-pro-copy-button-pre" aria-hidden="true"><textarea class="code-block-pro-copy-button-textarea" tabindex="-1" aria-hidden="true" readonly>from fastmcp import FastMCP

# 1. Instancia o servidor com um nome
mcp = FastMCP("nome-do-servidor")

# 2. Define tools, resources e prompts
@mcp.tool()
def minha_tool(parametro: str) -> str:
    """Descrição da tool — o LLM vai ler isso"""
    return f"Resultado: {parametro}"

# 3. Ponto de entrada
if __name__ == "__main__":
    mcp.run()</textarea></pre><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #81A1C1">from</span><span style="color: #D8DEE9FF"> fastmcp </span><span style="color: #81A1C1">import</span><span style="color: #D8DEE9FF"> FastMCP</span></span>
<span class="line"></span>
<span class="line"><span style="color: #616E88"># 1. Instancia o servidor com um nome</span></span>
<span class="line"><span style="color: #D8DEE9FF">mcp </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">FastMCP</span><span style="color: #ECEFF4">(</span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">nome-do-servidor</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">)</span></span>
<span class="line"></span>
<span class="line"><span style="color: #616E88"># 2. Define tools, resources e prompts</span></span>
<span class="line"><span style="color: #ECEFF4">@</span><span style="color: #D08770">mcp</span><span style="color: #ECEFF4">.</span><span style="color: #D08770">tool</span><span style="color: #ECEFF4">()</span></span>
<span class="line"><span style="color: #81A1C1">def</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">minha_tool</span><span style="color: #ECEFF4">(</span><span style="color: #D8DEE9">parametro</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">str</span><span style="color: #ECEFF4">)</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">-&gt;</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">str</span><span style="color: #ECEFF4">:</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #ECEFF4">&quot;&quot;&quot;</span><span style="color: #A3BE8C">Descrição da tool — o LLM vai ler isso</span><span style="color: #ECEFF4">&quot;&quot;&quot;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #81A1C1">return</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">f</span><span style="color: #A3BE8C">&quot;Resultado: </span><span style="color: #EBCB8B">{</span><span style="color: #D8DEE9FF">parametro</span><span style="color: #EBCB8B">}</span><span style="color: #A3BE8C">&quot;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #616E88"># 3. Ponto de entrada</span></span>
<span class="line"><span style="color: #81A1C1">if</span><span style="color: #D8DEE9FF"> __name__ </span><span style="color: #81A1C1">==</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">__main__</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">:</span></span>
<span class="line"><span style="color: #D8DEE9FF">    mcp</span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">run</span><span style="color: #ECEFF4">()</span></span></code></pre></div>



<p class="wp-block-paragraph">Três partes: <strong>instância</strong>, <strong>definição</strong> e <strong>execução</strong>. Simples assim.</p>



<p class="wp-block-paragraph"><a href="https://ramondomingos.com.br/criando-seu-primeiro-servidor-fastmcp-do-zero/">No próximo post</a>, vamos pegar exatamente essa estrutura e transformar em um servidor funcional, rodando localmente e conectado a um cliente MCP real.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<p class="wp-block-paragraph">O FastMCP remove a fricção entre a ideia e a implementação. Com ele, você não precisa conhecer os detalhes do protocolo JSON-RPC, nem gerenciar manualmente schemas e serialização — tudo isso é abstraído de forma elegante.</p>



<p class="wp-block-paragraph">Se o MCP é a &#8220;tomada universal&#8221; dos agentes de IA, o FastMCP é o cabo que torna tudo mais fácil de conectar.</p>



<p class="wp-block-paragraph"><strong><a href="https://ramondomingos.com.br/criando-seu-primeiro-servidor-fastmcp-do-zero/">No próximo post</a></strong>, vamos colocar a mão na massa: criar um servidor FastMCP do zero, definir tools reais, rodar localmente e conectar ao Claude Desktop para ver tudo funcionando.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<p class="wp-block-paragraph"><em>Está acompanhando a série? Deixa um comentário ou compartilha com alguém que trabalha com IA!</em></p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<p class="wp-block-paragraph"></p>



<p class="wp-block-paragraph"></p>
<p>O post <a href="https://ramondomingos.com.br/fastmcp-a-forma-mais-rapida-de-criar-servidores-mcp-em-python/">FastMCP: a forma mais rápida de criar servidores MCP em Python</a> apareceu primeiro em <a href="https://ramondomingos.com.br">Ramon Domingos Blog</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://ramondomingos.com.br/fastmcp-a-forma-mais-rapida-de-criar-servidores-mcp-em-python/feed/</wfw:commentRss>
			<slash:comments>2</slash:comments>
		
		
			</item>
		<item>
		<title>O que é MCP e por que ele importa para o futuro dos agentes de IA?</title>
		<link>https://ramondomingos.com.br/o-que-e-mcp-e-por-que-ele-importa-para-o-futuro-dos-agentes-de-ia/</link>
					<comments>https://ramondomingos.com.br/o-que-e-mcp-e-por-que-ele-importa-para-o-futuro-dos-agentes-de-ia/#comments</comments>
		
		<dc:creator><![CDATA[Ramon Domingos]]></dc:creator>
		<pubDate>Wed, 22 Apr 2026 14:37:09 +0000</pubDate>
				<category><![CDATA[FastMCP]]></category>
		<guid isPermaLink="false">https://ramondomingos.com.br/?p=297</guid>

					<description><![CDATA[<p>Se você acompanha o ecossistema de inteligência artificial nos últimos anos, provavelmente já se deparou com termos como agentes de IA, function calling, RAG e ferramentas externas. Mas existe um protocolo que está silenciosamente se tornando a espinha dorsal de como os modelos de linguagem se comunicam com o mundo real: o MCP — Model&#8230;</p>
<p>O post <a href="https://ramondomingos.com.br/o-que-e-mcp-e-por-que-ele-importa-para-o-futuro-dos-agentes-de-ia/">O que é MCP e por que ele importa para o futuro dos agentes de IA?</a> apareceu primeiro em <a href="https://ramondomingos.com.br">Ramon Domingos Blog</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">Se você acompanha o ecossistema de inteligência artificial nos últimos anos, provavelmente já se deparou com termos como <em>agentes de IA</em>, <em>function calling</em>, <em>RAG</em> e <em>ferramentas externas</em>. Mas existe um protocolo que está silenciosamente se tornando a espinha dorsal de como os modelos de linguagem se comunicam com o mundo real: o <strong>MCP — Model Context Protocol</strong>.</p>



<p class="wp-block-paragraph">Neste post, vamos entender o que é o MCP, por que ele foi criado, qual problema ele resolve e por que você, desenvolvedor, deveria prestar atenção nele agora.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">O problema que o MCP resolve</h2>



<p class="wp-block-paragraph">Imagine que você quer construir um agente de IA capaz de:</p>



<ul class="wp-block-list">
<li>Consultar um banco de dados</li>



<li>Ler arquivos do seu sistema</li>



<li>Chamar uma API externa</li>



<li>Executar código</li>
</ul>



<p class="wp-block-paragraph">Antes do MCP, cada integração era feita de forma <strong>ad hoc</strong>. Cada LLM tinha sua própria forma de lidar com ferramentas externas. O OpenAI tinha o <em>function calling</em>, o LangChain tinha seus <em>tools</em>, o LlamaIndex tinha seus <em>query engines</em>&#8230; e assim por diante.</p>



<p class="wp-block-paragraph">O resultado? <strong>Fragmentação total.</strong> Uma ferramenta construída para funcionar com GPT-4 não funcionava nativamente com Claude. Um servidor de contexto construído para LangChain não era reaproveitável em outro framework.</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p class="wp-block-paragraph">Era como se cada fabricante de eletrônicos usasse um tipo diferente de tomada — e você precisasse de um adaptador diferente para cada aparelho.</p>
</blockquote>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">O que é o MCP?</h2>



<p class="wp-block-paragraph">O <strong>Model Context Protocol</strong> é um protocolo aberto, criado pela <strong>Anthropic</strong> e lançado em novembro de 2024, que define uma forma <strong>padronizada</strong> de conectar modelos de linguagem a fontes de dados e ferramentas externas.</p>



<p class="wp-block-paragraph">Em termos simples: o MCP é uma <strong>interface universal</strong> entre LLMs e o mundo externo.</p>



<p class="wp-block-paragraph">Ele define como:</p>



<ul class="wp-block-list">
<li>Um <strong>cliente</strong> (ex: Claude Desktop, um agente, uma IDE) se comunica com</li>



<li>Um <strong>servidor MCP</strong> (ex: um serviço que acessa seu banco de dados, seu sistema de arquivos, uma API)</li>
</ul>



<p class="wp-block-paragraph">Essa separação é poderosa. O servidor MCP não sabe — e não precisa saber — qual LLM está do outro lado. E o cliente não precisa saber como o servidor foi implementado.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">A arquitetura do MCP</h2>



<p class="wp-block-paragraph">O protocolo é baseado em três conceitos centrais:</p>



<h3 class="wp-block-heading">Tools (Ferramentas)</h3>



<p class="wp-block-paragraph">São funções que o LLM pode <strong>invocar</strong>. Exemplos: buscar um registro no banco, enviar um e-mail, executar um script.</p>



<h3 class="wp-block-heading"> Resources (Recursos)</h3>



<p class="wp-block-paragraph">São fontes de dados que o LLM pode <strong>ler</strong>. Exemplos: um arquivo de texto, um endpoint REST, um documento PDF.</p>



<h3 class="wp-block-heading"> Prompts</h3>



<p class="wp-block-paragraph">São templates de prompt <strong>reutilizáveis</strong> que o servidor pode expor para o cliente. Útil para padronizar interações complexas.</p>



<p class="wp-block-paragraph">A comunicação entre cliente e servidor acontece via <strong>JSON-RPC 2.0</strong>, podendo usar diferentes transportes: <code>stdio</code> (processo local) ou <code>SSE</code> (HTTP, para servidores remotos).</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<svg width="100%" viewBox="0 0 680 520" font-family="Arial, sans-serif">
  <defs>
    <marker id="arrow" markerWidth="8" markerHeight="8" refX="6" refY="3" orient="auto">
      <path d="M0,0 L0,6 L8,3 z" fill="#888"/>
    </marker>
  </defs>

  <!-- Título -->
  <text x="340" y="28" text-anchor="middle" font-size="16" font-weight="500" fill="#333">Model Context Protocol — Arquitetura</text>

  <!-- CLIENTE MCP -->
  <rect x="20" y="50" width="200" height="420" rx="16" fill="none" stroke="#4A90D9" stroke-width="1.2"/>
  <text x="120" y="74" text-anchor="middle" font-size="13" font-weight="500" fill="#4A90D9">CLIENTE MCP</text>

  <rect x="36" y="86" width="168" height="52" rx="8" fill="#4A90D9" fill-opacity="0.12" stroke="#4A90D9" stroke-width="0.8"/>
  <text x="120" y="108" text-anchor="middle" font-size="13" font-weight="500" fill="#333">Claude Desktop</text>
  <text x="120" y="126" text-anchor="middle" font-size="11" fill="#666">Anthropic</text>

  <rect x="36" y="150" width="168" height="52" rx="8" fill="#4A90D9" fill-opacity="0.12" stroke="#4A90D9" stroke-width="0.8"/>
  <text x="120" y="172" text-anchor="middle" font-size="13" font-weight="500" fill="#333">Cursor / Windsurf</text>
  <text x="120" y="190" text-anchor="middle" font-size="11" fill="#666">IDEs com IA</text>

  <rect x="36" y="214" width="168" height="52" rx="8" fill="#4A90D9" fill-opacity="0.12" stroke="#4A90D9" stroke-width="0.8"/>
  <text x="120" y="236" text-anchor="middle" font-size="13" font-weight="500" fill="#333">Agente Customizado</text>
  <text x="120" y="254" text-anchor="middle" font-size="11" fill="#666">Python / JS / etc.</text>

  <rect x="36" y="278" width="168" height="52" rx="8" fill="#4A90D9" fill-opacity="0.12" stroke="#4A90D9" stroke-width="0.8"/>
  <text x="120" y="300" text-anchor="middle" font-size="13" font-weight="500" fill="#333">VS Code</text>
  <text x="120" y="318" text-anchor="middle" font-size="11" fill="#666">via extensões</text>

  <rect x="36" y="390" width="168" height="52" rx="8" fill="#4A90D9" fill-opacity="0.08" stroke="#4A90D9" stroke-width="0.5" stroke-dasharray="4,3"/>
  <text x="120" y="412" text-anchor="middle" font-size="12" fill="#666">LLM (GPT, Gemini,</text>
  <text x="120" y="430" text-anchor="middle" font-size="12" fill="#666">Claude, etc.)</text>

  <!-- PROTOCOLO MCP (centro) -->
  <rect x="240" y="200" width="200" height="120" rx="16" fill="none" stroke="#888" stroke-width="1.2"/>
  <text x="340" y="224" text-anchor="middle" font-size="13" font-weight="500" fill="#888">PROTOCOLO MCP</text>

  <rect x="256" y="234" width="168" height="36" rx="6" fill="#888" fill-opacity="0.1" stroke="#888" stroke-width="0.6"/>
  <text x="340" y="248" text-anchor="middle" font-size="12" fill="#333">JSON-RPC 2.0</text>
  <text x="340" y="263" text-anchor="middle" font-size="11" fill="#666">stdio  |  SSE (HTTP)</text>

  <rect x="256" y="278" width="168" height="30" rx="6" fill="#888" fill-opacity="0.1" stroke="#888" stroke-width="0.6"/>
  <text x="340" y="298" text-anchor="middle" font-size="11" fill="#666">Interface Universal Padronizada</text>

  <!-- Setas cliente <-> protocolo -->
  <path d="M220 260 L240 260" fill="none" stroke="#888" stroke-width="1.2" marker-end="url(#arrow)"/>
  <path d="M240 270 L220 270" fill="none" stroke="#888" stroke-width="1.2" marker-end="url(#arrow)"/>

  <!-- Setas protocolo <-> servidor -->
  <path d="M440 260 L460 260" fill="none" stroke="#888" stroke-width="1.2" marker-end="url(#arrow)"/>
  <path d="M460 270 L440 270" fill="none" stroke="#888" stroke-width="1.2" marker-end="url(#arrow)"/>

  <!-- SERVIDOR MCP -->
  <rect x="460" y="50" width="200" height="420" rx="16" fill="none" stroke="#2ABFBF" stroke-width="1.2"/>
  <text x="560" y="74" text-anchor="middle" font-size="13" font-weight="500" fill="#2ABFBF">SERVIDOR MCP</text>

  <rect x="476" y="86" width="168" height="80" rx="8" fill="#2ABFBF" fill-opacity="0.12" stroke="#2ABFBF" stroke-width="0.8"/>
  <text x="560" y="108" text-anchor="middle" font-size="13" font-weight="500" fill="#333"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f527.png" alt="🔧" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Tools</text>
  <text x="560" y="126" text-anchor="middle" font-size="11" fill="#666">Funções que o LLM</text>
  <text x="560" y="142" text-anchor="middle" font-size="11" fill="#666">pode invocar</text>
  <text x="560" y="158" text-anchor="middle" font-size="10" fill="#999">ex: buscar DB, enviar e-mail</text>

  <rect x="476" y="178" width="168" height="80" rx="8" fill="#2ABFBF" fill-opacity="0.12" stroke="#2ABFBF" stroke-width="0.8"/>
  <text x="560" y="200" text-anchor="middle" font-size="13" font-weight="500" fill="#333"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f4e6.png" alt="📦" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Resources</text>
  <text x="560" y="218" text-anchor="middle" font-size="11" fill="#666">Fontes de dados que</text>
  <text x="560" y="234" text-anchor="middle" font-size="11" fill="#666">o LLM pode ler</text>
  <text x="560" y="250" text-anchor="middle" font-size="10" fill="#999">ex: arquivos, APIs, PDFs</text>

  <rect x="476" y="270" width="168" height="80" rx="8" fill="#2ABFBF" fill-opacity="0.12" stroke="#2ABFBF" stroke-width="0.8"/>
  <text x="560" y="292" text-anchor="middle" font-size="13" font-weight="500" fill="#333"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f4ac.png" alt="💬" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Prompts</text>
  <text x="560" y="310" text-anchor="middle" font-size="11" fill="#666">Templates reutilizáveis</text>
  <text x="560" y="326" text-anchor="middle" font-size="11" fill="#666">expostos pelo servidor</text>
  <text x="560" y="342" text-anchor="middle" font-size="10" fill="#999">ex: padrões de interação</text>

  <rect x="476" y="362" width="168" height="80" rx="8" fill="#2ABFBF" fill-opacity="0.08" stroke="#2ABFBF" stroke-width="0.5" stroke-dasharray="4,3"/>
  <text x="560" y="384" text-anchor="middle" font-size="12" fill="#666">Banco de Dados</text>
  <text x="560" y="400" text-anchor="middle" font-size="12" fill="#666">APIs Externas</text>
  <text x="560" y="416" text-anchor="middle" font-size="12" fill="#666">Sistema de Arquivos</text>
  <text x="560" y="432" text-anchor="middle" font-size="10" fill="#999">Fontes reais de dados</text>

  <!-- Rodapé -->
  <text x="340" y="490" text-anchor="middle" font-size="11" fill="#999">O servidor não sabe qual LLM está do outro lado — e o cliente não sabe como o servidor foi implementado. </text>
<text x="360" y="510" text-anchor="middle" font-size="11" fill="#999"> Imagem gerada com auxilio de IA.</text>
</svg>
</blockquote>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">Por que isso é importante?</h2>



<p class="wp-block-paragraph">O MCP resolve um problema clássico de engenharia de software: <strong>acoplamento</strong>. Antes dele, sua lógica de integração estava amarrada ao framework ou ao modelo que você escolhia. Com o MCP, você desacopla completamente o <em>como conectar</em> do <em>o que conectar</em>.</p>



<p class="wp-block-paragraph">Isso traz benefícios concretos:</p>



<ul class="wp-block-list">
<li><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2705.png" alt="✅" class="wp-smiley" style="height: 1em; max-height: 1em;" /> <strong>Reusabilidade</strong> — Um servidor MCP pode ser usado por qualquer cliente compatível</li>



<li><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2705.png" alt="✅" class="wp-smiley" style="height: 1em; max-height: 1em;" /> <strong>Interoperabilidade</strong> — Funciona com Claude, com agentes customizados, com IDEs como Cursor e VS Code</li>



<li><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2705.png" alt="✅" class="wp-smiley" style="height: 1em; max-height: 1em;" /> <strong>Ecossistema crescente</strong> — Empresas como Cloudflare, Stripe, GitHub e Notion já publicaram servidores MCP oficiais</li>



<li><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2705.png" alt="✅" class="wp-smiley" style="height: 1em; max-height: 1em;" /> <strong>Padronização</strong> — Menos reinvenção de roda, mais foco no que realmente importa</li>
</ul>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h2 class="wp-block-heading">MCP na prática: onde ele já está sendo usado?</h2>



<p class="wp-block-paragraph">Hoje, o MCP já é suportado nativamente por:</p>



<ul class="wp-block-list">
<li><strong>Claude Desktop</strong> (Anthropic)</li>



<li><strong>Cursor</strong> e <strong>Windsurf</strong> (IDEs com IA)</li>



<li><strong>VS Code</strong> (via extensões)</li>



<li><strong>Amazon Bedrock</strong> e <strong>Google Gemini</strong> (suporte em expansão)</li>
</ul>



<p class="wp-block-paragraph">E o número de servidores MCP públicos cresce diariamente. Existe até um repositório comunitário chamado <a href="https://mcp.so/">mcp.so</a> que cataloga centenas deles.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<p class="wp-block-paragraph">O MCP não é apenas mais um padrão técnico. Ele representa uma mudança de paradigma na forma como construímos sistemas com IA: saindo de integrações frágeis e acopladas para uma arquitetura modular, interoperável e escalável.</p>



<p class="wp-block-paragraph">Se você quer construir agentes de IA sérios — seja para uso pessoal, para sua empresa ou para o mercado — entender o MCP é essencial.</p>



<p class="wp-block-paragraph"><strong><a href="https://ramondomingos.com.br/fastmcp-a-forma-mais-rapida-de-criar-servidores-mcp-em-python/">No próximo post</a></strong>, vamos conhecer o <strong>FastMCP</strong>, a biblioteca Python que torna a criação de servidores MCP algo surpreendentemente simples e elegante.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<p class="wp-block-paragraph"><em>Gostou do post? Deixa um comentário e volta no blog nos próximos dias para ler  os próximos post  da série!</em></p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<p class="wp-block-paragraph"></p>
<p>O post <a href="https://ramondomingos.com.br/o-que-e-mcp-e-por-que-ele-importa-para-o-futuro-dos-agentes-de-ia/">O que é MCP e por que ele importa para o futuro dos agentes de IA?</a> apareceu primeiro em <a href="https://ramondomingos.com.br">Ramon Domingos Blog</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://ramondomingos.com.br/o-que-e-mcp-e-por-que-ele-importa-para-o-futuro-dos-agentes-de-ia/feed/</wfw:commentRss>
			<slash:comments>2</slash:comments>
		
		
			</item>
		<item>
		<title>Além do Código e dos Dados: O que o Mestrado me ensinou sobre a Vida (e sobre mim)</title>
		<link>https://ramondomingos.com.br/alem-do-codigo-e-dos-dados-o-que-o-mestrado-me-ensinou-sobre-a-vida-e-sobre-mim/</link>
					<comments>https://ramondomingos.com.br/alem-do-codigo-e-dos-dados-o-que-o-mestrado-me-ensinou-sobre-a-vida-e-sobre-mim/#respond</comments>
		
		<dc:creator><![CDATA[Ramon Domingos]]></dc:creator>
		<pubDate>Sat, 04 Apr 2026 15:41:10 +0000</pubDate>
				<category><![CDATA[Sem categoria]]></category>
		<guid isPermaLink="false">https://ramondomingos.com.br/?p=291</guid>

					<description><![CDATA[<p>Muitas vezes este blog é um espaço de tutoriais, atualizações de frameworks e resoluções de bugs. Mas hoje, o commit é diferente. Recentemente, fechei um dos ciclos mais intensos da minha trajetória acadêmica e profissional: defendi meu mestrado. Se você me perguntasse há alguns meses como eu estava, a resposta técnica seria, processamento em 100%&#8230;</p>
<p>O post <a href="https://ramondomingos.com.br/alem-do-codigo-e-dos-dados-o-que-o-mestrado-me-ensinou-sobre-a-vida-e-sobre-mim/">Além do Código e dos Dados: O que o Mestrado me ensinou sobre a Vida (e sobre mim)</a> apareceu primeiro em <a href="https://ramondomingos.com.br">Ramon Domingos Blog</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">Muitas vezes este blog é um espaço de tutoriais, atualizações de frameworks e resoluções de bugs. Mas hoje, o <em>commit</em> é diferente. Recentemente, fechei um dos ciclos mais intensos da minha trajetória acadêmica e profissional: <strong>defendi meu mestrado.</strong></p>



<p class="wp-block-paragraph">Se você me perguntasse há alguns meses como eu estava, a resposta técnica seria, processamento em 100% de CPU, com vazamento de memória constante, pod em CrashLoopBackOff, <em>race conditions</em> , <em>deadlocks</em>  e <em>resource exhaustion</em>;  Mas a resposta humana é mais profunda. Olhar para a ata de defesa assinada não foi apenas o recebimento de um título; foi o momento em que o silêncio finalmente venceu o barulho mental de anos de cobrança.</p>



<h4 class="wp-block-heading">A Síndrome do Impostor: O Bug no Sistema</h4>



<p class="wp-block-paragraph">No mundo técnico, somos treinados para ter respostas. No mestrado, a primeira lição é aceitar que não sabemos quase nada. E é aí que a <strong>Síndrome do Impostor</strong> se instala.</p>



<p class="wp-block-paragraph">Em muitas noites, enquanto eu revisava o capítulo de teoria sobre <strong>Middleware, processamento distribuído</strong>, uma voz no fundo da mente dizia: <em>&#8220;Em algum momento, a banca vai perceber que eu não sou tão bom quanto pareço, passar na seleção foi pura sorte&#8221;</em>.</p>



<p class="wp-block-paragraph">A verdade que aprendi é que a síndrome do impostor não é um erro de sistema; ela é uma consequência de estar na fronteira do conhecimento. Se você sente que não sabe tudo, é porque finalmente chegou onde ninguém mais pisou exatamente do seu jeito. O título não cura a síndrome, mas te ensina que você é capaz de entregar resultados mesmo quando não se sente um &#8220;expert&#8221;.</p>



<h4 class="wp-block-heading">Atalhos que são, na verdade, Labirintos &#8211; DICA PARA QUEM TA COMEÇANDO NA PESQUISA! </h4>



<p class="wp-block-paragraph">Para quem está entrando agora no mestrado ou começando uma pesquisa, o instinto de desenvolvedor, o de otimizar processos, pode ser perigoso. No mestrado, <strong>atalhos raramente funcionam</strong>. </p>



<p class="wp-block-paragraph">RETIRE SEU CHAPEUZINHO DE DEV <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f9e2.png" alt="🧢" class="wp-smiley" style="height: 1em; max-height: 1em;" /> E BOTE O DE PESQUISADOR<img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f3a9.png" alt="🎩" class="wp-smiley" style="height: 1em; max-height: 1em;" />.</p>



<ul class="wp-block-list">
<li><strong>O atalho da leitura rápida:</strong> Tentar escrever sua fundamentação sem ler os artigos clássicos a fundo é como construir um sistema em cima de uma biblioteca que você não entende. Mais cedo ou mais tarde, o código quebra e você terá que refazer tudo do zero.</li>



<li><strong>Confie no processo</strong>: O seu orientador(a) ja fez isso várias vezes, ele/a sabe a ordem dos passos, se perder faz parte do processo, uma hora voce encontra o seu caminho.</li>



<li><strong>O atalho da &#8220;Ferramenta da Moda&#8221;:</strong> Não escolha um método ou tecnologia só porque ela está no topo do Hype Cycle. Se a ferramenta não resolve o seu problema científico, ela é apenas ruído acumulado no seu cronograma.</li>



<li><strong>O atalho do isolamento:</strong> Achar que pesquisar é um ato solitário é o erro mais comum. O mestrado é um esporte de equipe. O tempo que você economiza não falando com seu orientador ou com seus pares, você perde dando voltas em problemas que uma conversa de 15 minutos resolveria.</li>
</ul>



<h4 class="wp-block-heading">Conselhos de quem &#8220;sobreviveu&#8221; ao Quilômetro Zero</h4>



<p class="wp-block-paragraph">Se você está começando hoje, aqui estão três coisas que eu gostaria de ter ouvido logo no primeiro dia:</p>



<ol class="wp-block-list">
<li><strong>Documente seus &#8220;Erros&#8221;:</strong> No desenvolvimento, amamos logs. Na pesquisa, o resultado que deu errado também é ciência. Anote por que aquela abordagem não funcionou. Isso vale ouro na hora de escrever a conclusão.</li>



<li><strong>Defina seu MVP (Minimum Viable Thesis):</strong> O mestrado não é para resolver todos os problemas do mundo, mas para resolver UM problema com profundidade. Foque no coração da sua contribuição e deixe a perfumaria para o doutorado.</li>



<li><strong>Saúde Mental é Infraestrutura:</strong> Se o seu hardware (você) pifar, o software (a tese) não roda. Reserve janelas de tempo onde a tese não existe. Se puder, faça terapia, isso me ajudou muito. Normalmente, sua vida não irá parar para você fazer seu mestrado, problemas pessoais, familiares, e do trabalho irão continuar acontecendo, e irão concorrer com esse novo projeto.</li>
</ol>



<h4 class="wp-block-heading">Conclusão: A Realização é um Processo</h4>



<p class="wp-block-paragraph">A sensação de realização não veio na assinatura da ata, mas na percepção de que hoje sou capaz de encarar um problema complexo e sem resposta sem entrar em pânico. O mestrado me deu o título de Mestre, mas a jornada me deu a resiliência de quem sabe que, para debugar a vida, é preciso paciência e muitas iterações.</p>



<p class="wp-block-paragraph">Obrigado por me acompanharem nesta jornada técnica (e agora pessoal). Se você está no meio desse furacão chamado mestrado, saiba que o &#8220;deployment&#8221; final vale cada linha de esforço. </p>



<p class="wp-block-paragraph">E eu acho que já estou com saudades da UFRN&#8230;.</p>



<p class="wp-block-paragraph"></p>
<p>O post <a href="https://ramondomingos.com.br/alem-do-codigo-e-dos-dados-o-que-o-mestrado-me-ensinou-sobre-a-vida-e-sobre-mim/">Além do Código e dos Dados: O que o Mestrado me ensinou sobre a Vida (e sobre mim)</a> apareceu primeiro em <a href="https://ramondomingos.com.br">Ramon Domingos Blog</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://ramondomingos.com.br/alem-do-codigo-e-dos-dados-o-que-o-mestrado-me-ensinou-sobre-a-vida-e-sobre-mim/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>O Que é Dual Write? Escrevendo Dados em Dois Lugares ao Mesmo Tempo</title>
		<link>https://ramondomingos.com.br/o-que-e-dual-write-escrevendo-dados-em-dois-lugares-ao-mesmo-tempo/</link>
					<comments>https://ramondomingos.com.br/o-que-e-dual-write-escrevendo-dados-em-dois-lugares-ao-mesmo-tempo/#respond</comments>
		
		<dc:creator><![CDATA[Ramon Domingos]]></dc:creator>
		<pubDate>Tue, 29 Jul 2025 20:45:24 +0000</pubDate>
				<category><![CDATA[Sem categoria]]></category>
		<guid isPermaLink="false">https://ramondomingos.com.br/?p=284</guid>

					<description><![CDATA[<p>No cotidiano do engenheiro de software, frequentemente nos deparamos com desafios complexos de integração de sistemas. Um conceito que surge bastante em discussões sobre sincronização de dados é o Dual Write. Pode parecer um termo técnico, mas vou tentar explicar de forma acessível para que todos, independentemente da área, possam entender o que é e&#8230;</p>
<p>O post <a href="https://ramondomingos.com.br/o-que-e-dual-write-escrevendo-dados-em-dois-lugares-ao-mesmo-tempo/">O Que é Dual Write? Escrevendo Dados em Dois Lugares ao Mesmo Tempo</a> apareceu primeiro em <a href="https://ramondomingos.com.br">Ramon Domingos Blog</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">No cotidiano do engenheiro de software, frequentemente nos deparamos com desafios complexos de integração de sistemas. Um conceito que surge bastante em discussões sobre sincronização de dados é o <strong>Dual Write</strong>. Pode parecer um termo técnico, mas vou tentar explicar de forma acessível para que todos, independentemente da área, possam entender o que é e por que é importante.</p>



<h3 class="wp-block-heading">A Base: O Que Acontece Quando Você Salva Dados?</h3>



<p class="wp-block-paragraph">Imagine que você está usando um aplicativo bancário para transferir dinheiro. Quando você clica em &#8220;confirmar&#8221;, o sistema precisa registrar essa transação. Na maioria das vezes, essa informação é escrita em um <strong>banco de dados primário</strong>. Tudo simples até aqui, certo?</p>



<h3 class="wp-block-heading">Entendendo o Dual Write</h3>



<p class="wp-block-paragraph">O Dual Write (escrita dupla, em tradução livre) é exatamente o que o nome sugere: <strong>o processo de escrever os mesmos dados em dois sistemas de armazenamento de dados diferentes, de forma simultânea ou quase simultânea</strong>.</p>



<p class="wp-block-paragraph">Pense no nosso exemplo do aplicativo bancário. Se, além do banco de dados principal do banco, a informação da sua transação também fosse registrada <em>ao mesmo tempo</em> em um sistema de relatórios ou em um data warehouse para análise de dados. Isso seria um cenário de Dual Write.</p>



<h3 class="wp-block-heading">Por Que Usamos Dual Write?</h3>



<p class="wp-block-paragraph">Existem várias razões pelas quais um engenheiro de software escolheria implementar o Dual Write. As mais comuns incluem:</p>



<ul class="wp-block-list">
<li><strong>Sincronização de Dados em Tempo Real:</strong> Em muitos cenários, precisamos que as informações estejam atualizadas em múltiplos sistemas imediatamente. Por exemplo, se uma venda é feita no sistema de e-commerce, o estoque no sistema de gerenciamento de armazém precisa ser atualizado instantaneamente. O Dual Write garante que ambos os sistemas recebam a informação ao mesmo tempo.</li>



<li><strong>Redundância e Recuperação de Desastres:</strong> Ao escrever dados em dois lugares, você cria uma cópia de segurança. Se um sistema falhar, o outro ainda tem os dados, o que ajuda na recuperação e garante a continuidade do negócio.</li>



<li><strong>Integração de Sistemas Distintos:</strong> Às vezes, diferentes departamentos usam sistemas diferentes que precisam da mesma informação. Em vez de construir integrações complexas que puxam e empurram dados de um lado para o outro, o Dual Write pode ser uma solução mais direta para manter ambos atualizados.</li>



<li><strong>Desempenho Otimizado:</strong> Em alguns casos, um sistema pode ser otimizado para transações rápidas (por exemplo, um banco de dados de pedidos), enquanto outro é otimizado para análises complexas (um data warehouse). O Dual Write permite que cada sistema use os dados da forma mais eficiente para sua finalidade.</li>
</ul>



<h3 class="wp-block-heading">Os Desafios do Dual Write</h3>



<p class="wp-block-paragraph">Apesar de seus benefícios, o Dual Write não é uma bala de prata e apresenta seus próprios desafios:</p>



<ul class="wp-block-list">
<li><strong>Consistência dos Dados:</strong> O maior desafio é garantir que os dados sejam exatamente os mesmos em ambos os sistemas. O que acontece se uma escrita em um sistema falha e no outro não? É preciso ter mecanismos robustos para lidar com essas falhas e garantir a <strong>consistência</strong>.</li>



<li><strong>Complexidade na Implementação:</strong> Gerenciar duas escritas simultâneas, lidar com erros, retentativas e garantir a ordem correta das operações pode tornar a arquitetura do sistema mais complexa.</li>



<li><strong>Desempenho:</strong> Embora possa otimizar o desempenho para propósitos específicos, o Dual Write adiciona uma sobrecarga, pois cada operação de escrita precisa ser realizada duas vezes. Isso pode impactar a latência, especialmente se os sistemas estiverem geograficamente distantes.</li>



<li><strong>Tratamento de Conflitos:</strong> Se ambos os sistemas permitirem escritas independentes, pode haver conflitos que precisam ser resolvidos de forma inteligente para evitar dados inconsistentes.</li>
</ul>



<h3 class="wp-block-heading">Alternativas ao Dual Write</h3>



<p class="wp-block-paragraph">É importante mencionar que o Dual Write não é a única forma de sincronizar dados. Existem outras abordagens, como:</p>



<ul class="wp-block-list">
<li><strong>Event-Driven Architecture (Arquitetura Orientada a Eventos):</strong> Onde um sistema publica um &#8220;evento&#8221; (ex: &#8220;pedido criado&#8221;) e outros sistemas interessados escutam e reagem a esse evento, atualizando seus próprios dados. Isso é geralmente mais robusto e escalável para cenários complexos.</li>



<li><strong>ETL (Extract, Transform, Load):</strong> Processos que extraem dados de uma fonte, os transformam e os carregam em um destino. Isso geralmente acontece em lotes e é mais comum para data warehouses ou sistemas de relatórios onde a latência de tempo real não é crítica.</li>
</ul>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="1024" src="https://ramondomingos.com.br/wp-content/uploads/2025/07/Gemini_Generated_Image_auwr30auwr30auwr-1024x1024.png" alt="" class="wp-image-285" srcset="https://ramondomingos.com.br/wp-content/uploads/2025/07/Gemini_Generated_Image_auwr30auwr30auwr-1024x1024.png 1024w, https://ramondomingos.com.br/wp-content/uploads/2025/07/Gemini_Generated_Image_auwr30auwr30auwr-300x300.png 300w, https://ramondomingos.com.br/wp-content/uploads/2025/07/Gemini_Generated_Image_auwr30auwr30auwr-150x150.png 150w, https://ramondomingos.com.br/wp-content/uploads/2025/07/Gemini_Generated_Image_auwr30auwr30auwr-768x768.png 768w, https://ramondomingos.com.br/wp-content/uploads/2025/07/Gemini_Generated_Image_auwr30auwr30auwr-1536x1536.png 1536w, https://ramondomingos.com.br/wp-content/uploads/2025/07/Gemini_Generated_Image_auwr30auwr30auwr.png 2048w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>



<h3 class="wp-block-heading"></h3>



<p class="wp-block-paragraph">O Dual Write é uma técnica valiosa no arsenal de um engenheiro de software para manter sistemas em sincronia. Embora ofereça benefícios significativos em termos de sincronização em tempo real e redundância, é crucial entender seus desafios e considerar se é a melhor abordagem para um determinado problema. A escolha da estratégia de sincronização de dados depende das necessidades específicas do negócio, da tolerância a falhas e dos requisitos de desempenho.</p>



<p class="wp-block-paragraph">Espero que esta explicação tenha desmistificado o Dual Write para vocês! Se tiverem alguma dúvida ou quiserem compartilhar suas experiências, deixem um comentário.</p>
<p>O post <a href="https://ramondomingos.com.br/o-que-e-dual-write-escrevendo-dados-em-dois-lugares-ao-mesmo-tempo/">O Que é Dual Write? Escrevendo Dados em Dois Lugares ao Mesmo Tempo</a> apareceu primeiro em <a href="https://ramondomingos.com.br">Ramon Domingos Blog</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://ramondomingos.com.br/o-que-e-dual-write-escrevendo-dados-em-dois-lugares-ao-mesmo-tempo/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Qualificado! Minha Jornada e os Desafios da LGPD em Microsserviços</title>
		<link>https://ramondomingos.com.br/qualificado-minha-jornada-e-os-desafios-da-lgpd-em-microsservicos/</link>
					<comments>https://ramondomingos.com.br/qualificado-minha-jornada-e-os-desafios-da-lgpd-em-microsservicos/#respond</comments>
		
		<dc:creator><![CDATA[Ramon Domingos]]></dc:creator>
		<pubDate>Fri, 11 Jul 2025 16:57:49 +0000</pubDate>
				<category><![CDATA[Sem categoria]]></category>
		<guid isPermaLink="false">https://ramondomingos.com.br/?p=278</guid>

					<description><![CDATA[<p>É com uma enorme alegria e um grande alívio que venho compartilhar uma excelente notícia: fui qualificado no meu mestrado! Este é um marco muito importante na minha jornada acadêmica e pessoal, e quero aproveitar para contar um pouco sobre essa experiência e, claro, apresentar o tema que me consumiu (no bom sentido!) nos últimos&#8230;</p>
<p>O post <a href="https://ramondomingos.com.br/qualificado-minha-jornada-e-os-desafios-da-lgpd-em-microsservicos/">Qualificado! Minha Jornada e os Desafios da LGPD em Microsserviços</a> apareceu primeiro em <a href="https://ramondomingos.com.br">Ramon Domingos Blog</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">É com uma enorme alegria e um grande alívio que venho compartilhar uma excelente notícia: <strong>fui qualificado no meu mestrado</strong>! Este é um marco muito importante na minha jornada acadêmica e pessoal, e quero aproveitar para contar um pouco sobre essa experiência e, claro, apresentar o tema que me consumiu (no bom sentido!) nos últimos tempos.<br><br>A qualificação é um momento de grande tensão, mas também de muito aprendizado. Foram meses de dedicação intensa, de imersão profunda na literatura, de noites de poucas horas de sono e de muito café. Enfrentar a banca, com professores tão experientes como <strong>Eiji Adachi Medeiros Barbosa (presidente,orientador), Frederico Araujo da Silva Lopes (membro interno) e Carlos Eduardo da Silva (membro externo)</strong>, foi desafiador, mas incrivelmente enriquecedor. As perguntas e sugestões foram cruciais para lapidar ainda mais a minha pesquisa e me deixam ainda mais motivado(a) para a próxima etapa.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<h3 class="wp-block-heading">Meu Tema: Adaptando-se à LGPD com Middleware em Sistemas Distribuídos</h3>



<p class="wp-block-paragraph">Minha pesquisa, intitulada &#8220;<strong>Adaptação à LGPD: Proposta de Middleware para a Implementação do Direito ao Esquecimento em Sistemas Distribuídos</strong>&#8220;, mergulha em um desafio crescente para muitas empresas: como garantir o <strong>direito ao esquecimento</strong> de dados, exigido pela <strong>LGPD</strong>, em sistemas modernos baseados em <strong>microsserviços</strong>?</p>



<p class="wp-block-paragraph">Para quem não está familiarizado, sistemas de microsserviços são complexos, com dados espalhados e gerenciados de forma independente. Isso torna a exclusão consistente e confiável de dados uma tarefa manual e suscetível a erros, com grandes ramificações legais se não for bem executada.</p>



<p class="wp-block-paragraph">É aí que entra a minha proposta! Desenvolvi uma solução de <strong>middleware automatizada</strong>, utilizando o padrão <em>two-phase commit (2PC)</em>, para orquestrar a exclusão de dados de forma consistente e segura nesses ambientes distribuídos. Além disso, criei uma biblioteca que pode ser facilmente importada em códigos existentes, simplificando a vida dos desenvolvedores e facilitando a adesão às regulamentações. Em minhas 118 páginas de trabalho, detalho a arquitetura e avalio o desempenho dessa abordagem, demonstrando sua eficácia para um problema que hoje é repleto de complexidade manual.</p>



<p class="wp-block-paragraph">Em resumo, o objetivo é oferecer uma solução robusta e escalável que capacite as organizações a gerenciar efetivamente a exclusão de dados em ambientes de microsserviços, promovendo maior confiança e adesão às regulamentações de proteção de dados.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<p class="wp-block-paragraph">Quem é próximo a mim, sabe que eu, mesmo fazendo um trabalho bom, fico diversas vezes inseguro; Em relação a essa apresentação não poderia ser diferente; Quando eu vi meu nome no site da UFRN, com a data da defesa (<a href="https://sigaa.ufrn.br/sigaa/public/programa/noticias_desc.jsf?lc=pt_BR&amp;id=7872&amp;noticia=182750128">link</a>), começou o nervosismo, o medo de não responder adequadamente alguma pergunta, mesmo estando imerso no tema por 2 anos.</p>



<p class="wp-block-paragraph">Minha dica pra quem chegou nesse momento:</p>



<p class="wp-block-paragraph">Os professores estão ali para contribuir como seu trabalho, para ele ficar mais maduro;</p>



<p class="wp-block-paragraph">Seu orientador JAMAIS iria deixar você levar algo que não esteja suficiente para aquele momento;</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="576" height="1024" src="https://ramondomingos.com.br/wp-content/uploads/2025/07/932CA0B5-EA30-4696-88B9-25459E720F72-576x1024.jpeg" alt="" class="wp-image-279" srcset="https://ramondomingos.com.br/wp-content/uploads/2025/07/932CA0B5-EA30-4696-88B9-25459E720F72-576x1024.jpeg 576w, https://ramondomingos.com.br/wp-content/uploads/2025/07/932CA0B5-EA30-4696-88B9-25459E720F72-169x300.jpeg 169w, https://ramondomingos.com.br/wp-content/uploads/2025/07/932CA0B5-EA30-4696-88B9-25459E720F72-768x1365.jpeg 768w, https://ramondomingos.com.br/wp-content/uploads/2025/07/932CA0B5-EA30-4696-88B9-25459E720F72-864x1536.jpeg 864w, https://ramondomingos.com.br/wp-content/uploads/2025/07/932CA0B5-EA30-4696-88B9-25459E720F72-1152x2048.jpeg 1152w, https://ramondomingos.com.br/wp-content/uploads/2025/07/932CA0B5-EA30-4696-88B9-25459E720F72-scaled.jpeg 1440w" sizes="(max-width: 576px) 100vw, 576px" /></figure>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<p class="wp-block-paragraph">Este é um passo gigante e sou imensamente grato a todos que me apoiaram nessa jornada. A energia agora se renova para os próximos desafios até a defesa final!</p>
<p>O post <a href="https://ramondomingos.com.br/qualificado-minha-jornada-e-os-desafios-da-lgpd-em-microsservicos/">Qualificado! Minha Jornada e os Desafios da LGPD em Microsserviços</a> apareceu primeiro em <a href="https://ramondomingos.com.br">Ramon Domingos Blog</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://ramondomingos.com.br/qualificado-minha-jornada-e-os-desafios-da-lgpd-em-microsservicos/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Conciliando a Tese e o Blog: Um Desafio da Vida de TI!</title>
		<link>https://ramondomingos.com.br/conciliando-a-tese-e-o-blog-um-desafio-da-vida-de-ti/</link>
					<comments>https://ramondomingos.com.br/conciliando-a-tese-e-o-blog-um-desafio-da-vida-de-ti/#respond</comments>
		
		<dc:creator><![CDATA[Ramon Domingos]]></dc:creator>
		<pubDate>Tue, 03 Jun 2025 17:51:52 +0000</pubDate>
				<category><![CDATA[Sem categoria]]></category>
		<guid isPermaLink="false">https://ramondomingos.com.br/?p=270</guid>

					<description><![CDATA[<p>Olá, pessoal! Se você notou um silêncio maior do que o normal por aqui, tem uma boa razão para isso: estou imerso na escrita da minha tese de mestrado! Como muitos de vocês que trabalham com TI e buscam aprofundar seus conhecimentos, sei que a jornada acadêmica exige uma dedicação enorme. Conciliar as horas de&#8230;</p>
<p>O post <a href="https://ramondomingos.com.br/conciliando-a-tese-e-o-blog-um-desafio-da-vida-de-ti/">Conciliando a Tese e o Blog: Um Desafio da Vida de TI!</a> apareceu primeiro em <a href="https://ramondomingos.com.br">Ramon Domingos Blog</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">Olá, pessoal!</p>



<p class="wp-block-paragraph">Se você notou um silêncio maior do que o normal por aqui, tem uma boa razão para isso: estou imerso na escrita da minha tese de mestrado! Como muitos de vocês que trabalham com TI e buscam aprofundar seus conhecimentos, sei que a jornada acadêmica exige uma dedicação enorme.</p>



<p class="wp-block-paragraph">Conciliar as horas de pesquisa, escrita e revisão com a rotina de um blog de TI e o meu trabalho, é, sem dúvida, um desafio. Confesso que tem sido uma verdadeira maratona, mas estou aprendendo muito no processo – tanto sobre o tema da minha tese quanto sobre <strong>gerenciamento de tempo e prioridades</strong>!</p>



<p class="wp-block-paragraph">Ainda não quero detalhar muito sobre o assunto da tese, mas em breve, espero trazer alguns insights e, quem sabe, até um post mais aprofundado sobre a minha pesquisa. Por enquanto, a prioridade máxima é entregar um trabalho de qualidade.</p>



<p class="wp-block-paragraph">Agradeço a compreensão de todos vocês e prometo que, assim que tiver um fôlego, voltarei com conteúdo novo e interessante. Enquanto isso, continuem explorando os posts antigos e deixando seus comentários!</p>



<p class="wp-block-paragraph">Em breve, mais novidades!</p>



<p class="wp-block-paragraph">Um abraço,</p>
<p>O post <a href="https://ramondomingos.com.br/conciliando-a-tese-e-o-blog-um-desafio-da-vida-de-ti/">Conciliando a Tese e o Blog: Um Desafio da Vida de TI!</a> apareceu primeiro em <a href="https://ramondomingos.com.br">Ramon Domingos Blog</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://ramondomingos.com.br/conciliando-a-tese-e-o-blog-um-desafio-da-vida-de-ti/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Rastreando Requisições no FastAPI com Trace IDs: Desvendando o Fluxo da sua Aplicação! 🕵️‍♂️</title>
		<link>https://ramondomingos.com.br/rastreando-requisicoes-no-fastapi-com-trace-ids-desvendando-o-fluxo-da-sua-aplicacao-%f0%9f%95%b5%ef%b8%8f%e2%99%82%ef%b8%8f/</link>
					<comments>https://ramondomingos.com.br/rastreando-requisicoes-no-fastapi-com-trace-ids-desvendando-o-fluxo-da-sua-aplicacao-%f0%9f%95%b5%ef%b8%8f%e2%99%82%ef%b8%8f/#respond</comments>
		
		<dc:creator><![CDATA[Ramon Domingos]]></dc:creator>
		<pubDate>Fri, 18 Apr 2025 01:49:51 +0000</pubDate>
				<category><![CDATA[Sem categoria]]></category>
		<guid isPermaLink="false">https://ramondomingos.com.br/?p=263</guid>

					<description><![CDATA[<p>Em aplicações distribuídas ou mesmo em backends complexos construídos com FastAPI, rastrear o caminho completo de uma requisição pode ser um desafio. Quando ocorrem erros ou gargalos de performance, saber exatamente qual serviço ou parte do código foi o responsável é crucial para um debugging eficiente. É aí que entram os Trace IDs (IDs de&#8230;</p>
<p>O post <a href="https://ramondomingos.com.br/rastreando-requisicoes-no-fastapi-com-trace-ids-desvendando-o-fluxo-da-sua-aplicacao-%f0%9f%95%b5%ef%b8%8f%e2%99%82%ef%b8%8f/">Rastreando Requisições no FastAPI com Trace IDs: Desvendando o Fluxo da sua Aplicação! 🕵️‍♂️</a> apareceu primeiro em <a href="https://ramondomingos.com.br">Ramon Domingos Blog</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">Em aplicações distribuídas ou mesmo em backends complexos construídos com FastAPI, rastrear o caminho completo de uma requisição pode ser um desafio. Quando ocorrem erros ou gargalos de performance, saber exatamente qual serviço ou parte do código foi o responsável é crucial para um debugging eficiente.</p>



<p class="wp-block-paragraph">É aí que entram os <strong>Trace IDs</strong> (IDs de rastreamento)! <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f680.png" alt="🚀" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>



<p class="wp-block-paragraph">Um Trace ID é um identificador único gerado para cada requisição que entra na sua aplicação. Esse ID é propagado por todos os serviços e componentes envolvidos no processamento daquela requisição, permitindo que você correlacione logs e métricas de diferentes partes do sistema.</p>



<p class="wp-block-paragraph"><strong>Por que usar Trace IDs no seu FastAPI?</strong></p>



<ul class="wp-block-list">
<li><strong>Debugging Facilitado:</strong> Rastreie o fluxo completo de uma requisição, desde o ponto de entrada até a resposta final, identificando exatamente onde ocorreu um erro ou lentidão.</li>



<li><strong>Análise de Performance:</strong> Visualize o tempo gasto em cada etapa do processamento, identificando gargalos e áreas para otimização.</li>



<li><strong>Observabilidade Aprimorada:</strong> Integre com ferramentas de logging e monitoramento (como ELK Stack, Grafana Loki, Datadog) para ter uma visão centralizada do comportamento da sua aplicação.</li>



<li><strong>Microserviços:</strong> Essencial em arquiteturas de microsserviços para entender a interação entre diferentes serviços em uma única requisição.</li>
</ul>



<p class="wp-block-paragraph"><strong>Como implementar Trace IDs no FastAPI?</strong></p>



<p class="wp-block-paragraph">Existem algumas maneiras de implementar Trace IDs no seu FastAPI:</p>



<p class="wp-block-paragraph"><strong>1. Middleware Personalizado:</strong></p>



<p class="wp-block-paragraph">Você pode criar um middleware personalizado para gerar um Trace ID para cada requisição e adicioná-lo aos headers da requisição e/ou ao contexto da aplicação.</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" data-code="from fastapi import FastAPI, Request, Response
from uuid import uuid4
import logging

app = FastAPI()
logger = logging.getLogger(__name__)

TRACE_ID_HEADER = &quot;X-Request-ID&quot;

@app.middleware(&quot;http&quot;)
async def add_trace_id(request: Request, call_next):
    trace_id = request.headers.get(TRACE_ID_HEADER) or str(uuid4())
    request.state.trace_id = trace_id
    response: Response = await call_next(request)
    response.headers[TRACE_ID_HEADER] = trace_id
    logger.info(f&quot;Request: {request.method} {request.url} - Trace ID: {trace_id}&quot;)
    return response

@app.get(&quot;/&quot;)
async def read_root(request: Request):
    trace_id = request.state.trace_id
    logger.info(f&quot;Processing root endpoint - Trace ID: {trace_id}&quot;)
    return {&quot;Hello&quot;: &quot;World&quot;, &quot;trace_id&quot;: trace_id}" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #81A1C1">from</span><span style="color: #D8DEE9FF"> fastapi </span><span style="color: #81A1C1">import</span><span style="color: #D8DEE9FF"> FastAPI</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> Request</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> Response</span></span>
<span class="line"><span style="color: #81A1C1">from</span><span style="color: #D8DEE9FF"> uuid </span><span style="color: #81A1C1">import</span><span style="color: #D8DEE9FF"> uuid4</span></span>
<span class="line"><span style="color: #81A1C1">import</span><span style="color: #D8DEE9FF"> logging</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF">app </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">FastAPI</span><span style="color: #ECEFF4">()</span></span>
<span class="line"><span style="color: #D8DEE9FF">logger </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> logging</span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">getLogger</span><span style="color: #ECEFF4">(</span><span style="color: #D8DEE9FF">__name__</span><span style="color: #ECEFF4">)</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF">TRACE_ID_HEADER </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">X-Request-ID</span><span style="color: #ECEFF4">&quot;</span></span>
<span class="line"></span>
<span class="line"><span style="color: #ECEFF4">@</span><span style="color: #D08770">app</span><span style="color: #ECEFF4">.</span><span style="color: #D08770">middleware</span><span style="color: #ECEFF4">(</span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">http</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">)</span></span>
<span class="line"><span style="color: #81A1C1">async</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">def</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">add_trace_id</span><span style="color: #ECEFF4">(</span><span style="color: #D8DEE9">request</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> Request</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">call_next</span><span style="color: #ECEFF4">):</span></span>
<span class="line"><span style="color: #D8DEE9FF">    trace_id </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> request</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9FF">headers</span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">get</span><span style="color: #ECEFF4">(</span><span style="color: #D8DEE9FF">TRACE_ID_HEADER</span><span style="color: #ECEFF4">)</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">or</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">str</span><span style="color: #ECEFF4">(</span><span style="color: #88C0D0">uuid4</span><span style="color: #ECEFF4">())</span></span>
<span class="line"><span style="color: #D8DEE9FF">    request</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9FF">state</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9FF">trace_id </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> trace_id</span></span>
<span class="line"><span style="color: #D8DEE9FF">    response</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> Response </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">await</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">call_next</span><span style="color: #ECEFF4">(</span><span style="color: #D8DEE9FF">request</span><span style="color: #ECEFF4">)</span></span>
<span class="line"><span style="color: #D8DEE9FF">    response</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9FF">headers</span><span style="color: #ECEFF4">[</span><span style="color: #D8DEE9FF">TRACE_ID_HEADER</span><span style="color: #ECEFF4">]</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> trace_id</span></span>
<span class="line"><span style="color: #D8DEE9FF">    logger</span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">info</span><span style="color: #ECEFF4">(</span><span style="color: #81A1C1">f</span><span style="color: #A3BE8C">&quot;Request: </span><span style="color: #EBCB8B">{</span><span style="color: #D8DEE9FF">request</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9FF">method</span><span style="color: #EBCB8B">}</span><span style="color: #A3BE8C"> </span><span style="color: #EBCB8B">{</span><span style="color: #D8DEE9FF">request</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9FF">url</span><span style="color: #EBCB8B">}</span><span style="color: #A3BE8C"> - Trace ID: </span><span style="color: #EBCB8B">{</span><span style="color: #D8DEE9FF">trace_id</span><span style="color: #EBCB8B">}</span><span style="color: #A3BE8C">&quot;</span><span style="color: #ECEFF4">)</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #81A1C1">return</span><span style="color: #D8DEE9FF"> response</span></span>
<span class="line"></span>
<span class="line"><span style="color: #ECEFF4">@</span><span style="color: #D08770">app</span><span style="color: #ECEFF4">.</span><span style="color: #D08770">get</span><span style="color: #ECEFF4">(</span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">/</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">)</span></span>
<span class="line"><span style="color: #81A1C1">async</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">def</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">read_root</span><span style="color: #ECEFF4">(</span><span style="color: #D8DEE9">request</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> Request</span><span style="color: #ECEFF4">):</span></span>
<span class="line"><span style="color: #D8DEE9FF">    trace_id </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> request</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9FF">state</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9FF">trace_id</span></span>
<span class="line"><span style="color: #D8DEE9FF">    logger</span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">info</span><span style="color: #ECEFF4">(</span><span style="color: #81A1C1">f</span><span style="color: #A3BE8C">&quot;Processing root endpoint - Trace ID: </span><span style="color: #EBCB8B">{</span><span style="color: #D8DEE9FF">trace_id</span><span style="color: #EBCB8B">}</span><span style="color: #A3BE8C">&quot;</span><span style="color: #ECEFF4">)</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #81A1C1">return</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">{</span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">Hello</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">World</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">trace_id</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> trace_id</span><span style="color: #ECEFF4">}</span></span></code></pre></div>



<p class="wp-block-paragraph"><strong>Explicação:</strong></p>



<ul class="wp-block-list">
<li>O middleware <code>add_trace_id</code> é executado para cada requisição HTTP.</li>



<li>Ele tenta obter um Trace ID do header <code>X-Request-ID</code> (uma prática comum). Se não existir, gera um novo UUID.</li>



<li>O Trace ID é armazenado no <code>request.state</code> para ser acessado em outras partes da sua aplicação.</li>



<li>O Trace ID também é adicionado como um header na resposta.</li>



<li>Você pode incluir o Trace ID nos seus logs para facilitar o rastreamento.</li>
</ul>



<p class="wp-block-paragraph"><strong>2. Utilizando Bibliotecas de Observabilidade:</strong></p>



<p class="wp-block-paragraph">Bibliotecas como <strong>Opentracing</strong> ou <strong>Opentelemetry</strong> oferecem soluções mais completas para tracing distribuído, incluindo a geração e propagação de Trace IDs, além de integração com diversas ferramentas de observabilidade.</p>



<p class="wp-block-paragraph"><strong>Exemplo com Opentelemetry (simplificado):</strong></p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" data-code="from fastapi import FastAPI, Request
from opentelemetry import trace
from opentelemetry.trace.propagation.tracecontext import TraceContextTextMapPropagator

app = FastAPI()
propagator = TraceContextTextMapPropagator()
tracer = trace.get_tracer(__name__)

@app.middleware(&quot;http&quot;)
async def trace_request(request: Request, call_next):
    carrier = {}
    for k, v in request.headers.items():
        carrier[k] = v
    context = propagator.extract(carrier)
    with tracer.start_as_current_span(f&quot;{request.method} {request.url.path}&quot;, context=context) as span:
        span.set_attribute(&quot;http.method&quot;, request.method)
        span.set_attribute(&quot;http.url&quot;, str(request.url))
        response = await call_next(request)
        span.set_attribute(&quot;http.status_code&quot;, response.status_code)
        return response

@app.get(&quot;/&quot;)
async def read_root():
    current_span = trace.get_current_span()
    current_span.set_attribute(&quot;greeting&quot;, &quot;Hello World&quot;)
    return {&quot;Hello&quot;: &quot;World&quot;}" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #81A1C1">from</span><span style="color: #D8DEE9FF"> fastapi </span><span style="color: #81A1C1">import</span><span style="color: #D8DEE9FF"> FastAPI</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> Request</span></span>
<span class="line"><span style="color: #81A1C1">from</span><span style="color: #D8DEE9FF"> opentelemetry </span><span style="color: #81A1C1">import</span><span style="color: #D8DEE9FF"> trace</span></span>
<span class="line"><span style="color: #81A1C1">from</span><span style="color: #D8DEE9FF"> opentelemetry</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9FF">trace</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9FF">propagation</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9FF">tracecontext </span><span style="color: #81A1C1">import</span><span style="color: #D8DEE9FF"> TraceContextTextMapPropagator</span></span>
<span class="line"></span>
<span class="line"><span style="color: #D8DEE9FF">app </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">FastAPI</span><span style="color: #ECEFF4">()</span></span>
<span class="line"><span style="color: #D8DEE9FF">propagator </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">TraceContextTextMapPropagator</span><span style="color: #ECEFF4">()</span></span>
<span class="line"><span style="color: #D8DEE9FF">tracer </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> trace</span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">get_tracer</span><span style="color: #ECEFF4">(</span><span style="color: #D8DEE9FF">__name__</span><span style="color: #ECEFF4">)</span></span>
<span class="line"></span>
<span class="line"><span style="color: #ECEFF4">@</span><span style="color: #D08770">app</span><span style="color: #ECEFF4">.</span><span style="color: #D08770">middleware</span><span style="color: #ECEFF4">(</span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">http</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">)</span></span>
<span class="line"><span style="color: #81A1C1">async</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">def</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">trace_request</span><span style="color: #ECEFF4">(</span><span style="color: #D8DEE9">request</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> Request</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">call_next</span><span style="color: #ECEFF4">):</span></span>
<span class="line"><span style="color: #D8DEE9FF">    carrier </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">{}</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #81A1C1">for</span><span style="color: #D8DEE9FF"> k</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> v </span><span style="color: #81A1C1">in</span><span style="color: #D8DEE9FF"> request</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9FF">headers</span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">items</span><span style="color: #ECEFF4">():</span></span>
<span class="line"><span style="color: #D8DEE9FF">        carrier</span><span style="color: #ECEFF4">[</span><span style="color: #D8DEE9FF">k</span><span style="color: #ECEFF4">]</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> v</span></span>
<span class="line"><span style="color: #D8DEE9FF">    context </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> propagator</span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">extract</span><span style="color: #ECEFF4">(</span><span style="color: #D8DEE9FF">carrier</span><span style="color: #ECEFF4">)</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #81A1C1">with</span><span style="color: #D8DEE9FF"> tracer</span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">start_as_current_span</span><span style="color: #ECEFF4">(</span><span style="color: #81A1C1">f</span><span style="color: #A3BE8C">&quot;</span><span style="color: #EBCB8B">{</span><span style="color: #D8DEE9FF">request</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9FF">method</span><span style="color: #EBCB8B">}</span><span style="color: #A3BE8C"> </span><span style="color: #EBCB8B">{</span><span style="color: #D8DEE9FF">request</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9FF">url</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9FF">path</span><span style="color: #EBCB8B">}</span><span style="color: #A3BE8C">&quot;</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">context</span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF">context</span><span style="color: #ECEFF4">)</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">as</span><span style="color: #D8DEE9FF"> span</span><span style="color: #ECEFF4">:</span></span>
<span class="line"><span style="color: #D8DEE9FF">        span</span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">set_attribute</span><span style="color: #ECEFF4">(</span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">http.method</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> request</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9FF">method</span><span style="color: #ECEFF4">)</span></span>
<span class="line"><span style="color: #D8DEE9FF">        span</span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">set_attribute</span><span style="color: #ECEFF4">(</span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">http.url</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">str</span><span style="color: #ECEFF4">(</span><span style="color: #D8DEE9FF">request</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9FF">url</span><span style="color: #ECEFF4">))</span></span>
<span class="line"><span style="color: #D8DEE9FF">        response </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">await</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">call_next</span><span style="color: #ECEFF4">(</span><span style="color: #D8DEE9FF">request</span><span style="color: #ECEFF4">)</span></span>
<span class="line"><span style="color: #D8DEE9FF">        span</span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">set_attribute</span><span style="color: #ECEFF4">(</span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">http.status_code</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> response</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9FF">status_code</span><span style="color: #ECEFF4">)</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #81A1C1">return</span><span style="color: #D8DEE9FF"> response</span></span>
<span class="line"></span>
<span class="line"><span style="color: #ECEFF4">@</span><span style="color: #D08770">app</span><span style="color: #ECEFF4">.</span><span style="color: #D08770">get</span><span style="color: #ECEFF4">(</span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">/</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">)</span></span>
<span class="line"><span style="color: #81A1C1">async</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">def</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">read_root</span><span style="color: #ECEFF4">():</span></span>
<span class="line"><span style="color: #D8DEE9FF">    current_span </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> trace</span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">get_current_span</span><span style="color: #ECEFF4">()</span></span>
<span class="line"><span style="color: #D8DEE9FF">    current_span</span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">set_attribute</span><span style="color: #ECEFF4">(</span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">greeting</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">Hello World</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">)</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #81A1C1">return</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">{</span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">Hello</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">World</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">}</span></span></code></pre></div>



<p class="wp-block-paragraph"><strong>Considerações Importantes:</strong></p>



<ul class="wp-block-list">
<li><strong>Propagação:</strong> Em arquiteturas com múltiplos serviços, é crucial garantir que o Trace ID seja propagado corretamente entre as chamadas HTTP. Isso geralmente envolve passar o Trace ID em headers HTTP.</li>



<li><strong>Logging:</strong> Configure sua solução de logging para incluir o Trace ID em cada log, permitindo a correlação de eventos relacionados à mesma requisição.</li>



<li><strong>Ferramentas de Observabilidade:</strong> Integre sua aplicação com ferramentas de observabilidade para visualizar os traces, analisar a performance e identificar problemas de forma mais intuitiva.</li>
</ul>



<p class="wp-block-paragraph">Implementar Trace IDs no seu FastAPI é um investimento valioso que melhora significativamente a capacidade de entender, depurar e otimizar sua aplicação, especialmente em cenários mais complexos. Comece com um middleware simples e explore bibliotecas de observabilidade para uma solução mais robusta! <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f609.png" alt="😉" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>
<p>O post <a href="https://ramondomingos.com.br/rastreando-requisicoes-no-fastapi-com-trace-ids-desvendando-o-fluxo-da-sua-aplicacao-%f0%9f%95%b5%ef%b8%8f%e2%99%82%ef%b8%8f/">Rastreando Requisições no FastAPI com Trace IDs: Desvendando o Fluxo da sua Aplicação! 🕵️‍♂️</a> apareceu primeiro em <a href="https://ramondomingos.com.br">Ramon Domingos Blog</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://ramondomingos.com.br/rastreando-requisicoes-no-fastapi-com-trace-ids-desvendando-o-fluxo-da-sua-aplicacao-%f0%9f%95%b5%ef%b8%8f%e2%99%82%ef%b8%8f/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Desenvolvedores precisam Dominar o Google Analytics? Um Guia Prático com Next.js</title>
		<link>https://ramondomingos.com.br/desenvolvedores-precisam-dominar-o-google-analytics-um-guia-pratico-com-next-js/</link>
					<comments>https://ramondomingos.com.br/desenvolvedores-precisam-dominar-o-google-analytics-um-guia-pratico-com-next-js/#respond</comments>
		
		<dc:creator><![CDATA[Ramon Domingos]]></dc:creator>
		<pubDate>Wed, 25 Sep 2024 16:31:38 +0000</pubDate>
				<category><![CDATA[Sem categoria]]></category>
		<guid isPermaLink="false">https://ramondomingos.com.br/?p=254</guid>

					<description><![CDATA[<p>Olá, devs! Já pararam para pensar na importância de entender como seus projetos são utilizados? Enquanto o pessoal de marketing se concentra em analisar os dados para criar estratégias, os desenvolvedores têm um papel fundamental em garantir que os dados coletados sejam precisos e completos. Neste post, vamos explorar por que o Google Analytics é&#8230;</p>
<p>O post <a href="https://ramondomingos.com.br/desenvolvedores-precisam-dominar-o-google-analytics-um-guia-pratico-com-next-js/">Desenvolvedores precisam Dominar o Google Analytics? Um Guia Prático com Next.js</a> apareceu primeiro em <a href="https://ramondomingos.com.br">Ramon Domingos Blog</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">Olá, devs! </p>



<blockquote class="wp-block-quote has-text-align-center is-layout-flow wp-block-quote-is-layout-flow">
<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p class="has-text-align-left wp-block-paragraph">Recentemente consegui minha <a href="https://skillshop.credential.net/012ceb69-932e-44ff-b11d-57b112b85a2c">certificação Individual do Google Analytics </a>, e no início da jornada de estudo me perguntei, isso é para o pessoal de  Marketing ou para desenvolvedor?  Mas ao final, entendi que todo mundo precisa entender um pouco de analytics. Fazer sua aplicação gerar dados é fundamental, para identificar insights de todos os aspectos da aplicação. No fundo, ser guiados por dados é mais importante do que seguir seu sentimento.  E ter um google analytcs bem configurado, promoverá esses dados para toda equipe.</p>
</blockquote>
</blockquote>



<p class="wp-block-paragraph">Já pararam para pensar na importância de entender como seus projetos são utilizados? Enquanto o pessoal de marketing se concentra em analisar os dados para criar estratégias, os desenvolvedores têm um papel fundamental em garantir que os dados coletados sejam precisos e completos. Neste post, vamos explorar por que o Google Analytics é uma ferramenta importante para desenvolvedores coletar esses dados, nesse post especialmente iremos aplicar o GA numa aplicação  Next.js, mas facilmente é adaptável para outras aplicações, Te guiarei passo a passo na instalação e configuração do funil de vendas. Identificando desde o início da sessão, a primeira visita ao site, até efetuar a compra no checkout. Podendo assim, identificar a porcentagem de abandono de carrinhos, por exemplo.</p>



<p class="wp-block-paragraph"></p>



<p class="wp-block-paragraph">P<strong>or que os Desenvolvedores Devem Entender o Google Analytics?</strong></p>



<ul class="wp-block-list">
<li><strong>Otimização de Desempenho:</strong> Ao acompanhar métricas como tempo de carregamento de página, taxa de rejeição e erros, os desenvolvedores podem identificar gargalos e implementar melhorias para otimizar a experiência do usuário.</li>



<li><strong>Qualidade do Código:</strong> Analisando eventos e interações do usuário, é possível identificar bugs e problemas de usabilidade que podem passar despercebidos em testes.</li>



<li><strong>Validação de Hipóteses:</strong> Ao desenvolver novas funcionalidades, o Google Analytics permite validar se as mudanças estão tendo o impacto esperado nos usuários.</li>



<li><strong>Integração com Outras Ferramentas:</strong> O Google Analytics pode ser integrado com outras ferramentas de desenvolvimento, como ferramentas de monitoramento de desempenho e sistemas de versionamento, proporcionando uma visão mais completa do ciclo de vida do software.</li>
</ul>



<p class="wp-block-paragraph"><strong>Instalando o Google Analytics com Funil de Vendas em um Aplicação Next.js</strong></p>



<ul class="wp-block-list">
<li><strong>Criar uma Conta no Google Analytics:</strong> Se você ainda não tem uma conta, acesse o Google Analytics e crie uma nova propriedade para o seu site. (Provavelmente o marketing da empresa ja possuirá ) </li>



<li><strong>Obter o Código de Rastreamento:</strong> Após criar a propriedade, você receberá um código de rastreamento único.</li>



<li><strong>Instalar o Pacote do Google Analytics:</strong> No seu projeto Next.js, instale o pacote oficial do Google Analytics.</li>
</ul>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" data-code=" npm install @google/analytics" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">npm</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">install</span><span style="color: #D8DEE9FF"> </span><span style="color: #A3BE8C">@google/analytics</span></span></code></pre></div>



<ul class="wp-block-list">
<li><strong>Configurar o Rastreamento:</strong> Crie um componente customizado para envolver o seu aplicativo e enviar os dados para o Google Analytics.</li>
</ul>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" data-code="const GoogleAnalytics = () =&gt; {
return (&lt;&gt;
/* 1. Initialize the Google tag and gtag.js library */
   &lt;!-- Google tag (gtag.js) --&gt;
   &lt;script async src=&quot;https://www.googletagmanager.com/gtag/js?id=TAG_ID&quot;&gt;&lt;/script&gt;
   &lt;script&gt;
     window.dataLayer = window.dataLayer || [];
     function gtag(){dataLayer.push(arguments)};
     gtag('js', new Date());
     gtag('config', 'TAG_ID');
   &lt;/script&gt;
   &lt;/&gt;
   )
   
export { GoogleAnalytics };" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #81A1C1">const</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">GoogleAnalytics</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">()</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=&gt;</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #81A1C1">return</span><span style="color: #D8DEE9FF"> (</span><span style="color: #81A1C1">&lt;&gt;</span></span>
<span class="line"><span style="color: #D8DEE9FF">/* 1. Initialize the Google tag and gtag.js library */</span></span>
<span class="line"><span style="color: #D8DEE9FF">   &lt;!-- Google tag (gtag.js) --&gt;</span></span>
<span class="line"><span style="color: #D8DEE9FF">   </span><span style="color: #81A1C1">&lt;script</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">async</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">src</span><span style="color: #81A1C1">=</span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">https://www.googletagmanager.com/gtag/js?id=TAG_ID</span><span style="color: #ECEFF4">&quot;</span><span style="color: #81A1C1">&gt;&lt;/script&gt;</span></span>
<span class="line"><span style="color: #D8DEE9FF">   </span><span style="color: #81A1C1">&lt;script&gt;</span></span>
<span class="line"><span style="color: #D8DEE9FF">     window.dataLayer = window.dataLayer || [];</span></span>
<span class="line"><span style="color: #D8DEE9FF">     function gtag()</span><span style="color: #81A1C1">{</span><span style="color: #D8DEE9">dataLayer</span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">push</span><span style="color: #D8DEE9FF">(</span><span style="color: #81A1C1">arguments</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">}</span><span style="color: #D8DEE9FF">;</span></span>
<span class="line"><span style="color: #D8DEE9FF">     gtag(&#39;js&#39;, new Date());</span></span>
<span class="line"><span style="color: #D8DEE9FF">     gtag(&#39;config&#39;, &#39;TAG_ID&#39;);</span></span>
<span class="line"><span style="color: #D8DEE9FF">   </span><span style="color: #81A1C1">&lt;/script&gt;</span></span>
<span class="line"><span style="color: #D8DEE9FF">   </span><span style="color: #81A1C1">&lt;/&gt;</span></span>
<span class="line"><span style="color: #D8DEE9FF">   )</span></span>
<span class="line"><span style="color: #D8DEE9FF">   </span></span>
<span class="line"><span style="color: #81A1C1">export</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">{</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">GoogleAnalytics</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">}</span><span style="color: #81A1C1">;</span></span></code></pre></div>



<ul class="wp-block-list">
<li>Use esse componente no layout principal da sua aplicação.</li>
</ul>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" data-code="import { GoogleAnalytics } from &quot;seu_componente_google-analytics&quot;;
export default function RootLayout({
  children,
}: Readonly&lt;{
  children: React.ReactNode;
}&gt;) {
  return (
    &lt;html&gt;
      &lt;body&gt;
        {children}
        &lt;GoogleAnalytics /&gt;
      &lt;/body&gt;
    &lt;/html&gt;
  );
}" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #81A1C1">import</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">{</span><span style="color: #D8DEE9FF"> </span><span style="color: #8FBCBB">GoogleAnalytics</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">}</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">from</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">seu_componente_google-analytics</span><span style="color: #ECEFF4">&quot;</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #81A1C1">export</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">default</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">function</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">RootLayout</span><span style="color: #ECEFF4">({</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #D8DEE9">children</span><span style="color: #ECEFF4">,</span></span>
<span class="line"><span style="color: #ECEFF4">}</span><span style="color: #81A1C1">:</span><span style="color: #D8DEE9FF"> Readonly</span><span style="color: #ECEFF4">&lt;{</span></span>
<span class="line"><span style="color: #D8DEE9FF">  children</span><span style="color: #81A1C1">:</span><span style="color: #D8DEE9FF"> React</span><span style="color: #ECEFF4">.</span><span style="color: #D8DEE9FF">ReactNode</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #ECEFF4">}&gt;)</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #81A1C1">return</span><span style="color: #D8DEE9FF"> (</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #81A1C1">&lt;html&gt;</span></span>
<span class="line"><span style="color: #D8DEE9FF">      </span><span style="color: #81A1C1">&lt;body&gt;</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #81A1C1">{</span><span style="color: #D8DEE9">children</span><span style="color: #81A1C1">}</span></span>
<span class="line"><span style="color: #D8DEE9FF">        </span><span style="color: #81A1C1">&lt;</span><span style="color: #8FBCBB">GoogleAnalytics</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">/&gt;</span></span>
<span class="line"><span style="color: #D8DEE9FF">      </span><span style="color: #81A1C1">&lt;/body&gt;</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #81A1C1">&lt;/html&gt;</span></span>
<span class="line"><span style="color: #D8DEE9FF">  )</span><span style="color: #81A1C1">;</span></span>
<span class="line"><span style="color: #ECEFF4">}</span></span></code></pre></div>



<h2 class="wp-block-heading">Eventos principais</h2>



<p class="wp-block-paragraph">Para criar um funil de vendas, você precisa mapear alguns eventos:</p>



<ol class="wp-block-list">
<li>Início da sessão (o número de usuários que acionaram o evento  <a href="https://support.google.com/analytics/answer/9234069#session_start">session_start</a>)</li>



<li>Ver produto (o número de usuários que acionaram o evento  <a href="https://support.google.com/analytics/answer/9267735">view_item</a>)</li>



<li>Adicionar ao carrinho (o número de usuários que acionaram o evento <a href="https://support.google.com/analytics/answer/9267735">add_to_cart</a>)</li>



<li>Iniciar checkout (o número de usuários que acionaram o evento <a href="https://support.google.com/analytics/answer/9267735">begin_checkout</a>)</li>



<li>Compra (o número de usuários que acionaram  o evento <a href="https://support.google.com/analytics/answer/9267735">purchase</a> ou <a href="https://support.google.com/analytics/answer/9234069#in-app-purchase">in_app_purchase</a>)</li>
</ol>



<p class="wp-block-paragraph">Nos links de cada evento tem o formato de dados que devem ser enviados junto do evento, alguns não precisa enviar nada além do titulo do evento. É muito importante enviar exatamente os campos necessários, dados faltando, ou em excesso irá fazer com que o evento seja descartado.</p>



<p class="wp-block-paragraph">Para fazer o envio, basicamente será necessário usa a função, gtag. Aconselho criar uma função mais generalista e reutilizar em todos os lugares, pois será importante caso precise debugar, adicionar o <em>debug_mode:true</em>, em cada envio.)</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" data-code=" window.gtag(&quot;event&quot;, event,eventParams ) " style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">window</span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">gtag</span><span style="color: #D8DEE9FF">(</span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">event</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">event</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9">eventParams</span><span style="color: #D8DEE9FF"> ) </span></span></code></pre></div>



<p class="wp-block-paragraph">Exemplo para adicionar um  ou mais item ao carrinho:</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" data-code="gtag(&quot;event&quot;, &quot;add_to_cart&quot;, {
  currency: &quot;BRL&quot;,
  value: 9.99,
  items: [
    {
      item_id: &quot;SKU_12345&quot;,
      item_name: &quot;Stan and Friends Tee&quot;,
      index: 0,
      price: 9.99,
      quantity: 1
    }
  ]
});" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #88C0D0">gtag</span><span style="color: #D8DEE9FF">(</span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">event</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">add_to_cart</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #88C0D0">currency</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">BRL</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">,</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #88C0D0">value</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">9.99</span><span style="color: #ECEFF4">,</span></span>
<span class="line"><span style="color: #D8DEE9FF">  </span><span style="color: #88C0D0">items</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> [</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">      </span><span style="color: #88C0D0">item_id</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">SKU_12345</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">,</span></span>
<span class="line"><span style="color: #D8DEE9FF">      </span><span style="color: #88C0D0">item_name</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">Stan and Friends Tee</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">,</span></span>
<span class="line"><span style="color: #D8DEE9FF">      </span><span style="color: #88C0D0">index</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">0</span><span style="color: #ECEFF4">,</span></span>
<span class="line"><span style="color: #D8DEE9FF">      </span><span style="color: #88C0D0">price</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">9.99</span><span style="color: #ECEFF4">,</span></span>
<span class="line"><span style="color: #D8DEE9FF">      </span><span style="color: #88C0D0">quantity</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">1</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #ECEFF4">}</span></span>
<span class="line"><span style="color: #D8DEE9FF">  ]</span></span>
<span class="line"><span style="color: #ECEFF4">}</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span></span></code></pre></div>



<p class="wp-block-paragraph">Exemplo de purchase:</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" data-code="gtag(&quot;event&quot;, &quot;purchase&quot;, {
    transaction_id: &quot;T_12345&quot;,
    value: 25.42,
    tax: 4.90,
    shipping: 5.99,
    currency: &quot;USD&quot;,
    coupon: &quot;SUMMER_SALE&quot;,
    items: [
     {
      item_id: &quot;SKU_12345&quot;,
      item_name: &quot;Stan and Friends Tee&quot;,
      affiliation: &quot;Google Merchandise Store&quot;,
      coupon: &quot;SUMMER_FUN&quot;,
      discount: 2.22,
      index: 0,
      item_brand: &quot;Google&quot;,
      item_category: &quot;Apparel&quot;,
      item_category2: &quot;Adult&quot;,
      item_category3: &quot;Shirts&quot;,
      item_category4: &quot;Crew&quot;,
      item_category5: &quot;Short sleeve&quot;,
      item_list_id: &quot;related_products&quot;,
      item_list_name: &quot;Related Products&quot;,
      item_variant: &quot;green&quot;,
      location_id: &quot;ChIJIQBpAG2ahYAR_6128GcTUEo&quot;,
      price: 9.99,
      quantity: 1
    },
    {
      item_id: &quot;SKU_12346&quot;,
      item_name: &quot;Google Grey Women's Tee&quot;,
      affiliation: &quot;Google Merchandise Store&quot;,
      coupon: &quot;SUMMER_FUN&quot;,
      discount: 3.33,
      index: 1,
      item_brand: &quot;Google&quot;,
      item_category: &quot;Apparel&quot;,
      item_category2: &quot;Adult&quot;,
      item_category3: &quot;Shirts&quot;,
      item_category4: &quot;Crew&quot;,
      item_category5: &quot;Short sleeve&quot;,
      item_list_id: &quot;related_products&quot;,
      item_list_name: &quot;Related Products&quot;,
      item_variant: &quot;gray&quot;,
      location_id: &quot;ChIJIQBpAG2ahYAR_6128GcTUEo&quot;,
      price: 20.99,
      promotion_id: &quot;P_12345&quot;,
      promotion_name: &quot;Summer Sale&quot;,
      quantity: 1
    }]
});" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #88C0D0">gtag</span><span style="color: #D8DEE9FF">(</span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">event</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">purchase</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">transaction_id</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">T_12345</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">,</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">value</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">25.42</span><span style="color: #ECEFF4">,</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">tax</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">4.90</span><span style="color: #ECEFF4">,</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">shipping</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">5.99</span><span style="color: #ECEFF4">,</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">currency</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">USD</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">,</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">coupon</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">SUMMER_SALE</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">,</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #88C0D0">items</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> [</span></span>
<span class="line"><span style="color: #D8DEE9FF">     </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">      </span><span style="color: #88C0D0">item_id</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">SKU_12345</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">,</span></span>
<span class="line"><span style="color: #D8DEE9FF">      </span><span style="color: #88C0D0">item_name</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">Stan and Friends Tee</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">,</span></span>
<span class="line"><span style="color: #D8DEE9FF">      </span><span style="color: #88C0D0">affiliation</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">Google Merchandise Store</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">,</span></span>
<span class="line"><span style="color: #D8DEE9FF">      </span><span style="color: #88C0D0">coupon</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">SUMMER_FUN</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">,</span></span>
<span class="line"><span style="color: #D8DEE9FF">      </span><span style="color: #88C0D0">discount</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">2.22</span><span style="color: #ECEFF4">,</span></span>
<span class="line"><span style="color: #D8DEE9FF">      </span><span style="color: #88C0D0">index</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">0</span><span style="color: #ECEFF4">,</span></span>
<span class="line"><span style="color: #D8DEE9FF">      </span><span style="color: #88C0D0">item_brand</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">Google</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">,</span></span>
<span class="line"><span style="color: #D8DEE9FF">      </span><span style="color: #88C0D0">item_category</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">Apparel</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">,</span></span>
<span class="line"><span style="color: #D8DEE9FF">      </span><span style="color: #88C0D0">item_category2</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">Adult</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">,</span></span>
<span class="line"><span style="color: #D8DEE9FF">      </span><span style="color: #88C0D0">item_category3</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">Shirts</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">,</span></span>
<span class="line"><span style="color: #D8DEE9FF">      </span><span style="color: #88C0D0">item_category4</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">Crew</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">,</span></span>
<span class="line"><span style="color: #D8DEE9FF">      </span><span style="color: #88C0D0">item_category5</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">Short sleeve</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">,</span></span>
<span class="line"><span style="color: #D8DEE9FF">      </span><span style="color: #88C0D0">item_list_id</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">related_products</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">,</span></span>
<span class="line"><span style="color: #D8DEE9FF">      </span><span style="color: #88C0D0">item_list_name</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">Related Products</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">,</span></span>
<span class="line"><span style="color: #D8DEE9FF">      </span><span style="color: #88C0D0">item_variant</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">green</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">,</span></span>
<span class="line"><span style="color: #D8DEE9FF">      </span><span style="color: #88C0D0">location_id</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">ChIJIQBpAG2ahYAR_6128GcTUEo</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">,</span></span>
<span class="line"><span style="color: #D8DEE9FF">      </span><span style="color: #88C0D0">price</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">9.99</span><span style="color: #ECEFF4">,</span></span>
<span class="line"><span style="color: #D8DEE9FF">      </span><span style="color: #88C0D0">quantity</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">1</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #ECEFF4">},</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #ECEFF4">{</span></span>
<span class="line"><span style="color: #D8DEE9FF">      </span><span style="color: #88C0D0">item_id</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">SKU_12346</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">,</span></span>
<span class="line"><span style="color: #D8DEE9FF">      </span><span style="color: #88C0D0">item_name</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">Google Grey Women&#39;s Tee</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">,</span></span>
<span class="line"><span style="color: #D8DEE9FF">      </span><span style="color: #88C0D0">affiliation</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">Google Merchandise Store</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">,</span></span>
<span class="line"><span style="color: #D8DEE9FF">      </span><span style="color: #88C0D0">coupon</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">SUMMER_FUN</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">,</span></span>
<span class="line"><span style="color: #D8DEE9FF">      </span><span style="color: #88C0D0">discount</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">3.33</span><span style="color: #ECEFF4">,</span></span>
<span class="line"><span style="color: #D8DEE9FF">      </span><span style="color: #88C0D0">index</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">1</span><span style="color: #ECEFF4">,</span></span>
<span class="line"><span style="color: #D8DEE9FF">      </span><span style="color: #88C0D0">item_brand</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">Google</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">,</span></span>
<span class="line"><span style="color: #D8DEE9FF">      </span><span style="color: #88C0D0">item_category</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">Apparel</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">,</span></span>
<span class="line"><span style="color: #D8DEE9FF">      </span><span style="color: #88C0D0">item_category2</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">Adult</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">,</span></span>
<span class="line"><span style="color: #D8DEE9FF">      </span><span style="color: #88C0D0">item_category3</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">Shirts</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">,</span></span>
<span class="line"><span style="color: #D8DEE9FF">      </span><span style="color: #88C0D0">item_category4</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">Crew</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">,</span></span>
<span class="line"><span style="color: #D8DEE9FF">      </span><span style="color: #88C0D0">item_category5</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">Short sleeve</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">,</span></span>
<span class="line"><span style="color: #D8DEE9FF">      </span><span style="color: #88C0D0">item_list_id</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">related_products</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">,</span></span>
<span class="line"><span style="color: #D8DEE9FF">      </span><span style="color: #88C0D0">item_list_name</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">Related Products</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">,</span></span>
<span class="line"><span style="color: #D8DEE9FF">      </span><span style="color: #88C0D0">item_variant</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">gray</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">,</span></span>
<span class="line"><span style="color: #D8DEE9FF">      </span><span style="color: #88C0D0">location_id</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">ChIJIQBpAG2ahYAR_6128GcTUEo</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">,</span></span>
<span class="line"><span style="color: #D8DEE9FF">      </span><span style="color: #88C0D0">price</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">20.99</span><span style="color: #ECEFF4">,</span></span>
<span class="line"><span style="color: #D8DEE9FF">      </span><span style="color: #88C0D0">promotion_id</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">P_12345</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">,</span></span>
<span class="line"><span style="color: #D8DEE9FF">      </span><span style="color: #88C0D0">promotion_name</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">Summer Sale</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">,</span></span>
<span class="line"><span style="color: #D8DEE9FF">      </span><span style="color: #88C0D0">quantity</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #B48EAD">1</span></span>
<span class="line"><span style="color: #D8DEE9FF">    </span><span style="color: #ECEFF4">}</span><span style="color: #D8DEE9FF">]</span></span>
<span class="line"><span style="color: #ECEFF4">}</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span></span></code></pre></div>



<p class="wp-block-paragraph">Visualizando o funil de vendas. Em Relatório > Monetization/sales/vendas > Purchase Journey.  Ficará algo parecido com isso:</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="1000" height="506" src="https://ramondomingos.com.br/wp-content/uploads/2024/09/image.png" alt="" class="wp-image-256" srcset="https://ramondomingos.com.br/wp-content/uploads/2024/09/image.png 1000w, https://ramondomingos.com.br/wp-content/uploads/2024/09/image-300x152.png 300w, https://ramondomingos.com.br/wp-content/uploads/2024/09/image-768x389.png 768w" sizes="(max-width: 1000px) 100vw, 1000px" /></figure>



<h2 class="wp-block-heading">Debug view</h2>



<p class="wp-block-paragraph">Os dados do GA podem demorar ate 24h para surgirem nos relatório. Para você acompanhar em tempo real os eventos chegando, voce pode adicionar o modo debug,</p>



<div class="wp-block-kevinbatdorf-code-block-pro" data-code-block-pro-font-family="Code-Pro-JetBrains-Mono" style="font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)"><span style="display:block;padding:16px 0 0 16px;margin-bottom:-1px;width:100%;text-align:left;background-color:#2e3440ff"><svg xmlns="http://www.w3.org/2000/svg" width="54" height="14" viewBox="0 0 54 14"><g fill="none" fill-rule="evenodd" transform="translate(1 1)"><circle cx="6" cy="6" r="6" fill="#FF5F56" stroke="#E0443E" stroke-width=".5"></circle><circle cx="26" cy="6" r="6" fill="#FFBD2E" stroke="#DEA123" stroke-width=".5"></circle><circle cx="46" cy="6" r="6" fill="#27C93F" stroke="#1AAB29" stroke-width=".5"></circle></g></svg></span><span role="button" tabindex="0" data-code=" window.gtag(&quot;event&quot;, event,{ ...eventParams, debug_mode: true});" style="color:#d8dee9ff;display:none" aria-label="Copy" class="code-block-pro-copy-button"><svg xmlns="http://www.w3.org/2000/svg" style="width:24px;height:24px" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path class="with-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4"></path><path class="without-check" stroke-linecap="round" stroke-linejoin="round" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path></svg></span><pre class="shiki nord" style="background-color: #2e3440ff" tabindex="0"><code><span class="line"><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">window</span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">gtag</span><span style="color: #D8DEE9FF">(</span><span style="color: #ECEFF4">&quot;</span><span style="color: #A3BE8C">event</span><span style="color: #ECEFF4">&quot;</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">event</span><span style="color: #ECEFF4">,{</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">...</span><span style="color: #D8DEE9">eventParams</span><span style="color: #ECEFF4">,</span><span style="color: #D8DEE9FF"> </span><span style="color: #88C0D0">debug_mode</span><span style="color: #ECEFF4">:</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">true</span><span style="color: #ECEFF4">}</span><span style="color: #D8DEE9FF">)</span><span style="color: #81A1C1">;</span></span></code></pre></div>



<p class="wp-block-paragraph">(lembra que falei de criar uma função e reutilizar?)</p>



<p class="wp-block-paragraph">Em admin > Data Display > Debug view. Você irá acompanhar em tempo real todos os eventos. </p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="561" src="https://ramondomingos.com.br/wp-content/uploads/2024/09/image-1-1024x561.png" alt="" class="wp-image-258" srcset="https://ramondomingos.com.br/wp-content/uploads/2024/09/image-1-1024x561.png 1024w, https://ramondomingos.com.br/wp-content/uploads/2024/09/image-1-300x164.png 300w, https://ramondomingos.com.br/wp-content/uploads/2024/09/image-1-768x421.png 768w, https://ramondomingos.com.br/wp-content/uploads/2024/09/image-1-1536x841.png 1536w, https://ramondomingos.com.br/wp-content/uploads/2024/09/image-1-2048x1122.png 2048w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>



<p class="wp-block-paragraph">Eventos que possuem parâmetros, como <strong>items</strong> ficará assim:</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="806" height="511" src="https://ramondomingos.com.br/wp-content/uploads/2024/09/image-2.png" alt="" class="wp-image-259" srcset="https://ramondomingos.com.br/wp-content/uploads/2024/09/image-2.png 806w, https://ramondomingos.com.br/wp-content/uploads/2024/09/image-2-300x190.png 300w, https://ramondomingos.com.br/wp-content/uploads/2024/09/image-2-768x487.png 768w" sizes="(max-width: 806px) 100vw, 806px" /></figure>



<p class="wp-block-paragraph">Você pode estranhar o preço. Mas nesse <a href="https://stackoverflow.com/questions/67224841/ga4-price-is-appended-with-multiple-zeros">link do StackOverflow</a>, encontrei esse reposta:</p>



<p class="wp-block-paragraph">Isso não é um problema em relatórios reais e só aparece no DebugView.</p>



<p class="wp-block-paragraph">Internamente, o valor é multiplicado por 1000000 para que possa ser armazenado como um inteiro para economizar espaço. A ferramenta de depuração falha em convertê-lo de volta, mas relatórios reais parecem acertar.</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="1024" height="332" src="https://ramondomingos.com.br/wp-content/uploads/2024/09/image-3-1024x332.png" alt="" class="wp-image-260" srcset="https://ramondomingos.com.br/wp-content/uploads/2024/09/image-3-1024x332.png 1024w, https://ramondomingos.com.br/wp-content/uploads/2024/09/image-3-300x97.png 300w, https://ramondomingos.com.br/wp-content/uploads/2024/09/image-3-768x249.png 768w, https://ramondomingos.com.br/wp-content/uploads/2024/09/image-3.png 1500w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>



<p class="wp-block-paragraph">Dominar o Google Analytics é uma habilidade fundamental para qualquer desenvolvedor que busca criar produtos digitais de sucesso. Ao entender como os usuários interagem com seus aplicativos, você pode tomar decisões mais informadas e entregar experiências cada vez melhores.</p>



<p class="wp-block-paragraph"><strong>Dicas Extras:</strong></p>



<ul class="wp-block-list">
<li><strong>Personalização:</strong> Explore as opções de personalização do Google Analytics para criar relatórios personalizados e segmentar seus dados.</li>



<li><strong>Integrações:</strong> Descubra as diversas integrações do Google Analytics com outras ferramentas para obter uma visão mais completa dos seus dados.</li>



<li><strong>Aprendizado Contínuo:</strong> O Google Analytics está em constante evolução. Mantenha-se atualizado sobre as novas funcionalidades e recursos.</li>
</ul>



<p class="wp-block-paragraph">E aí, gostou deste guia? Compartilhe suas experiências nos comentários e me diga quais outras ferramentas você utiliza para analisar seus projetos.</p>
<p>O post <a href="https://ramondomingos.com.br/desenvolvedores-precisam-dominar-o-google-analytics-um-guia-pratico-com-next-js/">Desenvolvedores precisam Dominar o Google Analytics? Um Guia Prático com Next.js</a> apareceu primeiro em <a href="https://ramondomingos.com.br">Ramon Domingos Blog</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://ramondomingos.com.br/desenvolvedores-precisam-dominar-o-google-analytics-um-guia-pratico-com-next-js/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>
