Command Palette

Search for a command to run...

UnylyUnyly
Browse all

Searcher

FreeNot checked

A template for creating MCP servers in Node.js/TypeScript with a modular architecture. It simplifies adding new tools and includes an example Elasticsearch sear

GitHubEmbed

About

A template for creating MCP servers in Node.js/TypeScript with a modular architecture. It simplifies adding new tools and includes an example Elasticsearch search tool.

README

Template hexagonal para crear MCP servers en Node.js/TypeScript. Objetivo: agregar un nuevo tool = crear 1 archivo + 1 línea.

Estructura

src/
├── index.ts                     ← entrypoint (3 líneas)
│
├── core/
│   ├── registry.ts              ← ToolRegistry: registro + dispatcher automático
│   ├── server.ts                ← factory de instancias McpServer
│   └── run.ts                   ← transporte dual stdio/HTTP
│
├── tools/
│   ├── index.ts                 ← ← ← ÚNICO ARCHIVO QUE EDITAS AL AGREGAR TOOLS
│   └── examples/
│       └── es-search.tool.ts    ← ejemplo completo (patrón a seguir)
│
├── infra/
│   ├── clients/
│   │   └── elasticsearch.client.ts   ← singleton de ES
│   └── formatters/
│       └── result.formatter.ts       ← limpieza de resultados para el LLM
│
├── config/
│   ├── env.ts                   ← variables de entorno validadas con Zod
│   └── logger.ts                ← pino → stderr (MCP-safe)
│
└── shared/
    ├── types/
    │   └── tool.types.ts        ← ToolDefinition interface
    └── errors/
        └── mcp.error.ts         ← toMcpError / toMcpSuccess helpers

Agregar un nuevo tool (3 pasos)

Paso 1 — Crea src/tools/mi-feature.tool.ts

import { z } from "zod";
import { ToolDefinition } from "../shared/types/tool.types.js";
import { toMcpSuccess } from "../shared/errors/mcp.error.js";

const MiInput = z.object({
  param: z.string().describe("Descripción para el LLM"),
});

async function miHandler(input: z.infer<typeof MiInput>) {
  // tu lógica aquí
  return toMcpSuccess({ resultado: input.param });
}

export const miTool: ToolDefinition<z.infer<typeof MiInput>> = {
  name: "mi_tool",
  description: "Descripción para el LLM",
  inputSchema: MiInput,
  handler: miHandler,
};

Paso 2 — Regístralo en src/tools/index.ts

import { miTool } from "./mi-feature.tool.js";

export function registerAllTools(registry: ToolRegistry): void {
  registry
    .register(esSearchKeywordTool)
    .register(miTool);  // ← esta línea
}

Paso 3 — Listo. El dispatcher, JSON Schema y listado MCP se actualizan solos.

Variables de entorno

SERVER_NAME=mi-mcp-server
SERVER_VERSION=1.0.0
MCP_TRANSPORT=stdio          # stdio | http
PORT=3001
ELASTICSEARCH_URL=http://localhost:9200
LOG_LEVEL=info

Comandos

npm install
npm run dev           # dev stdio
npm run dev:http      # dev MCP over HTTP
npm run prod          # prod MCP over HTTP

Regla de oro del MCP logging

Nunca uses console.log en un MCP server en modo stdio. stdout es el canal del protocolo. Un console.log rompe el handshake. Usa siempre logger.info(...) de config/logger.ts — escribe a stderr.

from github.com/ljutreras/mcp-searcher

Installing Searcher

This server has no published package — it is built from source. Open the repository and follow its README.

▸ github.com/ljutreras/mcp-searcher

FAQ

Is Searcher MCP free?

Yes, Searcher MCP is free — one-click install via Unyly at no cost.

Does Searcher need an API key?

No, Searcher runs without API keys or environment variables.

Is Searcher hosted or self-hosted?

Self-hosted: the server runs locally on your machine via the install command above.

How do I install Searcher in Claude Desktop, Claude Code or Cursor?

Open Searcher on unyly.org, pick your client tab (Claude Desktop, Claude Code, Cursor) and press Install — the config is generated automatically, no JSON editing.

Related MCPs

Compare Searcher with

Not sure what to pick?

Find your stack in 60 seconds

Author?

Embed badge for your README

Browse similar

All development MCPs