

{"id":204973,"date":"2025-07-16T08:53:39","date_gmt":"2025-07-16T11:53:39","guid":{"rendered":"https:\/\/goias.gov.br\/ligo\/?p=204973"},"modified":"2025-08-25T11:50:34","modified_gmt":"2025-08-25T14:50:34","slug":"criando-um-agente-de-ia-local-e-personalizado-com-google-adk-sem-e-com-mcp","status":"publish","type":"post","link":"https:\/\/goias.gov.br\/ligo\/criando-um-agente-de-ia-local-e-personalizado-com-google-adk-sem-e-com-mcp\/","title":{"rendered":"Criando um Agente de IA Local e Personalizado com Google ADK, sem e com MCP"},"content":{"rendered":"<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img fetchpriority=\"high\" decoding=\"async\" width=\"960\" height=\"500\" src=\"https:\/\/goias.gov.br\/ligo\/wp-content\/uploads\/sites\/61\/2025\/07\/agente-adk-mcp-teste-1.png\" alt=\"\" class=\"wp-image-205138\" srcset=\"https:\/\/goias.gov.br\/ligo\/wp-content\/uploads\/sites\/61\/2025\/07\/agente-adk-mcp-teste-1.png 960w, https:\/\/goias.gov.br\/ligo\/wp-content\/uploads\/sites\/61\/2025\/07\/agente-adk-mcp-teste-1-300x156.png 300w, https:\/\/goias.gov.br\/ligo\/wp-content\/uploads\/sites\/61\/2025\/07\/agente-adk-mcp-teste-1-768x400.png 768w\" sizes=\"(max-width: 960px) 100vw, 960px\" \/><\/figure>\n<\/div>\n\n\n<p>Neste guia detalhado, voc\u00ea aprender\u00e1 a configurar um agente inteligente local utilizando o Google Agent Development Kit (ADK) sem e com servidor Model Context Protocol (MCP). Esta abordagem \u00e9 ideal para projetos que exigem privacidade, controle total e flexibilidade, especialmente em cen\u00e1rios sens\u00edveis ou opera\u00e7\u00f5es offline. A grande vantagem de um agente local \u00e9 que ele permite o desenvolvimento e a execu\u00e7\u00e3o de funcionalidades de IA no seu pr\u00f3prio ambiente, sem depender de servi\u00e7os em nuvem externos, garantindo assim maior autonomia e seguran\u00e7a de dados.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Componentes Chave:<\/strong><\/h2>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>1. Google ADK (Agent Development Kit):<\/strong><\/h2>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;\u25e6 O ADK \u00e9 um framework robusto da Google projetado para facilitar a cria\u00e7\u00e3o de agentes inteligentes.<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;\u25e6 Ele oferece suporte nativo a ferramentas personalizadas e capacidades de orquestra\u00e7\u00e3o, permitindo a constru\u00e7\u00e3o de arquiteturas de agente modulares e escal\u00e1veis.<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;\u25e6 O ADK suporta diversas formas de intera\u00e7\u00e3o, incluindo HTTP, Server-Sent Events (SSE) e at\u00e9 mesmo comunica\u00e7\u00e3o via processos stdio. Para mais detalhes, voc\u00ea pode consultar a documenta\u00e7\u00e3o oficial.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>2. MCP (Model Context Protocol) &#8211; Opcional:<\/strong><\/h2>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;\u25e6 O Model Context Protocol \u00e9 uma forma padronizada e organizada de estruturar as informa\u00e7\u00f5es que s\u00e3o enviadas para Modelos de Linguagem (LLMs).<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;\u25e6 Seu objetivo \u00e9 otimizar a comunica\u00e7\u00e3o com LLMs, tornando-a mais eficiente e consistente.<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;\u25e6 \u00c9 importante notar que, embora o MCP possa ser utilizado, a cria\u00e7\u00e3o do agente local com o Google <\/p>\n\n\n\n<p>ADK pode ser feita com ou sem um servidor MCP.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Guia de Implementa\u00e7\u00e3o:<\/strong><\/h2>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>1. Instalando as Depend\u00eancias:<\/strong><\/h2>\n\n\n\n<p>Para come\u00e7ar, voc\u00ea precisar\u00e1 instalar as bibliotecas necess\u00e1rias. Escolha o gerenciador de pacotes de sua prefer\u00eancia:<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;\u25e6 Usando pip:&nbsp;<\/p>\n\n\n\n<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:#1E1E1E\"><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:#D4D4D4;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><textarea class=\"code-block-pro-copy-button-textarea\" aria-hidden=\"true\" readonly>pip install google-adk litellm<\/textarea><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 dark-plus\" style=\"background-color: #1E1E1E\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D4D4D4\">pip install google-adk litellm<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;\u25e6 Usando uv (alternativa mais r\u00e1pida):<\/p>\n\n\n\n<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:#1E1E1E\"><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:#D4D4D4;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><textarea class=\"code-block-pro-copy-button-textarea\" aria-hidden=\"true\" readonly>pip install uv\nuv init\nuv add google-adk litellm<\/textarea><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 dark-plus\" style=\"background-color: #1E1E1E\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D4D4D4\">pip install uv<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">uv init<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">uv add google-adk litellm<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p>Estas ferramentas s\u00e3o essenciais para o desenvolvimento com Google ADK, sendo o litellm crucial para a integra\u00e7\u00e3o com modelos de linguagem locais.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>2. Criando a Estrutura B\u00e1sica do Agente:<\/strong><\/h2>\n\n\n\n<p>O Google ADK simplifica o in\u00edcio de novos projetos, fornecendo um comando para gerar uma estrutura de arquivos b\u00e1sicos, eliminando a necessidade de come\u00e7ar do zero. No seu ambiente onde o google-adk foi instalado, execute:<\/p>\n\n\n\n<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:#1E1E1E\"><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:#D4D4D4;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><textarea class=\"code-block-pro-copy-button-textarea\" aria-hidden=\"true\" readonly>adk create primeiro_agente<\/textarea><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 dark-plus\" style=\"background-color: #1E1E1E\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D4D4D4\">adk create primeiro_agente<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p>Este comando cria automaticamente a estrutura de diret\u00f3rios e arquivos fundamentais para o seu agente.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>3. Configurando o Modelo Local e Importa\u00e7\u00f5es:<\/strong><\/h2>\n\n\n\n<p>Para utilizar um modelo de linguagem local, \u00e9 necess\u00e1rio importar as classes Agent e LiteLlm do Google ADK. A classe LiteLlm \u00e9 a ponte para a integra\u00e7\u00e3o com modelos locais:<\/p>\n\n\n\n<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:#1E1E1E\"><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:#D4D4D4;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><textarea class=\"code-block-pro-copy-button-textarea\" aria-hidden=\"true\" readonly>from google.adk.agents import Agent\nfrom google.adk.models.lite_llm import LiteLlm<\/textarea><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 dark-plus\" style=\"background-color: #1E1E1E\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #C586C0\">from<\/span><span style=\"color: #D4D4D4\"> google.adk.agents <\/span><span style=\"color: #C586C0\">import<\/span><span style=\"color: #D4D4D4\"> Agent<\/span><\/span>\n<span class=\"line\"><span style=\"color: #C586C0\">from<\/span><span style=\"color: #D4D4D4\"> google.adk.models.lite_llm <\/span><span style=\"color: #C586C0\">import<\/span><span style=\"color: #D4D4D4\"> LiteLlm<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p>O LiteLlm permite que voc\u00ea especifique o modelo local a ser usado, como um servidor Ollama configurado na sua m\u00e1quina.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>4. Desenvolvendo uma Ferramenta Personalizada:<\/strong><\/h2>\n\n\n\n<p>Agentes inteligentes frequentemente precisam interagir com o mundo exterior para coletar informa\u00e7\u00f5es ou executar a\u00e7\u00f5es. No Google ADK, isso \u00e9 feito atrav\u00e9s de ferramentas (tools). Vamos criar uma ferramenta simples para obter a hora atual:<\/p>\n\n\n\n<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:#1E1E1E\"><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:#D4D4D4;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><textarea class=\"code-block-pro-copy-button-textarea\" aria-hidden=\"true\" readonly>from datetime import datetime\nfrom typing import Final\ndef pegar_horas() -> dict:\n\u00a0\u00a0\u00a0 &#8220;&#8221;&#8221;\n\u00a0\u00a0\u00a0 Ferramenta: Obter a hora atual.\n\u00a0\u00a0\u00a0 Descri\u00e7\u00e3o:\n\u00a0\u00a0\u00a0 Retorna a hora atual do sistema no formato &#8220;HH:MM:SS&#8221;.\n\u00a0\u00a0\u00a0 Par\u00e2metros:\n\u00a0\u00a0\u00a0 &#8211; Nenhum\n\u00a0\u00a0\u00a0 Retorna:\n\u00a0\u00a0\u00a0 &#8211; Um dicion\u00e1rio com a hora atual.\n\u00a0\u00a0\u00a0 &#8220;&#8221;&#8221;\n\u00a0\u00a0\u00a0 agora: Final[datetime] = datetime.now()\n\u00a0\u00a0\u00a0 hora_formatada: str = agora.strftime(&#8220;%H:%M:%S&#8221;)\n\u00a0\u00a0\u00a0 return {&#8220;text&#8221;: hora_formatada}<\/textarea><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 dark-plus\" style=\"background-color: #1E1E1E\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #C586C0\">from<\/span><span style=\"color: #D4D4D4\"> datetime <\/span><span style=\"color: #C586C0\">import<\/span><span style=\"color: #D4D4D4\"> datetime<\/span><\/span>\n<span class=\"line\"><span style=\"color: #C586C0\">from<\/span><span style=\"color: #D4D4D4\"> typing <\/span><span style=\"color: #C586C0\">import<\/span><span style=\"color: #D4D4D4\"> Final<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #569CD6\">def<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">pegar_horas<\/span><span style=\"color: #D4D4D4\">() -&gt; <\/span><span style=\"color: #4EC9B0\">dict<\/span><span style=\"color: #D4D4D4\">:<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\u00a0\u00a0\u00a0 <\/span><span style=\"color: #CE9178\">&quot;&quot;&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #CE9178\">\u00a0\u00a0\u00a0 Ferramenta: Obter a hora atual.<\/span><\/span>\n<span class=\"line\"><span style=\"color: #CE9178\">\u00a0\u00a0\u00a0 Descri\u00e7\u00e3o:<\/span><\/span>\n<span class=\"line\"><span style=\"color: #CE9178\">\u00a0\u00a0\u00a0 Retorna a hora atual do sistema no formato &quot;HH:MM:SS&quot;.<\/span><\/span>\n<span class=\"line\"><span style=\"color: #CE9178\">\u00a0\u00a0\u00a0 Par\u00e2metros:<\/span><\/span>\n<span class=\"line\"><span style=\"color: #CE9178\">\u00a0\u00a0\u00a0 - Nenhum<\/span><\/span>\n<span class=\"line\"><span style=\"color: #CE9178\">\u00a0\u00a0\u00a0 Retorna:<\/span><\/span>\n<span class=\"line\"><span style=\"color: #CE9178\">\u00a0\u00a0\u00a0 - Um dicion\u00e1rio com a hora atual.<\/span><\/span>\n<span class=\"line\"><span style=\"color: #CE9178\">\u00a0\u00a0\u00a0 &quot;&quot;&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\u00a0\u00a0\u00a0 agora: Final[datetime] = datetime.now()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\u00a0\u00a0\u00a0 hora_formatada: <\/span><span style=\"color: #4EC9B0\">str<\/span><span style=\"color: #D4D4D4\"> = agora.strftime(<\/span><span style=\"color: #CE9178\">&quot;%H:%M:%S&quot;<\/span><span style=\"color: #D4D4D4\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\u00a0\u00a0\u00a0 <\/span><span style=\"color: #C586C0\">return<\/span><span style=\"color: #D4D4D4\"> {<\/span><span style=\"color: #CE9178\">&quot;text&quot;<\/span><span style=\"color: #D4D4D4\">: hora_formatada}<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p>Pontos Cruciais para Ferramentas:<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;\u25e6 Documenta\u00e7\u00e3o Clara: \u00c9 fundamental que a fun\u00e7\u00e3o esteja muito bem documentada (usando docstrings). Essa documenta\u00e7\u00e3o \u00e9 o que permite ao agente saber como e por que usar a ferramenta, interpretando sua finalidade e seus par\u00e2metros.<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;\u25e6 Retorno de Dicion\u00e1rio: A fun\u00e7\u00e3o deve retornar um dicion\u00e1rio (dict), pois este \u00e9 o padr\u00e3o esperado pelo Google ADK para processar as sa\u00eddas das ferramentas.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>5. Construindo o Primeiro Agente:<\/strong><\/h2>\n\n\n\n<p>Finalmente, iremos instanciar nosso agente principal, configurando seu modelo, nome, descri\u00e7\u00e3o, instru\u00e7\u00f5es e as ferramentas que ele pode utilizar:<\/p>\n\n\n\n<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:#1E1E1E\"><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:#D4D4D4;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><textarea class=\"code-block-pro-copy-button-textarea\" aria-hidden=\"true\" readonly>ollama_endpoint = &#8220;http:\/\/localhost:11434&#8243;\nroot_agent = Agent(\n\u00a0\u00a0\u00a0 model=LiteLlm(model=&#8221;ollama_chat\/qwen2.5:14b&#8221;, base_url=ollama_endpoint),\n\u00a0\u00a0\u00a0 name=&#8217;root_agent&#8217;,\n\u00a0\u00a0\u00a0 description=&#8217;Voc\u00ea \u00e9 um assistente que responde perguntas.&#8217;,\n\u00a0\u00a0\u00a0 instruction=&#8221;&#8217;Voc\u00ea \u00e9 um agente inteligente.\n\u00a0\u00a0\u00a0 Ferramentas:\n\u00a0\u00a0\u00a0 pegar_horas()\n\u00a0\u00a0\u00a0 Retorna a hora atual do sistema.\n\u00a0\u00a0\u00a0 &#8221;&#8217;,\n\u00a0\u00a0\u00a0 tools=[pegar_horas]\n)<\/textarea><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 dark-plus\" style=\"background-color: #1E1E1E\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D4D4D4\">ollama_endpoint = <\/span><span style=\"color: #CE9178\">&quot;http:\/\/localhost:11434&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">root_agent = Agent(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\u00a0\u00a0\u00a0 <\/span><span style=\"color: #9CDCFE\">model<\/span><span style=\"color: #D4D4D4\">=LiteLlm(<\/span><span style=\"color: #9CDCFE\">model<\/span><span style=\"color: #D4D4D4\">=<\/span><span style=\"color: #CE9178\">&quot;ollama_chat\/qwen2.5:14b&quot;<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #9CDCFE\">base_url<\/span><span style=\"color: #D4D4D4\">=ollama_endpoint),<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\u00a0\u00a0\u00a0 <\/span><span style=\"color: #9CDCFE\">name<\/span><span style=\"color: #D4D4D4\">=<\/span><span style=\"color: #CE9178\">&#39;root_agent&#39;<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\u00a0\u00a0\u00a0 <\/span><span style=\"color: #9CDCFE\">description<\/span><span style=\"color: #D4D4D4\">=<\/span><span style=\"color: #CE9178\">&#39;Voc\u00ea \u00e9 um assistente que responde perguntas.&#39;<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\u00a0\u00a0\u00a0 <\/span><span style=\"color: #9CDCFE\">instruction<\/span><span style=\"color: #D4D4D4\">=<\/span><span style=\"color: #CE9178\">&#39;&#39;&#39;Voc\u00ea \u00e9 um agente inteligente.<\/span><\/span>\n<span class=\"line\"><span style=\"color: #CE9178\">\u00a0\u00a0\u00a0 Ferramentas:<\/span><\/span>\n<span class=\"line\"><span style=\"color: #CE9178\">\u00a0\u00a0\u00a0 pegar_horas()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #CE9178\">\u00a0\u00a0\u00a0 Retorna a hora atual do sistema.<\/span><\/span>\n<span class=\"line\"><span style=\"color: #CE9178\">\u00a0\u00a0\u00a0 &#39;&#39;&#39;<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\u00a0\u00a0\u00a0 <\/span><span style=\"color: #9CDCFE\">tools<\/span><span style=\"color: #D4D4D4\">=[pegar_horas]<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">)<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p>Detalhes Importantes da Configura\u00e7\u00e3o do Agente:<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;\u25e6 model: Este par\u00e2metro utiliza a classe LiteLlm para configurar o modelo de linguagem local.<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\u25aa model=&#8221;ollama_chat\/qwen2.5:14b&#8221;: Define o nome do modelo espec\u00edfico que o agente utilizar\u00e1. Voc\u00ea pode alterar este valor conforme o modelo local que voc\u00ea tiver dispon\u00edvel.<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\u25aa base_url=ollama_endpoint: Aponta para o endere\u00e7o do seu servidor de modelo local (neste exemplo, um servidor Ollama rodando na porta 11434).<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;\u25e6 name e description: Atribuem um nome e uma breve descri\u00e7\u00e3o ao agente, auxiliando na sua identifica\u00e7\u00e3o.<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;\u25e6 instruction: Fornece as diretrizes e o comportamento esperado do agente. \u00c9 aqui que voc\u00ea tamb\u00e9m lista as ferramentas dispon\u00edveis, descrevendo brevemente suas funcionalidades para que o agente possa decidir quando us\u00e1-las.<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;\u25e6 tools: Uma lista das fun\u00e7\u00f5es (ferramentas) que o agente pode chamar. \u00c9 crucial que as fun\u00e7\u00f5es adicionadas aqui estejam corretamente documentadas para que o Google ADK as reconhe\u00e7a.<\/p>\n\n\n\n<p>Ap\u00f3s configurar o agente, o Google ADK oferece uma interface web intuitiva para test\u00e1-lo e interagir:<\/p>\n\n\n\n<p>No terminal, navegue at\u00e9 o diret\u00f3rio do seu projeto e digite:<\/p>\n\n\n\n<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:#1E1E1E\"><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:#D4D4D4;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><textarea class=\"code-block-pro-copy-button-textarea\" aria-hidden=\"true\" readonly>adk web<\/textarea><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 dark-plus\" style=\"background-color: #1E1E1E\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D4D4D4\">adk web<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p>Este comando iniciar\u00e1 o servidor web do ADK.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" width=\"886\" height=\"315\" src=\"https:\/\/goias.gov.br\/ligo\/wp-content\/uploads\/sites\/61\/2025\/07\/image.png\" alt=\"\" class=\"wp-image-204964\" srcset=\"https:\/\/goias.gov.br\/ligo\/wp-content\/uploads\/sites\/61\/2025\/07\/image.png 886w, https:\/\/goias.gov.br\/ligo\/wp-content\/uploads\/sites\/61\/2025\/07\/image-300x107.png 300w, https:\/\/goias.gov.br\/ligo\/wp-content\/uploads\/sites\/61\/2025\/07\/image-768x273.png 768w\" sizes=\"(max-width: 886px) 100vw, 886px\" \/><\/figure>\n\n\n\n<p>Abra seu navegador e acesse o endere\u00e7o:<\/p>\n\n\n\n<p>http:\/\/localhost:8000<\/p>\n\n\n\n<p>Voc\u00ea ver\u00e1 a interface do Google ADK.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" width=\"886\" height=\"369\" src=\"https:\/\/goias.gov.br\/ligo\/wp-content\/uploads\/sites\/61\/2025\/07\/image-1.png\" alt=\"\" class=\"wp-image-204965\" srcset=\"https:\/\/goias.gov.br\/ligo\/wp-content\/uploads\/sites\/61\/2025\/07\/image-1.png 886w, https:\/\/goias.gov.br\/ligo\/wp-content\/uploads\/sites\/61\/2025\/07\/image-1-300x125.png 300w, https:\/\/goias.gov.br\/ligo\/wp-content\/uploads\/sites\/61\/2025\/07\/image-1-768x320.png 768w\" sizes=\"(max-width: 886px) 100vw, 886px\" \/><\/figure>\n\n\n\n<p>Selecione o agente que voc\u00ea acabou de criar e comece a interagir com ele.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"885\" height=\"346\" src=\"https:\/\/goias.gov.br\/ligo\/wp-content\/uploads\/sites\/61\/2025\/07\/image-2.png\" alt=\"\" class=\"wp-image-204966\" srcset=\"https:\/\/goias.gov.br\/ligo\/wp-content\/uploads\/sites\/61\/2025\/07\/image-2.png 885w, https:\/\/goias.gov.br\/ligo\/wp-content\/uploads\/sites\/61\/2025\/07\/image-2-300x117.png 300w, https:\/\/goias.gov.br\/ligo\/wp-content\/uploads\/sites\/61\/2025\/07\/image-2-768x300.png 768w\" sizes=\"(max-width: 885px) 100vw, 885px\" \/><\/figure>\n\n\n\n<p>Comportamento Inteligente do Agente:<\/p>\n\n\n\n<p>Observe que, mesmo em intera\u00e7\u00f5es iniciais onde uma ferramenta pode n\u00e3o ser necess\u00e1ria, o agente \u00e9 capaz de discernir quando e como utilizar a ferramenta criada para fornecer a resposta mais adequada ao usu\u00e1rio. Por exemplo, ao perguntar &#8220;Que horas s\u00e3o?&#8221;,<strong> o agente identificar\u00e1 a necessidade de usar a fun\u00e7\u00e3o pegar_horas() para responder.<\/strong><\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>6. Entendendo o MCP (Model Context Protocol)<\/strong><\/h2>\n\n\n\n<p>Antes de mergulhar na implementa\u00e7\u00e3o, \u00e9 \u00fatil refor\u00e7ar o papel do MCP. Ele \u00e9 uma forma padronizada e organizada de <strong>estruturar as informa\u00e7\u00f5es enviadas para Modelos de Linguagem (LLMs)<\/strong>, visando <strong>otimizar a comunica\u00e7\u00e3o com LLMs, tornando-a mais eficiente e consistente<\/strong>. Embora seja opcional, ele permite uma abordagem mais robusta para o gerenciamento de ferramentas.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>7. Criando o Servidor MCP (Etapas e Componentes Chave)<\/strong><\/h2>\n\n\n\n<p>A se\u00e7\u00e3o do seu artigo pode detalhar as seguintes etapas para criar o servidor MCP:<\/p>\n\n\n\n<p>Importando as Bibliotecas Necess\u00e1rias:<\/p>\n\n\n\n<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:#1E1E1E\"><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:#D4D4D4;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><textarea class=\"code-block-pro-copy-button-textarea\" aria-hidden=\"true\" readonly>import asyncio\nimport json\nimport mcp.server.stdio \nfrom google.adk.tools.function_tool import FunctionTool\nfrom google.adk.tools.mcp_tool.conversion_utils import adk_to_mcp_tool_type\nfrom mcp import types as mcp_types\nfrom mcp.server.lowlevel import NotificationOptions, Server\nfrom mcp.server.models import InitializationOptions<\/textarea><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 dark-plus\" style=\"background-color: #1E1E1E\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #C586C0\">import<\/span><span style=\"color: #D4D4D4\"> asyncio<\/span><\/span>\n<span class=\"line\"><span style=\"color: #C586C0\">import<\/span><span style=\"color: #D4D4D4\"> json<\/span><\/span>\n<span class=\"line\"><span style=\"color: #C586C0\">import<\/span><span style=\"color: #D4D4D4\"> mcp.server.stdio <\/span><\/span>\n<span class=\"line\"><span style=\"color: #C586C0\">from<\/span><span style=\"color: #D4D4D4\"> google.adk.tools.function_tool <\/span><span style=\"color: #C586C0\">import<\/span><span style=\"color: #D4D4D4\"> FunctionTool<\/span><\/span>\n<span class=\"line\"><span style=\"color: #C586C0\">from<\/span><span style=\"color: #D4D4D4\"> google.adk.tools.mcp_tool.conversion_utils <\/span><span style=\"color: #C586C0\">import<\/span><span style=\"color: #D4D4D4\"> adk_to_mcp_tool_type<\/span><\/span>\n<span class=\"line\"><span style=\"color: #C586C0\">from<\/span><span style=\"color: #D4D4D4\"> mcp <\/span><span style=\"color: #C586C0\">import<\/span><span style=\"color: #D4D4D4\"> types <\/span><span style=\"color: #C586C0\">as<\/span><span style=\"color: #D4D4D4\"> mcp_types<\/span><\/span>\n<span class=\"line\"><span style=\"color: #C586C0\">from<\/span><span style=\"color: #D4D4D4\"> mcp.server.lowlevel <\/span><span style=\"color: #C586C0\">import<\/span><span style=\"color: #D4D4D4\"> NotificationOptions, Server<\/span><\/span>\n<span class=\"line\"><span style=\"color: #C586C0\">from<\/span><span style=\"color: #D4D4D4\"> mcp.server.models <\/span><span style=\"color: #C586C0\">import<\/span><span style=\"color: #D4D4D4\"> InitializationOptions<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;\u25e6 Para come\u00e7ar a construir o servidor MCP, \u00e9 fundamental importar um conjunto espec\u00edfico de bibliotecas. Isso inclui asyncio e json para opera\u00e7\u00f5es gerais, al\u00e9m de m\u00f3dulos espec\u00edficos do MCP (mcp.server.stdio, mcp.types, mcp.server.lowlevel, mcp.server.models) e do Google ADK para ferramentas (google.adk.tools.function_tool, google.adk.tools.mcp_tool.conversion_utils, google.adk.tools.mcp_tool.mcp_session_manager).<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;\u25e6 Um ponto <strong>importante a destacar<\/strong> \u00e9 a fun\u00e7\u00e3o adk_to_mcp_tool_type, que \u00e9 uma funcionalidade nativa do Google ADK para <strong>converter fun\u00e7\u00f5es Python diretamente para o protocolo de comunica\u00e7\u00e3o necess\u00e1rio para o MCP<\/strong>.<\/p>\n\n\n\n<p>Definindo as Ferramentas para o MCP Server:<\/p>\n\n\n\n<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:#1E1E1E\"><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:#D4D4D4;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><textarea class=\"code-block-pro-copy-button-textarea\" aria-hidden=\"true\" readonly>from datetime import datetime\nfrom typing import Final\ndef pegar_horas() -> dict:\n    &#8220;&#8221;&#8221;\n    Ferramenta: Obter a hora atual.\n    Descri\u00e7\u00e3o:\n    Retorna a hora atual do sistema no formato &#8220;HH:MM:SS&#8221;.\n    Par\u00e2metros:\n    &#8211; Nenhum\n    Retorna:\n    &#8211; Um dicion\u00e1rio com a hora atual.\n    &#8220;&#8221;&#8221;\n    agora: Final[datetime] = datetime.now()\n    hora_formatada: str = agora.strftime(&#8220;%H:%M:%S&#8221;)\n    return {&#8220;text&#8221;: hora_formatada}\n# &#8212; MCP Server Setup &#8212;\napp = Server(&#8220;mcp-server&#8221;)\n# Coloque todas as ferramentas\nADK_DB_TOOLS = {\n    &#8220;pegar_horas&#8221;: FunctionTool(func=pegar_horas)\n}<\/textarea><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 dark-plus\" style=\"background-color: #1E1E1E\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #C586C0\">from<\/span><span style=\"color: #D4D4D4\"> datetime <\/span><span style=\"color: #C586C0\">import<\/span><span style=\"color: #D4D4D4\"> datetime<\/span><\/span>\n<span class=\"line\"><span style=\"color: #C586C0\">from<\/span><span style=\"color: #D4D4D4\"> typing <\/span><span style=\"color: #C586C0\">import<\/span><span style=\"color: #D4D4D4\"> Final<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #569CD6\">def<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">pegar_horas<\/span><span style=\"color: #D4D4D4\">() -&gt; <\/span><span style=\"color: #4EC9B0\">dict<\/span><span style=\"color: #D4D4D4\">:<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #CE9178\">&quot;&quot;&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #CE9178\">    Ferramenta: Obter a hora atual.<\/span><\/span>\n<span class=\"line\"><span style=\"color: #CE9178\">    Descri\u00e7\u00e3o:<\/span><\/span>\n<span class=\"line\"><span style=\"color: #CE9178\">    Retorna a hora atual do sistema no formato &quot;HH:MM:SS&quot;.<\/span><\/span>\n<span class=\"line\"><span style=\"color: #CE9178\">    Par\u00e2metros:<\/span><\/span>\n<span class=\"line\"><span style=\"color: #CE9178\">    - Nenhum<\/span><\/span>\n<span class=\"line\"><span style=\"color: #CE9178\">    Retorna:<\/span><\/span>\n<span class=\"line\"><span style=\"color: #CE9178\">    - Um dicion\u00e1rio com a hora atual.<\/span><\/span>\n<span class=\"line\"><span style=\"color: #CE9178\">    &quot;&quot;&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    agora: Final[datetime] = datetime.now()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    hora_formatada: <\/span><span style=\"color: #4EC9B0\">str<\/span><span style=\"color: #D4D4D4\"> = agora.strftime(<\/span><span style=\"color: #CE9178\">&quot;%H:%M:%S&quot;<\/span><span style=\"color: #D4D4D4\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #C586C0\">return<\/span><span style=\"color: #D4D4D4\"> {<\/span><span style=\"color: #CE9178\">&quot;text&quot;<\/span><span style=\"color: #D4D4D4\">: hora_formatada}<\/span><\/span>\n<span class=\"line\"><span style=\"color: #6A9955\"># --- MCP Server Setup ---<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">app = Server(<\/span><span style=\"color: #CE9178\">&quot;mcp-server&quot;<\/span><span style=\"color: #D4D4D4\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #6A9955\"># Coloque todas as ferramentas<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">ADK_DB_TOOLS = {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #CE9178\">&quot;pegar_horas&quot;<\/span><span style=\"color: #D4D4D4\">: FunctionTool(<\/span><span style=\"color: #9CDCFE\">func<\/span><span style=\"color: #D4D4D4\">=pegar_horas)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">}<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;\u25e6 A fonte demonstra a reutiliza\u00e7\u00e3o da ferramenta pegar_horas() (obter a hora atual). Essa ferramenta, assim como outras que voc\u00ea possa criar, ser\u00e1 exposta pelo servidor MCP.<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;\u25e6 As ferramentas s\u00e3o armazenadas em um dicion\u00e1rio, ADK_DB_TOOLS, onde a chave \u00e9 o nome da ferramenta e o valor \u00e9 uma inst\u00e2ncia de FunctionTool do Google ADK, que encapsula a fun\u00e7\u00e3o Python. Exemplo: ADK_DB_TOOLS = {&#8220;pegar_horas&#8221;: FunctionTool(func=pegar_horas)}.<\/p>\n\n\n\n<p>Implementando as Fun\u00e7\u00f5es Essenciais do Servidor MCP:<\/p>\n\n\n\n<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:#1E1E1E\"><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:#D4D4D4;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><textarea class=\"code-block-pro-copy-button-textarea\" aria-hidden=\"true\" readonly>@app.list_tools() \nasync def list_mcp_tools() -> list[mcp_types.Tool]:\n    &#8220;&#8221;&#8221;MCP handler to list tools this server exposes.&#8221;&#8221;&#8221;\n    mcp_tools_list = []\n    for tool_name, adk_tool_instance in ADK_DB_TOOLS.items():\n        if not adk_tool_instance.name:\n            adk_tool_instance.name = tool_name\n        mcp_tool_schema = adk_to_mcp_tool_type(adk_tool_instance)\n        mcp_tools_list.append(mcp_tool_schema)\n    return mcp_tools_list\n@app.call_tool()\nasync def call_mcp_tool(name: str, arguments: dict) -> list[mcp_types.TextContent]:\n    &#8220;&#8221;&#8221;MCP handler to execute a tool call requested by an MCP client.&#8221;&#8221;&#8221;\n    if name in ADK_DB_TOOLS:\n        adk_tool_instance = ADK_DB_TOOLS[name]\n        try:\n            adk_tool_response = await adk_tool_instance.run_async(\n                args=arguments,\n                tool_context=None,  # type: ignore\n            )\n            response_text = json.dumps(adk_tool_response, indent=2)\n            return [mcp_types.TextContent(type=&#8221;text&#8221;, text=response_text)]\n        except Exception as e:\n            error_payload = {\n                &#8220;success&#8221;: False,\n                &#8220;message&#8221;: f&#8221;Failed to execute tool &#8216;{name}&#8217;: {str(e)}&#8221;,\n            }\n            error_text = json.dumps(error_payload)\n            return [mcp_types.TextContent(type=&#8221;text&#8221;, text=error_text)]\n    else:\n        error_payload = {\n            &#8220;success&#8221;: False,\n            &#8220;message&#8221;: f&#8221;Tool &#8216;{name}&#8217; not implemented by this server.&#8221;,\n        }\n        error_text = json.dumps(error_payload)\n        return [mcp_types.TextContent(type=&#8221;text&#8221;, text=error_text)]\n<\/textarea><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 dark-plus\" style=\"background-color: #1E1E1E\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #DCDCAA\">@app.list_tools<\/span><span style=\"color: #D4D4D4\">() <\/span><\/span>\n<span class=\"line\"><span style=\"color: #569CD6\">async<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">def<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">list_mcp_tools<\/span><span style=\"color: #D4D4D4\">() -&gt; list[mcp_types.Tool]:<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #CE9178\">&quot;&quot;&quot;MCP handler to list tools this server exposes.&quot;&quot;&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    mcp_tools_list = []<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #C586C0\">for<\/span><span style=\"color: #D4D4D4\"> tool_name, adk_tool_instance <\/span><span style=\"color: #C586C0\">in<\/span><span style=\"color: #D4D4D4\"> ADK_DB_TOOLS.items():<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #C586C0\">if<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">not<\/span><span style=\"color: #D4D4D4\"> adk_tool_instance.name:<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">            adk_tool_instance.name = tool_name<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        mcp_tool_schema = adk_to_mcp_tool_type(adk_tool_instance)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        mcp_tools_list.append(mcp_tool_schema)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #C586C0\">return<\/span><span style=\"color: #D4D4D4\"> mcp_tools_list<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #DCDCAA\">@app.call_tool<\/span><span style=\"color: #D4D4D4\">()<\/span><\/span>\n<span class=\"line\"><span style=\"color: #569CD6\">async<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">def<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">call_mcp_tool<\/span><span style=\"color: #D4D4D4\">(<\/span><span style=\"color: #9CDCFE\">name<\/span><span style=\"color: #D4D4D4\">: <\/span><span style=\"color: #4EC9B0\">str<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #9CDCFE\">arguments<\/span><span style=\"color: #D4D4D4\">: <\/span><span style=\"color: #4EC9B0\">dict<\/span><span style=\"color: #D4D4D4\">) -&gt; list[mcp_types.TextContent]:<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #CE9178\">&quot;&quot;&quot;MCP handler to execute a tool call requested by an MCP client.&quot;&quot;&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #C586C0\">if<\/span><span style=\"color: #D4D4D4\"> name <\/span><span style=\"color: #569CD6\">in<\/span><span style=\"color: #D4D4D4\"> ADK_DB_TOOLS:<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        adk_tool_instance = ADK_DB_TOOLS[name]<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #C586C0\">try<\/span><span style=\"color: #D4D4D4\">:<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">            adk_tool_response = <\/span><span style=\"color: #C586C0\">await<\/span><span style=\"color: #D4D4D4\"> adk_tool_instance.run_async(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                <\/span><span style=\"color: #9CDCFE\">args<\/span><span style=\"color: #D4D4D4\">=arguments,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                <\/span><span style=\"color: #9CDCFE\">tool_context<\/span><span style=\"color: #D4D4D4\">=<\/span><span style=\"color: #569CD6\">None<\/span><span style=\"color: #D4D4D4\">,  <\/span><span style=\"color: #6A9955\"># type: ignore<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">            )<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">            response_text = json.dumps(adk_tool_response, <\/span><span style=\"color: #9CDCFE\">indent<\/span><span style=\"color: #D4D4D4\">=<\/span><span style=\"color: #B5CEA8\">2<\/span><span style=\"color: #D4D4D4\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">            <\/span><span style=\"color: #C586C0\">return<\/span><span style=\"color: #D4D4D4\"> [mcp_types.TextContent(<\/span><span style=\"color: #9CDCFE\">type<\/span><span style=\"color: #D4D4D4\">=<\/span><span style=\"color: #CE9178\">&quot;text&quot;<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #9CDCFE\">text<\/span><span style=\"color: #D4D4D4\">=response_text)]<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #C586C0\">except<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #4EC9B0\">Exception<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #C586C0\">as<\/span><span style=\"color: #D4D4D4\"> e:<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">            error_payload = {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                <\/span><span style=\"color: #CE9178\">&quot;success&quot;<\/span><span style=\"color: #D4D4D4\">: <\/span><span style=\"color: #569CD6\">False<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                <\/span><span style=\"color: #CE9178\">&quot;message&quot;<\/span><span style=\"color: #D4D4D4\">: <\/span><span style=\"color: #569CD6\">f<\/span><span style=\"color: #CE9178\">&quot;Failed to execute tool &#39;<\/span><span style=\"color: #569CD6\">{<\/span><span style=\"color: #D4D4D4\">name<\/span><span style=\"color: #569CD6\">}<\/span><span style=\"color: #CE9178\">&#39;: <\/span><span style=\"color: #569CD6\">{<\/span><span style=\"color: #4EC9B0\">str<\/span><span style=\"color: #D4D4D4\">(e)<\/span><span style=\"color: #569CD6\">}<\/span><span style=\"color: #CE9178\">&quot;<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">            }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">            error_text = json.dumps(error_payload)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">            <\/span><span style=\"color: #C586C0\">return<\/span><span style=\"color: #D4D4D4\"> [mcp_types.TextContent(<\/span><span style=\"color: #9CDCFE\">type<\/span><span style=\"color: #D4D4D4\">=<\/span><span style=\"color: #CE9178\">&quot;text&quot;<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #9CDCFE\">text<\/span><span style=\"color: #D4D4D4\">=error_text)]<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #C586C0\">else<\/span><span style=\"color: #D4D4D4\">:<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        error_payload = {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">            <\/span><span style=\"color: #CE9178\">&quot;success&quot;<\/span><span style=\"color: #D4D4D4\">: <\/span><span style=\"color: #569CD6\">False<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">            <\/span><span style=\"color: #CE9178\">&quot;message&quot;<\/span><span style=\"color: #D4D4D4\">: <\/span><span style=\"color: #569CD6\">f<\/span><span style=\"color: #CE9178\">&quot;Tool &#39;<\/span><span style=\"color: #569CD6\">{<\/span><span style=\"color: #D4D4D4\">name<\/span><span style=\"color: #569CD6\">}<\/span><span style=\"color: #CE9178\">&#39; not implemented by this server.&quot;<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        error_text = json.dumps(error_payload)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #C586C0\">return<\/span><span style=\"color: #D4D4D4\"> [mcp_types.TextContent(<\/span><span style=\"color: #9CDCFE\">type<\/span><span style=\"color: #D4D4D4\">=<\/span><span style=\"color: #CE9178\">&quot;text&quot;<\/span><span style=\"color: #D4D4D4\">, <\/span><span style=\"color: #9CDCFE\">text<\/span><span style=\"color: #D4D4D4\">=error_text)]<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;\u25e6 Dois m\u00e9todos s\u00e3o <strong>obrigat\u00f3rios<\/strong> no servidor MCP para que ele possa listar e chamar ferramentas: list_mcp_tools e call_mcp_tool.<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;\u25e6 @app.list_tools() async def list_mcp_tools() -&gt; list[mcp_types.Tool]::<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\u25aa Esta fun\u00e7\u00e3o \u00e9 respons\u00e1vel por <strong>listar todas as ferramentas que o servidor MCP exp\u00f5e<\/strong>.<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\u25aa Ela itera sobre as ferramentas definidas em ADK_DB_TOOLS e utiliza adk_to_mcp_tool_type para converter cada inst\u00e2ncia de ferramenta do ADK para o formato de esquema de ferramenta que o MCP espera.<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;\u25e6 @app.call_tool() async def call_mcp_tool(name: str, arguments: dict) -&gt; list[mcp_types.TextContent]::<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\u25aa Esta fun\u00e7\u00e3o \u00e9 o <strong>manipulador do MCP para executar uma chamada de ferramenta<\/strong> solicitada por um cliente MCP.<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\u25aa Ela verifica se o nome da ferramenta solicitado (name) existe em ADK_DB_TOOLS.<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\u25aa Se a ferramenta existir, ela executa a fun\u00e7\u00e3o associada (adk_tool_instance.run_async) e retorna a resposta formatada como mcp_types.TextContent.<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\u25aa \u00c9 crucial que o c\u00f3digo inclua o <strong>tratamento de erros<\/strong>, retornando uma mensagem clara se a execu\u00e7\u00e3o da ferramenta falhar ou se a ferramenta n\u00e3o for implementada pelo servidor<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>8. Executando o Servidor MCP<\/strong>:<\/h2>\n\n\n\n<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:#1E1E1E\"><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:#D4D4D4;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><textarea class=\"code-block-pro-copy-button-textarea\" aria-hidden=\"true\" readonly># &#8212; MCP Server Runner &#8212;\nasync def run_mcp_stdio_server():\n    &#8220;&#8221;&#8221;Runs the MCP server, listening for connections over standard input\/output.&#8221;&#8221;&#8221;\n    async with mcp.server.stdio.stdio_server() as (read_stream, write_stream):\n        await app.run(\n            read_stream,\n            write_stream,\n            InitializationOptions(\n                server_name=app.name,\n                server_version=&#8221;0.1.0&#8243;,\n                capabilities=app.get_capabilities(\n                    notification_options=NotificationOptions(),\n                    experimental_capabilities={},\n                ),\n            ),\n        )\nif __name__ == &#8220;__main__&#8221;:\n    asyncio.run(run_mcp_stdio_server())\n<\/textarea><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 dark-plus\" style=\"background-color: #1E1E1E\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #6A9955\"># --- MCP Server Runner ---<\/span><\/span>\n<span class=\"line\"><span style=\"color: #569CD6\">async<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">def<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #DCDCAA\">run_mcp_stdio_server<\/span><span style=\"color: #D4D4D4\">():<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #CE9178\">&quot;&quot;&quot;Runs the MCP server, listening for connections over standard input\/output.&quot;&quot;&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #C586C0\">async<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #C586C0\">with<\/span><span style=\"color: #D4D4D4\"> mcp.server.stdio.stdio_server() <\/span><span style=\"color: #C586C0\">as<\/span><span style=\"color: #D4D4D4\"> (read_stream, write_stream):<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #C586C0\">await<\/span><span style=\"color: #D4D4D4\"> app.run(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">            read_stream,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">            write_stream,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">            InitializationOptions(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                <\/span><span style=\"color: #9CDCFE\">server_name<\/span><span style=\"color: #D4D4D4\">=app.name,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                <\/span><span style=\"color: #9CDCFE\">server_version<\/span><span style=\"color: #D4D4D4\">=<\/span><span style=\"color: #CE9178\">&quot;0.1.0&quot;<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                <\/span><span style=\"color: #9CDCFE\">capabilities<\/span><span style=\"color: #D4D4D4\">=app.get_capabilities(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                    <\/span><span style=\"color: #9CDCFE\">notification_options<\/span><span style=\"color: #D4D4D4\">=NotificationOptions(),<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                    <\/span><span style=\"color: #9CDCFE\">experimental_capabilities<\/span><span style=\"color: #D4D4D4\">={},<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">                ),<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">            ),<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        )<\/span><\/span>\n<span class=\"line\"><span style=\"color: #C586C0\">if<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #9CDCFE\">__name__<\/span><span style=\"color: #D4D4D4\"> == <\/span><span style=\"color: #CE9178\">&quot;__main__&quot;<\/span><span style=\"color: #D4D4D4\">:<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    asyncio.run(run_mcp_stdio_server())<\/span><\/span>\n<span class=\"line\"><\/span><\/code><\/pre><\/div>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;\u25e6 A fun\u00e7\u00e3o run_mcp_stdio_server() \u00e9 respons\u00e1vel por <strong>iniciar o servidor MCP, ouvindo conex\u00f5es via entrada\/sa\u00edda padr\u00e3o (stdio)<\/strong>.<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;\u25e6 Ela utiliza mcp.server.stdio.stdio_server() para gerenciar os streams de leitura e escrita.<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;\u25e6 A inicializa\u00e7\u00e3o do servidor app.run inclui a configura\u00e7\u00e3o do server_name, server_version e capabilities.<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;\u25e6 Finalmente, o if __name__ == &#8220;__main__&#8221;: asyncio.run(run_mcp_stdio_server()) garante que o servidor seja iniciado quando o script Python for executado.<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;\u25e6 Para subir o servidor, basta <strong>executar o arquivo Python no terminal<\/strong>. A fonte indica que o servidor estar\u00e1 ativo na porta 3333.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"885\" height=\"180\" src=\"https:\/\/goias.gov.br\/ligo\/wp-content\/uploads\/sites\/61\/2025\/07\/image-3.png\" alt=\"\" class=\"wp-image-204967\" srcset=\"https:\/\/goias.gov.br\/ligo\/wp-content\/uploads\/sites\/61\/2025\/07\/image-3.png 885w, https:\/\/goias.gov.br\/ligo\/wp-content\/uploads\/sites\/61\/2025\/07\/image-3-300x61.png 300w, https:\/\/goias.gov.br\/ligo\/wp-content\/uploads\/sites\/61\/2025\/07\/image-3-768x156.png 768w\" sizes=\"(max-width: 885px) 100vw, 885px\" \/><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>9. Criando o Agente para Comunicar com o Servidor MCP<\/strong><\/h2>\n\n\n\n<p>Uma vez que o servidor MCP esteja ativo e expondo as ferramentas, a configura\u00e7\u00e3o do agente do Google ADK muda para apontar para este servidor:<\/p>\n\n\n\n<p><strong>Importa\u00e7\u00f5es para o Agente MCP:<\/strong><\/p>\n\n\n\n<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:#1E1E1E\"><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:#D4D4D4;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><textarea class=\"code-block-pro-copy-button-textarea\" aria-hidden=\"true\" readonly>from google.adk.agents import Agent\nfrom google.adk.models.lite_llm import LiteLlm\nfrom google.adk.tools.mcp_tool.mcp_toolset import MCPToolset\nfrom google.adk.tools.mcp_tool.mcp_session_manager import SseServerParams<\/textarea><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 dark-plus\" style=\"background-color: #1E1E1E\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #C586C0\">from<\/span><span style=\"color: #D4D4D4\"> google.adk.agents <\/span><span style=\"color: #C586C0\">import<\/span><span style=\"color: #D4D4D4\"> Agent<\/span><\/span>\n<span class=\"line\"><span style=\"color: #C586C0\">from<\/span><span style=\"color: #D4D4D4\"> google.adk.models.lite_llm <\/span><span style=\"color: #C586C0\">import<\/span><span style=\"color: #D4D4D4\"> LiteLlm<\/span><\/span>\n<span class=\"line\"><span style=\"color: #C586C0\">from<\/span><span style=\"color: #D4D4D4\"> google.adk.tools.mcp_tool.mcp_toolset <\/span><span style=\"color: #C586C0\">import<\/span><span style=\"color: #D4D4D4\"> MCPToolset<\/span><\/span>\n<span class=\"line\"><span style=\"color: #C586C0\">from<\/span><span style=\"color: #D4D4D4\"> google.adk.tools.mcp_tool.mcp_session_manager <\/span><span style=\"color: #C586C0\">import<\/span><span style=\"color: #D4D4D4\"> SseServerParams<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;\u25e6 Voc\u00ea precisar\u00e1 importar MCPToolset e SseServerParams do Google ADK.<\/p>\n\n\n\n<p><strong>Configurando o Agente com o Servidor MCP<\/strong>:<\/p>\n\n\n\n<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:#1E1E1E\"><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:#D4D4D4;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><textarea class=\"code-block-pro-copy-button-textarea\" aria-hidden=\"true\" readonly>tools = MCPToolset(connection_params=SseServerParams(\n        url=&#8221;http:\/\/localhost:3333\/sse&#8221;,\n    )\n)\nollama_endpoint = &#8220;http:\/\/localhost:11434&#8243;\nroot_agent = Agent(\n    name=&#8217;agente_com_mcp&#8217;,\n    model=LiteLlm(model=&#8221;ollama_chat\/qwen2.5:14b&#8221;,base_url=ollama_endpoint),\n    description=&#8217;Agent for tools&#8217;,\n    instruction=&#8221;&#8221;&#8221;Voc\u00ea \u00e9 um agente inteligente com acesso a um servidor MCP com ferramentas. Use as ferramentas somente quando necess\u00e1rio para responder com precis\u00e3o.&#8221;&#8221;&#8221;,\n    tools=[tools]\n)<\/textarea><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 dark-plus\" style=\"background-color: #1E1E1E\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D4D4D4\">tools = MCPToolset(<\/span><span style=\"color: #9CDCFE\">connection_params<\/span><span style=\"color: #D4D4D4\">=SseServerParams(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #9CDCFE\">url<\/span><span style=\"color: #D4D4D4\">=<\/span><span style=\"color: #CE9178\">&quot;http:\/\/localhost:3333\/sse&quot;<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    )<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">ollama_endpoint = <\/span><span style=\"color: #CE9178\">&quot;http:\/\/localhost:11434&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">root_agent = Agent(<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #9CDCFE\">name<\/span><span style=\"color: #D4D4D4\">=<\/span><span style=\"color: #CE9178\">&#39;agente_com_mcp&#39;<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #9CDCFE\">model<\/span><span style=\"color: #D4D4D4\">=LiteLlm(<\/span><span style=\"color: #9CDCFE\">model<\/span><span style=\"color: #D4D4D4\">=<\/span><span style=\"color: #CE9178\">&quot;ollama_chat\/qwen2.5:14b&quot;<\/span><span style=\"color: #D4D4D4\">,<\/span><span style=\"color: #9CDCFE\">base_url<\/span><span style=\"color: #D4D4D4\">=ollama_endpoint),<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #9CDCFE\">description<\/span><span style=\"color: #D4D4D4\">=<\/span><span style=\"color: #CE9178\">&#39;Agent for tools&#39;<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #9CDCFE\">instruction<\/span><span style=\"color: #D4D4D4\">=<\/span><span style=\"color: #CE9178\">&quot;&quot;&quot;Voc\u00ea \u00e9 um agente inteligente com acesso a um servidor MCP com ferramentas. Use as ferramentas somente quando necess\u00e1rio para responder com precis\u00e3o.&quot;&quot;&quot;<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    <\/span><span style=\"color: #9CDCFE\">tools<\/span><span style=\"color: #D4D4D4\">=[tools]<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">)<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;\u25e6 Em vez de listar as ferramentas diretamente no construtor do Agent, voc\u00ea agora <strong>indica o servidor MCP de ferramentas ao agente<\/strong>.<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;\u25e6 Isso \u00e9 feito instanciando MCPToolset e passando os par\u00e2metros de conex\u00e3o (connection_params) que incluem a <strong>URL do servidor MCP<\/strong> (SseServerParams(url=&#8221;http:\/\/localhost:3333\/sse&#8221;)).<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;\u25e6 A inst\u00e2ncia de MCPToolset (por exemplo, tools = MCPToolset(&#8230;)) \u00e9 ent\u00e3o passada para o par\u00e2metro tools do Agent.<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;\u25e6 A configura\u00e7\u00e3o do modelo local (LiteLlm) e o ollama_endpoint permanecem os mesmos.<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;\u25e6 A instruction do agente tamb\u00e9m muda; agora ela deve indicar que o agente tem acesso a um servidor MCP com ferramentas, e que deve us\u00e1-las quando necess\u00e1rio.<\/p>\n\n\n\n<p>Vantagem Crucial:<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;\u25e6 Um <strong>detalhe importante<\/strong> para destacar \u00e9 que, com o servidor MCP, <strong>voc\u00ea n\u00e3o precisa mais descrever as ferramentas existentes no instruction (prompt) do agente<\/strong>, pois o servidor MCP as comunica diretamente ao agente. Isso simplifica a manuten\u00e7\u00e3o do agente e a adi\u00e7\u00e3o de novas ferramentas.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>10. Testando o Agente com MCP<\/strong>:<\/h2>\n\n\n\n<p>Com o servidor MCP ativo:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"885\" height=\"180\" src=\"https:\/\/goias.gov.br\/ligo\/wp-content\/uploads\/sites\/61\/2025\/07\/image-4.png\" alt=\"\" class=\"wp-image-204968\" srcset=\"https:\/\/goias.gov.br\/ligo\/wp-content\/uploads\/sites\/61\/2025\/07\/image-4.png 885w, https:\/\/goias.gov.br\/ligo\/wp-content\/uploads\/sites\/61\/2025\/07\/image-4-300x61.png 300w, https:\/\/goias.gov.br\/ligo\/wp-content\/uploads\/sites\/61\/2025\/07\/image-4-768x156.png 768w\" sizes=\"(max-width: 885px) 100vw, 885px\" \/><\/figure>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;\u25e6 Voc\u00ea executa em outro terminal o comando adk web dentro do diret\u00f3rio do seu projeto.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"886\" height=\"315\" src=\"https:\/\/goias.gov.br\/ligo\/wp-content\/uploads\/sites\/61\/2025\/07\/image-5.png\" alt=\"\" class=\"wp-image-204969\" srcset=\"https:\/\/goias.gov.br\/ligo\/wp-content\/uploads\/sites\/61\/2025\/07\/image-5.png 886w, https:\/\/goias.gov.br\/ligo\/wp-content\/uploads\/sites\/61\/2025\/07\/image-5-300x107.png 300w, https:\/\/goias.gov.br\/ligo\/wp-content\/uploads\/sites\/61\/2025\/07\/image-5-768x273.png 768w\" sizes=\"(max-width: 886px) 100vw, 886px\" \/><\/figure>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;\u25e6 Em seguida, acessa http:\/\/localhost:8000 no navegador.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"886\" height=\"350\" src=\"https:\/\/goias.gov.br\/ligo\/wp-content\/uploads\/sites\/61\/2025\/07\/image-6.png\" alt=\"\" class=\"wp-image-204970\" srcset=\"https:\/\/goias.gov.br\/ligo\/wp-content\/uploads\/sites\/61\/2025\/07\/image-6.png 886w, https:\/\/goias.gov.br\/ligo\/wp-content\/uploads\/sites\/61\/2025\/07\/image-6-300x119.png 300w, https:\/\/goias.gov.br\/ligo\/wp-content\/uploads\/sites\/61\/2025\/07\/image-6-768x303.png 768w\" sizes=\"(max-width: 886px) 100vw, 886px\" \/><\/figure>\n\n\n\n<p>Note que agora voc\u00ea pode perguntar ao agente quais as ferramentas existem no servidor dele sem ter que especificar no prompt de comando.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>11. Interagindo com o Agente via API HTTP<\/strong><\/h2>\n\n\n\n<p>O Google ADK oferece diversas maneiras de interagir com o agente que voc\u00ea criou. Al\u00e9m da flexibilidade de configurar agentes localmente para privacidade e controle total, ele tamb\u00e9m permite a <strong>intera\u00e7\u00e3o program\u00e1tica atrav\u00e9s de uma API HTTP<\/strong>. Isso \u00e9 crucial para integrar seu agente a outras aplica\u00e7\u00f5es, sistemas ou para realizar testes automatizados.<\/p>\n\n\n\n<p>Com o servidor web do ADK ativo (http:\/\/localhost:8000), voc\u00ea pode enviar requisi\u00e7\u00f5es HTTP POST para interagir com o agente de forma program\u00e1tica.<\/p>\n\n\n\n<p>\u2022 <strong>Endpoint da API:<\/strong> As intera\u00e7\u00f5es com o agente s\u00e3o realizadas atrav\u00e9s do endpoint \/run do servidor web do ADK.<\/p>\n\n\n\n<p>POST http:\/\/localhost:8000\/run<\/p>\n\n\n\n<p>\u2022 <strong>Corpo da Requisi\u00e7\u00e3o (Formato JSON):<\/strong> A requisi\u00e7\u00e3o deve incluir um corpo JSON estruturado com as informa\u00e7\u00f5es necess\u00e1rias para a intera\u00e7\u00e3o com o agente. \u00c9 importante que este corpo esteja corretamente formatado:<\/p>\n\n\n\n<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:#1E1E1E\"><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:#D4D4D4;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><textarea class=\"code-block-pro-copy-button-textarea\" aria-hidden=\"true\" readonly>{\n\t&#8220;appName&#8221;: &#8220;agente_com_mcp&#8221;,\n\t&#8220;userId&#8221;: &#8220;1&#8221;,\n\t&#8220;sessionId&#8221;: &#8220;1&#8221;,\n\t&#8220;newMessage&#8221;: {\n\t\t&#8220;parts&#8221;: [{\n\t\t\t&#8220;text&#8221;: &#8220;oi tudo bem&#8221;\n\t\t}],\n\t\t&#8220;role&#8221;: &#8220;user&#8221;\n\t},\n\t&#8220;streaming&#8221;: false\n}<\/textarea><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 dark-plus\" style=\"background-color: #1E1E1E\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D4D4D4\">{<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t<\/span><span style=\"color: #9CDCFE\">&quot;appName&quot;<\/span><span style=\"color: #D4D4D4\">: <\/span><span style=\"color: #CE9178\">&quot;agente_com_mcp&quot;<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t<\/span><span style=\"color: #9CDCFE\">&quot;userId&quot;<\/span><span style=\"color: #D4D4D4\">: <\/span><span style=\"color: #CE9178\">&quot;1&quot;<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t<\/span><span style=\"color: #9CDCFE\">&quot;sessionId&quot;<\/span><span style=\"color: #D4D4D4\">: <\/span><span style=\"color: #CE9178\">&quot;1&quot;<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t<\/span><span style=\"color: #9CDCFE\">&quot;newMessage&quot;<\/span><span style=\"color: #D4D4D4\">: {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t\t<\/span><span style=\"color: #9CDCFE\">&quot;parts&quot;<\/span><span style=\"color: #D4D4D4\">: [{<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t\t\t<\/span><span style=\"color: #9CDCFE\">&quot;text&quot;<\/span><span style=\"color: #D4D4D4\">: <\/span><span style=\"color: #CE9178\">&quot;oi tudo bem&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t\t}],<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t\t<\/span><span style=\"color: #9CDCFE\">&quot;role&quot;<\/span><span style=\"color: #D4D4D4\">: <\/span><span style=\"color: #CE9178\">&quot;user&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t},<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">\t<\/span><span style=\"color: #9CDCFE\">&quot;streaming&quot;<\/span><span style=\"color: #D4D4D4\">: <\/span><span style=\"color: #569CD6\">false<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">}<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;\u25e6 &#8220;appName&#8221;: Este campo \u00e9 <strong>crucial<\/strong> e deve corresponder exatamente ao name que voc\u00ea atribuiu ao seu agente durante a configura\u00e7\u00e3o. Por exemplo, para o agente configurado com MCP, o nome utilizado foi &#8216;agente_com_mcp&#8217;, e para o primeiro agente sem MCP, foi &#8216;root_agent&#8217;.<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;\u25e6 &#8220;userId&#8221;: Um identificador para o usu\u00e1rio que est\u00e1 interagindo. Pode ser usado para distinguir conversas de diferentes usu\u00e1rios.<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;\u25e6 &#8220;sessionId&#8221;: Um identificador para a sess\u00e3o de conversa. O agente usa este ID para manter o contexto de uma conversa ao longo de v\u00e1rias intera\u00e7\u00f5es.<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;\u25e6 &#8220;newMessage&#8221;: Cont\u00e9m a mensagem atual do usu\u00e1rio que ser\u00e1 enviada ao agente.<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\u25aa &#8220;parts&#8221;: Uma lista de partes da mensagem. Atualmente, a parte textual \u00e9 a mais comum.<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\u25aa &#8220;text&#8221;: O conte\u00fado textual da sua mensagem.<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\u25aa &#8220;role&#8221;: O papel do remetente da mensagem. Para mensagens do usu\u00e1rio, o valor \u00e9 &#8220;user&#8221;.<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;\u25e6 &#8220;streaming&#8221;: Um valor booleano (true ou false) que indica se a resposta do agente deve ser transmitida em tempo real (streaming) ou entregue de uma vez ap\u00f3s a conclus\u00e3o. Para este exemplo, false indica que a resposta ser\u00e1 completa.<\/p>\n\n\n\n<p>Exemplo de Uso:<\/p>\n\n\n\n<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:#1E1E1E\"><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:#D4D4D4;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><textarea class=\"code-block-pro-copy-button-textarea\" aria-hidden=\"true\" readonly>curl -X POST http:\/\/localhost:8000\/run \\\u00a0 \n-d &#8216;{&#8220;appName&#8221;: &#8220;agente_com_mcp&#8221;,&#8221;userId&#8221;: &#8220;1&#8221;,&#8221;sessionId&#8221;: &#8220;1&#8221;,&#8221;newMessage&#8221;: {&#8220;parts&#8221;: [{&#8220;text&#8221;: &#8220;qual as horas?&#8221;}],&#8221;role&#8221;: &#8220;user&#8221;},&#8221;streaming&#8221;: False}&#8217;<\/textarea><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 dark-plus\" style=\"background-color: #1E1E1E\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #DCDCAA\">curl<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #569CD6\">-X<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #CE9178\">POST<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #CE9178\">http:\/\/localhost:8000\/run<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #D7BA7D\">\\\u00a0<\/span><span style=\"color: #D4D4D4\"> <\/span><\/span>\n<span class=\"line\"><span style=\"color: #DCDCAA\">-d<\/span><span style=\"color: #D4D4D4\"> <\/span><span style=\"color: #CE9178\">&#39;{&quot;appName&quot;: &quot;agente_com_mcp&quot;,&quot;userId&quot;: &quot;1&quot;,&quot;sessionId&quot;: &quot;1&quot;,&quot;newMessage&quot;: {&quot;parts&quot;: [{&quot;text&quot;: &quot;qual as horas?&quot;}],&quot;role&quot;: &quot;user&quot;},&quot;streaming&quot;: False}&#39;<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>12. Acesso ao Swagger<\/strong><\/h2>\n\n\n\n<p>Para acessar o Swagger v\u00e1 no endere\u00e7o:<\/p>\n\n\n\n<p><a href=\"http:\/\/localhost:8000\/docs\">http:\/\/localhost:8000\/docs<\/a><\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"886\" height=\"458\" src=\"https:\/\/goias.gov.br\/ligo\/wp-content\/uploads\/sites\/61\/2025\/07\/image-7.png\" alt=\"\" class=\"wp-image-204971\" srcset=\"https:\/\/goias.gov.br\/ligo\/wp-content\/uploads\/sites\/61\/2025\/07\/image-7.png 886w, https:\/\/goias.gov.br\/ligo\/wp-content\/uploads\/sites\/61\/2025\/07\/image-7-300x155.png 300w, https:\/\/goias.gov.br\/ligo\/wp-content\/uploads\/sites\/61\/2025\/07\/image-7-768x397.png 768w\" sizes=\"(max-width: 886px) 100vw, 886px\" \/><\/figure>\n\n\n\n<p><strong>Refer\u00eancias:<\/strong><\/p>\n\n\n\n<p><br>https:\/\/google.github.io\/adk-docs\/<br>https:\/\/modelcontextprotocol.io\/introduction<br>https:\/\/ollama.com\/<br>https:\/\/google.github.io\/adk-docs\/tools\/mcp-tools\/<br>https:\/\/medium.com\/@ssupinma\/implementing-google-adk-and-mcp-on-windows-a-practical-guide-e27e78d1b165<br>https:\/\/medium.com\/hostspaceng\/building-ai-agents-with-google-adk-fastapi-and-mcp-031447925896<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Neste guia detalhado, voc\u00ea aprender\u00e1 a configurar um agente inteligente local utilizando o Google Agent Development Kit (ADK) sem e com servidor Model Context Protocol (MCP). Esta abordagem \u00e9 ideal para projetos que exigem privacidade, controle total e flexibilidade, especialmente em cen\u00e1rios sens\u00edveis ou opera\u00e7\u00f5es offline. A grande vantagem de um agente local \u00e9 que ele permite o desenvolvimento e a execu\u00e7\u00e3o de funcionalidades de IA no seu pr\u00f3prio ambiente, sem depender de servi\u00e7os em nuvem externos, garantindo assim maior autonomia e seguran\u00e7a de dados. Componentes Chave: 1. Google ADK (Agent Development Kit): &nbsp;&nbsp;&nbsp;&nbsp;\u25e6 O ADK \u00e9 um framework robusto da Google projetado para facilitar a cria\u00e7\u00e3o de agentes inteligentes. &nbsp;&nbsp;&nbsp;&nbsp;\u25e6 Ele oferece suporte nativo a ferramentas personalizadas e capacidades de orquestra\u00e7\u00e3o, permitindo a constru\u00e7\u00e3o de arquiteturas de agente modulares e escal\u00e1veis. &nbsp;&nbsp;&nbsp;&nbsp;\u25e6 O ADK suporta diversas formas de intera\u00e7\u00e3o, incluindo HTTP, Server-Sent Events (SSE) e at\u00e9 mesmo comunica\u00e7\u00e3o via processos stdio. Para mais detalhes, voc\u00ea pode consultar a documenta\u00e7\u00e3o oficial. 2. MCP (Model Context Protocol) &#8211; Opcional: &nbsp;&nbsp;&nbsp;&nbsp;\u25e6 O Model Context Protocol \u00e9 uma forma padronizada e organizada de estruturar as informa\u00e7\u00f5es que s\u00e3o enviadas para Modelos de Linguagem (LLMs). &nbsp;&nbsp;&nbsp;&nbsp;\u25e6 Seu objetivo \u00e9 otimizar a comunica\u00e7\u00e3o com LLMs, tornando-a mais eficiente e consistente. &nbsp;&nbsp;&nbsp;&nbsp;\u25e6 \u00c9 importante notar que, embora o MCP possa ser utilizado, a cria\u00e7\u00e3o do agente local com o Google ADK pode ser feita com ou sem um servidor MCP. Guia de Implementa\u00e7\u00e3o: 1. Instalando as Depend\u00eancias: Para come\u00e7ar, voc\u00ea precisar\u00e1 instalar as bibliotecas necess\u00e1rias. Escolha o gerenciador de pacotes de sua prefer\u00eancia: &nbsp;&nbsp;&nbsp;&nbsp;\u25e6 Usando pip:&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;\u25e6 Usando uv (alternativa mais r\u00e1pida): Estas ferramentas s\u00e3o essenciais para o desenvolvimento com Google ADK, sendo o litellm crucial para a integra\u00e7\u00e3o com modelos de linguagem locais. 2. Criando a Estrutura B\u00e1sica do Agente: O Google ADK simplifica o in\u00edcio de novos projetos, fornecendo um comando para gerar uma estrutura de arquivos b\u00e1sicos, eliminando a necessidade de come\u00e7ar do zero. No seu ambiente onde o google-adk foi instalado, execute: Este comando cria automaticamente a estrutura de diret\u00f3rios e arquivos fundamentais para o seu agente. 3. Configurando o Modelo Local e Importa\u00e7\u00f5es: Para utilizar um modelo de linguagem local, \u00e9 necess\u00e1rio importar as classes Agent e LiteLlm do Google ADK. A classe LiteLlm \u00e9 a ponte para a integra\u00e7\u00e3o com modelos locais: O LiteLlm permite que voc\u00ea especifique o modelo local a ser usado, como um servidor Ollama configurado na sua m\u00e1quina. 4. Desenvolvendo uma Ferramenta Personalizada: Agentes inteligentes frequentemente precisam interagir com o mundo exterior para coletar informa\u00e7\u00f5es ou executar a\u00e7\u00f5es. No Google ADK, isso \u00e9 feito atrav\u00e9s de ferramentas (tools). Vamos criar uma ferramenta simples para obter a hora atual: Pontos Cruciais para Ferramentas: &nbsp;&nbsp;&nbsp;&nbsp;\u25e6 Documenta\u00e7\u00e3o Clara: \u00c9 fundamental que a fun\u00e7\u00e3o esteja muito bem documentada (usando docstrings). Essa documenta\u00e7\u00e3o \u00e9 o que permite ao agente saber como e por que usar a ferramenta, interpretando sua finalidade e seus par\u00e2metros. &nbsp;&nbsp;&nbsp;&nbsp;\u25e6 Retorno de Dicion\u00e1rio: A fun\u00e7\u00e3o deve retornar um dicion\u00e1rio (dict), pois este \u00e9 o padr\u00e3o esperado pelo Google ADK para processar as sa\u00eddas das ferramentas. 5. Construindo o Primeiro Agente: Finalmente, iremos instanciar nosso agente principal, configurando seu modelo, nome, descri\u00e7\u00e3o, instru\u00e7\u00f5es e as ferramentas que ele pode utilizar: Detalhes Importantes da Configura\u00e7\u00e3o do Agente: &nbsp;&nbsp;&nbsp;&nbsp;\u25e6 model: Este par\u00e2metro utiliza a classe LiteLlm para configurar o modelo de linguagem local. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\u25aa model=&#8221;ollama_chat\/qwen2.5:14b&#8221;: Define o nome do modelo espec\u00edfico que o agente utilizar\u00e1. Voc\u00ea pode alterar este valor conforme o modelo local que voc\u00ea tiver dispon\u00edvel. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;\u25aa base_url=ollama_endpoint: Aponta para o endere\u00e7o do seu servidor de modelo local (neste exemplo, um servidor Ollama rodando na porta 11434). &nbsp;&nbsp;&nbsp;&nbsp;\u25e6 name e description: Atribuem um nome e uma breve descri\u00e7\u00e3o ao agente, auxiliando na sua identifica\u00e7\u00e3o. &nbsp;&nbsp;&nbsp;&nbsp;\u25e6 instruction: Fornece as diretrizes e o comportamento esperado do agente. \u00c9 aqui que voc\u00ea tamb\u00e9m lista as ferramentas dispon\u00edveis, descrevendo brevemente suas funcionalidades para que o agente possa decidir quando us\u00e1-las. &nbsp;&nbsp;&nbsp;&nbsp;\u25e6 tools: Uma lista das fun\u00e7\u00f5es (ferramentas) que o agente pode chamar. \u00c9 crucial que as fun\u00e7\u00f5es adicionadas aqui estejam corretamente documentadas para que o Google ADK as reconhe\u00e7a. Ap\u00f3s configurar o agente, o Google ADK oferece uma interface web intuitiva para test\u00e1-lo e interagir: No terminal, navegue at\u00e9 o diret\u00f3rio do seu projeto e digite: Este comando iniciar\u00e1 o servidor web do ADK. Abra seu navegador e acesse o endere\u00e7o: http:\/\/localhost:8000 Voc\u00ea ver\u00e1 a interface do Google ADK. Selecione o agente que voc\u00ea acabou de criar e comece a interagir com ele. Comportamento Inteligente do Agente: Observe que, mesmo em intera\u00e7\u00f5es iniciais onde uma ferramenta pode n\u00e3o ser necess\u00e1ria, o agente \u00e9 capaz de discernir quando e como utilizar a ferramenta criada para fornecer a resposta mais adequada ao usu\u00e1rio. Por exemplo, ao perguntar &#8220;Que horas s\u00e3o?&#8221;, o agente identificar\u00e1 a necessidade de usar a fun\u00e7\u00e3o pegar_horas() para responder. 6. Entendendo o MCP (Model Context Protocol) Antes de mergulhar na implementa\u00e7\u00e3o, \u00e9 \u00fatil refor\u00e7ar o papel do MCP. Ele \u00e9 uma forma padronizada e organizada de estruturar as informa\u00e7\u00f5es enviadas para Modelos de Linguagem (LLMs), visando otimizar a comunica\u00e7\u00e3o com LLMs, tornando-a mais eficiente e consistente. Embora seja opcional, ele permite uma abordagem mais robusta para o gerenciamento de ferramentas. 7. Criando o Servidor MCP (Etapas e Componentes Chave) A se\u00e7\u00e3o do seu artigo pode detalhar as seguintes etapas para criar o servidor MCP: Importando as Bibliotecas Necess\u00e1rias: &nbsp;&nbsp;&nbsp;&nbsp;\u25e6 Para come\u00e7ar a construir o servidor MCP, \u00e9 fundamental importar um conjunto espec\u00edfico de bibliotecas. Isso inclui asyncio e json para opera\u00e7\u00f5es gerais, al\u00e9m de m\u00f3dulos espec\u00edficos do MCP (mcp.server.stdio, mcp.types, mcp.server.lowlevel, mcp.server.models) e do Google ADK para ferramentas (google.adk.tools.function_tool, google.adk.tools.mcp_tool.conversion_utils, google.adk.tools.mcp_tool.mcp_session_manager). &nbsp;&nbsp;&nbsp;&nbsp;\u25e6 Um ponto importante a destacar \u00e9 a fun\u00e7\u00e3o adk_to_mcp_tool_type, que \u00e9 uma funcionalidade nativa do Google ADK para converter fun\u00e7\u00f5es Python diretamente para o protocolo de comunica\u00e7\u00e3o necess\u00e1rio para o MCP. Definindo as Ferramentas para o MCP Server: &nbsp;&nbsp;&nbsp;&nbsp;\u25e6 A fonte demonstra a reutiliza\u00e7\u00e3o da ferramenta pegar_horas() (obter a hora atual). Essa ferramenta, assim como outras que voc\u00ea possa criar, ser\u00e1 exposta pelo servidor MCP. &nbsp;&nbsp;&nbsp;&nbsp;\u25e6 As ferramentas<\/p>\n","protected":false},"author":712,"featured_media":205137,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":"","_links_to":"","_links_to_target":""},"categories":[54,26],"tags":[],"class_list":["post-204973","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-programacao","category-publicacoes-ligo"],"rttpg_featured_image_url":{"full":["https:\/\/goias.gov.br\/ligo\/wp-content\/uploads\/sites\/61\/2025\/07\/logo2.png",200,260,false],"landscape":["https:\/\/goias.gov.br\/ligo\/wp-content\/uploads\/sites\/61\/2025\/07\/logo2.png",200,260,false],"portraits":["https:\/\/goias.gov.br\/ligo\/wp-content\/uploads\/sites\/61\/2025\/07\/logo2.png",200,260,false],"thumbnail":["https:\/\/goias.gov.br\/ligo\/wp-content\/uploads\/sites\/61\/2025\/07\/logo2-150x150.png",150,150,true],"medium":["https:\/\/goias.gov.br\/ligo\/wp-content\/uploads\/sites\/61\/2025\/07\/logo2.png",200,260,false],"large":["https:\/\/goias.gov.br\/ligo\/wp-content\/uploads\/sites\/61\/2025\/07\/logo2.png",200,260,false],"1536x1536":["https:\/\/goias.gov.br\/ligo\/wp-content\/uploads\/sites\/61\/2025\/07\/logo2.png",200,260,false],"2048x2048":["https:\/\/goias.gov.br\/ligo\/wp-content\/uploads\/sites\/61\/2025\/07\/logo2.png",200,260,false]},"rttpg_author":{"display_name":"Adriano Pericles","author_link":"https:\/\/goias.gov.br\/ligo\/author\/adrianorodrigues\/"},"rttpg_comment":1,"rttpg_category":"<a href=\"https:\/\/goias.gov.br\/ligo\/categoria\/publicacoes-ligo\/programacao\/\" rel=\"category tag\">Programa\u00e7\u00e3o<\/a> <a href=\"https:\/\/goias.gov.br\/ligo\/categoria\/publicacoes-ligo\/\" rel=\"category tag\">Publica\u00e7\u00f5es Ligo<\/a>","rttpg_excerpt":"Neste guia detalhado, voc\u00ea aprender\u00e1 a configurar um agente inteligente local utilizando o Google Agent Development Kit (ADK) sem e com servidor Model Context Protocol (MCP). Esta abordagem \u00e9 ideal para projetos que exigem privacidade, controle total e flexibilidade, especialmente em cen\u00e1rios sens\u00edveis ou opera\u00e7\u00f5es offline. A grande vantagem de um agente local \u00e9 que&hellip;","_links":{"self":[{"href":"https:\/\/goias.gov.br\/ligo\/wp-json\/wp\/v2\/posts\/204973","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/goias.gov.br\/ligo\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/goias.gov.br\/ligo\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/goias.gov.br\/ligo\/wp-json\/wp\/v2\/users\/712"}],"replies":[{"embeddable":true,"href":"https:\/\/goias.gov.br\/ligo\/wp-json\/wp\/v2\/comments?post=204973"}],"version-history":[{"count":2,"href":"https:\/\/goias.gov.br\/ligo\/wp-json\/wp\/v2\/posts\/204973\/revisions"}],"predecessor-version":[{"id":205139,"href":"https:\/\/goias.gov.br\/ligo\/wp-json\/wp\/v2\/posts\/204973\/revisions\/205139"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/goias.gov.br\/ligo\/wp-json\/wp\/v2\/media\/205137"}],"wp:attachment":[{"href":"https:\/\/goias.gov.br\/ligo\/wp-json\/wp\/v2\/media?parent=204973"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/goias.gov.br\/ligo\/wp-json\/wp\/v2\/categories?post=204973"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/goias.gov.br\/ligo\/wp-json\/wp\/v2\/tags?post=204973"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}