Skip to content

alejaosm/mcp-server

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

4 Commits
 
 

Repository files navigation

MCP Server LAB

Laboratory Create your first MCP Server with AWS architecture

Este es un laboratorio avanzado de nivel arquitectónico. Configurar el Model Context Protocol (MCP) con Amazon Bedrock AgentCore Gateway (el componente que conecta agentes con servidores MCP externos a través de endpoints seguros) requiere una alineación perfecta entre Java, Docker, AWS (EKS/ECR) y Kubernetes.

Para que no te falte absolutamente nada y mantengas la agilidad que necesitas en tus laboratorios, he estructurado todo en una guía integral paso a paso de principio a fin, incluyendo la herramienta local necesaria (kubectl y aws-cli) para desplegar desde tu máquina.


1. Proyecto Java: MCP Server con Spring AI y WebFlux (Clean Architecture)

Elegiremos 2 herramientas (Tools) lógicas para el agente: get_exchange_rate (tasas de cambio para Palma/Polonia) y get_city_safety_index (datos de seguridad/consejos).

Estructura del Proyecto

mcp-server/
├── src/main/java/com/lab/mcp/
│   ├── domain/                  # Reglas de negocio puras (Modelos y contratos)
│   │   ├── model/ToolRequest.java
│   │   └── repository/CityToolRepository.java
│   ├── infrastructure/          # Spring AI, WebFlux, Controladores (Detalles técnicos)
│   │   ├── controller/McpHttpController.java
│   │   └── repository/MockCityToolRepository.java
│   └── McpServerApplication.java
├── pom.xml

pom.xml (Dependencias clave)

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-webflux</artifactId>
    </dependency>
    <!-- Agregamos Spring AI para estructurar el formato de tools si se requiere, 
         pero para cumplir el estándar estricto de MCP sobre HTTP de Bedrock: -->
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <optional>true</optional>
    </dependency>
</dependencies>

Capa de Dominio (Domain)

// domain/model/ToolResponse.java
package com.lab.mcp.domain.model;
import lombok.AllArgsConstructor;
import lombok.Data;

@Data
@AllArgsConstructor
public class ToolResponse {
    private String result;
}

Capa de Infraestructura (Controlador WebFlux)

Bedrock AgentCore Gateway invoca los servidores MCP remotos utilizando el protocolo estandarizado MCP sobre transporte HTTP (POST /tools/call).

// infrastructure/controller/McpHttpController.java
package com.lab.mcp.infrastructure.controller;

import org.springframework.web.bind.annotation.*;
import reactor.core.publisher.Mono;
import java.util.Map;

@RestController
@RequestMapping("/mcp")
public class McpHttpController {

    // endpoint 1: Listar las herramientas disponibles (Requerido por MCP)
    @GetMapping("/tools")
    public Mono<Map<String, Object>> listTools() {
        return Mono.just(Map.of(
            "tools", java.util.List.of(
                Map.of(
                    "name", "get_exchange_rate",
                    "description", "Get the current exchange rate for a target currency compared to EUR.",
                    "inputSchema", Map.of(
                        "type", "object",
                        "properties", Map.of("currency", Map.of("type", "string", "description", "e.g., PLN, USD"))
                    )
                ),
                Map.of(
                    "name", "get_city_safety_index",
                    "description", "Get safety index and tips for a specific city.",
                    "inputSchema", Map.of(
                        "type", "object",
                        "properties", Map.of("city", Map.of("type", "string"))
                    )
                )
            )
        ));
    }

    // endpoint 2: Ejecutar la herramienta (Call Tool)
    @PostMapping("/tools/call")
    public Mono<Map<String, Object>> callTool(@RequestBody Map<String, Object> request) {
        String toolName = (String) request.get("name");
        Map<String, Object> arguments = (Map<String, Object>) request.get("arguments");

        if ("get_exchange_rate".equals(toolName)) {
            String curr = (String) arguments.getOrDefault("currency", "PLN");
            return Mono.just(Map.of("content", java.util.List.of(Map.of("type", "text", "text", "Current rate: 1 EUR = 4.32 " + curr))));
        } else if ("get_city_safety_index".equals(toolName)) {
            String city = (String) arguments.getOrDefault("city", "Palma");
            return Mono.just(Map.of("content", java.util.List.of(Map.of("type", "text", "text", city + " is very safe (Index: 85/100). Normal precautions apply."))));
        }
        
        return Mono.just(Map.of("isError", true, "content", java.util.List.of(Map.of("type", "text", "text", "Tool not found"))));
    }
}

2. Infraestructura: CloudFormation (infra-eks.yaml)

Este template creará el repositorio ECR, la red VPC, el clúster EKS y un grupo de nodos administrados. Guardar como infra-eks.yaml.

AWSTemplateFormatVersion: '2010-09-09'
Description: 'Infraestructura base para MCP: ECR, VPC y clúster EKS básico.'

Resources:
  McpRepository:
    Type: AWS::ECR::Repository
    Properties:
      RepositoryName: mcp-server-repo

  McpVPC:
    Type: AWS::ECR::Repository # (Nota simplificada para el lab: puedes usar la vpc default o un wizard de EKS)
    # Para agilidad en laboratorios, crearemos el EKS usando eksctl directamente o referenciando recursos existentes.

💡 Nota de Agilidad para Labs: Crear un EKS completo por CloudFormation puro toma más de 500 líneas de código JSON/YAML de redes. La herramienta oficial y estándar de la industria para laboratorios rápidos es eksctl. Ejecuta esto en tu terminal en lugar del CFN pesado para crear el clúster en 10 minutos:

eksctl create cluster --name lab-mcp-cluster --region us-east-2 --nodegroup-name standard-nodes --node-type t3.medium --nodes 2

3. Dockerfile

Optimizado con Multi-stage building para reducir el tamaño de la imagen final usando la distro oficial de Java:

# Stage 1: Build
FROM maven:3.9.6-eclipse-temurin-17 AS build
WORKDIR /app
COPY pom.xml .
COPY src ./src
RUN mvn clean package -DskipTests

# Stage 2: Run
FROM eclipse-temurin:17-jre-jammy
WORKDIR /app
COPY --from=build /app/target/*.jar app.jar
EXPOSE 8080
ENTRYPOINT ["java", "-jar", "app.jar"]

4. Paso a paso: Cómo desplegar desde tu máquina Local a ECR y EKS

Requisitos en tu PC

Debes tener instalados: aws-cli, docker y kubectl.

Paso 4.1: Publicar en ECR desde tu terminal local

  1. Autentica tu Docker local con tu ECR de AWS (reemplaza 123456789012 y la región):
aws ecr get-login-password --region us-east-2 | docker login --username AWS --password-stdin 123456789012.dkr.ecr.us-east-2.amazonaws.com
  1. Construye tu imagen Docker:
docker build -t mcp-server-repo .
  1. Taggea la imagen apuntando a tu repositorio de AWS:
docker tag mcp-server-repo:latest 123456789012.dkr.ecr.us-east-2.amazonaws.com/mcp-server-repo:latest
  1. Sube la imagen a la nube (Push):
docker push 123456789012.dkr.ecr.us-east-2.amazonaws.com/mcp-server-repo:latest

Paso 4.2: Conectar tu terminal local al clúster EKS

Para que tu comando kubectl local sepa a dónde enviar los recursos:

aws eks update-kubeconfig --region us-east-2 --name lab-mcp-cluster

5. Recursos K8s y Configuración del Ingress (Exposición a Internet)

Para exponer de forma ágil el servicio, utilizaremos el AWS Load Balancer Controller o, de manera aún más nativa para laboratorios sin instalar controladores externos, un Service de tipo LoadBalancer (creará un Classic o Network Load Balancer automáticamente en tu cuenta de AWS).

Guarda este archivo único como k8s-mcp-deployment.yaml:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: mcp-server-deployment
  labels:
    app: mcp-server
namespace: default
spec:
  replicas: 1
  selector:
    matchLabels:
      app: mcp-server
  template:
    metadata:
      labels:
        app: mcp-server
    spec:
      containers:
      - name: mcp-server
        image: 123456789012.dkr.ecr.us-east-2.amazonaws.com/mcp-server-repo:latest
        ports:
        - containerPort: 8080
        imagePullPolicy: Always
---
apiVersion: v1
kind: Service
metadata:
  name: mcp-server-service
namespace: default
spec:
  type: LoadBalancer # Crea el componente de red público de AWS de inmediato
  ports:
  - port: 80
    targetPort: 8080
    protocol: TCP
  selector:
    app: mcp-server

Aplicar en EKS desde tu Local:

kubectl apply -f k8s-mcp-deployment.yaml

Para obtener la URL pública asignada por AWS que utilizaremos en el Gateway:

kubectl get svc mcp-server-service -w

Espera a que la columna EXTERNAL-IP cambie de <pending> a un DNS largo de AWS (ej: a123bc...us-east-2.elb.amazonaws.com). Tu URL MCP para el Gateway será: http://<TU-EXTERNAL-IP>/mcp.


6. Configuración de Amazon Bedrock AgentCore Gateway

El AgentCore Gateway permite registrar este endpoint HTTP externo como un Endpoint MCP compatible dentro de tu entorno de agentes de Bedrock.

Pasos en la consola de AWS Bedrock:

  1. Ingresa a Amazon Bedrock usando el Rol que creamos previamente.
  2. En el panel de navegación izquierdo, expande la sección Builder tools y selecciona Agents.
  3. Dirígete a la pestaña o consola de AgentCore (Harness Playground / Enterprise Integration).
  4. Selecciona External MCP Servers / Gateways y haz clic en Register New Server.
  5. Configura los siguientes campos:
  • Name: CityExplorerMcpServer
  • Transport Type: Selecciona HTTP (o SSE si requiere streaming continuo).
  • URL Endpoint: Pega la URL pública de tu Balanceador de EKS: http://<TU-EXTERNAL-IP>/mcp
  1. En la sección de autenticación (si estás en producción, requiere API Key mediante AWS Secrets Manager; para tu laboratorio, puedes configurarlo como None / No Auth si abriste el puerto libremente).

  2. Haz clic en Save and Verify. Bedrock enviará una petición de prueba a tu pod de EKS ejecutando WebFlux para obtener el mapa de /tools.

Una vez que el Gateway marque el estado en Active, abre el Harness Playground, asocia el servidor MCP a tu agente (CityExplorerAgent002) y lánzale una de tus queries de prueba: "Give me the current exchange rate for PLN". El agente entenderá la instrucción, llamará al Gateway, este pasará por internet al EKS, y tu código Java retornará el resultado.

About

Laboratory Create your first MCP Server with AWS architecture

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors