Crear un agente de investigación local en LM Studio con cuatro servidores MCP.
Un agente de investigación local en LM Studio con cuatro servidores MCP: filesystem, GitHub, SearXNG y Camofox, un esquema de herramientas simplificado, una instrucción de planificación y una demostración de grounding.
Fuentes: How to Turn LM Studio Into a Local Research Agent With MCP Servers
Un modelo local que pueda buscar, leer un archivo o abrir una solicitud de integración es útil. Un modelo local que pueda combinar todas esas acciones en una sola línea de razonamiento para responder a una pregunta es un asistente de investigación. Pasar del primer caso al segundo en LM Studio requiere cuatro servidores MCP trabajando en paralelo, un plan para evitar que los esquemas de herramientas combinados ocupen toda la ventana de contexto, y un mecanismo que haga que un modelo de 9 mil millones de parámetros lleve a cabo tareas multietapas en lugar de usar solo una herramienta y detenerse.
Los cuatro servidores son un servidor de sistema de archivos, un servidor de GitHub, una instancia de SearXNG autohospedada para búsquedas y un navegador basado en Camoufox (Camofox) para leer las páginas que muestra la búsqueda. El servidor de sistema de archivos es @modelcontextprotocol/server-filesystem, restringido a un directorio permitido. Se accede a GitHub a través de OAuth en api.githubcopilot.com/mcp/. SearXNG y Camofox se ejecutan en Docker y se conectan mediante mcp-searxng y camofox-mcp. Cada uno funciona por separado. Lo interesante es lo que ocurre cuando un único chat los incluye a todos.
Una advertencia sobre el enmarcado antes de realizar cualquier conexión: todo esto está pensado para investigaciones en línea ordinarias, como el análisis competitivo, la verificación de un proveedor o la comprobación de una afirmación en un artículo. El agente no tiene idea de qué se está investigando y no le importa. Busca, obtiene y lee todo aquello a lo que se le indica.
La configuración se divide en cuatro etapas: combinar los servidores, reducir la lista de herramientas, darle al modelo un plan y ejecutar una demostración de funcionamiento.
Etapa 1: los cuatro servidores en una misma conversación
LM Studio no limita la cantidad de servidores MCP que puede utilizar una conversación. Carga cada uno de ellos y le entrega al modelo el esquema de herramientas de cada uno. Ese es el atractivo de esta configuración, y, como mostrará la siguiente etapa, también es lo primero que representa un desafío.
El sistema de archivos y las entradas de GitHub están configurados como lo estarían en una instalación independiente, al igual que las entradas de SearXNG y Camofox. Los contenedores de respaldo deben estar ya en funcionamiento, con sus docker-compose.yml y searxng/settings.yml en su lugar, ya que esos archivos no se repiten aquí. Lo que cambia es que ahora las cuatro entradas se encuentran en un único mcp.json:
{
"mcpServers": {
"filesystem": {
"command": "npx",
"args": [
"-y",
"@modelcontextprotocol/server-filesystem",
"/Users/jes/research-workspace"
]
},
"github": {
"url": "https://api.githubcopilot.com/mcp/",
"auth": {
"CLIENT_ID": "<your Client ID>",
"CLIENT_SECRET": "<your client secret>"
}
},
"searxng": {
"command": "npx",
"args": ["-y", "mcp-searxng"],
"env": {
"SEARXNG_URL": "http://localhost:8080"
}
},
"camofox": {
"command": "npx",
"args": ["-y", "camofox-mcp"],
"env": {
"CAMOFOX_URL": "http://localhost:8765",
"CAMOFOX_API_KEY": "your-camofox-api-key",
"CAMOFOX_AUTH_MODE": "api_key"
}
}
}
}
Tres detalles merecen atención.
- La entrada
githubactiva su propio paso de OAuth. LM Studio lo solicita la primera vez que el servidor intenta cargarlo. Dado que el endpoint de GitHub no admite el registro dinámico de clientes, el flujo utiliza una aplicación OAuth de GitHub que debe registrarse manualmente con antelación. No existe atajo para esto. - El directorio permitido para el servidor de sistema de archivos es una elección arbitraria. Una carpeta dedicada
research-workspacefunciona mejor que el directorio personal, sobre todo porque deja claro qué puede acceder el modelo. CAMOFOX_URLySEARXNG_URLdeben apuntar a los contenedores Docker. Si estos no están en ejecución, los servidores aún se cargan en LM Studio, pero todas las llamadas a las herramientas dirigidas a ellos fallan, lo que genera veinte minutos de confusión la primera vez que ocurre.
Cuando los cuatro están habilitados y los pequeños puntos verdes junto a cada nombre de servidor en el panel MCP se vuelven sólidos, el chat cuenta con cuatro herramientas de sistema de archivos, docenas de herramientas de GitHub, cuatro herramientas de SearXNG y aproximadamente cuarenta y cinco herramientas de Camofox. Eso representa una gran cantidad de información sobre la que debe razonar un modelo de 9 mil millones de parámetros, y ese es el problema que aborda la siguiente etapa.
Etapa 2: mantener activo el presupuesto de contexto
Solo el número de herramientas de GitHub ya representa un riesgo, al igual que el de Camofox por sí solo. Juntos, sumados a las herramientas de SearXNG y de sistema de archivos, la carga se vuelve considerable.
El nombre, la descripción y el esquema de parámetros de cada herramienta se tokenizan en el contexto del modelo antes de que este haya leído siquiera una palabra de la pregunta real. En un modelo pequeño con un margen de contexto limitado, ese sobrecargo puede ocupar una parte importante de todo lo disponible.
La solución más directa es simplemente no habilitar todas las herramientas de cada servidor. Para GitHub existe una forma mejor que activar las herramientas manualmente en el panel MCP. El servidor remoto acepta un encabezado X-MCP-Readonly, que limita toda la conexión a herramientas de solo lectura antes de que LM Studio vea el resto del esquema. Con esto, la entrada github de la etapa anterior pasa a ser:
{
"github": {
"url": "https://api.githubcopilot.com/mcp/",
"auth": {
"CLIENT_ID": "<your Client ID>",
"CLIENT_SECRET": "<your client secret>"
},
"headers": {
"X-MCP-Readonly": "true"
}
}
}
Con el encabezado activado, el servidor solo admite herramientas de lectura: pull_request_read, issue_read, list_commits, get_file_contents, search_repositories y search_code. Cualquier herramienta capaz de eliminar, fusionar, enviar o crear contenido simplemente no está disponible. Esta restricción se aplica por parte de GitHub, y no porque LM Studio oculte un botón, por lo que se trata de un límite real. También significa que los esquemas de las herramientas de escritura deshabilitadas nunca se incluyen en el contexto, que es precisamente el objetivo de esta etapa.
Quien desee un alcance más restringido puede utilizar X-MCP-Tools, el cual acepta una lista de permisos separada por comas, como por ejemplo search_code,search_repositories,get_file_contents,list_commits. Esto es adecuado en casos en los que claramente no se necesitarán las herramientas relacionadas con issues y pull requests.
Una captura de pantalla del GitHub MCP en este estado mostraría solo las herramientas get, read, list, scan y search, ya que la bandera de solo lectura estaba establecida en true, con la opción de desactivar otras herramientas que no se necesitan y que aumentan el costo del token.
Camofox no tiene una bandera equivalente en el lado del servidor, por lo que sus herramientas se desactivan una por una en el panel MCP. Para un chat exclusivo de investigación, las opciones para desactivar son delete_download, import_cookies y todo lo relacionado con la gestión de perfiles, como save_profile y load_profile, ya que una sesión de investigación no tiene motivo para modificar los perfiles del navegador guardados.
El principio es mantener solo lo que necesita el caso de uso y desactivar el resto. En la mayoría de los servidores, esto es una decisión relacionada con los recursos disponibles y no con la seguridad. El encabezado de GitHub es la excepción, ya que su propio servidor lo impone.
La demostración en la Etapa 4 nunca necesita acceso de escritura en GitHub, ya que la única acción de GitHub es leer un manifiesto, lo que significa que la restricción de solo lectura puede mantenerse en vigor. Si una tarea posterior sí necesita escribir, por ejemplo para abrir un problema que registre lo que encontró el agente, se debe eliminar el encabezado correspondiente a esa conversación. Mezclar conexiones de GitHub de solo lectura con conexiones con capacidad de escritura en una misma sesión no es la forma adecuada de manejarlo.
También es necesario prestar atención a la ventana de contexto en sí. Un mínimo de 4096 tokens era un límite razonable cuando el esquema disponible provenía de un único servidor. Con cuatro servidores y una lista de herramientas reducida pero aún considerable, 4096 resulta demasiado bajo. Ajuste el deslizador hacia arriba, posiblemente por encima de 32k, dependiendo de lo que pueda manejar el modelo y el hardware, así como de cuánto tiempo se espera que dure el intercambio de mensajes. No existe un número único correcto; se trata de un equilibrio entre el espacio para el razonamiento y la VRAM disponible, así que observe el porcentaje de llenado del contexto que muestra LM Studio debajo de la zona de entrada de mensajes y ajuste en consecuencia.
Etapa 3: un plan que el modelo pueda seguir
Un agente codificado a mano tiene una ventaja que la interfaz de chat de LM Studio no proporciona automáticamente. En un script, el prompt del sistema es una cadena de Python bajo control total, y se puede especificar explícitamente el ciclo: buscar, elegir una fuente, obtenerla y luego decidir si eso responde a la pregunta o si se necesita otra búsqueda.
Es mejor ser claro sobre lo que realmente ofrece LM Studio en lugar de insinuar que existe una opción de planificación oculta. Esa opción no existe; no hay un parámetro de planificación separado.
Lo que sí existe es un campo de Prompt del Sistema en la barra lateral del chat, bajo Parámetros del Modelo. Ese prompt se puede guardar junto con los ajustes de temperatura y contexto como un Preset con nombre, de modo que no es necesario volver a escribirlo en cada sesión. Esta es la misma herramienta que utiliza un agente codificado a mano, solo que se presenta como un cuadro de texto y no como una cadena de código.
Un prompt del sistema de este tipo funciona bien para un chat de investigación:
You are a research assistant with tools for web search, page fetching,
file storage, and GitHub. When asked a factual question you cannot
answer with confidence from memory, follow this plan:
1. Search for the topic using searxng_web_search. Look at more than one
result before deciding a source is good.
2. Fetch the most promising source with camofox's navigate and
snapshot or extract_structured tools, not just the search snippet.
When using camofox always open a new tab before trying to navigate
to a page.
3. If the question needs more than one source to answer confidently,
search again and fetch again before answering.
4. If asked to save findings, write them to a markdown file in the
workspace using the filesystem tools, don't just describe them in chat.
5. State which sources you actually fetched, not just which ones you
found in search results.
Algunas notas sobre su comportamiento:
- Se trata de prosa simple, sin una máquina de estados que la regule. Las instrucciones son lo que ve el modelo, y generalmente sigue su esquema, aunque sin garantías, al igual que lo haría con una instrucción de sistema dentro de un script.
- El paso 5 es más importante de lo que parece. Sin él, el modelo tiende a responder únicamente con el fragmento de búsqueda y a omitir el paso de obtención de datos, lo cual anula el propósito de incluir a Camofox en el proceso.
- Guardar el resultado como un valor predefinido permite que se mantenga entre chats sin tener que volver a pegarlo.
En la captura de pantalla, la instrucción se encuentra debajo de “Parámetros del modelo” y el valor predefinido se guarda como “Research Chat”. Con la instrucción y la lista de herramientas seleccionadas en su lugar, el modelo cuenta con la capacidad y algo similar a un plan para utilizarlas. La pregunta que queda es si realmente lo hace.
Etapa 4: una demostración que prueba que se utilizaron las herramientas
Una buena prueba de conocimientos básicos debe obligar al uso real de herramientas. La recuperación confiada de información de la memoria no puede producir la respuesta correcta, por lo que el modelo o bien obtiene una fuente real o adivina. La tarea debe ser algo que no pueda haber memorizado, verificable de forma independiente y lo suficientemente general como para no referirse a una persona específica.
Un ejemplo adecuado: dirigir al agente hacia un repositorio que se mantenga o del cual se dependa, y hacer que siga la versión fija de una dependencia hasta cualquier advertencia de seguridad registrada contra esa versión exacta. Se puede pegar el siguiente prompt en el chat después de rellenar tres marcadores de posición:
I want you to check one dependency in a GitHub repository for known
security advisories. Do this:
1. In the repository <owner>/<repo>, read <manifest-file> using
get_file_contents.
2. From that file, find the exact pinned version of the dependency
"<dependency-name>".
3. Search the web for known security advisories filed against that
specific version of "<dependency-name>".
4. Fetch the actual advisory page(s) you find rather than relying on
the search snippet alone.
5. Write a short summary to dependency-risk.md in the workspace: the
dependency name, the pinned version, any advisories found (with
severity and a link), and a one-line recommendation.
Los marcadores de posición funcionan de la siguiente manera:
<owner>/<repo>es cualquier repositorio con acceso de lectura. Un proyecto personal es tan válido como uno público que resulte ser una dependencia.<manifest-file>indica el nombre del archivo de dependencias del que depende el proyecto, por ejemplogo.mod,pyproject.toml,requirements.txtopackage.json.<dependency-name>es una sola dependencia de ese archivo de manifestación, idealmente una que sea de interés real.
Al no contar con un repositorio adecuado, juice-shop/juice-shop, la aplicación de entrenamiento intencionalmente insegura de OWASP, puede servir de sustituto. Su package.json contiene suficientes dependencias anteriormente marcadas como problemáticas para que el paso de búsqueda suele encontrar algo relevante, y tanto express-jwt como sanitize-html son opciones razonables como punto de partida. Una versión completada se ve así:
I want you to check one dependency in a GitHub repository for known
security advisories. Do this:
1. In the repository juice-shop/juice-shop, read package.json using
get_file_contents.
2. From that file, find the exact pinned version of the dependency
"express-jwt".
3. Search the web for known security advisories filed against that
specific version of "express-jwt".
4. Fetch the actual advisory page(s) you find rather than relying
on the search snippet alone.
5. Write a short summary to dependency-risk.md in the workspace:
the dependency name, the pinned version,
any advisories found (with severity and a link),
and a one-line recommendation.
Al enviarlo, el agente debería seguir los cinco pasos en orden: una lectura desde GitHub, una búsqueda externa, una obtención de datos externa y, finalmente, una escritura de archivo, al ritmo que permita el hardware.
Una ejecución completa de esta instrucción utilizó los cuatro servidores MCP y consumió un total de 37803 tokens.
Esta instrucción se eligió intencionadamente. La respuesta depende del repositorio y de lo que esté fijado en él, además las bases de datos CVE a las que se accede mediante las búsquedas se actualizan continuamente, por lo que no se puede citar de antemano ningún resultado fijo.
Verificar el funcionamiento del modelo implica dos pasos. Abra el manifiesto y lea personalmente la versión marcada como fija para confirmar qué devolvió la consulta en GitHub. Después, pruebe la afirmación relacionada con la advertencia en la búsqueda de Advertencias de Seguridad de GitHub o en NVD. Si ambos resultados coinciden con el informe del agente, eso constituye una prueba real de fundamento: el modelo realmente leyó el manifiesto y obtuvo una página con la advertencia, y no respondió basándose en un recuerdo vago de que alguna biblioteca había tenido un CVE en algún momento.
La demostración también muestra que el encabezado de solo lectura de la Etapa 2 es suficiente. Todo el proceso consiste en lecturas desde GitHub, búsquedas externas, obtención de datos desde fuentes externas y escritura en un archivo local; por lo tanto, no se necesita acceso de escritura de GitHub y el encabezado puede permanecer activo. Una sola solicitud utiliza los cuatro servidores en una sola pasada: GitHub lee el manifiesto, SearXNG busca las advertencias, Camofox obtiene las páginas correspondientes y el sistema de archivos guarda el resumen. Esto constituye una forma rápida de confirmar que toda la configuración está correctamente conectada antes de utilizarla en investigaciones reales.
Dónde falla
Es mejor identificar los puntos débiles en lugar de fingir que la cadena es fiable de extremo a extremo.
A veces el modelo responde con el fragmento de búsqueda y omite buscar la página, incluso cuando la instrucción del sistema indica lo contrario. Esto ocurre con mayor frecuencia en preguntas cortas y sencillas, donde el modelo parece considerar que el fragmento es suficientemente bueno. Un mensaje adicional que le indica buscar la página suele solucionar el problema. No es que el modelo no pueda hacerlo, sino que un modelo de 9 mil millones de parámetros comete errores en algunas de estas decisiones.
Ocasionalmente, al enfrentarse a docenas de herramientas de GitHub que nunca ha utilizado, el modelo elige una que parece plausible pero es incorrecta, como list_pull_requests cuando lo que se pretendía era list_issues. El proceso de selección en la Etapa 2 es la mejor defensa; un menú más corto con opciones similares reduce las posibilidades de elegir la incorrecta.
Nada de esto convierte al agente en un proceso determinista. Cuando se requiere determinismo, un script es la herramienta adecuada, y un bucle codificado a mano está más cerca de eso. La ventaja de conectar todo en LM Studio es que el modelo se adapta a cualquier pregunta que se le haga, pero el precio a pagar es que a veces se adapta mal. Observar cómo resuelve algunas preguntas de investigación es la forma más rápida de saber en qué casos se puede confiar en él y en cuáles necesita un estímulo adicional.
La configuración final
Las cuatro etapas mantienen un único chat de LM Studio ejecutando cuatro servidores MCP. Su lista de herramientas se ha reducido para que el contexto siga teniendo espacio para el razonamiento. Un prompt del sistema proporciona al modelo de 9B una estructura a seguir donde antes había una página en blanco, y una demostración de anclaje muestra que se están cargando páginas reales en lugar de recuperar respuestas de la memoria. En términos concretos:
- El sistema de archivos, GitHub, SearXNG y Camofox están todos habilitados en una sola conversación.
- Un conjunto reducido de herramientas, además de una ventana de contexto lo suficientemente grande para el esquema combinado, en lugar de la limitación de un solo servidor.
- Un prompt del sistema guardado como preestablecido, que hace que el modelo planifique por sí mismo un ciclo de búsqueda, obtención y guardado, utilizando lo que realmente ofrece la interfaz de LM Studio y no una opción de configuración que no existe.
- Una demostración reproducible de grounding, cada parte de la cual puede verificarse de forma independiente, que accede a los cuatro servidores con un único prompt.
Hay espacio para ampliarlo. Un segundo backend de búsqueda junto a SearXNG permitiría verificar los resultados entre sí. Una fase de resumen después de cada consulta evitaría que las páginas largas consumieran demasiado contexto al cargarse. Para quienes lo hagan con regularidad, programar la creación de ajustes preestablecidos permitiría iniciar cada nueva conversación de investigación correctamente configurada, sin necesidad de ajustes manuales.
Una conclusión vuelve una y otra vez. Después de conectar manualmente las partes básicas, como el sistema de archivos, la búsqueda, la navegación y el servidor de código, y observar dónde falla cada una, un framework de agente más complejo resulta ser simplemente lo mismo: las mismas partes móviles ocultas tras una abstracción adicional. Aceptar ese compromiso solo tiene sentido para quienes ya comprenden lo que hay debajo.
Leer más
- Notas prácticas: Construir un agente financiero AI con el servidor MCP de EODHD — Guía paso a paso de las Notas prácticas: Construir un agente financiero AI con el servidor MCP de EODHD: contratos, verificaciones y espacios para código listo para usar para equipos que desarrollan sistemas MCP sin él.
- Playwright o agentes del navegador? Donde la automatización por script sigue siendo la mejor opción — Comparación entre scripts de Playwright y agentes del navegador impulsados por MCP: fragilidad, determinismo, costo, una tarea de facturación ejemplar, herramientas a vigilar, riesgos de seguridad y un marco de toma de decisiones.