dllm-network

Una pestaña Network de DevTools para tu Ollama local.

Observa el tráfico HTTP entre tus herramientas y un Ollama local y lo muestra como un inspector de solicitudes. Cualquier cliente MCP lee esa captura, en modo solo lectura, para que un LLM responda preguntas sobre tu inferencia.

Respuesta
Captura real de la aplicación en ejecución. Cada número de la franja se leyó de la respuesta que la herramienta observó realmente, y los 1017 eventos detrás del cuerpo son los fragmentos de streaming individuales que reensambló.
Captura

Ve todo lo que le habla a Ollama, incluido software que no escribiste

Lee el tráfico en sí, así que una extensión de editor, un cliente de código cerrado y un script propio aparecen todos por igual. Cada uno conserva la configuración que ya tiene.

La captura es inspección de paquetes mediante WinDivert, en la capa de red, por debajo de la aplicación que originó la solicitud. La aplicación reensambla el flujo TCP, analiza el intercambio HTTP y deriva sus métricas de la respuesta que realmente observó.

  • Funciona con software que nunca escribiste

    Tu proyecto conserva intactas sus dependencias y sus imports, así que cualquier herramienta de tu máquina se observa tal como viene. Una extensión de editor o un cliente de código cerrado aparecen en los mismos términos que el código propio.

  • Tu inferencia conserva su velocidad original

    La captura lee una copia en el cable, fuera del camino de la solicitud. Tu petición llega a Ollama por la ruta de siempre, a la velocidad de siempre, y si el inspector deja de funcionar la inferencia sigue su curso.

  • Nada que configurar, nada que deshacer

    Tu cliente sigue apuntando a 127.0.0.1:11434. Al abrir la aplicación el tráfico aparece; al cerrarla, la configuración queda tal como la dejaste.

  • Fidelidad byte a byte

    Lo que inspeccionas es lo que recibió Ollama. El objeto de solicitud que construyó tu código viaja intacto, y el payload en pantalla es el que cruzó el cable, hasta los fragmentos de streaming, reensamblados en orden.

Cabeceras
Ambos conjuntos de cabeceras, leídos del cable. Transfer-encoding chunked y el tipo de contenido ndjson son los bytes que Ollama envió realmente, y son también la forma en que la herramienta sabe que la respuesta fue transmitida por streaming.
Un cliente ajeno
Una sesión distinta: esta solicitud provino de una extensión de editor sobre un endpoint diferente, observada tal como viene, y su prompt de sistema completo se lee aquí.
Procedencia

Cada número en pantalla se leyó de una respuesta

Cada cifra proviene de la respuesta que la aplicación capturó, así que dos ejecuciones se pueden comparar y la diferencia entre ellas es real. Un campo sin nada que leer muestra un guion hasta que llega la respuesta.

En curso
12:23:38, en curso. Cuatro campos muestran un guion, porque la respuesta de la que se leen todavía no llegó.
Completada
12:24:09, completada. La respuesta llegó, y esos mismos cuatro campos ahora llevan los números tomados de ella.

Una misma solicitud, con treinta y un segundos de diferencia. Los cuatro campos esperan hasta tener algo que leer, así que un número en pantalla indica que la medición existe.

CampoDe dónde sale el valor
Latencia de la solicitudMedida sobre el intercambio capturado
Conteo de tokensLeído del cuerpo de la respuesta
Tokens por segundoDerivado de esos dos, nunca estimado
Código de estado HTTPObservado en el cable
Cuerpos de solicitud y respuestaAlmacenados textualmente, hasta 16 MiB
Fragmentos de streamingReensamblados en orden: 1017 en la captura anterior
Modelos cargadosConfirmados contra la API de Ollama

Lo que eso te da

  • Dos ejecuciones se pueden comparar directamente, porque ambas cifras se midieron de la misma forma.
  • Una solicitud lenta es genuinamente lenta, cronometrada sobre el intercambio mismo.
  • La telemetría medida se mantiene como categoría propia, así que una cifra nunca mezcla en silencio una lectura con una estimación.
  • Todo lo que la aplicación infiere de señales indirectas llega etiquetado, con un nivel de confianza y las observaciones que lo respaldan.
La superficie MCP

Tres herramientas, llamadas en orden, cada una barata

El contrato es escalonado, así que un cliente gasta contexto solo en lo que pidió. Cada llamada acota la pregunta que responde la siguiente, y un cuerpo llega una vez que el modelo eligió un identificador estable.

  1. 01resolve_inference_context

    Orientación. Qué modelos, endpoints y estados existen, y en qué rango de tiempo.

    Entradas

    • ()

    Salidas

    • models[]
    • endpoints[]
    • statuses[]
    • timeRange
    • counts.total
    • supportedFilters

    Es barata porque: Solo agregados. Nunca incluye un cuerpo, una cabecera ni detalle por inferencia.

  2. 02search_inferences

    Acotamiento. Paginar entre candidatos bajo filtros combinados con AND.

    Entradas

    • model
    • endpoint
    • status
    • since
    • until
    • limit ≤ 100
    • cursor

    Salidas

    • items[].id
    • at
    • model
    • endpoint
    • method
    • status
    • statusCode
    • streaming
    • promptSize
    • nextCursor

    Es barata porque: Los resúmenes solo llevan campos estables; las cabeceras pesadas y los cuerpos se omiten por construcción.

  3. 03get_inference_context

    Detalle acotado. Un identificador conocido, solo las secciones solicitadas y un cuerpo leído por porciones.

    Entradas

    • id
    • sections[] ⊂ {metadata, tokens, request_headers, response_headers}
    • body{name, offset, limit}

    Salidas

    • availableSections
    • requested sections
    • bodyChunk{offset, nextOffset, hasMore, totalBytes, truncated}

    Es barata porque: El cliente define la ventana de bytes, así que un cuerpo grande llega en varias llamadas, en las porciones que solicitó.

Paginación estable
  1. Principalat DESC

    La inferencia más reciente primero.

  2. Desempateid DESC

    Varias inferencias pueden compartir la misma marca de tiempo, así que esto mantiene firme el límite de una página entre dos consultas idénticas.

El cursor lleva

  • at
  • id
  • Filtros activos

Un cursor reutilizado con filtros distintos se rechaza.

Registrar el sidecar

{
  "mcpServers": {
    "dllm-network": {
      "command": "C:\\path\\to\\dllm-network-mcp.exe"
    }
  }
}

El sidecar resuelve por sí mismo la ubicación de la base de datos. Regístralo con la ruta absoluta y reinicia el cliente.

Confianza

Dos procesos, un archivo, exactamente un escritor

La interfaz gráfica y el sidecar MCP son dos procesos del sistema operativo con ciclos de vida independientes: la interfaz la inicias tú y el sidecar lo inicia tu cliente MCP cuando lo necesita. Se encuentran en un único archivo SQLite en disco, y cuatro reglas que el linter impone en cada compilación mantienen al sidecar incapaz de escribir en él.

El archivo que abren ambos procesos

%LOCALAPPDATA%\dllm-network\telemetry.db
  • La interfaz gráfica

    Lectura y escritura
    dllm-network

    Opciones del DSN

    • _pragma=journal_mode(WAL)
    • _pragma=busy_timeout(5000)
    • _txlock=immediate

    Se abre una vez por sesión mediante sqlite.Open. Es la única conexión autorizada a escribir, y las escrituras llegan agrupadas desde una goroutine de drenaje independiente para que el bucle de captura nunca espere al disco.

  • El sidecar MCP

    Solo lectura
    dllm-network-mcp

    Opciones del DSN

    • mode=ro
    • _pragma=query_only(true)
    • _pragma=journal_mode(WAL)
    • _pragma=busy_timeout(5000)

    Un binario stdio independiente y sin banderas, iniciado por el cliente MCP. Resuelve la ruta de la base de datos con el mismo resolutor compartido que usa la interfaz, de modo que ambos nunca puedan discrepar sobre dónde está el archivo.

El sidecar no puede escribir, físicamente

Todo lo que conectes al sidecar (Claude Desktop, Claude Code, un cliente propio) llega a tu telemetría por una conexión en la que SQLite se niega a aceptar una sentencia de escritura, y una prueba de regresión lo mantiene así. Apunta un LLM a tu historial de inferencias sabiendo que lo peor que puede hacer es leerlo.

Cuatro propiedades que la compilación demuestra en cada commit

Cada una es una propiedad del binario publicado, porque el linter detiene una compilación que la rompería.

  • El servidor MCP solo puede leer

    El lado de lectura depende de un puerto de lectura, así que «solo lectura» es una forma del programa. Eso es lo que hace seguro entregar el sidecar a un LLM.

    Impuesta pormcp-not-captureinternal/mcp/**
  • Los vaivenes del protocolo quedan en un solo paquete

    El SDK de MCP existe en un único lugar, así que un cambio incompatible aguas arriba tiene un solo paquete donde aterrizar. Todos los demás paquetes compilan y se prueban sin el SDK presente.

    Impuesta porsdk-confined-to-mcpeverywhere except internal/mcp/**
  • El modelo de dominio se prueba por sí solo

    El tipo de inferencia se mantiene libre de todo controlador de almacenamiento, así que una prueba puede ejercitar el dominio sin nada corriendo detrás. Cómo se guarda una inferencia es asunto exclusivo del paquete sqlite.

    Impuesta porinference-domain-purityinternal/telemetry/inference/**
  • Un segundo transporte no cuesta cambios de dominio

    El mismo tipo se mantiene libre del SDK de MCP, así que lo que un protocolo quiere que parezca una inferencia nunca llega al modelo. Agregar un transporte HTTP junto al de stdio no toca código de dominio.

    Impuesta porinference-domain-purityinternal/telemetry/inference/**

Cada nombre de regla de arriba es una línea en la configuración del linter del repositorio, así que cada límite aquí se puede comprobar.

Primeros pasos

De un clon a una solicitud capturada, en tres pasos

Ejecuta cada paso desde la raíz del repositorio, en una terminal abierta como administrador para que la captura esté activa. Para compilarlo necesitas tener instalados Go 1.26 o superior, Bun y la CLI de Wails v2.

Windows
La captura es un controlador WinDivert y la aplicación se ejecuta desde la bandeja del sistema.
Privilegios de administrador
Para la captura de paquetes por solicitud. Una compilación de lanzamiento los solicita mediante UAC al abrirse; ejecutar desde el código con wails dev necesita una terminal elevada en su lugar. Sin ellos, la aplicación recurre a consultar la API.
Una instancia local de Ollama
Por defecto en http://127.0.0.1:11434.
  1. 01

    Instala el frontend

    cd frontend && bun install

    Descarga las dependencias de React y Vite que necesita el panel.

  2. 02

    Ejecuta la aplicación

    wails dev

    La aplicación de bandeja se abre y empieza a capturar. Genera tráfico contra Ollama y aparecerá en la tabla; el icono de limpiar en el panel la vacía para partir de cero sin reiniciar la aplicación.

    Generación
    La pestaña Generation a mitad de la transmisión, capturada en vivo: el razonamiento y la salida se llenan mientras el modelo responde, y el icono de limpiar solicitudes (arriba a la izquierda del panel) es el control que menciona el resultado anterior.
  3. 03

    Compila el sidecar MCP

    go build -o dllm-network-mcp.exe ./cmd/dllm-network-mcp

    Produce el binario stdio que un cliente MCP registra por ruta absoluta. Lee la base de datos que creó el paso anterior, así que ejecuta antes la aplicación al menos una vez.