Skip to main content
Glama
ErnestoZeferinoDiaz

Gestion MCP Server

Human Resources Management — MCP Server

Servidor MCP (Model Context Protocol) para el sistema de gestión de recursos humanos. Expone tools que un LLM o agente puede invocar mediante Streamable HTTP (y opcionalmente stdio).


Stack

Componente

Tecnología

Runtime

Node.js 20 Alpine

Lenguaje

TypeScript 5.7 (compilado con tsc, ejecutado con node)

Sistema de módulos

ESM ("type": "module" en package.json)

SDK MCP

@modelcontextprotocol/server v2.0.0

Transporte HTTP

WebStandardStreamableHTTPServerTransport (stateless)

Transporte Stdio

StdioServerTransport (desde @modelcontextprotocol/server/stdio)

Validación

Zod v4

Servidor HTTP

node:http nativo (createServer). Sin Express ni frameworks.

Contenedor

Docker (Dockerfile en ../docker/mcp.Dockerfile)


Related MCP server: agentforge

Arquitectura: Clean Architecture con módulos

El código sigue Clean Architecture (Puertos y Adaptadores). Las dependencias siempre apuntan hacia adentro:

Infrastructure ──→ Application ──→ Domain
   (adaptadores)     (casos de uso)   (lógica pura)

src/shared/types.ts es accesible desde cualquier capa.

Estructura de directorios

src/
├── main.ts                              ← Entry point: elige transporte según --http / --stdio
│
├── shared/
│   └── types.ts                         ← Tipos transversales: MCPToolResponse, Result<T>
│
├── template/                            ← MÓDULO: tools de plantilla/demo
│   ├── domain/
│   │   └── entities/
│   │       └── HealthStatus.ts          ← Entidad de dominio: estado del servidor
│   ├── application/
│   │   ├── dto/
│   │   │   └── index.ts                 ← DTOs planos: GreetInput/Output, CalculateInput/Output
│   │   └── use-cases/
│   │       ├── greet/
│   │       │   ├── IGreetUseCase.ts     ← Puerto (interfaz)
│   │       │   └── GreetUseCase.ts      ← Implementación del caso de uso
│   │       ├── calculate/
│   │       │   ├── ICalculateUseCase.ts
│   │       │   └── CalculateUseCase.ts
│   │       └── health-check/
│   │           ├── IHealthCheckUseCase.ts
│   │           └── HealthCheckUseCase.ts
│   └── infrastructure/
│       └── mcp/
│           └── schemas.ts               ← Zod schemas + registerTemplateTools()
│
├── infrastructure/                       ← Infraestructura COMPARTIDA entre módulos
│   ├── config/
│   │   └── env.ts                       ← Tipado y carga de variables de entorno
│   ├── mcp/
│   │   └── server-factory.ts            ← Orquestador: crea McpServer y registra tools de todos los módulos
│   └── transport/
│       ├── http-server.ts               ← Servidor HTTP (StreamableHTTP, stateless)
│       └── stdio-server.ts              ← Servidor stdio (para MCP Inspector)
│
└── (futuro) personnel/                   ← EJEMPLO: futuro módulo que conectará al Backend
    ├── domain/...
    ├── application/...
    └── infrastructure/mcp/schemas.ts

Reglas de dependencia por capa

Capa

Puede importar de

NO puede importar de

domain/

shared/

application/, infrastructure/

application/

domain/, shared/, application/dto/

infrastructure/

infrastructure/ (compartida)

domain/, application/, shared/

<modulo>/infrastructure/

domain/, application/, shared/ del mismo módulo

otros módulos directamente

Responsabilidad de cada archivo

Archivo

Capa

Función

main.ts

Punto de entrada. Parsea --http/--stdio. Por defecto HTTP.

shared/types.ts

Shared

MCPToolResponse (formato que espera registerTool), Result<T>

infrastructure/config/env.ts

Infra

loadEnvironment() → tipa NODE_ENV, PORT, BACKEND_URL, LOG_LEVEL

infrastructure/mcp/server-factory.ts

Infra

createServerFactory() → instancia McpServer, llama a registerTemplateTools(). Aquí se agregan futuros módulos.

infrastructure/transport/http-server.ts

Infra

startHttpServer(env) → crea node:http server, convierte IncomingMessage → Web Request, invoca transport.handleRequest(). Stateless.

infrastructure/transport/stdio-server.ts

Infra

startStdioServer()StdioServerTransport + server.connect()

template/domain/entities/HealthStatus.ts

Domain

Entidad pura con factory methods create() y degraded(), método toSummary()

template/application/dto/index.ts

Application

DTOs planos: GreetInput, GreetOutput, CalculateInput, CalculateOutput, HealthCheckOutput

template/application/use-cases/*/I*UseCase.ts

Application

Puerto: interfaz del caso de uso (execute method)

template/application/use-cases/*/*UseCase.ts

Application

Implementación del caso de uso (lógica de negocio)

template/infrastructure/mcp/schemas.ts

Infra (módulo)

Zod schemas + registerTemplateTools(server, version). Adaptador que conecta use cases con McpServer.


Flujo de una tool call

┌─────────────────────────────────────────────────────────────────────┐
│ 1. Cliente HTTP POST /mcp                                          │
│    Body: {"jsonrpc":"2.0","method":"tools/call","params":{...}}     │
│    Headers: Accept: application/json, text/event-stream             │
└────────────────────────────┬────────────────────────────────────────┘
                             ▼
┌─────────────────────────────────────────────────────────────────────┐
│ 2. http-server.ts: node:http.createServer                          │
│    readRequestBody() → toWebRequest() → transport.handleRequest()  │
└────────────────────────────┬────────────────────────────────────────┘
                             ▼
┌─────────────────────────────────────────────────────────────────────┐
│ 3. WebStandardStreamableHTTPServerTransport (stateless)            │
│    Parsea JSON-RPC, enruta al McpServer                            │
└────────────────────────────┬────────────────────────────────────────┘
                             ▼
┌─────────────────────────────────────────────────────────────────────┐
│ 4. McpServer (creado en server-factory.ts)                         │
│    Valida input con Zod schema → ejecuta handler de la tool        │
└────────────────────────────┬────────────────────────────────────────┘
                             ▼
┌─────────────────────────────────────────────────────────────────────┐
│ 5. template/infrastructure/mcp/schemas.ts                          │
│    Handler: Zod valida params → crea DTO → llama UseCase.execute() │
└────────────────────────────┬────────────────────────────────────────┘
                             ▼
┌─────────────────────────────────────────────────────────────────────┐
│ 6. UseCase.execute(dto) → lógica pura                              │
│    Puede usar entidades de domain/                                 │
└────────────────────────────┬────────────────────────────────────────┘
                             ▼
┌─────────────────────────────────────────────────────────────────────┐
│ 7. Handler retorna { content: [{ type: "text", text: "..." }] }    │
│    McpServer → Transport → JSON-RPC response → HTTP response       │
└─────────────────────────────────────────────────────────────────────┘

Tools actuales (módulo template)

Tool

Descripción

Input

Output

greet

Saludo personalizado

{ name: string }

"Hello, {name}! Welcome to the HRM MCP Server."

calculate

Operaciones aritméticas

{ operation: enum, a: number, b: number }

"5 add 3 = 8"

health_check

Estado del servidor

{}

"Status: healthy | Uptime: 4m 0s | Version: 1.0.0 | ..."


Guía: Cómo agregar una nueva tool

Dentro de un módulo existente (ej: template)

Paso 1: Agregar DTOs en src/template/application/dto/index.ts

export class MyInput {
  constructor(public readonly param: string) {}
}
export class MyOutput {
  constructor(public readonly result: string) {}
}

Paso 2: Crear interfaz src/template/application/use-cases/my-tool/IMyUseCase.ts

import type { MyInput, MyOutput } from '../../dto/index.js';
export interface IMyUseCase {
  execute(input: MyInput): Promise<MyOutput>;
}

Paso 3: Crear implementación src/template/application/use-cases/my-tool/MyUseCase.ts

import type { IMyUseCase } from './IMyUseCase.js';
import { MyInput, MyOutput } from '../../dto/index.js';
export class MyUseCase implements IMyUseCase {
  public async execute(input: MyInput): Promise<MyOutput> {
    return new MyOutput(`Processed: ${input.param}`);
  }
}

Paso 4: Agregar Zod schema y handler en src/template/infrastructure/mcp/schemas.ts

const myInputSchema = z.object({
  param: z.string().describe('Description of param'),
});

// Dentro de registerTemplateTools():
server.registerTool(
  'my_tool',
  {
    description: 'What this tool does.',
    inputSchema: myInputSchema,
  },
  async (params: z.infer<typeof myInputSchema>) => {
    const input = new MyInput(params.param);
    const output = await myUseCase.execute(input);
    return {
      content: [{ type: 'text' as const, text: output.result }],
    };
  }
);

Errores en tools

Para reportar errores al LLM, retorna isError: true:

catch (error) {
  return {
    content: [{ type: 'text' as const, text: `Error: ${error.message}` }],
    isError: true,
  };
}

Guía: Cómo crear un nuevo módulo

Cuando necesites una funcionalidad completamente nueva (ej: conexión al backend para gestión de personal), crea un módulo:

Paso 1: Crear la estructura de carpetas

src/personnel/
├── domain/
│   └── entities/
│       └── Employee.ts
├── application/
│   ├── dto/
│   │   └── index.ts
│   └── use-cases/
│       └── get-employee/
│           ├── IGetEmployeeUseCase.ts
│           └── GetEmployeeUseCase.ts
└── infrastructure/
    └── mcp/
        └── schemas.ts           ← export function registerPersonnelTools(server, version)

Paso 2: El schemas.ts del módulo debe exportar una función con esta firma:

import type { McpServer } from '@modelcontextprotocol/server';
import { z } from 'zod';

export function registerPersonnelTools(server: McpServer, version: string): void {
  const useCase = new GetEmployeeUseCase(/* dependencias */);

  server.registerTool('get_employee', {
    description: 'Get employee by ID',
    inputSchema: z.object({ id: z.string() }),
  }, async ({ id }) => {
    const output = await useCase.execute(new GetEmployeeInput(id));
    return { content: [{ type: 'text' as const, text: JSON.stringify(output) }] };
  });
}

Paso 3: Registrar el módulo en src/infrastructure/mcp/server-factory.ts

import { registerTemplateTools } from '../../template/infrastructure/mcp/schemas.js';
import { registerPersonnelTools } from '../../personnel/infrastructure/mcp/schemas.js'; // ← nuevo

export function createServerFactory(): McpServer {
  const server = new McpServer({ name: 'hrm-mcp', version: SERVER_VERSION });
  registerTemplateTools(server, SERVER_VERSION);
  registerPersonnelTools(server, SERVER_VERSION);  // ← nuevo
  return server;
}

Transportes

HTTP (Streamable HTTP) — por defecto

  • Endpoint: POST /mcp (también acepta POST /)

  • Headers requeridos: Accept: application/json, text/event-stream

  • Modo: Stateless (sessionIdGenerator: undefined). Cada request es independiente.

  • Puerto: 3001 (configurable con PORT)

  • Health check: GET /health{"status":"ok"}

  • Arranque: node dist/main.js o node dist/main.js --http

Stdio — opcional

  • Arranque: node dist/main.js --stdio

  • Uso: MCP Inspector o clientes que lancen el proceso como hijo

  • Logs: Usar console.error (stdout es el canal del protocolo)


Docker

Dockerfile

Ubicado en ../docker/mcp.Dockerfile. Tiene 3 stages:

Stage

Propósito

Comando

builder

Clona repo, npm ci, npm run build, npm prune --production

production

Imagen mínima con solo dist/ + node_modules prod

node dist/index.js

development

Copia source, instala deps, compila y ejecuta

npm run build && node dist/main.js --http

Comandos Docker Compose

# Construir sin caché
docker compose -f docker-compose.dev.yml build --no-cache mcp-server

# Ejecutar
docker compose -f docker-compose.dev.yml up mcp-server

# Ejecutar en background
docker compose -f docker-compose.dev.yml up -d mcp-server

# Ver logs
docker compose -f docker-compose.dev.yml logs -f mcp-server

# Detener
docker compose -f docker-compose.dev.yml down

Volumes en desarrollo

volumes:
  - ./HumanResourcesManagement-MCP:/app       # Código fuente (live)
  - mcp_node_modules:/app/node_modules        # node_modules preservado

El CMD del stage development ejecuta npm run build && node dist/main.js --http, por lo que recompila el TypeScript al iniciar el contenedor.


Testing manual

Health check

curl http://localhost:3001/health

MCP: Listar tools

curl -X POST http://localhost:3001/mcp \
  -H "Content-Type: application/json" \
  -H "Accept: application/json, text/event-stream" \
  -d '{"jsonrpc":"2.0","method":"tools/list","id":1}'

MCP: Inicializar conexión

curl -X POST http://localhost:3001/mcp \
  -H "Content-Type: application/json" \
  -H "Accept: application/json, text/event-stream" \
  -d '{"jsonrpc":"2.0","method":"initialize","params":{"protocolVersion":"2026-07-28","capabilities":{},"clientInfo":{"name":"test","version":"1.0"}},"id":1}'

MCP: Llamar una tool

curl -X POST http://localhost:3001/mcp \
  -H "Content-Type: application/json" \
  -H "Accept: application/json, text/event-stream" \
  -d '{"jsonrpc":"2.0","method":"tools/call","params":{"name":"greet","arguments":{"name":"World"}},"id":2}'

Variables de entorno

Variable

Default

Descripción

NODE_ENV

development

Entorno (development, production, test)

PORT

3001

Puerto del servidor HTTP

BACKEND_URL

http://localhost:8080

URL del backend (para futura conexión)

LOG_LEVEL

info

Nivel de log (debug, info, warn, error)

Se cargan desde ../.env.dev en el contenedor de desarrollo.


Convenciones de código

Imports

Todos los imports relativos llevan extensión .js al final (requerido por "moduleResolution": "NodeNext"):

// ✅ Correcto
import { GreetUseCase } from '../../application/use-cases/greet/GreetUseCase.js';

// ❌ Incorrecto
import { GreetUseCase } from '../../application/use-cases/greet/GreetUseCase';

Logging

Usar console.error para todos los logs. En modo stdio, stdout es el canal del protocolo JSON-RPC.

console.error('Server started on port 3001'); // ✅
console.log('Server started on port 3001');    // ❌ (corrompe el protocolo en stdio)

Tipos literales en tool responses

return {
  content: [{ type: 'text' as const, text: 'Hello' }],
};

El as const es necesario para que TypeScript infiera el tipo literal 'text' en lugar de string.

Entidades de dominio

  • Constructor private + factory methods estáticos (create, reconstitute)

  • Propiedades privadas con prefijo _ (_status, _version)

  • Getters públicos para acceso de solo lectura

  • Sin imports de application/ ni infrastructure/

DTOs

  • Clases con constructor(public readonly ...) — objetos planos, sin lógica

  • Sin dependencias externas

  • Sin validaciones de negocio

Use cases

  • Interfaz (I*UseCase) + implementación (*UseCase) en archivos separados

  • Reciben DTOs de entrada, retornan DTOs de salida

  • Pueden usar entidades de dominio y shared/types.ts

  • No conocen MCP, HTTP, ni Zod


Dependencias npm

{
  "dependencies": {
    "@modelcontextprotocol/server": "^2.0.0",
    "zod": "^4.4.0"
  },
  "devDependencies": {
    "@types/node": "^20.0.0",
    "typescript": "^5.7.0"
  }
}

Nota: El paquete @modelcontextprotocol/server v2 exporta desde su entry point principal WebStandardStreamableHTTPServerTransport y McpServer. StdioServerTransport se importa desde el subpath @modelcontextprotocol/server/stdio.


Scripts npm

npm run build        # tsc → dist/
npm start            # node dist/main.js (HTTP por defecto)
npm run start:http   # node dist/main.js --http
npm run start:stdio  # node dist/main.js --stdio

Resumen para un LLM

Si eres un LLM que va a modificar este código, recuerda:

  1. La lógica de negocio va en use cases (application/use-cases/), nunca en schemas ni en handlers.

  2. Los DTOs son planos, sin comportamiento. Se crean en application/dto/.

  3. Cada tool se registra en <modulo>/infrastructure/mcp/schemas.ts con server.registerTool(name, config, handler).

  4. El handler de la tool convierte params (validados por Zod) → DTO → UseCase → DTO → { content: [...] }.

  5. Para crear un nuevo módulo, replica la estructura de template/ y registra su función en server-factory.ts.

  6. Nunca uses console.log — usa console.error para logs.

  7. Todos los imports relativos llevan .js al final.

  8. No instales dependencias en el host — todo se prueba dentro del contenedor Docker.

Available Tools

10 tools
create_personaA

Create a new person in the system. Requires ADMIN or MANAGER role.

ParametersJSON Schema
NameRequiredDescriptionDefault
nombreYesFirst name
apellidoMaternoNoMaternal last name
apellidoPaternoYesPaternal last name
fechaNacimientoNoBirth date (YYYY-MM-DD)
nombresAdicionalesNoAdditional/middle names

TDQS

A3.9/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are present, so the description carries the burden. It discloses the role requirement, which is useful behavioral context, but doesn't mention side effects, return values, or failure modes. This is acceptable but below average.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single sentence with no filler. It conveys the action, target, and a key constraint efficiently.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple CRUD create with 5 well-documented params and no output schema, the description is adequate. However, it omits any mention of uniqueness, error behavior, or what happens on success, which would be more complete. Still, it's a minimum viable description.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so all parameters already have descriptions. The tool description adds no parameter-specific meaning, but the baseline of 3 is appropriate given the schema's completeness.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Description clearly states 'Create a new person in the system', a specific verb + resource. This cleanly differentiates from sibling tools like list_personas, update_persona, and delete_persona.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly states the required ADMIN or MANAGER role, giving clear context for who can use it. While it doesn't explicitly mention alternatives like update_persona, the create/inherit intent is clear from the name and description.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

delete_personaB

Delete a person by ID. Requires ADMIN role only.

ParametersJSON Schema
NameRequiredDescriptionDefault
idYesPerson ID to delete

TDQS

B3.4/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are present, so the description must bear the full burden of disclosing behavior. It notes the destructive nature and admin-only requirement, but omits irreversibility, side effects, error handling, or return behavior, which are important for a delete operation.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, effectively front-loaded sentence with no redundant words. It conveys the action and the key prerequisite without padding.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the lack of an output schema and annotations, the description is too spare. It does not indicate what happens after deletion (success response, permanent removal, cascading effects), making it less complete than expected for a simple but consequential mutation tool.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% with a well-described 'id' parameter. The description's 'by ID' adds no new meaning beyond the schema, so the baseline score of 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the action (delete) and the target (person by ID), making it easy to distinguish from sibling tools like get_persona, create_persona, and update_persona. The verb-resource pairing is unambiguous.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides a clear precondition (requires ADMIN role) but does not explicitly contrast with alternatives or specify when to choose this over update_persona or other tools. Usage is implied from the verb but not elaborated with exclusions.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_meA

Get the current authenticated user's session information. Requires prior login via the 'login' tool.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

A4.2/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full burden. It discloses one key behavioral constraint: the need for prior login. However, it doesn't mention side effects (likely none), whether the session is read-only, or what happens if called without login (error vs. null). This adds some context but not comprehensive behavioral coverage.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, concise, front-loaded sentence. It states the tool's action and the prerequisite without any filler. Both pieces of information are essential, and there is zero redundancy.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given it is a simple getter with no parameters and no output schema, the description is mostly complete. It defines the operation and a critical prerequisite. It doesn't describe what 'session information' includes, but for a trivial tool, this is acceptable. A minor gap is not detailing the failure mode when not logged in.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool has zero parameters, so the schema fully covers the parameter space. Per the rubric, a baseline of 4 is appropriate since there are no parameters to describe. The description adds no parameter-specific detail, but none is needed.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool's function: 'Get the current authenticated user's session information.' The verb 'Get' and the specific resource 'current authenticated user's session information' precisely define what it does, and it is distinct from sibling tools like list_personas or get_persona.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description explicitly states a prerequisite: 'Requires prior login via the login tool,' which tells the agent when this tool is appropriate. It doesn't explicitly exclude alternative tools, but the purpose is unique enough that little else is needed. If the user hasn't logged in, this tool should not be used, which is implied.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_personaA

Get a single person by their ID. Requires authentication.

ParametersJSON Schema
NameRequiredDescriptionDefault
idYesPerson ID to retrieve

TDQS

A3.5/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the full burden of behavioral disclosure. It mentions authentication as a requirement, which is useful, but does not state whether the operation is read-only, what the return format is, how errors are handled, or any side effects. The verb 'get' implies non-destructive behavior, but it is not explicitly stated.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two short sentences, front-loaded with the core action and followed by the authentication requirement. There is no redundant or extraneous information—every word earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple one-parameter read tool with no output schema, the description covers the essential action and the auth prerequisite. However, it does not mention what the returned person object contains or whether the tool can return null/error for missing IDs, which would improve completeness for a 'get' operation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The input schema already provides 100% coverage with a description for the single 'id' parameter ('Person ID to retrieve'). The description reinforces this with 'by their ID' but adds no new semantics beyond what the schema already conveys.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description 'Get a single person by their ID' uses a specific verb and resource, clearly distinguishing it from sibling tools like list_personas, create_persona, update_persona, and delete_persona. It also clarifies the singular nature versus list operations, and the term 'person' differentiates it from the 'usuario' tools.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description states a prerequisite ('Requires authentication') but offers no explicit when-to-use guidance or alternatives. It does not mention when to prefer get_persona over list_personas or get_me, so usage context is only implied by the tool name and the action described.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_usuario_by_emailA

Find a user by their email address. Requires ADMIN or MANAGER role.

ParametersJSON Schema
NameRequiredDescriptionDefault
emailYesEmail address to search for

TDQS

A3.8/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the burden. It discloses the role requirement (ADMIN or MANAGER), which is a behavioral trait. However, it does not mention whether the operation is read-only, what happens if the email is not found, or any other behavioral details. It adds minimal but important context.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two sentences with no redundant words. It front-loads the primary purpose and follows with the prerequisite. Every sentence earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple one-parameter lookup tool with no annotations and no output schema, the description covers the core purpose and access requirement. However, it does not describe the return value or error behavior, which would be helpful since there is no output schema. Overall, it is nearly complete for its simplicity.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the schema already fully documents the 'email' parameter. The description does not add further semantic details (e.g., case-sensitivity, format nuances) beyond the schema, so the baseline score of 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the action ('Find'), the resource ('a user'), and the specific lookup method ('by their email address'). This distinguishes it from sibling tools like list_usuarios (list all) and get_persona (likely by ID).

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies when to use the tool (to find a user by email) and provides a prerequisite (ADMIN or MANAGER role), but does not explicitly mention alternatives or exclusions relative to sibling tools like list_usuarios. Usage guidance is implied rather than explicit.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_personasA

List people from the backend with optional search, pagination, and sorting. Requires authentication (ADMIN, MANAGER, or USER role).

ParametersJSON Schema
NameRequiredDescriptionDefault
pageNoPage number (0-based)
sizeNoPage size
searchNoSearch term to filter by name or last name
sortByNoField to sort by (e.g., nombre, apellidoPaterno, fechaRegistro)
directionNoSort direction

TDQS

A3.6/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the full burden of behavioral disclosure. It adds value by stating authentication requirements (roles) and implying a read-only list operation. It does not disclose return format, default pagination behavior, or performance implications, but the essential safety and access context is present.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is extremely concise: two sentences with no redundancy. The first sentence states the core action and optional features, and the second provides the required authentication. Every word earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the five parameters, no annotations, and no output schema, the description covers the purpose, authentication, and key options. It could explicitly mention that the result is a paginated list of persons, but the term 'List people' implies that. The auth requirement is an important contextual addition.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The input schema already describes all five parameters with 100% coverage, including defaults and constraints. The description only groups them as 'optional search, pagination, and sorting' without adding new semantic detail, thus meeting the baseline of 3 without exceeding it.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool's action ('List people') and resource ('from the backend'), along with optional search, pagination, and sorting. However, it does not explicitly distinguish itself from the sibling tool 'list_usuarios' or mention that 'get_persona' serves single-record lookups.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides a clear context for usage by specifying the required authentication roles (ADMIN, MANAGER, or USER). It does not, however, offer guidance on when to prefer this tool over alternatives like 'list_usuarios' or 'get_persona', nor does it exclude specific cases.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_usuariosA

List users from the backend with optional filters, pagination, and sorting. Requires ADMIN or MANAGER role.

ParametersJSON Schema
NameRequiredDescriptionDefault
rolNoFilter by role
pageNoPage number (0-based)
sizeNoPage size
searchNoSearch term to filter by email
sortByNoField to sort by
directionNoSort direction

TDQS

A3.7/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The only behavioral disclosure is the role requirement. No annotations are provided, so the description carries the full burden. It does not mention response format, pagination behavior, or any side effects beyond the role check.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, front-loaded sentence that conveys the purpose and a key constraint. Every word earns its place; no fluff or redundancy.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

There is no output schema, so the description should clarify what the tool returns (e.g., a list of users or a paginated response). It also does not mention error behavior or any other contextual details, leaving the description somewhat incomplete for a tool with six optional parameters.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The input schema has 100% description coverage for all six parameters, with types, defaults, enums, and descriptions. The description only summarizes 'optional filters, pagination, and sorting' without adding any new meaning beyond the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the verb 'List' and the resource 'users from the backend', distinguishing it from sibling tools like list_personas (different resource) and get_usuario_by_email (different operation).

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description mentions the role requirement (ADMIN or MANAGER) but does not explicitly state when to use this tool versus alternatives like list_personas or get_usuario_by_email. Usage is implied rather than clearly contrasted.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

loginA

Authenticate with the backend API using email and password. Stores the JWT token for subsequent authenticated requests. Call this first before any other tool that requires authentication.

ParametersJSON Schema
NameRequiredDescriptionDefault
emailYesUser email address
passwordYesUser password

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the transparency burden. It discloses a key side effect: 'Stores the JWT token for subsequent authenticated requests.' This adds valuable behavioral context beyond the schema.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two concise sentences: first states the action, second states the invocation order. No wasted words, front-loaded with the most critical information.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple authentication tool, the description adequately covers purpose, usage, and side effects. No output schema exists, but the tool's behavior is sufficiently described given its simplicity.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% (email and password are both documented). The description does not add additional parameter-level details, but the schema already fully explains them, so baseline 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool's purpose: 'Authenticate with the backend API using email and password.' It also distinguishes it from siblings by noting this should be called first before any auth-required tools.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly instructs when to use: 'Call this first before any other tool that requires authentication.' This provides clear usage context, though it does not mention explicit alternatives or when-not scenarios.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

logoutA

Clear the stored JWT token and end the current session.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

A4.5/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the burden. It clearly discloses the primary behavior: clearing the stored token and ending the session. It doesn't elaborate on side effects like server-side invalidation or whether other sessions are affected, but for a simple logout this is adequate.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single sentence that conveys both the action and the object precisely. No wasted words, front-loaded with the main verb.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's simplicity, no parameters, and no output schema, the description fully covers what an agent needs to know. It explains what the tool does and its effect on the session.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool has zero parameters, and schema coverage is 100% by default. The description doesn't add parameter information, but since there are none to document, the baseline of 4 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses specific verbs ('Clear', 'end') and explicitly names the resources ('stored JWT token', 'current session'). It clearly distinguishes from sibling tools like 'login' (which starts a session) and 'get_me' (which reads session info), making the purpose unambiguous.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description clearly implies when to use the tool: when the current session needs to be terminated. It doesn't explicitly mention alternatives or exclusions, but for a logout operation the context is self-evident given the sibling tools.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

update_personaA

Update an existing person by ID. Only the fields provided will be updated. Requires ADMIN or MANAGER role.

ParametersJSON Schema
NameRequiredDescriptionDefault
idYesPerson ID to update
nombreNoFirst name
estadoRegistroNoRecord status
apellidoMaternoNoMaternal last name
apellidoPaternoNoPaternal last name
fechaNacimientoNoBirth date (YYYY-MM-DD)
nombresAdicionalesNoAdditional/middle names

TDQS

A4.1/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the burden of disclosing behavior. It adds partial-update semantics and a role requirement (ADMIN or MANAGER), but it does not disclose the return format, error handling, or behavior for nonexistent IDs.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two concise sentences: the first states the action and target, the second provides key behavioral details. Every sentence earns its place without unnecessary verbosity.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given no output schema and no annotations, the description should cover return values or error conditions. It omits these, though it does cover the essential update behavior and authorization. The tool has 7 parameters, and the description is minimal for that complexity.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the baseline is 3. The description adds value by clarifying that only provided fields are updated, which explains the optional parameter semantics in a way the schema alone does not.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool updates an existing person by ID, using a specific verb and resource. It distinguishes itself from sibling tools like create_persona, delete_persona, and get_persona.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It provides clear context that the tool is for updating an existing person and mentions partial update behavior ('Only the fields provided will be updated'), which guides usage. It doesn't explicitly state when not to use it, but the purpose is unambiguous.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections. Dates show when Glama detected each change.

  1. 10 tool updatesv1.0.0
    • First observedcreate_persona
    • First observeddelete_persona
    • First observedget_me
    • First observedget_persona
    • First observedget_usuario_by_email
    • First observedlist_personas
    • First observedlist_usuarios
    • First observedlogin
    • First observedlogout
    • First observedupdate_persona

TDQS

A3.7/5.0
Disambiguation3/5

Authentication tools are clearly distinct, but personas and usuarios overlap conceptually. While descriptions distinguish 'people' from 'users', the boundary is unclear, and get_usuario_by_email could be confused with get_persona. There is potential for an agent to misselect between persona and usuario tools.

Naming Consistency4/5

Most tools follow a consistent verb_noun pattern (list_personas, create_persona, delete_persona). Exceptions are login, logout, and get_me, which are imperative or pronoun-based but still readable. The overall naming is predictable and mostly consistent.

Tool Count5/5

10 tools is well within the typical 3-15 range and appropriate for a management server covering authentication and entity CRUD. Each tool appears purposeful and the set is not bloated.

Completeness3/5

Persona CRUD is fully covered, and authentication has login, logout, and session info. However, usuario operations are limited to listing and fetching by email, lacking create, update, and delete. This creates an asymmetry and potential dead end if user management is expected in a 'Gestion' server.

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Connectors

Related MCP Servers

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/ErnestoZeferinoDiaz/GeSoft-MCP'

If you have feedback or need assistance with the MCP directory API, please join our Discord server