O servidor MCP da Azion opera como uma ponte entre assistentes de IA e a Plataforma Azion, fornecendo acesso seguro a documentação, ferramentas e recursos através de um protocolo padronizado.


Arquitetura Técnica

O MCP implementa um modelo cliente-servidor usando o protocolo Model Context Protocol da Anthropic. A arquitetura consiste em três componentes principais:

Stack Tecnológica

ComponenteTecnologiaPropósito
RuntimeNode.js 20+Ambiente de execução JavaScript
LinguagemTypeScriptTipagem estática e segurança
ProtocoloMCP SDKImplementação do protocolo Anthropic
HospedagemEdge FunctionsExecução distribuída na Azion
AutenticaçãoPersonal Token / OAuthControle de acesso seguro

Fluxo de Comunicação

Assistente de IA (Cliente)
↓ Conexão HTTP/WebSocket
Servidor MCP (Edge Function)
↓ Chamadas de API
Plataforma Azion (Recursos)

O fluxo funciona da seguinte maneira:

  1. Conexão: O cliente MCP estabelece conexão com o servidor usando HTTP ou WebSocket
  2. Autenticação: O Personal Token valida a identidade do usuário
  3. Descoberta: O cliente descobre ferramentas e recursos disponíveis
  4. Execução: O assistente invoca ferramentas conforme necessário
  5. Resposta: O servidor retorna dados estruturados ao cliente

Componentes do MCP

O protocolo MCP define três tipos principais de capacidades que um servidor pode expor:

Tools (Ferramentas)

Tools são funções que o assistente de IA pode invocar para realizar ações ou buscar informações. Cada tool possui:

  • Nome: Identificador único (ex: search_azion_docs_and_site)
  • Descrição: Explica o propósito e quando usar
  • Schema de entrada: Define parâmetros esperados usando JSON Schema
  • Handler: Função que executa a lógica

Exemplo de definição de tool:

server.tool(
'search_azion_docs_and_site',
{
description: 'Fornece informações sobre a Plataforma Azion, produtos e serviços',
inputSchema: {
type: 'object',
properties: {
query: {
type: 'string',
description: 'Consulta para buscar documentação'
},
docsAmount: {
type: 'number',
description: 'Quantidade de documentos a retornar',
default: 5
}
},
required: ['query']
}
},
async (args) => {
// Implementação da busca
const results = await searchDocs(args.query, args.docsAmount);
return {
content: [{
type: 'text',
text: JSON.stringify(results)
}]
};
}
);

Resources (Recursos)

Resources são dados estruturados que podem ser lidos pelo cliente, similar a arquivos. Eles usam URIs para identificação:

server.resource(
'static-site-deploy-guide',
'azion://static-site/deploy/step-0-preparation',
async () => ({
contents: [{
uri: 'azion://static-site/deploy/step-0-preparation',
name: 'step-0-preparation.md',
mimeType: 'text/markdown',
text: guideContent
}]
})
);

URIs de recursos seguem o formato: azion://[categoria]/[recurso]/[item]

Prompts

Prompts são templates pré-configurados que ajudam em cenários comuns:

server.prompt(
'deploy-static-site',
{
description: 'Guia passo a passo para deploy de sites estáticos',
arguments: [
{
name: 'framework',
description: 'Framework utilizado (ex: nextjs, astro, hugo)',
required: true
}
]
},
async (args) => {
return {
messages: [{
role: 'user',
content: {
type: 'text',
text: 'Ajude-me a fazer deploy de um site ' + args.framework + ' na Azion'
}
}]
};
}
);

Implementação de um Servidor MCP

Para implementar seu próprio servidor MCP, siga estes passos:

Estrutura do Projeto

meu-mcp-server/
├── src/
│ ├── index.ts # Ponto de entrada
│ ├── core/
│ │ ├── tools.ts # Definição de tools
│ │ ├── resources.ts # Definição de resources
│ │ ├── prompts.ts # Definição de prompts
│ │ └── services/ # Lógica de negócio
│ └── middlewares/
│ └── auth.ts # Autenticação
├── package.json
├── tsconfig.json
└── azion.config.ts # Configuração para deploy

Ponto de Entrada

O arquivo principal inicializa o servidor e registra as capacidades:

src/index.ts
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
import { registerTools } from './core/tools';
import { registerResources } from './core/resources';
import { registerPrompts } from './core/prompts';
const server = new McpServer({
name: 'meu-mcp-server',
version: '1.0.0'
});
// Registrar capacidades
registerTools(server);
registerResources(server);
registerPrompts(server);
// Iniciar servidor
export default {
async fetch(request: Request): Promise<Response> {
return server.handleRequest(request);
}
};

Autenticação

O servidor MCP suporta múltiplos métodos de autenticação:

src/middlewares/auth.ts
export async function authenticate(request: Request): Promise<AuthResult> {
const authHeader = request.headers.get('Authorization');
if (!authHeader) {
return { success: false, error: 'Token não fornecido' };
}
const token = authHeader.replace('Bearer ', '');
// Verificar Personal Token (formato: azion + 35 chars)
if (token.startsWith('azion') && token.length === 40) {
return validatePersonalToken(token);
}
// Verificar OAuth token via SSO
return validateOAuthToken(token);
}

Deploy na Azion

O servidor MCP pode ser deployado como uma Edge Function na Azion:

Configuração

Crie um arquivo azion.config.ts na raiz do projeto:

export default {
build: {
preset: 'typescript',
polyfills: true
},
functions: [
{
name: '$FUNCTION_NAME',
path: './functions/index.js'
}
],
applications: [
{
name: '$APPLICATION_NAME',
rules: {
request: [
{
name: 'Execute Function',
description: 'Execute function for all requests',
active: true,
criteria: [
[
{
variable: '${uri}',
conditional: 'if',
operator: 'matches',
argument: '^/'
}
]
],
behaviors: [
{
type: 'run_function',
attributes: {
value: '$FUNCTION_NAME'
}
}
]
}
]
},
functionsInstances: [
{
name: '$FUNCTION_INSTANCE_NAME',
ref: '$FUNCTION_NAME'
}
]
}
],
workloads: [
{
name: '$WORKLOAD_NAME',
active: true,
infrastructure: 1,
deployments: [
{
name: '$DEPLOYMENT_NAME',
current: true,
active: true,
strategy: {
type: 'default',
attributes: {
application: '$APPLICATION_NAME'
}
}
}
]
}
]
}

Deploy

Use o Azion CLI para fazer deploy:

Terminal window
# Link do projeto
azion link
# Build do projeto
azion build
# Deploy para produção
azion deploy

O deploy cria uma URL acessível publicamente que pode ser configurada nos clientes MCP.


Boas Práticas

Design de Tools

  1. Nomes descritivos: Use verbos e substantivos claros (ex: search_docs, create_rule)
  2. Parâmetros tipados: Defina schemas JSON Schema completos
  3. Descrições claras: Explique quando e como usar cada tool
  4. Tratamento de erros: Retorne mensagens de erro informativas
  5. Idempotência: Tools devem ser seguras para múltiplas chamadas

Performance

  1. Cache de respostas: Implemente cache para dados frequentemente acessados
  2. Paginação: Use paginação para grandes conjuntos de dados
  3. Timeouts: Defina timeouts apropriados para operações longas
  4. Compressão: Comprima respostas grandes

Segurança

  1. Validação de entrada: Sempre valide parâmetros de entrada
  2. Rate limiting: Implemente limites de taxa por token
  3. Logs de auditoria: Registre todas as operações sensíveis
  4. Sanitização: Remova dados sensíveis antes de retornar

Exemplo Completo

Veja um exemplo completo de tool para buscar documentação:

src/core/services/docsService.ts
import { z } from 'zod';
const SearchSchema = z.object({
query: z.string().min(1),
docsAmount: z.number().min(1).max(20).default(5)
});
export async function searchDocumentation(args: unknown) {
// Validar entrada
const validated = SearchSchema.parse(args);
// Buscar documentos
const response = await fetch('https://api.azion.com/docs/search', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer ' + process.env.AZION_API_KEY
},
body: JSON.stringify({
query: validated.query,
limit: validated.docsAmount
})
});
if (!response.ok) {
throw new Error('Falha na busca: ' + response.statusText);
}
const results = await response.json();
// Formatar resposta
return {
content: [{
type: 'text',
text: JSON.stringify(results, null, 2)
}]
};
}

Recursos Adicionais