powerplatform-mcp
Un servidor del Protocolo de Contexto de Modelo (MCP) y CLI independiente para consultar entornos de PowerPlatform / Dataverse. Admite múltiples entornos, metadatos de entidades, registros, complementos, flujos, soluciones, flujos de trabajo, reglas de negocio, roles de seguridad y más.
Documentación
PowerPlatform MCP / CLI
Un servidor de Model Context Protocol (MCP) y CLI independiente para consultar y configurar entornos de PowerPlatform / Dataverse. Admite múltiples entornos, metadatos de entidades, registros, plugins, flujos, soluciones, flujos de trabajo, reglas de negocio, roles de seguridad, API personalizadas, recursos web y más, incluidas operaciones de escritura para la configuración automatizada de entornos.
¿Por qué MCP + CLI?
MCP se integra directamente con clientes de IA (Claude, Cursor, GitHub Copilot) para la exploración interactiva y conversacional de tus entornos.
CLI escribe los resultados en una caché del sistema de archivos en lugar de devolverlos en línea. Las respuestas de las herramientas MCP están limitadas por la ventana de contexto del cliente de IA, lo que puede truncar o degradar los resultados al consultar entornos con cientos de entidades, flujos o pasos de plugins. El CLI evita esta limitación al persistir los resultados completos en disco, haciéndolos disponibles para análisis posteriores sin presión de contexto. Ambas interfaces comparten las mismas herramientas y capacidades.
Instalación
Requiere Node.js 22+ (< 25).
Servidor MCP
npm install -g powerplatform-mcp
# or
npx powerplatform-mcp
CLI
npm install -g powerplatform-cli
# or
npx powerplatform-cli
Docker
# MCP Server
docker pull ghcr.io/michsob/powerplatform-mcp
docker run --env-file .env ghcr.io/michsob/powerplatform-mcp
# CLI
docker pull ghcr.io/michsob/powerplatform-cli
docker run --env-file .env ghcr.io/michsob/powerplatform-cli entity-attributes account
Configuración
La herramienta admite múltiples entornos. Defínelos mediante variables de entorno:
POWERPLATFORM_ENVIRONMENTS=DEV,UAT,PROD
# For each environment, set:
POWERPLATFORM_DEV_URL=https://dev-org.crm.dynamics.com
POWERPLATFORM_DEV_CLIENT_ID=your-client-id
POWERPLATFORM_DEV_CLIENT_SECRET=your-client-secret
POWERPLATFORM_DEV_TENANT_ID=your-tenant-id
POWERPLATFORM_UAT_URL=https://uat-org.crm.dynamics.com
POWERPLATFORM_UAT_CLIENT_ID=...
POWERPLATFORM_UAT_CLIENT_SECRET=...
POWERPLATFORM_UAT_TENANT_ID=...
Para desarrollo local, copia .env.example a .env y completa tus credenciales.
Servidor MCP
El servidor MCP está diseñado para clientes impulsados por IA (Claude, Cursor, GitHub Copilot).
Herramientas MCP disponibles (67)
Todas las herramientas aceptan un parámetro opcional environment para apuntar a un entorno específico (por defecto, el primero configurado).
Entidad
| Herramienta | Descripción | Parámetros requeridos | Opcional |
|---|---|---|---|
get-entity-metadata | Obtener metadatos de entidad | entityName | |
get-entity-attributes | Listar todos los atributos/campos | entityName | |
get-entity-attribute | Obtener un atributo específico | entityName, attributeName | |
get-entity-relationships | Obtener relaciones 1:N y N:N | entityName | |
create-entity-string-attribute | Crear una columna de texto de una sola línea | entityName, schemaName, displayName | maxLength, requiredLevel, description, solutionName |
get-entity-keys | Listar claves alternativas en una entidad | entityName | |
create-entity-alternate-key | Crear una clave alternativa | entityName, schemaName, displayName, keyAttributes | solutionName |
Registros
| Herramienta | Descripción | Parámetros requeridos | Opcional |
|---|---|---|---|
get-record | Obtener un registro por ID | entityNamePlural, recordId | |
query-records | Consulta OData | entityNamePlural, filter | maxRecords (por defecto 50) |
Plugins
| Herramienta | Descripción | Parámetros requeridos | Opcional |
|---|---|---|---|
get-plugin-assemblies | Listar ensamblados de plugins | includeManaged, maxRecords | |
get-plugin-assembly-complete | Ensamblado con tipos, pasos, imágenes | assemblyName | includeDisabled |
get-entity-plugin-pipeline | Plugins que se ejecutan en una entidad | entityName | messageFilter, includeDisabled |
get-plugin-trace-logs | Registros de seguimiento de plugins | entityName, messageName, correlationId, pluginStepId, exceptionOnly, hoursBack, maxRecords | |
get-all-plugin-steps | Todos los pasos de procesamiento de mensajes del SDK | includeDisabled, maxRecords | |
get-plugin-type | Buscar un tipo de plugin por nombre de clase | typeName | |
get-sdk-message | Buscar un mensaje del SDK por nombre | messageName | |
create-plugin-step | Registrar un paso de plugin | name, pluginTypeId, sdkMessageId, stage, mode | rank, supportedDeployment, description, configuration, sdkMessageFilterId, solutionName |
Flujos (Power Automate)
| Herramienta | Descripción | Parámetros requeridos | Opcional |
|---|---|---|---|
get-flows | Listar flujos en la nube (filtrado inteligente) | activeOnly, maxRecords, nameContains, excludeSystem, excludeCustomerInsights, excludeCopilotSales | |
search-workflows | Buscar flujos de trabajo y flujos | name, primaryEntity, description, category, statecode, includeDescription, maxResults | |
get-flow-definition | Definición completa o resumen analizado | flowId | summary |
get-flow-runs | Historial de ejecuciones de flujo | flowId | status, startedAfter, startedBefore, maxRecords |
get-flow-run-details | Detalles de ejecución con errores a nivel de acción | flowId, runId | |
cancel-flow-run | Cancelar una ejecución en curso/en espera | flowId, runId | |
resubmit-flow-run | Reintentar una ejecución fallida | flowId, runId | |
scan-flow-health | Escaneo de salud por lotes (tasas de éxito) | daysBack, maxRunsPerFlow, maxFlows, activeOnly | |
get-flow-inventory | Inventario ligero de flujos | maxRecords |
Soluciones
| Herramienta | Descripción | Parámetros requeridos | Opcional |
|---|---|---|---|
get-publishers | Listar publicadores no de solo lectura | ||
get-solutions | Listar soluciones visibles | ||
get-solution | Obtener solución por nombre único | uniqueName | |
get-solution-components | Listar componentes en una solución | solutionUniqueName | |
export-solution | Exportar solución (base64) | solutionName | managed |
add-solution-component | Agregar un componente a una solución | solutionUniqueName, componentId, componentType | addRequiredComponents |
publish-customizations | Publicar entidad o todas las personalizaciones | entityLogicalName |
Flujos de trabajo (clásicos)
| Herramienta | Descripción | Parámetros requeridos | Opcional |
|---|---|---|---|
get-workflows | Listar flujos de trabajo clásicos | activeOnly, maxRecords | |
get-workflow-definition | Definición XAML o resumen | workflowId | summary |
get-ootb-workflows | En segundo plano, BPF, acciones, bajo demanda | maxRecords, categories |
Reglas de negocio
| Herramienta | Descripción | Parámetros requeridos | Opcional |
|---|---|---|---|
get-business-rules | Listar reglas de negocio | activeOnly, maxRecords | |
get-business-rule | Regla de negocio con XAML | workflowId |
Conjuntos de opciones
| Herramienta | Descripción | Parámetros requeridos |
|---|---|---|
get-global-option-set | Obtener una definición de conjunto de opciones global | optionSetName |
Configuración
| Herramienta | Descripción | Parámetros requeridos | Opcional |
|---|---|---|---|
get-connection-references | Referencias de conexión | maxRecords, managedOnly, hasConnection, inactive | |
get-environment-variables | Definiciones de variables de entorno + valores | maxRecords, managedOnly | |
create-environment-variable | Crear una definición de variable de entorno | schemaName, displayName, type | defaultValue, description, solutionName |
set-environment-variable-value | Establecer o actualizar un valor de variable de entorno | definitionId, value | existingValueId |
API personalizadas
| Herramienta | Descripción | Parámetros requeridos | Opcional |
|---|---|---|---|
get-custom-apis | Listar definiciones de API personalizadas | maxRecords, includeManaged | |
get-custom-api | Obtener una API personalizada por nombre único | uniqueName | |
create-custom-api | Crear una definición de API personalizada | uniqueName, name, displayName, bindingType, isFunction, isPrivate, allowedCustomProcessingStepType | description, pluginTypeId, pluginTypeName, boundEntityLogicalName, solutionName |
get-custom-api-response-properties | Listar propiedades de respuesta | customApiId | |
create-custom-api-response-property | Crear una propiedad de respuesta | customApiId, uniqueName, name, displayName, type | description, logicalEntityName, isOptional, solutionName |
get-custom-api-request-parameters | Listar parámetros de solicitud | customApiId | |
create-custom-api-request-parameter | Crear un parámetro de solicitud | customApiId, uniqueName, name, displayName, type | description, logicalEntityName, isOptional, solutionName |
Recursos web
| Herramienta | Descripción | Parámetros requeridos | Opcional |
|---|---|---|---|
get-web-resources | Listar recursos web | maxRecords, webResourceType, nameFilter | |
get-web-resource | Obtener un recurso web por nombre | name | |
create-web-resource | Subir un nuevo recurso web | name, displayName, webResourceType, content | description, solutionName |
Roles de seguridad
| Herramienta | Descripción | Parámetros requeridos | Opcional |
|---|---|---|---|
get-security-roles | Listar roles de seguridad personalizables | solutionUniqueName, excludeSystemRoles, includePrivileges, maxRecords | |
get-security-role-privileges | Privilegios para un rol (nombre, derecho de acceso, máscara de profundidad) | roleId | entityFilter, accessRightFilter |
list-privileges | Explorar el catálogo de privilegios del sistema para descubrir GUID de privilegeId y profundidades admitidas | entityFilter, accessRightFilter, maxRecords | |
create-security-role | Crear un nuevo rol (por defecto, unidad de negocio raíz); solutionUniqueName opcional lo agrega a una solución en un solo paso | name | businessUnitId, description, solutionUniqueName |
clone-security-role | Clonar un rol con sus privilegios. Usa CloneAsRole con un respaldo de crear-y-copiar cuando la acción no está disponible | sourceRoleId | newName, targetBusinessUnitId, solutionUniqueName |
update-security-role | Actualizar el nombre, la descripción o la unidad de negocio de un rol | roleId | name, description, businessUnitId, solutionUniqueName |
delete-security-role | Eliminar un rol (destructivo: requiere confirm: true) | roleId, confirm | |
add-security-role-privileges | Agregar privilegios a un rol (AddPrivilegesRole: deja los privilegios existentes intactos) | roleId, privileges[] | |
remove-security-role-privileges | Eliminar privilegios de un rol (recorre RemovePrivilegeRole) | roleId, privilegeIds[] | |
replace-security-role-privileges | Borrar y reemplazar el conjunto completo de privilegios (ReplacePrivilegesRole: destructivo, requiere confirm: true) | roleId, privileges[], confirm |
Cada elemento en privileges[] es { privilegeId, depth, businessUnitId? }. La profundidad es una de Basic (usuario), Local (BU), Deep (BU + secundaria), Global (organización).
Dependencias
| Herramienta | Descripción | Parámetros requeridos |
|---|---|---|
check-component-dependencies | Dependencias que bloquean la eliminación | componentId, componentType |
check-delete-eligibility | Verificar si un componente se puede eliminar | componentId, componentType |
Puntos de conexión de servicio
| Herramienta | Descripción | Opcional |
|---|---|---|
get-service-endpoints | Service Bus, webhooks, Event Hub, Event Grid | maxRecords |
Prompts de MCP
| Prompt | Descripción | Argumentos requeridos |
|---|---|---|
entity-overview | Resumen de entidad con atributos y relaciones clave | entityName |
attribute-details | Información detallada de atributos (tipo, formato, requisitos) | entityName, attributeName |
query-template | Plantilla de consulta OData con filtros de ejemplo | entityName |
relationship-map | Mapa completo de relaciones 1:N y N:N | entityName |
CLI
Las mismas herramientas que el servidor MCP, pero los resultados se almacenan en caché en el sistema de archivos para una salida de fidelidad completa en conjuntos de datos grandes.
Opción Global
--env <name> — entorno de destino (por defecto, el primero configurado).
Comandos
Entidad
entity-metadata <entityName>
entity-attributes <entityName>
entity-attribute <entityName> <attributeName>
entity-relationships <entityName>
entity-keys <entityName>
create-entity <schemaName> <displayName> <displayCollectionName> [--primary-name-schema <name>] [--primary-name-display <name>] [--description <desc>] [--ownership <UserOwned|OrganizationOwned>] [--has-activities] [--has-notes] [--solution <name>]
create-entity-string-attribute <entityName> <schemaName> <displayName> [--max-length <n>] [--required-level <level>] [--description <desc>] [--solution <name>]
create-entity-memo-attribute <entityName> <schemaName> <displayName> [--max-length <n>] [--required-level <level>] [--description <desc>] [--solution <name>]
create-entity-integer-attribute <entityName> <schemaName> <displayName> [--min <n>] [--max <n>] [--required-level <level>] [--description <desc>] [--solution <name>]
create-entity-decimal-attribute <entityName> <schemaName> <displayName> [--precision <n>] [--min <n>] [--max <n>] [--required-level <level>] [--description <desc>] [--solution <name>]
create-entity-money-attribute <entityName> <schemaName> <displayName> [--precision-source <0|1|2>] [--precision <n>] [--min <n>] [--max <n>] [--required-level <level>] [--description <desc>] [--solution <name>]
create-entity-boolean-attribute <entityName> <schemaName> <displayName> [--true-label <label>] [--false-label <label>] [--default-value <true|false>] [--required-level <level>] [--description <desc>] [--solution <name>]
create-entity-datetime-attribute <entityName> <schemaName> <displayName> [--format <DateOnly|DateAndTime>] [--behavior <UserLocal|DateOnly|TimeZoneIndependent>] [--required-level <level>] [--description <desc>] [--solution <name>]
create-entity-picklist-attribute <entityName> <schemaName> <displayName> [-o <value:label>]... [--required-level <level>] [--description <desc>] [--solution <name>]
create-entity-lookup <referencingEntity> <referencedEntity> <relationshipSchemaName> <lookupSchemaName> <displayName> [--required-level <level>] [--description <desc>] [--cascade-delete <NoCascade|RemoveLink|Restrict|Cascade>] [--solution <name>]
create-entity-alternate-key <entityName> <schemaName> <displayName> <keyAttributes...> [--solution <name>]
delete-entity-attribute <entityName> <attributeName>
Registros
record <entityNamePlural> <recordId>
query-records <entityNamePlural> <filter> [--max <n>]
create-record <entityNamePlural> <jsonBody>
update-record <entityNamePlural> <recordId> <jsonBody>
delete-record <entityNamePlural> <recordId>
associate-records <entityNamePlural> <recordId> <navigationProperty> <relatedEntityNamePlural> <relatedRecordId>
disassociate-records <entityNamePlural> <recordId> <navigationProperty> [relatedRecordId]
Plugins
plugin-assemblies [--include-managed] [--max <n>]
plugin-assembly <assemblyName> [--include-disabled]
plugin-packages [--include-managed] [--max <n>]
plugin-type <typeName>
entity-pipeline <entityName> [--message <msg>] [--include-disabled]
plugin-trace-logs [--entity <name>] [--message <msg>] [--correlation-id <id>] [--step-id <id>] [--hours <n>] [--max <n>] [--exceptions-only]
all-plugin-steps [--include-disabled] [--max <n>]
sdk-message <messageName>
register-plugin-package <filePath> [--pkg-version <version>] [--solution <name>]
update-plugin-package <filePath> --plugin-package-id <id> [--pkg-version <version>]
create-plugin-step <name> <pluginTypeId> <sdkMessageId> [--stage <n>] [--mode <n>] [--rank <n>] [--supported-deployment <n>] [--description <desc>] [--configuration <cfg>] [--message-filter-id <id>] [--solution <name>]
create-plugin-step-image <stepId> [--name <name>] [--entity-alias <alias>] [--image-type <0|1|2>] [--message-property-name <name>] [--attributes <csv>]
Flujos
flows [--active] [--name <contains>] [--include-managed] [--max <n>]
flow-definition <flowId> [--summary]
flow-inventory [--max <n>]
flow-runs <flowId> [--status <s>] [--after <iso>] [--before <iso>] [--max <n>]
flow-run-details <flowId> <runId>
flow-health [--days <n>] [--max-runs <n>] [--max-flows <n>] [--active]
search-workflows [--name <name>] [--entity <entity>] [--category <n>] [--active] [--max <n>]
create-cloud-flow <clientDataFile> [--primary-entity <entity>] [--solution <name>]
activate-flow <flowId>
deactivate-flow <flowId>
Soluciones
solutions
solution <uniqueName>
solution-components <uniqueName>
publishers
add-solution-component <solutionUniqueName> <componentId> <componentType> [--add-required]
publish-customizations [--entity <logicalName>]
Flujos de trabajo
workflows [--active] [--max <n>]
workflow-definition <workflowId> [--summary]
ootb-workflows [--categories <0,1,2,3,4>]
Reglas de negocio
business-rules [--active] [--max <n>]
business-rule <workflowId>
Conjuntos de opciones
optionset <optionSetName>
Dependencias
check-dependencies <componentId> <componentType>
Configuración
connection-references [--managed-only] [--has-connection] [--no-connection] [--inactive] [--max-records <n>]
create-connection-reference <logicalName> <displayName> <connectorId> [--description <desc>] [--solution <name>]
environment-variables [--managed-only] [--max-records <n>]
create-environment-variable <schemaName> <displayName> [--type <type>] [--default-value <val>] [--description <desc>] [--solution <name>]
set-environment-variable-value <definitionId> <value> [--existing-value-id <id>]
API personalizadas
custom-apis [--include-managed] [--max <n>]
custom-api <uniqueName>
create-custom-api <uniqueName> <displayName> [--binding-type <n>] [--bound-entity <name>] [--is-function] [--is-private] [--processing-type <n>] [--plugin-type-id <id>] [--plugin-type-name <name>] [--description <desc>] [--solution <name>]
custom-api-response-properties <customApiId>
create-custom-api-response-property <customApiId> <uniqueName> <displayName> [--type <n>] [--description <desc>] [--solution <name>]
custom-api-request-parameters <customApiId>
create-custom-api-request-parameter <customApiId> <uniqueName> <displayName> [--type <n>] [--description <desc>] [--optional] [--solution <name>]
Recursos web
web-resources [--type <n>] [--name <contains>] [--max <n>]
web-resource <name>
create-web-resource <name> <displayName> <filePath> [--type <n>] [--description <desc>] [--solution <name>]
set-entity-icon <entityName> <svgFilePath> [--solution <name>] [--web-resource-name <name>] [--display-name <name>] [--no-publish]
Formularios y vistas
entity-forms <entityName> [--type <n>]
entity-form-fields <formId>
add-form-field <entityName> <formId> <attributeName>
remove-form-field <entityName> <formId> <attributeName>
entity-views <entityName>
add-view-column <entityName> <viewId> <attributeName> [--width <n>]
set-view-columns <entityName> <viewId> <columns...> [--order-by <attr>] [--desc]
remove-view-column <entityName> <viewId> <attributeName>
Integración con PAC
pac-auth Authenticate pac CLI using environment credentials
generate-models <outdirectory> [--settings <path>] [--entities <filter>] [--namespace <ns>]
deploy-plugin <pluginFile> --plugin-id <id> [--type <Nuget|Assembly>] [--configuration <config>]
Roles de seguridad
security-roles [--solution <name>] [--include-system] [--include-privileges] [--max-records <n>]
security-role-privileges <roleId> [--entity <name>] [--access-right <type>]
privileges [--entity <name>] [--access-right <type>] [--max-records <n>]
create-security-role --name <name> [--bu <id>] [--description <desc>] [--solution <name>]
clone-security-role <sourceRoleId> [--name <name>] [--target-bu <id>] [--solution <name>]
update-security-role <roleId> [--name <name>] [--description <desc>] [--bu <id>] [--solution <name>]
delete-security-role <roleId> --yes
add-role-privileges <roleId> --privileges <spec> # JSON array or shorthand <guid>:<Basic|Local|Deep|Global>,...
remove-role-privileges <roleId> --privileges <id,id,id>
replace-role-privileges <roleId> --privileges <spec> --yes
Puntos de conexión de servicios
service-endpoints [--max <n>]
Desarrollo
git clone https://github.com/michsob/powerplatform-mcp.git
cd powerplatform-mcp
npm install
cp .env.example .env # fill in credentials
npm run build
npm run inspector # test with MCP Inspector
Publicación
Para publicar una nueva versión:
- Actualiza
versionenpackage.json - Confirma el cambio en
main - Crea y envía una etiqueta de versión:
git tag v1.0.2 git push origin v1.0.2
GitHub Actions publicará automáticamente:
| Paquete | npm | GitHub Packages | Docker (GHCR) |
|---|---|---|---|
| Servidor MCP | npm i powerplatform-mcp | npm i @michsob/powerplatform-mcp | ghcr.io/michsob/powerplatform-mcp |
| CLI | npm i powerplatform-cli | npm i @michsob/powerplatform-cli | ghcr.io/michsob/powerplatform-cli |
La publicación en npm utiliza Publicación de confianza (OIDC) — no se necesitan tokens ni secretos. GitHub Packages y GHCR usan el GITHUB_TOKEN integrado automáticamente.
Licencia
MIT
