Claude se vuelve mucho más útil cuando deja de ser solo una interfaz de chat.
Un servidor MCP local permite que Claude interactúe con tu máquina real: archivos locales, comandos aprobados, capturas de pantalla y apertura de aplicaciones. Lo importante no es el acceso sin restricciones, sino el acceso controlado.
En esta guía, construiremos un servidor MCP local para Claude que sea práctico, específico y lo suficientemente seguro como para usarlo en flujos de trabajo reales.
Una nota rápida antes de construir algo
Este artículo evita intencionalmente la versión irresponsable del "control de computadora".
No le daremos a Claude acceso ilimitado al shell, autoridad total sobre el sistema de archivos, ni permiso para modificar tu máquina sin protecciones. La forma más rápida de construir un mal servidor MCP local es exponer una herramienta gigante run_anything() y llamarlo innovación.
El mejor patrón es:
- directorios en lista blanca
- comandos en lista blanca
- valores predeterminados seguros
- registros legibles por humanos
- respuestas explícitas
- separación clara entre herramientas de solo lectura y de acción
Si Claude puede hacerlo todo, has construido una demostración.
Si Claude puede hacer las cosas correctas de manera segura, has construido algo utilizable.
Por qué vale la pena aprender esta arquitectura
El valor de un servidor MCP local no es la novedad, sino la reducción de fricción.
Sin una capa de herramientas local, tu flujo de trabajo se ve así:
- Preguntarle a Claude qué hacer
- Copiar la respuesta
- Abrir la carpeta tú mismo
- Ejecutar el comando tú mismo
- Tomar la captura de pantalla tú mismo
- Pegar el resultado de nuevo en el chat
Con un servidor MCP local, ese ciclo se vuelve mucho más ajustado. Claude puede inspeccionar el contexto que necesita, usar herramientas con alcance limitado y devolver una respuesta basada en el estado real de tu máquina.
Eso es útil para:
- flujos de trabajo de desarrollo
- inspección de registros
- operaciones de contenido
- procesos de investigación
- automatización de escritorio
- tareas administrativas repetibles
Y como la capa de herramientas es tuya, tú eliges exactamente dónde se detiene el modelo.
¿Quieres aprender sobre IA y mantenerte adelante en tu carrera?
Comparto:
Más de 1,000 indicaciones de IA
Herramientas y automatizaciones de IA
Consejos de crecimiento profesional y LinkedIn
Recursos seleccionados de tecnología y productividad
Suscríbete aquí:
Sígueme para más consejos de IA
👇
El diseño que estamos construyendo

Vamos a construir un servidor local con cinco herramientas:
- list_files — ver qué existe dentro de las carpetas aprobadas
- read_file — abrir archivos de texto seguros
- run_command — ejecutar un pequeño conjunto de comandos locales aprobados
- take_screenshot — guardar una captura de pantalla en una ubicación conocida
- open_target — abrir una aplicación, archivo, carpeta o URL

Ese alcance es deliberado.
Es suficiente para que Claude sea significativamente útil en una máquina local sin caer en una automatización general insegura.
El modelo mental debería verse así:
Claude → MCP client → local MCP server → herramientas limitadas → operating system
Claude nunca debería hablar directamente con tu sistema operativo. Tu servidor MCP es el plano de control en el medio.
La pila tecnológica
Para una compilación local, Python es una opción limpia porque el SDK oficial de MCP es maduro, la abstracción FastMCP es concisa, y Python sigue siendo el lenguaje más fácil para trabajar con sistema de archivos, subprocesos y scripts de escritorio 4 2.
Usaremos:
- Python 3.11+
- mcp[cli] para el tiempo de ejecución del servidor MCP
- mss para capturas de pantalla multiplataforma
- módulos de la biblioteca estándar para acceso a archivos, llamadas a subprocesos y manejo del SO
Configura un nuevo proyecto:
1mkdir local-mcp-server2cd local-mcp-server3uv init --python 3.114uv add "mcp[cli]>=1.0,<2.0" "mss>=9.0,<10.0"
El estilo FastMCP basado en decoradores mantiene la capa de protocolo fuera de tu camino para que puedas centrarte en la calidad de las herramientas en lugar del cableado 4 5.
Una estructura de proyecto simple funciona bien:
1mkdir local-mcp-server2cd local-mcp-server3uv init --python 3.114uv add "mcp[cli]>=1.0,<2.0" "mss>=9.0,<10.0"
No necesitas una arquitectura compleja para la versión 1. Lo que necesitas es claridad.
El servidor real
Crea server.py y comienza con una implementación basada en políticas.
1from __future__ import annotations23import json4import os5import platform6import shlex7import subprocess8from pathlib import Path9from typing import Any1011import mss12from mcp.server.fastmcp import FastMCP1314app = FastMCP("local-computer-control", json_response=True)1516HOME = Path.home()17PROJECT_ROOT = Path(__file__).parent.resolve()18CAPTURE_DIR = PROJECT_ROOT / "captures"19CAPTURE_DIR.mkdir(exist_ok=True)2021ALLOWED_ROOTS = [22 HOME / "Documents",23 HOME / "Desktop",24 PROJECT_ROOT,25]2627ALLOWED_COMMANDS = {28 "pwd",29 "ls",30 "git status",31 "git diff --stat",32 "python --version",33 "node --version",34 "npm --version",35}3637READABLE_EXTENSIONS = {38 ".txt",39 ".md",40 ".json",41 ".py",42 ".js",43 ".ts",44 ".tsx",45 ".jsx",46 ".yaml",47 ".yml",48 ".toml",49 ".csv",50 ".log",51}5253def _resolve_path(raw_path: str) -> Path:54 path = Path(raw_path).expanduser().resolve()55 for root in ALLOWED_ROOTS:56 root = root.resolve()57 if path == root or root in path.parents:58 return path59 raise ValueError(f"Ruta no permitida: {path}")6061def _ensure_safe_command(command: str) -> str:62 normalized = " ".join(shlex.split(command))63 if normalized not in ALLOWED_COMMANDS:64 raise ValueError(65 "Comando no permitido. Agréguelo explícitamente a ALLOWED_COMMANDS si realmente lo necesita."66 )67 return normalized6869@app.tool()70def list_files(path: str = "~") -> dict[str, Any]:71 """Enumera archivos y carpetas dentro de un directorio aprobado."""72 target = _resolve_path(path)73 if not target.is_dir():74 raise ValueError(f"No es un directorio: {target}")7576 items = []77 for child in sorted(target.iterdir(), key=lambda p: (not p.is_dir(), p.name.lower())):78 items.append(79 {80 "name": child.name,81 "path": str(child),82 "type": "directory" if child.is_dir() else "file",83 }84 )8586 return {87 "path": str(target),88 "count": len(items),89 "items": items,90 }9192@app.tool()93def read_file(path: str, max_chars: int = 12000) -> dict[str, Any]:94 """Lee un archivo de texto seguro desde una ubicación aprobada."""95 target = _resolve_path(path)96 if not target.is_file():97 raise ValueError(f"No es un archivo: {target}")98 if target.suffix.lower() not in READABLE_EXTENSIONS:99 raise ValueError(f"Tipo de archivo no soportado: {target.suffix}")100101 content = target.read_text(encoding="utf-8", errors="replace")102 truncated = len(content) > max_chars103 content = content[:max_chars]104105 return {106 "path": str(target),107 "truncated": truncated,108 "content": content,109 }110111@app.tool()112def run_command(command: str, cwd: str | None = None, timeout: int = 15) -> dict[str, Any]:113 """Ejecuta un comando local en lista blanca."""114 safe_command = _ensure_safe_command(command)115 working_dir = _resolve_path(cwd) if cwd else PROJECT_ROOT116117 completed = subprocess.run(118 safe_command,119 shell=True,120 cwd=str(working_dir),121 capture_output=True,122 text=True,123 timeout=timeout,124 )125126 return {127 "command": safe_command,128 "cwd": str(working_dir),129 "returncode": completed.returncode,130 "stdout": completed.stdout.strip(),131 "stderr": completed.stderr.strip(),132 }133134@app.tool()135def take_screenshot(name: str = "latest") -> dict[str, Any]:136 """Captura una pantalla y guárdala localmente."""137 output_path = CAPTURE_DIR / f"{name}.png"138139 with mss.mss() as sct:140 sct.shot(output=str(output_path))141142 return {143 "saved": True,144 "path": str(output_path),145 }146147@app.tool()148def open_target(target: str) -> dict[str, Any]:149 """Abre un archivo, carpeta, aplicación o URL aprobado usando el SO local."""150 system = platform.system().lower()151152 if target.startswith("http://") or target.startswith("https://"):153 resolved = target154 else:155 resolved = str(_resolve_path(target))156157 if system == "darwin":158 subprocess.run(["open", resolved], check=True)159 elif system == "windows":160 os.startfile(resolved) # type: ignore[attr-defined]161 else:162 subprocess.run(["xdg-open", resolved], check=True)163164 return {165 "opened": True,166 "target": resolved,167 }168169if __name__ == "__main__":170 app.run(transport="stdio")
Este es un servidor compacto, pero lo importante no es su extensión. Lo importante es la forma de la interfaz:
- cada herramienta tiene un trabajo muy claro
- cada herramienta devuelve datos estructurados
- la ejecución de comandos está controlada
- el acceso a archivos está limitado a raíces
- las capturas de pantalla van a una carpeta conocida
Eso es exactamente lo que quieres en un servidor MCP local.
Por qué estas herramientas están diseñadas así
El contenido avanzado sobre herramientas de agentes nunca debería limitarse a "aquí está el código". La forma de la herramienta es la verdadera lección.
list_files
Esta herramienta le da a Claude una superficie de descubrimiento segura. Debería poder responder preguntas como:
- ¿Qué hay en esta carpeta de proyecto?
- ¿Qué notas existen en Documentos?
- ¿Ya hay un archivo de registro que pueda inspeccionar?
Pero no debería convertirse en un rastreador recursivo de todo el disco.
read_file
Esta es a menudo la herramienta local más útil de todas. Un gran porcentaje del trabajo real sigue oculto en notas locales de Markdown, registros, CSV, documentos y archivos de proyecto.
El límite de max_chars es importante. Los archivos grandes son un problema de contexto y latencia. Devolver todo el contenido de un archivo de registro gigante rara vez es útil.
run_command
Aquí es donde la mayoría de la gente se vuelve descuidada.
El patrón seguro no es "permitir acceso al shell y luego esperar lo mejor". El patrón seguro es "permitir un conjunto pequeño de comandos exactos y revisables". Por eso el ejemplo usa una lista blanca estricta.
take_screenshot
Una herramienta de captura de pantalla es valiosa porque permite que Claude participe en flujos de trabajo de escritorio. Incluso si tu primera versión solo guarda la imagen en el disco, ya es útil para informes, depuración de UI, captura de documentación y transferencias estructuradas.
open_target
El control de aplicaciones no necesita comenzar con automatización de GUI. Para muchos flujos de trabajo, "abrir la carpeta, archivo o URL correcta" es suficiente.
Esa es una versión 1 más sólida que pretender que necesitas automatización completa del cursor desde el primer día.
Conectando el servidor a Claude
Los servidores MCP locales se ejecutan comúnmente a través de stdio, lo que significa que Claude inicia el proceso localmente y se comunica directamente con él a través de stdin/stdout. Para un servidor de control de computadora local, ese es el valor predeterminado correcto porque evita exposición innecesaria a la red 4 5.
Claude Desktop admite servidores MCP locales mediante configuración, donde inicia el proceso del servidor por ti. En la práctica, usar rutas absolutas para el intérprete y el script es la configuración menos frágil porque los entornos de aplicaciones GUI locales suelen ser más estrictos que tu terminal 2.
Una configuración mínima se ve así:
1{2 "mcpServers": {3 "local-computer-control": {4 "command": "/absolute/path/to/python",5 "args": [6 "/absolute/path/to/local-mcp-server/server.py"7 ]8 }9 }10}
Si prefieres uv, también está bien:
1{2 "mcpServers": {3 "local-computer-control": {4 "command": "/absolute/path/to/uv",5 "args": [6 "--directory",7 "/absolute/path/to/local-mcp-server",8 "run",9 "python",10 "server.py"11 ]12 }13 }14}
Después de guardar la configuración y reiniciar Claude, las herramientas del servidor deberían aparecer en la lista de herramientas MCP locales. La configuración local-MCP de Claude Desktop se basa exactamente en este modelo: iniciar un proceso local, conectar a través de stdio y exponer las herramientas al modelo 2 3.

Indicaciones que realmente son útiles para probar
Una vez que el servidor está conectado, no comiences con orquestación complicada. Comienza con verificaciones directas y sencillas.
Prueba indicaciones como:
- "Enumera los archivos en mi carpeta de Escritorio."
- "Lee ~/Documents/todo.md y resume las tres principales prioridades."
- "Ejecuta git status en mi carpeta de proyecto local y explica qué cambió."
- "Toma una captura de pantalla llamada workspace-check."
- "Abre el README de mi proyecto."
Si esos flujos simples funcionan de manera consistente, tienes un servidor que vale la pena expandir.
Si no, agregar más herramientas solo ocultará los problemas reales.
Donde los servidores MCP locales se vuelven genuinamente valiosos
El caso de uso obvio es el desarrollo, pero ese es solo un carril.
Flujo de trabajo del desarrollador
Claude puede:
- inspeccionar una carpeta de repositorio
- leer un archivo de configuración
- ejecutar git status
- capturar una pantalla de un estado de error
- abrir el directorio del proyecto
Eso ya elimina muchos cambios de contexto.
Flujo de trabajo de investigación
Claude puede:
- enumerar carpetas de investigación
- abrir y resumir notas de Markdown
- leer CSV estructurados
- guardar capturas de pantalla de herramientas o paneles
- abrir archivos fuente o enlaces del navegador
Flujo de trabajo de contenido
Claude puede:
- escanear una carpeta de borradores
- leer ideas de publicaciones existentes
- capturar una pantalla de una referencia de diseño
- abrir el archivo de escritura o URL correcto
- ejecutar un comando limitado que genere un artefacto de compilación o exportación de borrador
Flujo de trabajo de operaciones
Claude puede:
- inspeccionar registros de directorios aprobados
- ejecutar un comando de diagnóstico de solo lectura
- abrir la carpeta relevante o el enlace del panel
- guardar una captura de pantalla como evidencia
Este es el verdadero punto de la arquitectura: no "control de computadora" como un truco, sino compresión del flujo de trabajo.
La capa de seguridad es el producto
Esta es la sección que demasiados artículos técnicos trivializan.
La parte peligrosa del MCP local no es el protocolo, sino el mal diseño de permisos.
Si quieres que este servidor sea utilizable más allá de una demostración, construye el modelo de seguridad temprano.

Usa listas blancas de directorios
Claude solo debería poder ver rutas que apruebes explícitamente. Por eso _resolve_path() es el núcleo de las herramientas de archivos.
Usa listas blancas de comandos
Nunca expongas ejecución arbitraria de shell en una primera versión. Comienza con comandos exactos que puedas auditar línea por línea.
Separa las herramientas de lectura de las herramientas de acción
Las herramientas de solo lectura deberían ser la opción predeterminada. Las herramientas de acción deben introducirse deliberadamente.
Registra todo
Incluso un registro JSON simple de solo agregar mejora drásticamente la depuración y la confianza.
Agrega una capa de confirmación para escrituras
Si luego agregas write_file, move_file o delete_file, haz que esas herramientas requieran un segundo token de confirmación o que permanezcan deshabilitadas de forma predeterminada.
Considera un modo de prueba en seco
Para herramientas que toman acciones, el modo de prueba en seco está subestimado. Permite que Claude explique lo que haría antes de hacerlo.
Ejecuta bajo un usuario restringido cuando sea posible
Si hablas en serio sobre la automatización local, no le des a tu servidor MCP más privilegios del sistema operativo de los que necesita.
Una regla general útil:
- Nivel 1: herramientas de solo lectura
- Nivel 2: acciones de bajo riesgo como abrir archivo / abrir aplicación
- Nivel 3: acciones de escritura confirmadas
- Nivel 4: acciones destructivas que probablemente no deberías exponer a la ligera
La mayoría de las personas nunca necesitan el Nivel 4.

Qué mejorar después de la versión 1
Una primera versión sólida gana el derecho a volverse más capaz.
Una vez que el servidor básico es estable, las siguientes mejoras sensatas son:
- Archivo de políticas centralizado
Mueve tus reglas a config/policy.json para que los cambios sean declarativos.
Ejemplo:
1 {2 "allowed_roots": [3 "~/Documents",4 "~/Desktop",5 "./"6 ],7 "allowed_commands": [8 "pwd",9 "ls",10 "git status",11 "git diff --stat",12 "python --version"13 ]14 }15
- Registro estructurado
Registra las llamadas a herramientas, marcas de tiempo, argumentos y resultados en logs/server.log o un archivo JSONL.
- Ejecución de comandos más segura
En lugar de una sola herramienta de comando genérica, divide los comandos en herramientas más específicas como:
- git_status
- show_current_directory
- list_project_files
Eso facilita la elección de herramientas para Claude y la seguridad para ti.
- Mejor manejo de capturas de pantalla
Puedes evolucionar desde "guardar una captura de pantalla en disco" a:
- capturas con marca de tiempo
- captura de ventana activa
- captura de región
- reglas de retención de archivos
- Adaptadores de automatización específicos del SO
En macOS, puedes agregar más tarde AppleScript o Shortcuts. En Windows, PowerShell o Automatización de UI. En Linux, lanzadores específicos de escritorio y herramientas de ventanas.
Pero eso debería venir después de que el núcleo local básico sea confiable.
Errores comunes que la gente comete con los servidores MCP locales
Los errores son predecibles.
Error 1: Demasiado poder, demasiado pronto
A la gente le encanta la idea del control total de la computadora. Odian depurarlo. Empieza más pequeño.
Error 2: Nombres de herramientas vagos
Si los nombres de tus herramientas son ambiguos, Claude las usará mal. Sé explícito.
Mal:
- system_action
- computer_control
Mejor:
- list_files
- read_file
- run_command
- take_screenshot
- open_target
Error 3: Salidas no estructuradas
Un bloque de texto mixto es más difícil para Claude razonar que un objeto JSON limpio.
Error 4: Sin registro
Si una herramienta falla y no puedes ver por qué, el sistema se convierte en suposiciones.
Error 5: Tratar al modelo como la capa de control
Claude es la capa de razonamiento. Tu servidor aún debe ser la capa de aplicación.
Esa distinción no es negociable.
Qué hace mejor esta arquitectura que la automatización simple
La automatización de escritorio tradicional suele ser una de dos cosas:
- scripts frágiles de GUI
- scripts aislados que requieren que un humano sepa exactamente cuándo ejecutarlos
Un servidor MCP local cambia eso porque Claude puede decidir qué herramienta usar según la solicitud del usuario y el contexto disponible.
Eso significa que no solo estás automatizando un comando. Estás construyendo una capa de capacidad local sobre la cual el modelo puede razonar.
Por eso MCP se siente importante. No es simplemente otro patrón de integración. Es una forma más limpia de exponer el uso de herramientas al modelo sin codificar de manera fija cada flujo de trabajo posible en la capa de la aplicación.
Los límites que debes respetar
Incluso un buen servidor MCP local tiene limitaciones reales.
- La automatización de escritorio puede ser inestable entre sistemas operativos.
- Las capturas de pantalla son útiles, pero no mágicas.
- Abrir aplicaciones es fácil; la manipulación confiable de la interfaz de usuario es más difícil.
- El acceso genérico al shell es peligroso.
- La hinchazón de contexto es real si las salidas de las herramientas son demasiado grandes.
- La aprobación humana sigue siendo valiosa para cualquier cosa importante.
En otras palabras: no confundas "el modelo puede tomar acciones" con "el modelo debe actuar sin supervisión".
El patrón más valioso es el control colaborativo, no la autonomía ciega.





