Despliegue de un MCP para corregir errores en MS Access 2016
Índice
- 1. Despliegue de un MCP para corregir errores en MS Access 2016
- 2. 1. Cambio de enfoque
- 3. 2. Arquitectura específica para UX
- 4. 3. Herramientas MCP recomendadas
- 5. 4. Ejemplo mínimo (Python + MCP)
- 6. 5. Mejoras UX que el LLM puede proponer automáticamente
- 7. 6. Flujo seguro de aplicación
- 8. 7. Guardarraíles (importante)
- 9. 8. Extras que suben mucho la UX
1. Despliegue de un MCP para corregir errores en MS Access 2016
1.1. 1. Clarificar el alcance del MCP (Model Context Protocol)
Antes de codificar, define qué tipo de MCP necesitas:
- Servidor MCP que exponga herramientas (tools) para que un LLM analice/corrija la BD Access.
- Cliente MCP integrado en tu flujo de trabajo (Claude Desktop, Cursor, etc.).
Para Access 2016 lo típico es un servidor MCP en Python o Node que ejecute consultas VBA/SQL contra el .accdb=/.mdb=.
1.2. 2. Arquitectura recomendada
[LLM/Cliente MCP] <--stdio/HTTP--> [Servidor MCP] <--COM/ODBC--> [Access 2016]
1.2.1. Componentes clave
- Driver:
Microsoft Access Database Engine 2016 (ACE.OLEDB.16.0)opyodbcconMicrosoft Access Driver (*.mdb, *.accdb). - Backend VBA: para operaciones que requieren el motor Access (compactar/reparar, refrescar vínculos, recompilar VBA).
- Automatización COM:
pywin32(win32com.client.Dispatch("Access.Application")).
1.3. 3. Pasos de implementación
1.3.1. Paso 1 — Entorno
python -m venv .venv .venv\Scripts\activate pip install mcp pyodbc pywin32
Instala el ACE OLEDB 2016 (arquitectura x86/x64 coincidente con Python).
1.3.2. Paso 2 — Esqueleto del servidor MCP (Python)
from mcp.server.fastmcp import FastMCP
import pyodbc, win32com.client
mcp = FastMCP("access-fixer")
DB = r"C:\ruta\sistema.accdb"
CONN = fr"DRIVER={{Microsoft Access Driver (*.mdb, *.accdb)}};DBQ={DB};"
@mcp.tool()
def ejecutar_sql(sql: str) -> str:
"""Ejecuta SQL de diagnóstico/corrección."""
with pyodbc.connect(CONN, autocommit=True) as cx:
cx.execute(sql)
return "OK"
@mcp.tool()
def compactar_reparar() -> str:
"""Compacta y repara el .accdb (requiere Access instalado)."""
acc = win32com.client.Dispatch("Access.Application")
acc.CompactRepair(DB, DB.replace(".accdb", "_fixed.accdb"), True)
acc.Quit()
return "Compactado"
@mcp.tool()
def recompilar_vba() -> str:
acc = win32com.client.Dispatch("Access.Application")
acc.OpenCurrentDatabase(DB)
acc.VBE.CommandBars.FindControl(Name="Compile").Execute()
acc.CloseCurrentDatabase(); acc.Quit()
return "VBA recompilado"
1.3.3. Paso 3 — Herramientas típicas para "corregir viejos errores"
listar_tablas_y_campos(detectar tipos inconsistentes).buscar_referencias_rotas(tablas vinculadas caídas).detectar_datos_huerfanos(integridad referencial).normalizar_fechas/textos(formato regional ES/US).comparar_esquemacontra un DDL esperado.generar_script_correccion(devuelve SQL idempotente).
1.3.4. Paso 4 — Registro en el cliente MCP
claude_desktop_config.json:
{
"mcpServers": {
"access-fixer": {
"command": "python",
"args": ["C:\\ruta\\servidor_mcp.py"]
}
}
}
1.4. 4. Buenas prácticas para Access 2016
| Riesgo | Mitigación |
|---|---|
Bloqueo del .laccdb |
Cerrar sesión antes de compactar |
| Corrupción en operaciones masivas | Backup previo + CompactRepair |
| Referencias VBA rotas | Re-registrar .dll=/.ocx= (mscomctl, comdlg32) |
| ADO vs DAO | Preferir DAO para esquema, ADO para datos externos |
| Split DB | Trabajar sobre el front-end, datos en back-end |
| Driver 32/64 bits | Alinear con la instalación de Office |
1.5. 5. Flujo sugerido
- Backup del
.accdb. - Auditoría: MCP ejecuta herramientas de diagnóstico → reporte.
- Aprobación humana de cada corrección (evita DDL destructivo).
- Aplicación por lotes en una copia.
- CompactRepair + recompilar VBA.
- Validación: ejecutar suite de pruebas / consultas de verificación.
- Despliegue al entorno productivo.
1.6. 6. Controles críticos
- Nunca
DROP=/=UPDATEmasivo sinWHEREauditado. - Usar transacciones (DAO
BeginTrans=/=CommitTrans). - Log de cada sentencia aplicada a
audit_fixestabla. - Versionar el
.accdb(aunque sea binario: guardar.bas,.frmexportados).
¿Quieres que te arme un ejemplo completo con una herramienta concreta (p. ej. detección de huérfanos o migración de tipos), o el requirements.txt y estructura de carpetas?
Más que nada me interesa que sea capaz de mejorar la experiencia del usuario, modificando los formularios, los reportes, etc.
- MCP para mejorar UX en Access 2016 (formularios, reportes, navegación)
2. 1. Cambio de enfoque
No es "corregir errores" sino modernizar la capa de presentación sin tocar la lógica de negocio. En Access eso vive en:
| Objeto | Qué tocar | Vía |
|---|---|---|
| Formularios | Controles, layout, propiedades, validación visible | DAO / COM |
| Reportes | Secciones, agrupación, totales, estilos | DAO / COM |
| Menús/Ribbon | Botones, iconos, accesos | XML USysRibbons |
| Macros/Nav | Puntos de entrada | VBA o macros |
| Estados/Mensajes | MsgBox feos, sin contexto |
VBA refactor |
Un LLM con MCP puede leer la spec actual, proponer mejoras y aplicarlas de forma controlada.
3. 2. Arquitectura específica para UX
[LLM] <--MCP--> [Servidor] <--COM--> [Access]
|
+--> exportar .frm/.bas a texto
+--> parsear / diff / proponer
+--> reimportar y validar
La clave: trabajar sobre la forma textual, no sobre el binario. Access exporta formularios/reportes a un formato legible (SaveAsText).
4. 3. Herramientas MCP recomendadas
*/ Lectura / diagnóstico
exportar_objeto(tipo, nombre)→ textofrm,report,bas,cls.listar_controles(formulario)→ nombre, tipo, posición, propiedades clave.inventariar_estilos→ fuentes, colores, tamaños inconsistentes.detectar_antipatrones_ux→ grillas sin cabecera, tab order roto, sinTabIndex, botones sinToolTip, etc.
*/ Propuesta / diff
proponer_refactor(objeto, criterio)→ devuelve texto nuevo + justificación.diff_objeto(actual, propuesto)→ para revisión humana.
*/ Aplicación
importar_objeto(texto)→LoadFromText(Access 2013+).aplicar_parche(objeto, hunks)→ parches quirúrgicos en lugar de reescritura.
*/ Validación
abrir_formulario_en_modo_vista(solo lectura).capturar_error_al_compilar.checklist_accesibilidad(labels asociados, contraste, nombres significativos).
5. 4. Ejemplo mínimo (Python + MCP)
from mcp.server.fastmcp import FastMCP
import win32com.client, tempfile, os
mcp = FastMCP("access-ux")
DB = r"C:\ruta\sistema.accdb"
def _acc():
a = win32com.client.Dispatch("Access.Application")
a.OpenCurrentDatabase(DB)
return a
@mcp.tool()
def exportar(tipo: str, nombre: str) -> str:
"""tipo: acForm|acReport|acModule. Devuelve texto exportado."""
a = _acc()
tmp = os.path.join(tempfile.gettempdir(), f"{nombre}.txt")
a.SaveAsText(getattr(a, f"Ac{tipo.capitalize()}") if False else None, nombre, tmp)
txt = open(tmp, encoding="utf-8", errors="ignore").read()
a.CloseCurrentDatabase(); a.Quit()
return txt
@mcp.tool()
def importar(tipo: str, nombre: str, texto: str) -> str:
a = _acc()
tmp = os.path.join(tempfile.gettempdir(), f"{nombre}.txt")
open(tmp, "w", encoding="utf-8").write(texto)
a.LoadFromText(getattr(a, f"Ac{tipo.capitalize()}"), nombre, tmp)
a.CloseCurrentDatabase(); a.Quit()
return "Importado"
(Nota: los nombres exactos de las constantes son acForm, acReport, acModule; ajusta el getattr según tu versión.)
6. 5. Mejoras UX que el LLM puede proponer automáticamente
*/ Formularios
- Consistencia visual: fuente Segoe UI 10, alto de control 0.2",
Themeunificado. - Layout: pasar de posicionamiento absoluto a Stacked/Tabular Layout.
- Navegación: botones Anterior/Siguiente/Nuevo/Buscar con atajos (
Ctrl+N,Ctrl+F). - Validación inline:
BeforeUpdatecon mensajes claros enlbl_erroren lugar deMsgBox. - Búsqueda: caja de filtro en vivo (
ApplyFilterconOnChange). - Accesibilidad:
TabIndexordenado,TabStopcorrecto, labels asociadas. - Estados vacíos: mensaje "No hay registros" en lugar de grid en blanco.
- Fechas: formato
dd/mm/aaaaoISOsegún público.
*/ Reportes
- Agrupación y totales con
GroupLevel, subtotales,Running Sum. - Encabezado con fecha/hora/usuario para trazabilidad.
- Logo y colores de marca en
ReportHeader. - Exportación directa a PDF con nombre inteligente.
- Condicional formatting (semáforos, negritas por umbral).
*/ Global
- Home/Dashboard con botones grandes en lugar de menú desplegable.
- Ribbon personalizado (USysRibbons) que esconda el nativo.
- Mensajes de error con acción sugerida, no códigos.
- Atajos de teclado documentados en un formulario de ayuda.
7. 6. Flujo seguro de aplicación
- Backup del
.accdby export masivo (SaveAsTextde todo). - Versionar en git los
.frm=/.=report=/.=basexportados. - LLM exporta el objeto → propone diff → tú apruebas.
- Aplicar con
LoadFromTextsobre copia. - Recompilar VBA y abrir el formulario/reporte en vista.
- Comparar capturas (opcional:
pywinautopara screenshots). - Promover a producción.
8. 7. Guardarraíles (importante)
- Nunca reescribir todo un formulario de una vez: parches por secciones.
- Preservar nombres de controles (el código VBA los referencia; romperlos = error silencioso).
- No tocar
RecordSourceniControlSourcesin revisar queries dependientes. - Detectar eventos VBA asociados antes de renombrar/eliminar controles.
- Log de cada
LoadFromTextcon timestamp y hash.
9. 8. Extras que suben mucho la UX
- Formulario de búsqueda global (
Ctrl+F) que salte a cualquier entidad. - Panel de "recientes" por usuario.
- Modo oscuro (sí, se puede con
Theme+ colores). - Tooltips en todos los botones (
ControlTipText). - Confirmaciones inteligentes: solo preguntar cuando hay cambios sin guardar.
- Undo en operaciones destructivas a nivel de app.
¿Quieres que te prepare (a) un catálogo de antipatrones UX detectables automáticamente con las consultas MSysObjects=/=SaveAsText, o (b) un prompt template que le pases al LLM para que produzca el diff de un formulario concreto?
Es importante tambien considerar la posibilidad de hacer un cambio en la lógica de negocio, o cómo manejamos el negocio en la actual estructura de tablas y base de datos.
- MCP con capacidad de refactor de lógica de negocio y modelo de datos
- 1. El problema real
Si el esquema actual refleja un modelo mental viejo del negocio, mejorar formularios es cosmético. Hay que poder:
- Entender la semántica que el esquema actual está codificando implícitamente.
- Contrastarla con cómo el negocio se entiende hoy.
- Proponer un nuevo modelo (tablas, relaciones, reglas) y una ruta de migración.
- Aplicarlo sin perder datos ni romper formularios/reportes/VBA.
Esto es mucho más delicado que UX: toca datos, integridad y procesos. El MCP debe ser asistente de refactor, no ejecutor ciego.
- 2. Tres niveles de intervención
| Nivel | Alcance | Riesgo | Cómo lo trata el MCP |
|---|---|---|---|
| L1 Reglas | Validaciones, defaults, cálculos en VBA/consultas | Bajo | Refactor de módulos y ValidationRule |
| L2 Esquema | Tablas, campos, tipos, índices, FKs | Medio-alto | DDL + script de migración + backfill |
| L3 Modelo | Descomposición, normalización, entidades nuevas | Alto | Proyecto de migración por fases |
Empieza siempre por L1, gana confianza, sube.
- 3. Cómo el MCP "entiende" el negocio actual
// Introspección del esquema
MSysObjects,MSysRelationships,MSysQueries(a veces bloqueadas).- DAO:
TableDefs,Fields,Indexes,Relations. - Exportar DDL real:
CREATE TABLEreconstruido desde DAO.
// Introspección de la semántica
- Consultas guardadas: son la lógica de negocio codificada en SQL. Exportar todas.
- Módulos VBA: reglas, cálculos, validaciones. Exportar todos
.bas=/.cls=. - Macros: flujos automáticos.
- Formularios:
RecordSource,ControlSource, eventosBeforeUpdate,AfterUpdate. - Reportes: agrupaciones y totales revelan KPIs y jerarquías.
// Señales de deuda de modelo
- Campos multivaluados (tipo Access
Complex) → violan 1FN. - Columnas tipo
Campo1,Campo2,Campo3→ entidad no descompuesta. - Tablas con 60+ campos → probable entidad gorda con subentidades latentes.
- Códigos duplicados en texto libre → falta tabla de dominio.
- Fechas en texto → tipo mal elegido.
- Sin PK/FK → integridad por código VBA (frágil).
Lookupen tabla (mala práctica Access) → confunde modelo con UI.- Nombres en español mezclados con inglés → deuda de nomenclatura.
- 4. Herramientas MCP sugeridas
// Inventario y documentación
exportar_esquema_completo()→ DDL + relaciones + índices.exportar_logica_negocio()→ todas las queries, módulos y eventos.mapa_dependencias(objeto)→ qué formularios/reportes/VBA usan esta tabla/campo.generar_diccionario_datos()→ tabla/campo/tipo/uso/descripcion inferida.
// Análisis de modelo
detectar_violaciones_normalizacion()→ 1FN, 2FN, 3FN.detectar_multivaluados().detectar_dominios_implicitos()→ valores repetidos que deberían ser catálogo.detectar_tablas_gordas().detectar_relaciones_faltantes()→ camposXxxIdsin FK formal.detectar_campos_muertos()→ nunca usados en queries/formularios/reportes.
// Propuesta de nuevo modelo
proponer_esquema_objetivo(criterios)→ entidades, atributos, relaciones.diff_esquemas()→ cambios concretos.generar_ddl_migracion()→ CREATE/ALTER para llegar al nuevo modelo.generar_script_backfill()→ poblar nuevas columnas desde las viejas.generar_vistas_compatibilidad()→ queries con los nombres viejos apuntando al nuevo esquema (clave para no tocar formularios de golpe).
// Reglas de negocio
extraer_reglas_de_vba()→ qué validaciones/reglas están dispersas.centralizar_reglas()→ mover a tablareglas_negocioo a un módulo único.detectar_reglas_duplicadas()→ la misma validación en 5 formularios.detectar_reglas_contradictorias()→ un formulario permite lo que otro prohíbe.- 5. Estrategia de migración: "Strangler Fig" para Access
No reescribas el modelo de una vez. Envuelve el viejo y sustitúyelo por partes.
Fase 0: Backup + export textual total + git init Fase 1: Diccionario de datos y mapa de dependencias Fase 2: Vistas de compatibilidad (queries con nombres viejos -> tablas nuevas) Fase 3: Migrar una entidad piloto de bajo riesgo Fase 4: Repuntar formularios/reportes a las vistas Fase 5: Migrar el resto por entidad Fase 6: Congelar viejas tablas, luego eliminarlas Fase 7: Refactor VBA a las nuevas reglas centralizadas
La magia de la Fase 2: los formularios siguen funcionando aunque el modelo cambie debajo. Eso te da tiempo.
- 6. Ejemplo de patrón: de tabla gorda a entidades
// Antes
Cliente( IdCliente, Nombre, Calle, Ciudad, CP, Pais, Tel1, Tel2, Tel3, Email1, Email2, Contacto1_Nombre, Contacto1_Tel, Contacto2_Nombre, Contacto2_Tel )
// Después
Cliente(IdCliente, Nombre, IdDireccionPrincipal) Direccion(IdDireccion, IdCliente, Calle, Ciudad, CP, Pais, Tipo) Contacto(IdContacto, IdCliente, Nombre, Rol) Comunicacion(IdComunicacion, IdContacto, Tipo, Valor) -- tel/email
// Puente de compatibilidad
CREATE VIEW qryCliente AS
SELECT c.IdCliente, c.Nombre,
d.Calle, d.Ciudad, d.CP, d.Pais,
(SELECT TOP 1 Valor FROM Comunicacion ...) AS Tel1,
...
FROM Cliente c LEFT JOIN Direccion d ON ...
Los formularios siguen apuntando a qryCliente y no se enteran.
- 7. Guardarraíles críticos (más estrictos que en UX)
- Nunca
ALTER TABLEen producción sin script reversible. - Toda migración con backfill idempotente y verificación de conteos.
- Congelar escritura en tablas que se migran (
solo lecturadurante la fase). - Doble escritura transitoria si hay usuarios concurrentes (trigger o VBA).
- Nombres de campos viejos preservados como columnas calculadas hasta el final.
- VBA que referencia campos debe migrarse junto con el esquema, o usar las vistas.
- Reportes históricos pueden requerir mantener el esquema viejo en paralelo (data warehouse).
- Auditoría de cada cambio: quién, cuándo, qué script, resultado.
- 8. ¿Cómo lo guía el LLM vía MCP?
El flujo típico sería:
exportar_logica_negocio()→ el LLM lee queries + VBA + eventos.generar_diccionario_datos()→ el LLM infiere significado de cada campo.detectar_problemas_modelo()→ lista de deudas con severidad.- Tú eliges qué atacar primero (recomendado: entidad con más dolor operativo).
proponer_esquema_objetivo(entidad)→ diagrama + DDL propuesto.generar_vistas_compatibilidad()→ puente.generar_script_migracion()+backfill.- Tú revisas el script, lo corres en copia, validas.
repuntar_objetos()→ actualizaRecordSourcede formularios/reportes a las nuevas fuentes si aplica.detectar_regresiones()→ abre formularios, corre pruebas, reporta errores.- 9. Lo que no debería hacer el MCP solo
- Ejecutar DDL en producción sin revisión humana.
- Decidir el modelo objetivo sin consultarte: el negocio lo sabes tú.
- Renombrar campos sin actualizar todo lo que los referencia (usar vistas evita esto).
- Asumir que lo que hay está mal: a veces el esquema viejo codifica reglas que ya no están escritas en ningún lado. Documentar antes de romper.
- 10. Coste y pragmatismo (por tu nota de los 10 mil)
Un refactor de L3 completo en Access es semanas o meses. Lo realista con presupuesto cero:
exportar_logica_negocio()+ diccionario → gratis, alto valor.- Detectar las 3-5 peores deudas de modelo → gratis, claridad.
- Vistas de compatibilidad para la entidad más dolorosa → 1 fin de semana.
- Refactor VBA de reglas duplicadas a un módulo → gratis, menos bugs.
- Dejar L3 para cuando haya presupuesto o cuando el dolor supere el coste.
Puedes empezar mañana con un script Python que exporte esquema + queries + VBA a texto, lo metas en git, y lo pases por el LLM para el diccionario. Sin MCP siquiera: un export.py y un prompt.
Created: 2026-10-05 lun 09:01