Skip to content

Channel automation additions#558

Open
BenCookie95 wants to merge 166 commits intomasterfrom
automation-demo
Open

Channel automation additions#558
BenCookie95 wants to merge 166 commits intomasterfrom
automation-demo

Conversation

@BenCookie95
Copy link
Copy Markdown
Contributor

@BenCookie95 BenCookie95 commented Mar 13, 2026

Summary

  • Added a new bridge function for other plugins to discover tools that are available to the requesting user. Useful for plugins if they are going to use the new bridge completion functionality. It won't return embedded mm mcp server tools unless a userID is passed.
  • Added a new field to the completion bridge endpoints called allowed_tools. This allows completion calls to use from tools from a pre-defined list. This list is checked at runtime each time to ensure the requesting user actually permission to use those tools. You can service account tools if you don't pass a requesting userID
  • Added MCP tools to interact with the new automation plugin. You can create, modify, delete and list automations. These tools are only added to context in channels where you are a channel admin or if you are in a DM with Matty. They are filtered out for other users in order to not pollute context.
  • Added a new ListAgents tool so that Matty can see what agents are available on the server when we are creating automations. These Agent IDs are needed at automation creation time.

Ticket Link

https://mattermost.atlassian.net/browse/MM-67712

Screenshots

Release Note

Allow tool execution through bridge and add mcp tools for managing automations

Summary by CodeRabbit

Release Notes

  • New Features

    • Added tool allowlist support for agent completions—control which tools agents can execute
    • Added endpoint to discover eligible tools for a given agent
    • Added agent discovery and listing capabilities
    • Added channel automation management—create, list, update, and delete automations
  • Bug Fixes

    • Improved input validation and error handling across bridge endpoints
    • Enhanced tool eligibility filtering based on user permissions
  • Documentation

    • Updated bridge client documentation with tool allowlist usage and agent tools discovery

cursoragent and others added 30 commits February 14, 2026 19:08
Co-authored-by: Nick Misasi <nick13misasi@gmail.com>
Co-authored-by: Nick Misasi <nick13misasi@gmail.com>
Co-authored-by: Nick Misasi <nick13misasi@gmail.com>
Co-authored-by: Nick Misasi <nick13misasi@gmail.com>
Co-authored-by: Nick Misasi <nick13misasi@gmail.com>
Co-authored-by: Nick Misasi <nick13misasi@gmail.com>
Co-authored-by: Nick Misasi <nick13misasi@gmail.com>
Co-authored-by: Nick Misasi <nick13misasi@gmail.com>
Co-authored-by: Nick Misasi <nick13misasi@gmail.com>
Co-authored-by: Nick Misasi <nick13misasi@gmail.com>
Co-authored-by: Nick Misasi <nick13misasi@gmail.com>
Co-authored-by: Nick Misasi <nick13misasi@gmail.com>
Co-authored-by: Nick Misasi <nick13misasi@gmail.com>
Co-authored-by: Nick Misasi <nick13misasi@gmail.com>
Co-authored-by: Nick Misasi <nick13misasi@gmail.com>
…iscovery

Co-authored-by: Nick Misasi <nick13misasi@gmail.com>
Co-authored-by: Nick Misasi <nick13misasi@gmail.com>
Co-authored-by: Nick Misasi <nick13misasi@gmail.com>
Co-authored-by: Nick Misasi <nick13misasi@gmail.com>
Co-authored-by: Nick Misasi <nick13misasi@gmail.com>
Co-authored-by: Nick Misasi <nick13misasi@gmail.com>
Co-authored-by: Nick Misasi <nick13misasi@gmail.com>
Co-authored-by: Nick Misasi <nick13misasi@gmail.com>
Co-authored-by: Nick Misasi <nick13misasi@gmail.com>
Co-authored-by: Nick Misasi <nick13misasi@gmail.com>
Co-authored-by: Nick Misasi <nick13misasi@gmail.com>
Co-authored-by: Nick Misasi <nick13misasi@gmail.com>
Co-authored-by: Nick Misasi <nick13misasi@gmail.com>
Co-authored-by: Nick Misasi <nick13misasi@gmail.com>
Co-authored-by: Nick Misasi <nick13misasi@gmail.com>
Copy link
Copy Markdown
Contributor

@cursor cursor bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Stale comment

Security Review — No Actionable Findings

I reviewed the full diff focusing on the areas outlined in the review checklist. Here is a summary of the analysis:

Bridge tool execution (new allowed_tools feature):

  • The bridge remains behind interPluginAuthorizationRequired middleware; only trusted plugins can invoke it.
  • allowed_tools is correctly rejected on service endpoints and only accepted on agent endpoints.
  • Tool scoping is enforced server-side: requested tools must exist in the agent's eligible tool set, tools-disabled agents reject the request, and empty/blank tool names are rejected.
  • WithAutoRunTools is applied only when the calling plugin explicitly provides an allowed_tools list, preserving the default tools-disabled behavior for bridge requests without it.
  • User/channel ID validation (ValidateID) is applied consistently via middleware and request-body checks across all endpoints.

Automation tools (new create_automation, update_automation, delete_automation, list_automations):

  • All CRUD operations forward the user's own Bearer token to the automation plugin API via doAutomationRequest, so the automation plugin enforces per-user and per-channel authorization.
  • shouldShowAutomationTools restricts visibility in public/private channels to channel admins and sysadmins, defaulting to visible in DMs/groups where the backend enforces per-channel checks.
  • The isAutomationPluginInstalled probe correctly uses an unauthenticated request (checking route existence only) and doesn't leak credentials.

Agent discovery (list_agents, handleGetAgentTools):

  • Both are read-only discovery endpoints behind inter-plugin auth. User permission filtering is applied when user_id is supplied.

File access in bridge posts:

  • convertBridgePostsToInternal uses server-level file access, which is pre-existing behavior unchanged by this PR. The bridge contract places permission responsibility on the calling plugin.

Reviewed and found adequate: ID validation, auth token scoping, tool store isolation, service vs. agent endpoint separation, WithToolsDisabled placement, automation tool filtering middleware, and prompt injection mitigations (user profile field sanitization was already in place).

Open in Web View Automation 

Sent by Cursor Automation: Find vulnerabilities

@BenCookie95 BenCookie95 requested a review from crspeller March 27, 2026 20:56
// with an auth error), false if it 404s or is unreachable.
func (p *MattermostToolProvider) isAutomationPluginInstalled() bool {
reqURL := p.automationAPIURL("/flows")
req, err := http.NewRequest(http.MethodGet, reqURL, nil)
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We were using some client4 doRequestWithHeaders function before but that changed in the latest release where it automatically prepends <serverURL>/api/v4 so it no longer works for us with plugins


// Add middleware to dynamically filter automation tools from tools/list
// when the channel automation plugin is not installed.
mcpServer.AddReceivingMiddleware(p.automationToolFilterMiddleware())
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Moved into a middleware to check for plugin existence when an agent requests a tool list. Previously if the automation plugin was uploaded after the agents plugin started up, we would never find the automation tools. We are caching the 'plugin installed` flow for 30 mins so we don't make redundant requests

Copy link
Copy Markdown
Contributor

@cursor cursor bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Stale comment

Security Review — No Actionable Findings

Re-reviewed the updated diff covering the new allowed_tools bridge feature, automation CRUD tools, agent discovery, and related refactors. All prior conclusions remain valid; no new vulnerabilities introduced.

Key controls verified:

  • Bridge auth boundary intact: All new endpoints (/agents/:agent/tools, agent completion with allowed_tools) remain behind interPluginAuthorizationRequired. The calling plugin owns user permission verification per the bridge contract.
  • Tool scoping enforced server-side: prepareAgentBridgeCompletion validates each requested tool exists in the agent's eligible set, rejects tools-disabled agents, and rejects empty/blank tool names. WithToolsDisabled() is correctly applied when no allowed_tools is provided, and explicitly on both service endpoints.
  • WithToolsDisabled() removal from convertRequestToLLMOptions is safe: Coverage is maintained — agent path handles it in prepareAgentBridgeCompletion (line 302-303), and service streaming/non-streaming handlers append it explicitly (lines 728, 808).
  • Automation tools delegate auth correctly: All CRUD operations in toolCreateAutomation, toolUpdateAutomation, toolDeleteAutomation, and toolListAutomations forward the user's own Bearer token via doAutomationRequest. The automation plugin enforces per-user and per-channel authorization. shouldShowAutomationTools gates tool visibility to channel admins/sysadmins in public/private channels.
  • isAutomationPluginInstalled probe: Uses an unauthenticated request to check route existence only. mmServerURL is server-configured, not user-controlled. No SSRF vector.
  • list_agents tool: Uses the user's auth token to call /ai_bots, which is behind MattermostAuthorizationRequired. Properly scoped.
  • Input validation consistent: ValidateID applied via middleware (validateAgentParam, validateUserIDQuery) and in request body parsing (validateCompletionRequestIDs). url.QueryEscape used for channel_id query parameter in automation list.
  • toolCreatePostAsUser URL change: mmInternalServerURL was consolidated into mmServerURL which still resolves to the internal URL when configured. No behavioral change.
Open in Web View Automation 

Sent by Cursor Automation: Find vulnerabilities

Resolve merge conflicts in api/api_test.go and add missing fmt import
in llm/stream.go.
Copy link
Copy Markdown
Contributor

@cursor cursor bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Security Review — No Actionable Findings

Re-reviewed the updated diff covering the allowed_tools bridge feature, automation CRUD tools, agent/tool discovery endpoints, and associated refactors. No medium, high, or critical vulnerabilities identified.

Controls verified:

  • Inter-plugin auth boundary: All new bridge endpoints (/agents/:agent/tools, agent completion with allowed_tools) remain behind interPluginAuthorizationRequired. Tool scoping and execution trust follows the established bridge contract where the calling plugin owns user permission verification.
  • Server-side tool scoping: prepareAgentBridgeCompletion validates every requested tool against the agent's eligible set, rejects agents with tools disabled, rejects empty/blank tool names via normalizeAllowedTools, and applies WithToolsDisabled() when no allowed_tools is provided. Service endpoints explicitly reject allowed_tools and append WithToolsDisabled().
  • WithToolsDisabled() removal from convertRequestToLLMOptions is safe: The agent path handles it in prepareAgentBridgeCompletion (lines 302-303), and both service handlers append it explicitly (lines 728, 808).
  • Automation tool auth delegation: All CRUD operations (toolCreateAutomation, toolUpdateAutomation, toolDeleteAutomation, toolListAutomations) forward the user's own Bearer token via doAutomationRequest. The automation plugin enforces per-user and per-channel authorization server-side.
  • Automation tool visibility gating: shouldShowAutomationTools restricts tool visibility to sysadmins and channel admins in public/private channels. The channel == nil case (DMs, bridge requests) returns true by design — the automation plugin backend enforces per-channel permissions at execution time.
  • isAutomationPluginInstalled probe: Uses server-configured mmServerURL (not user-controlled) with an unauthenticated request to check route existence only. No SSRF vector.
  • list_agents tool: Uses the user's auth token to call /ai_bots, which is behind MattermostAuthorizationRequired. Properly scoped.
  • Input validation: ValidateID applied consistently via middleware (validateAgentParam, validateUserIDQuery) and request-body checks (validateCompletionRequestIDs). url.QueryEscape used for channel_id query parameter.
  • mmServerURL consolidation: mmInternalServerURL merged into mmServerURL which still resolves to the internal URL when configured. The toolCreatePostAsUser URL change is functionally equivalent.
  • No secrets exposure: No hardcoded credentials, tokens, or keys in the diff. Test tokens are isolated to test helpers.
Open in Web View Automation 

Sent by Cursor Automation: Find vulnerabilities

Comment thread llmcontext/llm_context.go Outdated
mcpTools, mcpErrors := b.mcpToolProvider.GetToolsForUser(userID)

// Filter out automation tools for users without channel admin (or sysadmin) permission
showAutomation := shouldShowAutomationTools(b.pluginAPI, userID, c.Channel)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we still want to filter out tools that you don't even have permission to use, even from search. Let's go ahead and pass whatever we need to the MCP server to make this determination. This also means that we can make this determination for external MCP users as well as this solution currently does not cover those.

Comment thread mcpserver/tools/agents.go Outdated
Comment thread mcpserver/tools/agents.go Outdated
Comment thread mcpserver/tools/provider.go Outdated
@BenCookie95
Copy link
Copy Markdown
Contributor Author

@crspeller I also had to fix an issue where we need to include a server name when choosing a tools to include in allowed_tools for the bridge requests.

@BenCookie95 BenCookie95 requested a review from crspeller April 6, 2026 22:39
@crspeller
Copy link
Copy Markdown
Member

@BenCookie95 I think some merge conflicts are causing CI to fail. Need to fix those before merge.

@BenCookie95
Copy link
Copy Markdown
Contributor Author

@crspeller Just re-requesting review due to a few minor changes here: 880cf89.

Like we discussed on Tuesday, the bridge derives the server origin itself so the caller doesn't need to know it. Also, moved automation creation instructions over to the automation plugin.

This still needs to finish security review as well

@BenCookie95 BenCookie95 requested a review from crspeller April 16, 2026 03:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants