dynamics_list_plugin_assemblies
Lists registered plugin assemblies in Dynamics CRM to manage custom business logic and integrations. Filter by assembly name or entity to organize development workflows.
Instructions
Lista os assemblies de plugins registrados no Dynamics CRM
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| assemblyName | No | Filtrar por nome do assembly | |
| entityLogicalName | No | Filtrar por entidade |
Implementation Reference
- src/tools/plugins/index.ts:105-130 (handler)The handler implementation for the dynamics_list_plugin_assemblies tool.
server.tool( "dynamics_list_plugin_assemblies", "Lista os assemblies de plugins registrados no Dynamics CRM", ListPluginsSchema.shape, async (params: z.infer<typeof ListPluginsSchema>) => { let filter = "ishidden/Value eq false"; if (params.assemblyName) { filter += ` and contains(name,'${params.assemblyName}')`; } const result = await client.list("pluginassemblies", { select: ["pluginassemblyid", "name", "version", "publickeytoken", "culture", "description", "createdon", "modifiedon"], filter, orderby: "name asc", }); return { content: [ { type: "text" as const, text: `Encontrados ${result.value.length} assemblies:\n\n${JSON.stringify(result.value, null, 2)}`, }, ], }; } ); - src/tools/plugins/index.ts:24-27 (schema)The input schema definition for the tool.
export const ListPluginsSchema = z.object({ assemblyName: z.string().optional().describe("Filtrar por nome do assembly"), entityLogicalName: z.string().optional().describe("Filtrar por entidade"), }); - src/tools/plugins/index.ts:70-351 (registration)Registration of the plugin tools, including dynamics_list_plugin_assemblies.
export function registerPluginTools( server: { tool: Function }, client: DataverseClient ) { // 1. Generate Plugin Code server.tool( "dynamics_generate_plugin_code", "Gera código C# para um plugin do Dynamics CRM com base nos parâmetros fornecidos", CreatePluginSchema.shape, async (params: z.infer<typeof CreatePluginSchema>) => { const stageValue = STAGE_MAP[params.stage] || 40; const template = PLUGIN_TEMPLATES.standard; const code = template .replace(/{{CLASS_NAME}}/g, params.name) .replace(/{{ENTITY_LOGICAL_NAME}}/g, params.entityLogicalName) .replace(/{{MESSAGE}}/g, params.message) .replace(/{{STAGE}}/g, String(stageValue)) .replace(/{{EXECUTION_MODE}}/g, params.executionMode === "Synchronous" ? "0" : "1") .replace(/{{FILTERING_ATTRIBUTES}}/g, params.filteringAttributes || "") .replace(/{{DESCRIPTION}}/g, params.description || `Plugin ${params.name} for ${params.message} on ${params.entityLogicalName}`) .replace(/{{BUSINESS_LOGIC}}/g, params.businessLogic || "// TODO: Implement business logic here"); return { content: [ { type: "text" as const, text: `Plugin C# gerado com sucesso:\n\n\`\`\`csharp\n${code}\n\`\`\`\n\n**Configuração:**\n- Entidade: ${params.entityLogicalName}\n- Mensagem: ${params.message}\n- Estágio: ${params.stage} (${stageValue})\n- Modo: ${params.executionMode}\n${params.filteringAttributes ? `- Filtro: ${params.filteringAttributes}` : ""}`, }, ], }; } ); // 2. List Plugin Assemblies server.tool( "dynamics_list_plugin_assemblies", "Lista os assemblies de plugins registrados no Dynamics CRM", ListPluginsSchema.shape, async (params: z.infer<typeof ListPluginsSchema>) => { let filter = "ishidden/Value eq false"; if (params.assemblyName) { filter += ` and contains(name,'${params.assemblyName}')`; } const result = await client.list("pluginassemblies", { select: ["pluginassemblyid", "name", "version", "publickeytoken", "culture", "description", "createdon", "modifiedon"], filter, orderby: "name asc", }); return { content: [ { type: "text" as const, text: `Encontrados ${result.value.length} assemblies:\n\n${JSON.stringify(result.value, null, 2)}`, }, ], }; } ); // 3. List Plugin Types server.tool( "dynamics_list_plugin_types", "Lista os tipos de plugins (classes) de um assembly", z.object({ assemblyId: z.string().describe("ID do assembly") }).shape, async (params: { assemblyId: string }) => { const result = await client.list("plugintypes", { select: ["plugintypeid", "name", "friendlyname", "typename", "assemblyname", "description"], filter: `pluginassemblyid eq '${params.assemblyId}'`, orderby: "name asc", }); return { content: [ { type: "text" as const, text: `Tipos de plugin encontrados: ${result.value.length}\n\n${JSON.stringify(result.value, null, 2)}`, }, ], }; } ); // 4. List Plugin Steps server.tool( "dynamics_list_plugin_steps", "Lista os steps registrados para plugins, opcionalmente filtrados por entidade", z.object({ entityLogicalName: z.string().optional().describe("Filtrar por entidade"), pluginTypeId: z.string().optional().describe("Filtrar por tipo de plugin"), }).shape, async (params: { entityLogicalName?: string; pluginTypeId?: string }) => { const filters: string[] = []; if (params.entityLogicalName) { filters.push(`configuration eq '${params.entityLogicalName}' or sdkmessagefilterid/primaryobjecttypecode eq '${params.entityLogicalName}'`); } if (params.pluginTypeId) { filters.push(`_plugintypeid_value eq '${params.pluginTypeId}'`); } const result = await client.list("sdkmessageprocessingsteps", { select: [ "sdkmessageprocessingstepid", "name", "stage", "mode", "rank", "statecode", "filteringattributes", "description", "_sdkmessageid_value", "_plugintypeid_value", ], filter: filters.length > 0 ? filters.join(" and ") : undefined, orderby: "name asc", }); return { content: [ { type: "text" as const, text: `Steps encontrados: ${result.value.length}\n\n${JSON.stringify(result.value, null, 2)}`, }, ], }; } ); // 5. Register Plugin Step server.tool( "dynamics_register_plugin_step", "Registra um novo step de plugin no Dynamics CRM", RegisterPluginStepSchema.shape, async (params: z.infer<typeof RegisterPluginStepSchema>) => { const stepData = { name: params.name, stage: params.stage, mode: params.executionMode, rank: params.rank, "plugintypeid@odata.bind": `/plugintypes(${params.pluginTypeId})`, "sdkmessageid@odata.bind": `/sdkmessages?$filter=name eq '${params.message}'`, filteringattributes: params.filteringAttributes || null, supporteddeployment: 0, // Server only }; // Get the message filter for the entity const messageFilter = await client.list("sdkmessagefilters", { select: ["sdkmessagefilterid"], filter: `primaryobjecttypecode eq '${params.entityLogicalName}' and sdkmessageid/name eq '${params.message}'`, top: 1, }); if (messageFilter.value.length > 0) { const filterId = (messageFilter.value[0] as Record<string, unknown>).sdkmessagefilterid; (stepData as Record<string, unknown>)["sdkmessagefilterid@odata.bind"] = `/sdkmessagefilters(${filterId})`; } const result = await client.create("sdkmessageprocessingsteps", stepData); return { content: [ { type: "text" as const, text: `Step registrado com sucesso!\nID: ${result.entityId}\nNome: ${params.name}\nMensagem: ${params.message}\nEntidade: ${params.entityLogicalName}\nEstágio: ${params.stage}`, }, ], }; } ); // 6. Enable/Disable Plugin Step server.tool( "dynamics_toggle_plugin_step", "Ativa ou desativa um step de plugin", EnableDisablePluginStepSchema.shape, async (params: z.infer<typeof EnableDisablePluginStepSchema>) => { await client.update("sdkmessageprocessingsteps", params.stepId, { statecode: params.enabled ? 0 : 1, statuscode: params.enabled ? 1 : 2, }); return { content: [ { type: "text" as const, text: `Step ${params.stepId} ${params.enabled ? "ativado" : "desativado"} com sucesso!`, }, ], }; } ); // 7. Delete Plugin Step server.tool( "dynamics_delete_plugin_step", "Remove um step de plugin registrado", DeletePluginStepSchema.shape, async (params: z.infer<typeof DeletePluginStepSchema>) => { await client.remove("sdkmessageprocessingsteps", params.stepId); return { content: [ { type: "text" as const, text: `Step ${params.stepId} removido com sucesso!`, }, ], }; } ); // 8. Get Plugin Trace Logs server.tool( "dynamics_get_plugin_trace_logs", "Recupera logs de rastreamento de plugins para diagnóstico", GetPluginTraceLogsSchema.shape, async (params: z.infer<typeof GetPluginTraceLogsSchema>) => { const filters: string[] = []; if (params.pluginTypeName) { filters.push(`contains(typename,'${params.pluginTypeName}')`); } if (params.correlationId) { filters.push(`correlationid eq '${params.correlationId}'`); } const result = await client.list("plugintracelogs", { select: [ "plugintracelogid", "typename", "messagename", "performanceexecutionstarttime", "performanceexecutionduration", "operationtype", "messageblock", "exceptiondetails", "correlationid", "depth", "createdon", ], filter: filters.length > 0 ? filters.join(" and ") : undefined, orderby: "createdon desc", top: params.top, }); return { content: [ { type: "text" as const, text: `Logs de plugin encontrados: ${result.value.length}\n\n${JSON.stringify(result.value, null, 2)}`, }, ], }; } ); // 9. Generate Plugin Project server.tool( "dynamics_generate_plugin_project", "Gera a estrutura completa de um projeto de plugin C# (.csproj, classes, etc.)", z.object({ projectName: z.string().describe("Nome do projeto"), namespace: z.string().describe("Namespace do projeto"), plugins: z.array(CreatePluginSchema).describe("Lista de plugins a serem gerados"), }).shape, async (params: { projectName: string; namespace: string; plugins: z.infer<typeof CreatePluginSchema>[] }) => { const csproj = PLUGIN_TEMPLATES.csproj .replace(/{{PROJECT_NAME}}/g, params.projectName) .replace(/{{NAMESPACE}}/g, params.namespace); const pluginFiles: string[] = []; for (const plugin of params.plugins) { const stageValue = STAGE_MAP[plugin.stage] || 40; const code = PLUGIN_TEMPLATES.standard .replace(/{{NAMESPACE}}/g, params.namespace) .replace(/{{CLASS_NAME}}/g, plugin.name) .replace(/{{ENTITY_LOGICAL_NAME}}/g, plugin.entityLogicalName) .replace(/{{MESSAGE}}/g, plugin.message) .replace(/{{STAGE}}/g, String(stageValue)) .replace(/{{EXECUTION_MODE}}/g, plugin.executionMode === "Synchronous" ? "0" : "1") .replace(/{{FILTERING_ATTRIBUTES}}/g, plugin.filteringAttributes || "") .replace(/{{DESCRIPTION}}/g, plugin.description || `Plugin ${plugin.name}`) .replace(/{{BUSINESS_LOGIC}}/g, plugin.businessLogic || "// TODO: Implement business logic"); pluginFiles.push(`// File: ${plugin.name}.cs\n${code}`); } return { content: [ { type: "text" as const, text: `Projeto gerado: **${params.projectName}**\n\n## ${params.projectName}.csproj\n\`\`\`xml\n${csproj}\n\`\`\`\n\n## Plugins\n${pluginFiles.map((f) => `\`\`\`csharp\n${f}\n\`\`\``).join("\n\n")}`, }, ], }; } ); }