mcp-toolkit
# mcp-toolkit
Servidor MCP de propósito general para agentes de IA.
Construido con **Python 3.13**, **FastMCP** y **Playwright**.
## Herramientas disponibles
| Herramienta | Descripción |
|-----------------|-------------------------------------------------------------------|
| `web_search` | Busca en DuckDuckGo y extrae contenido web con Playwright |
| `fetch_url` | Extrae el contenido principal de una URL directa |
| `http_request` | Ejecuta peticiones HTTP genéricas sin Playwright |
| `time_now` | Devuelve la fecha y hora actual en una zona horaria |
| `date_utils` | Convierte zonas horarias y calcula fechas/duraciones |
| `memory_set` | Guarda un valor persistente en SQLite |
| `memory_get` | Recupera un valor guardado |
| `memory_delete` | Elimina una clave |
| `memory_list` | Lista todas las claves (con filtro por prefijo opcional) |
| `memory_clear` | Borra toda la memoria (¡irreversible!) |
| `memory_search` | Busca texto en claves y valores guardados |
| `run_python` | Ejecuta código Python en un sandbox con timeout |
| `run_js` | Ejecuta código JavaScript con Node.js en un sandbox con timeout |
---
## Instalación
### Requisitos previos
- [UV](https://docs.astral.sh/uv/getting-started/installation/) instalado
- Python 3.13 (UV lo descarga automáticamente si no está)
- Node.js (opcional, solo para `run_js`)
### Opción A — Instalar desde carpeta local
```bash
git clone https://github.com/YoshiLoL0526/mcp-toolkit
cd mcp-toolkit
uv tool install --python 3.13 .
```
### Opción B — Instalar directamente desde GitHub
```bash
uv tool install --python 3.13 git+https://github.com/YoshiLoL0526/mcp-toolkit
```
### Paso obligatorio: instalar Chromium para Playwright
Después de instalar el paquete, ejecuta este comando **una sola vez**:
```bash
# Obtener la ruta del entorno virtual creado por uv tool
uv tool run --from mcp-toolkit python -m playwright install chromium
```
O alternativamente, si sabes la ruta del entorno:
```bash
~/.local/share/uv/tools/mcp-toolkit/bin/python -m playwright install chromium
```
---
## Configuración en clientes MCP
### Claude Desktop (`~/Library/Application Support/Claude/claude_desktop_config.json`)
```json
{
"mcpServers": {
"mcp-toolkit": {
"command": "mcp-toolkit"
}
}
}
```
> En Windows la ruta es `%APPDATA%\Claude\claude_desktop_config.json`
### Cursor / VS Code (`.cursor/mcp.json` o `.vscode/mcp.json`)
```json
{
"servers": {
"mcp-toolkit": {
"type": "stdio",
"command": "mcp-toolkit"
}
}
}
```
### Servidor HTTP (para acceso remoto o múltiples clientes)
```bash
mcp-toolkit --transport http --host 0.0.0.0 --port 8080
```
El servidor quedará escuchando en `http://<host>:<port>/mcp` usando el transporte **streamable-http** (estándar MCP actual). Puedes cambiar la ruta con `--path /otra-ruta`.
> El transporte `--transport sse` se mantiene por compatibilidad con clientes antiguos, pero está deprecado desde FastMCP 2.3.
---
## Uso de las herramientas
### `web_search`
```
Parámetros:
query (str) — texto a buscar
max_results (int) — resultados a devolver, default 5, máximo 10
deep (bool) — si True, extrae el contenido completo de cada página
language (str) — idioma para las cabeceras HTTP, default "es-ES"
```
**Ejemplo (agente):**
```
Busca las últimas noticias sobre Python 3.13 con deep=True
```
### `fetch_url`
```
Parámetros:
url (str) — URL absoluta HTTP o HTTPS a leer
```
**Ejemplo (agente):**
```
Lee https://example.com/articulo con fetch_url
```
### `http_request`
```
Parámetros:
method (str) — método HTTP: GET, POST, PUT, PATCH, DELETE, HEAD u OPTIONS
url (str) — URL absoluta HTTP o HTTPS
headers (dict) — cabeceras opcionales
body (str) — cuerpo opcional como texto
timeout (int) — segundos máximos, default 10, máximo 60
```
**Ejemplo (agente):**
```
Haz un POST a https://api.example.com/items con http_request
```
### `time_now` / `date_utils`
```
time_now(timezone_name="UTC")
date_utils(
action="convert_timezone",
value="2026-04-21T12:00:00+00:00",
target_timezone="America/New_York"
)
```
Acciones soportadas por `date_utils`: `parse`, `convert_timezone`, `add` y
`diff`. Para fechas sin offset se usa `timezone_name`; las zonas horarias deben
ser nombres IANA como `UTC`, `America/New_York` o `Europe/Madrid`.
### `memory_set` / `memory_get`
```
memory_set(key="usuario_nombre", value="Carlos", namespace="default")
memory_get(key="usuario_nombre", namespace="default")
memory_list(prefix="usuario_", namespace="default")
memory_search(query="Carlos", namespace="default")
```
Los datos se guardan en `~/.local/share/mcp-toolkit/memory.db`.
Todas las herramientas de memoria aceptan `namespace` para separar datos por
proyecto, cliente o conversación. Si no se indica, se usa `default`.
### `run_python`
```
Parámetros:
code (str) — código Python a ejecutar
timeout (int) — segundos máximos, default 10, máximo 60
stdin (str) — entrada estándar opcional
```
**Restricciones de seguridad:**
- Entorno mínimo: no hereda secretos ni variables arbitrarias del proceso host
- Directorio de trabajo temporal por ejecución
- Proxies HTTP anulados por variables de entorno
- Límite de memoria: 256 MB (Linux/macOS)
- Timeout estricto: el proceso se mata al agotarse el tiempo
- En Windows no hay límite de memoria por proceso aplicado desde Python
- El bloqueo de red no es una garantía de aislamiento fuerte; para código no confiable se recomienda ejecutar el servidor dentro de un contenedor o VM con políticas de red
### `run_js`
Mismos parámetros que `run_python`. Requiere Node.js instalado en el sistema.
---
## Desarrollo
```bash
git clone https://github.com/YoshiLoL0526/mcp-toolkit
cd mcp-toolkit
uv sync
uv run python -m playwright install chromium
# Ejecutar en modo desarrollo
uv run mcp-toolkit
# Tests
uv run pytest
```
### Añadir una nueva herramienta
1. Crear `mcp_toolkit/tools/mi_tool.py` con una función `async def mi_tool(...) -> str`
2. Importarla y registrarla en `server.py` con `mcp.tool()(mi_tool)`
3. Reinstalar: `uv tool install --python 3.13 . --reinstall`
---
## Estructura del proyecto
```
mcp-toolkit/
├── pyproject.toml
├── README.md
├── mcp_toolkit/
│ ├── server.py # FastMCP app + registro
│ ├── tools/
│ │ ├── web_search.py # Playwright: buscar + extraer
│ │ ├── fetch_url.py # Extraer una URL directa
│ │ ├── http_request.py # Cliente HTTP genérico
│ │ ├── date_time.py # Fechas, zonas horarias y duraciones
│ │ ├── memory.py # SQLite KV store con namespaces
│ │ ├── run_python.py # Sandbox Python
│ │ └── run_js.py # Sandbox Node.js
│ └── utils/
│ ├── browser.py # Singleton Playwright
│ └── sandbox.py # Helpers de subprocess y timeout
└── tests/
```
---
## Licencia
MIT
TDQS
Scored across 8 tools
Every tool has a clearly distinct purpose with no ambiguity. The five memory_* tools handle different CRUD operations for persistent storage, while run_js and run_python execute code in different languages, and web_search performs internet searches. There is no overlap in functionality between these categories.
Tool names follow a consistent verb_noun pattern throughout. The memory tools use clear action verbs (clear, delete, get, list, set) paired with 'memory', while the execution tools use 'run_' followed by the language, and web_search follows the same convention. All names are in snake_case with no deviations.
With 8 tools, the count is reasonable for a toolkit server. However, the scope feels slightly broad, combining memory management, code execution in two languages, and web search into one server, which might be better split. The tools earn their place, but the domain is not tightly focused.
For the memory domain, the tools provide complete CRUD coverage (set, get, delete, list, clear). For code execution, both JavaScript and Python are covered. The web_search tool adds internet capability. Minor gaps include no update operation for memory (though set can overwrite) and no tool for executing other languages, but agents can work around these.