Como Construir Seu Primeiro Servidor MCP com Novita AI

Como Construir Seu Primeiro Servidor MCP com Novita AI

O Model Context Protocol (MCP) está se tornando rapidamente um dos conceitos mais comentados no mundo da IA. Apesar de ser relativamente novo, já conquistou a atenção de desenvolvedores e grandes empresas de tecnologia.

Criado pela Anthropic, o MCP é um protocolo padrão aberto, semelhante a outros protocolos como HTTP. No entanto, enquanto o HTTP é projetado para conectar usuários a recursos através de um servidor e um navegador web (ou cliente HTTP), o MCP é projetado para conectar Grandes Modelos de Linguagem (LLMs) a ferramentas e dados externos.

Digamos que você tenha um chatbot e queira que ele seja capaz de acessar o GitHub. Você quer que seus usuários usem o chatbot para criar issues, fechar issues, adicionar comentários ou visualizar pull requests existentes. Para permitir que seu chatbot execute todas essas ações, ele precisará de acesso a ferramentas.

É aí que entra um servidor MCP.

O servidor MCP hospeda várias ferramentas que o chatbot pode chamar usando seu LLM interno para obter acesso a essas capacidades. No caso do GitHub, podemos usar o servidor MCP oficial do GitHub para realizar todas as tarefas mencionadas.

Neste artigo, vamos construir um servidor MCP usando a API da Novita. Com este servidor MCP, qualquer aplicação que suporte o protocolo MCP poderá acessar todos os LLMs disponíveis na Novita, gerar imagens, criar vídeos e realizar síntese de fala.

Entendendo a Arquitetura MCP

A Arquitetura MCP

A Arquitetura MCP [fonte]

A arquitetura MCP é semelhante a uma configuração típica cliente-servidor. Possui quatro componentes importantes:

  • Cliente MCP
  • Servidor MCP
  • Transportes MCP
  • Host MCP

Cliente MCP

O cliente MCP serve como o gateway de comunicação entre a aplicação de IA e um servidor MCP. Assim que essa comunicação é estabelecida, a aplicação pode acessar todas as ferramentas e recursos que o servidor possui.

Servidor MCP

O servidor MCP hospeda todas as ferramentas e dados que o cliente pode fornecer à aplicação de IA. Ele hospeda:

  • Ferramentas
  • Recursos
  • Prompts

Ferramentas

As ferramentas fornecem capacidades externas aos LLMs que eles normalmente não teriam, como a capacidade de informar a hora, atualizar e ler de um banco de dados, obter a previsão do tempo e muito mais. Essas ferramentas são essencialmente funções definidas pelo programador que podem ser chamadas.

Um servidor MCP pode hospedar várias ferramentas. Essas ferramentas permitem que o LLM funcione como um agente, devido às ações que pode realizar.

As ferramentas são gerenciadas pelo agente e podem envolver supervisão humana opcional durante o uso. Elas são semelhantes a requisições POST no protocolo HTTP, pois realizam efeitos colaterais.

Recursos

Recursos são informações somente leitura que fornecem dados à aplicação de IA. Eles são análogos a requisições HTTP GET, pois não devem causar efeitos colaterais. Os recursos são gerenciados pela aplicação, que decide como os usuários ou o agente interagirão com eles. Exemplos de recursos incluem conteúdos de arquivos, respostas de APIs e registros de bancos de dados.

Prompts

Servidores MCP podem hospedar templates de prompts. Esses prompts permitem que o usuário busque prompts do servidor MCP, que podem então ser usados na aplicação de IA. Os prompts são gerenciados pelo usuário, que decide quais prompts fornecer ao agente.

Todos esses elementos compõem o servidor MCP. Neste artigo, implementaremos apenas ferramentas, pois são a parte mais utilizada do servidor MCP.

Transporte MCP

O transporte MCP refere-se ao método pelo qual o cliente MCP se comunica com o servidor MCP. Essa comunicação pode ocorrer localmente, quando tanto o cliente quanto o servidor rodam na mesma máquina, ou remotamente, quando estão em dispositivos separados. O MCP atualmente suporta dois mecanismos principais de transporte:

  • STDIO: Neste modo, o servidor e o cliente MCP rodam na mesma máquina e se comunicam através da entrada e saída padrão.
  • SSE: Neste modo, o servidor MCP roda sobre HTTP. HTTP POST é usado para enviar mensagens ao servidor, enquanto Server-Sent Events são usados para enviar mensagens do servidor para o cliente.
  • HTTP Streamable: Este modo também usa HTTP, mas depende de requisições HTTP GET e POST. Ele recorre ao SSE apenas quando precisa transmitir várias mensagens do servidor para o cliente.

Entrada/Saída Padrão

Transporte Usando STDIO

Transporte MCP Usando STDIO [fonte]

Legenda: Transporte MCP Usando STDIO [fonte]

O cliente e o servidor MCP podem se comunicar via Entrada e Saída Padrão (STDIO). Ao usar STDIO, tanto o cliente quanto o servidor estão rodando na mesma máquina. O cliente escreve todas as requisições no stdin, enquanto o servidor escreve a resposta no stdout.

HTTP Streamable

Transporte MCP Usando HTTP Streamable

Transporte MCP Usando HTTP Streamable [fonte]

O HTTP Streamable permite que o cliente e o servidor MCP se comuniquem via HTTP. Ele usa o método HTTP POST para enviar requisições do cliente e receber respostas do servidor. Quando necessário, pode opcionalmente alternar para Server-Sent Events (SSE) para transmitir mensagens do servidor para o cliente.

O HTTP Streamable é adequado para comunicação remota entre um cliente e um servidor e serve como substituto para o transporte MCP SSE obsoleto.

Host MCP

Onde o MCP difere da arquitetura típica cliente-servidor é no papel do host. A especificação MCP o define como uma arquitetura cliente-host-servidor. Isso porque o cliente e o host compõem o frontend da arquitetura. O host MCP consiste em dois componentes importantes:

  • O(s) cliente(s) MCP
  • Um grande modelo de linguagem

A função do cliente MCP é buscar ferramentas, recursos e prompts que o LLM necessita do servidor. Uma vez que os recursos são coletados, eles são colocados no contexto do modelo. Um único host MCP pode ter vários clientes, cada um conectado ao seu próprio servidor MCP individual.

O host MCP também pode ser considerado a aplicação na qual o usuário está trabalhando, que pode desempenhar outras funções. Por exemplo, o Claude Desktop é um host MCP que funciona como chatbot, o Cursor é um host MCP que também serve como IDE, e o Claude Code é um host MCP projetado como um agente de codificação de IA.

Trabalhando com um Servidor MCP

Antes de entrarmos na construção do nosso servidor MCP, vamos ver como podemos trabalhar com um servidor MCP existente. Usaremos o Python MCP SDK para interagir com o novita-mcp-server.

No momento da escrita deste artigo, o novita-mcp-server fornece as seguintes ferramentas:

  • Uma ferramenta para listar todos os clusters Novita
  • Uma ferramenta para listar os produtos de instância GPU Novita
  • Uma ferramenta para listar todas as instâncias GPU em execução
  • Uma ferramenta para criar novas instâncias GPU

Vamos confirmar isso escrevendo um script simples que se conecta ao servidor MCP via STDIO e lista todas as ferramentas disponíveis no servidor.

Para começar, vamos instalar o MCP SDK: pip install “mcp[cli]”

Depois de instalarmos o SDK, podemos criar um arquivo chamado client.py. Em seguida, faremos todas as importações necessárias:

from mcp import ClientSession, StdioServerParameters
from mcp.client.stdio import stdio_client
import os

Usaremos então o StdioServerParameters para definir nossos parâmetros para iniciar nosso servidor MCP via stdio. O novita-mcp-server é implementado em Node.js, então para usá-lo, precisamos executá-lo com o comando npx. Também precisamos armazenar nossa chave de API Novita na variável de ambiente NOVITA_API_KEY.

# Create server parameters for stdio connection
server_params = StdioServerParameters(
   command="npx",
   args=["-y", "@novitalabs/novita-mcp-server"],
   env={"NOVITA_API_KEY":  os.environ["NOVITA_API_KEY"]},
)

Em seguida, vamos criar uma função assíncrona. Dentro da função, passaremos os parâmetros do servidor para a função stdio_client, que criará um contexto retornando streams de leitura e escrita. Esses streams nos permitem ler e escrever no stdio, respectivamente.

async def run():
   async with stdio_client(server_params) as (read, write):
       async with ClientSession(read, write) as session:
           # Initialize the connection
           await session.initialize()

           # List available tools
           tools = await session.list_tools()
           print("Available tools:", tools)

Esses streams são então usados para criar uma sessão com a classe ClientSession. Depois de criarmos nossa sessão, podemos inicializá-la e listar todas as ferramentas no servidor.

Para executar este programa, basta usar a biblioteca asyncio para chamar a função run. Aqui está o código completo:

from mcp import ClientSession, StdioServerParameters
from mcp.client.stdio import stdio_client
import os

# Create server parameters for stdio connection
server_params = StdioServerParameters(
   command="npx",
   args=["-y", "@novitalabs/novita-mcp-server"],
   env={"NOVITA_API_KEY":  os.environ["NOVITA_API_KEY"]},
)

async def run():
   async with stdio_client(server_params) as (read, write):
       async with ClientSession(read, write) as session:
           # Initialize the connection
           await session.initialize()

           # List available tools
           tools = await session.list_tools()
           print("Available tools:", tools)

if __name__ == "__main__":
   import asyncio

   asyncio.run(run())

Ao executar o script, podemos ver todas as ferramentas no servidor MCP Novita.

Este exemplo demonstra como você pode usar o cliente MCP. Poderíamos adicionar um LLM a este exemplo e efetivamente transformá-lo em um host, mas esse não é o foco deste tutorial. O foco é construir um servidor MCP.

Construindo um Servidor MCP com FastMCP

No Python MCP SDK, existem duas maneiras de construir servidores MCP. Um método é usando o servidor de baixo nível, e o outro é usando o FastMCP. FastMCP é uma classe dentro do Python MCP SDK que se inspira no FastAPI para facilitar a criação de servidores MCP.

Vamos usar o FastMCP para criar nosso servidor MCP. Antes de começarmos, vamos considerar as funcionalidades do nosso servidor MCP. O servidor MCP Novita atual implementa apenas ferramentas que lidam com gerenciamento de GPU. Vamos tentar construir um servidor em torno da API Novita que vá além do gerenciamento de GPU.

Em vez disso, vamos construir um servidor MCP que forneça acesso aos modelos na plataforma Novita. Nosso servidor MCP terá apenas ferramentas, sem recursos ou prompts. Aqui está uma lista de ferramentas que o servidor terá:

  • list_models: Esta ferramenta listará todos os grandes modelos de linguagem na plataforma Novita.
  • get_model: Esta ferramenta recuperará e usará um modelo de linguagem específico.
  • text2image: Esta ferramenta gerará imagens a partir de um determinado prompt.
  • task_result: Esta ferramenta será usada para obter o status de uma tarefa em execução através de seu ID.
  • text_to_speech: Esta ferramenta converterá o texto fornecido em fala.
  • generate_video: Esta ferramenta gerará um vídeo a partir de um determinado prompt.

Agora que conhecemos as ferramentas que construiremos, vamos começar a criar nosso servidor. Primeiro, crie um arquivo chamado server.py e adicione o seguinte código:

import os
import sys
from mcp.server.fastmcp import FastMCP
import requests
import uvicorn
from starlette.applications import Starlette
from starlette.routing import Mount

base_url = "https://api.novita.ai/v3"

headers = {
   "Content-Type": "application/json",
   "Authorization": f"Bearer {os.environ['NOVITA_API_KEY']}"
}

mcp = FastMCP("Novita_API")

Com isso, importamos os módulos necessários, definimos nossa URL base e cabeçalhos para a API, e criamos uma instância da classe FastMCP. Vamos prosseguir com a criação de nossas ferramentas.

Listar modelos

Para criar uma ferramenta no FastMCP, precisamos decorar uma função com o método tool da instância FastMCP. A função list_models faz uma chamada ao endpoint de listar modelos para obter a lista de modelos. A resposta é então formatada adequadamente para ser passada ao LLM que a chamou.

@mcp.tool()
def list_models() -> str:
   """
   List all available models from the Novita API.
   """

   url = base_url + "/openai/models"

   response = requests.request("GET", url, headers=headers)
   data = response.json()["data"]
  
   text = ""
   for i, model in enumerate(data, start=1):
       text += f"Model id: {model['id']}\
"
       text += f"Model description: {model['description']}\
"
       text += f"Model type: {model['model_type']}\
\
"
  
   return text

A docstring na ferramenta serve como uma forma de descrever a funcionalidade da ferramenta para que o LLM entenda para que ela é usada.

Obter modelo

Esta ferramenta é usada para acessar os LLMs implantados na Novita. Ela recebe o ID do modelo e o prompt para o modelo. Ela utiliza o endpoint de chat completions da API Novita.

@mcp.tool()
def get_model(model_id: str, message):
   """
   Provide a model ID and a message to get a response from the Novita API.
   """

   url = base_url + "/openai/chat/completions"

   payload = {
       "model": model_id,
       "messages": [
           {
               "content": message,
               "role": "user",
           }
       ],
       "max_tokens": 200,
       "response_format": {
           "type": "text",
       },
   }

   response = requests.request("POST", url, json=payload, headers=headers)
  
   content = response.json()["choices"][0]["message"]["content"]

   return content

Texto para Imagem

Esta ferramenta gera imagens a partir de um prompt. Ela usa o endpoint de texto para imagem da Novita internamente. Este endpoint é assíncrono, então não retorna a imagem imediatamente; em vez disso, retorna um ID de tarefa.

@mcp.tool()
def text2Image(prompt):
   """
   Generate an image from a text prompt using the Novita API.
   """

   url = base_url + "/async/txt2img"

   payload = {
       "request": {
           "model_name": "sd_xl_base_1.0.safetensors",
           "prompt": prompt,
           "width": 1024,
           "height": 1024,
           "image_num": 1,
           "steps": 20,
           "clip_skip": 1,
           "sampler_name": "Euler a",
           "guidance_scale": 7.5,
       },
       "extra": {
           "response_image_type": "jpeg"
       }
   }

   response = requests.request("POST", url, json=payload, headers=headers)

   return response.json()["task_id"]

Resultado da tarefa

Esta ferramenta é usada para obter o status de uma tarefa em andamento na API Novita. Ela recebe apenas o ID da tarefa. Por exemplo, a ferramenta Imagem gera uma imagem de forma assíncrona e retorna um ID de tarefa para o host. O usuário pode então pedir ao host para recuperar o resultado dessa tarefa usando a ferramenta Resultado da Tarefa.

@mcp.tool()
def task_result(task_id: str):
   """
   Get the current status of a running task using it's task id
   """

   url = base_url + f'/async/task-result?task_id={task_id}'

   response = requests.request("GET", url, headers=headers)
   return response.json()

Gerar Vídeo

Esta ferramenta gera vídeos usando o endpoint Kling AI V1.6 Texto para Vídeo da API Novita. Assim como a ferramenta Imagem, ela gera vídeos de forma assíncrona e retorna um ID de tarefa.

@mcp.tool()
def generateVideo(prompt: str):
   """
   Generate an image using a prompt
   """

   url = base_url + "/async/kling-v1.6-t2v"

   payload = {
       "mode": "Standard",
       "prompt": prompt,
       "negative_prompt": "low quality",
       "guidance_scale": 0.6
   }

   response = requests.post(url, json=payload, headers=headers)
  
   return response.json()

Texto para Fala

Esta ferramenta gera fala usando o endpoint Texto para Fala da API Novita. Também é um endpoint assíncrono, então retorna um ID de tarefa.

@mcp.tool()
def textToSpeech(text, voice_id) -> str:
   """
   Generate speech using text and voice id.
   It returns the task id of the generated speech.
  
   The available voice ids are:
   - Emily
   - James
   - Olivia
   - Michael
   - Sarah
   - John
   """

   url = base_url + "/async/txt2speech"

   payload = {
       "request": {
           "voice_id": voice_id,
           "language": "en-US",
           "texts": [text]
       }
   }

   response = requests.post(url, json=payload, headers=headers)
  
   return response.json()["task_id"]

Com todas as nossas ferramentas definidas, podemos então configurar nosso mecanismo de transporte. Usaremos stdio.

if __name__ == "__main__":
   # Run using stdio transport
   mcp.run(transport="stdio")

Podemos agora juntar todo o código:

import os
import sys

from mcp.server.fastmcp import FastMCP

import requests

import uvicorn

from starlette.applications import Starlette
from starlette.routing import Mount

base_url = "https://api.novita.ai/v3"

headers = {
   "Content-Type": "application/json",
   "Authorization": f"Bearer {os.environ['NOVITA_API_KEY']}"
}

mcp = FastMCP("Novita_API")

@mcp.tool()
def list_models() -> str:
   """
   List all available models from the Novita API.
   """

   url = base_url + "/openai/models"

   response = requests.request("GET", url, headers=headers)
   data = response.json()["data"]
  
   text = ""
   for i, model in enumerate(data, start=1):
       text += f"Model id: {model['id']}\
"
       text += f"Model description: {model['description']}\
"
       text += f"Model type: {model['model_type']}\
\
"
  
   return text

@mcp.tool()
def get_model(model_id: str, message) -> str:
   """
   Provide a model ID and a message to get a response from the Novita API.
   """

   url = base_url + "/openai/chat/completions"

   payload = {
       "model": model_id,
       "messages": [
           {
               "content": message,
               "role": "user",
           }
       ],
       "max_tokens": 200,
       "response_format": {
           "type": "text",
       },
   }

   response = requests.request("POST", url, json=payload, headers=headers)
  
   content = response.json()["choices"][0]["message"]["content"]

   return content

@mcp.tool()
def text2Image(prompt: str) -> str:
   """
   Generate an image from a text prompt using the Novita API.
   """

   url = base_url + "/async/txt2img"

   payload = {
       "request": {
           "model_name": "sd_xl_base_1.0.safetensors",
           "prompt": prompt,
           "width": 1024,
           "height": 1024,
           "image_num": 1,
           "steps": 20,
           "clip_skip": 1,
           "sampler_name": "Euler a",
           "guidance_scale": 7.5,
       },
       "extra": {
           "response_image_type": "jpeg"
       }
   }

   response = requests.request("POST", url, json=payload, headers=headers)

   return response.json()["task_id"]

@mcp.tool()
def task_result(task_id: str) -> str:
   """
   Get the current status of a running task using it's task id
   """

   url = base_url + f'/async/task-result?task_id={task_id}'

   response = requests.request("GET", url, headers=headers)
   return response.json()

@mcp.tool()
def generateVideo(prompt: str) -> str:
   """
   Generate an image using a prompt
   """

   url = base_url + "/async/kling-v1.6-t2v"

   payload = {
       "mode": "Standard",
       "prompt": prompt,
       "negative_prompt": "low quality",
       "guidance_scale": 0.6
   }

   response = requests.post(url, json=payload, headers=headers)
  
   return response.json()["task_id"]

@mcp.tool()
def textToSpeech(text, voice_id) -> str:
   """
   Generate speech using text and voice id.
   It returns the task id of the generated speech.
  
   The available voice ids are:
   - Emily
   - James
   - Olivia
   - Michael
   - Sarah
   - John
   """

   url = base_url + "/async/txt2speech"

   payload = {
       "request": {
           "voice_id": voice_id,
           "language": "en-US",
           "texts": [text]
       }
   }

   response = requests.post(url, json=payload, headers=headers)
  
   return response.json()["task_id"]

if __name__ == "__main__":
   # Run using stdio transport
   mcp.run(transport="stdio")

Podemos testar nosso servidor MCP em qualquer host MCP, como Claude Desktop, Cursor ou VS Code, usando a seguinte configuração:

{
     "command": "python",
     "args": [
       "path/to/server.py" 
     ],
     "env": {
       "NOVITA_API_KEY": "sk_...."
     }
   }

Também podemos usar o script cliente que desenvolvemos anteriormente para testar nosso servidor.

Usando o Servidor MCP de Baixo Nível

O servidor que construímos na seção anterior utiliza a classe FastMCP, que fornece uma interface de alto nível para construir servidores MCP. Você também pode construir servidores MCP usando o servidor de baixo nível, que oferece controle granular sobre o protocolo MCP. Vamos ver como podemos modificar o servidor da seção anterior para usar o servidor de baixo nível.

Gerenciamento de Ferramentas

Uma das coisas que o FastMCP faz é gerenciar as ferramentas que você define. Quando você decora uma função com o decorador tool da classe FastMCP, o FastMCP adiciona essa ferramenta a uma lista. Quando o agente solicita essa ferramenta, o FastMCP a busca, a chama e envia o resultado de volta ao agente.

Com o servidor de baixo nível, podemos gerenciar esse processo nós mesmos usando o decorador call_tool.

@app.call_tool()
async def manage_tool(name: str, arguments: dict ) -> list[types.TextContent]:
   if name == "list_models":
       return await list_models_tool()
  
   if name == "get_model":
       return await get_model_tool(arguments)
  
   else:
       raise ValueError(f"Unknown tool: {name}")

O código acima mostra uma função que foi decorada com o método call_tool. Quando o agente chama uma ferramenta, ele passa o nome da ferramenta e quaisquer argumentos que a ferramenta espera. Usando o nome da função, podemos então determinar qual ferramenta o agente deseja chamar e executá-la.

Também podemos gerenciar a listagem das ferramentas usando o servidor de baixo nível, ao contrário do FastMCP, que faz isso automaticamente quando uma função é decorada com o método tool.

@app.list_tools()
async def list_tools() -> list[types.Tool]:
   return [
       types.Tool(
           name="list_models",
           description="List all available models from the Novita API.",
           inputSchema={"type": "object", "properties": {}},
       ),
       types.Tool(
           name="get_model",
           description="Provide a model ID and a message to get a response from the Novita API.",
           inputSchema={
               "type": "object",
               "required": ["model_id", "message"],
               "properties": {
                   "model_id": {
                       "type": "string",
                       "description": "The ID of the model to use.",
                   },
                   "message": {
                       "type": "string",
                       "description": "The input message to send.",
                   },
               },
           },
       ),
   ]

Aqui está o código completo do servidor de baixo nível. Ele contém duas ferramentas e pode se comunicar com o cliente via entrada e saída padrão.

import os
import asyncio
import requests
from mcp.server.lowlevel import Server
from mcp.server.stdio import stdio_server
import mcp.types as types

base_url = "https://api.novita.ai/v3"

headers = {
   "Content-Type": "application/json",
   "Authorization": f"Bearer {os.environ['NOVITA_API_KEY']}"
}

app = Server("Novita_API")

async def list_models_tool():
   """
   Lists all available models from the Novita API.
   """
   url = base_url + "/openai/models"
   response = requests.get(url, headers=headers)
   data = response.json()["data"]

   text = ""
   for i, model in enumerate(data, start=1):
       text += f"Model id: {model['id']}\
"
       text += f"Model description: {model['description']}\
"
       text += f"Model type: {model['model_type']}\
\
"

   return [types.TextContent(type="text", text=text)]

async def get_model_tool(arguments: dict):
   """
   Given a model ID and a user message, fetch a response from the Novita API.
   """
   model_id = arguments.get("model_id")
   message = arguments.get("message")

   if not model_id or not message:
       raise ValueError("Both 'model_id' and 'message' are required.")

   url = base_url + "/openai/chat/completions"

   payload = {
       "model": model_id,
       "messages": [
           {
               "content": message,
               "role": "user",
           }
       ],
       "max_tokens": 200,
       "response_format": {
           "type": "text",
       },
   }

   response = requests.post(url, json=payload, headers=headers)
   content = response.json()["choices"][0]["message"]["content"]
   return [types.TextContent(type="text", text=content)]

@app.call_tool()
async def manage_tool(name: str, arguments: dict ) -> list[types.TextContent]:
   if name == "list_models":
       return await list_models_tool()
  
   if name == "get_model":
       return await get_model_tool(arguments)
  
   else:
       raise ValueError(f"Unknown tool: {name}")

@app.list_tools()
async def list_tools() -> list[types.Tool]:
   return [
       types.Tool(
           name="list_models",
           description="List all available models from the Novita API.",
           inputSchema={"type": "object", "properties": {}},
       ),
       types.Tool(
           name="get_model",
           description="Provide a model ID and a message to get a response from the Novita API.",
           inputSchema={
               "type": "object",
               "required": ["model_id", "message"],
               "properties": {
                   "model_id": {
                       "type": "string",
                       "description": "The ID of the model to use.",
                   },
                   "message": {
                       "type": "string",
                       "description": "The input message to send.",
                   },
               },
           },
       ),
   ]

async def main():
   async with stdio_server() as streams:
       await app.run(streams[0], streams[1], app.create_initialization_options())

if __name__ == "__main__":
   asyncio.run(main())

O servidor de baixo nível não apenas oferece controle refinado sobre o gerenciamento de ferramentas, mas também fornece controle de baixo nível sobre recursos, prompts e outras partes do protocolo MCP, como gerenciamento de ciclo de vida.

Conclusão

Neste tutorial, construímos um servidor MCP que utiliza a API Novita para aprimorar as capacidades de qualquer host MCP. Você aprendeu os fundamentos do que é necessário para criar um servidor MCP, incluindo como definir e expor ferramentas.

Com essa base, você pode começar a explorar tópicos mais avançados, como autenticação, implantação de servidores MCP remotos e trabalho direto com a implementação Python de baixo nível.

Também exploramos a própria API Novita e vimos suas capacidades, desde um conjunto diversificado de modelos de linguagem até ferramentas de geração de vídeo, áudio e imagens. Visite o Novita LLM Playground para experimentar outras APIs que não cobrimos, como os endpoints de edição de imagem e rosto.

Novita AI é uma plataforma de nuvem de IA que oferece aos desenvolvedores uma maneira fácil de implantar modelos de IA usando nossa API simples, além de fornecer a nuvem GPU acessível e confiável para construção de aplicações.