Skip to content

feat: add forced arguments support for MCP tools #10502

@prenansantana

Description

@prenansantana

Problem

MCP tools in Onyx pass LLM-generated arguments directly to the MCP server with zero filtering or modification. Built-in tools use override_kwargs but MCP tools don't (mcp_tool.py has override_kwargs: None).

This means admins cannot guarantee specific argument values for MCP tool calls — they must rely on the LLM obeying the system prompt, which is unreliable. The LLM frequently "forgets" to include required arguments.

Use Cases

  • Presentation service (Alai MCP) — force theme_id so presentations always use the correct corporate theme
  • Slack MCP — force channel_id to restrict posts to a specific channel
  • CRM MCP — force organization_id for tenant isolation
  • Any MCP with fixed API keys or IDs in arguments

Proposed Solution

Add a forced_args field (JSONB, nullable) to the Tool model. When an MCP tool is called, forced args are merged over the LLM-provided arguments, ensuring admin-configured values always take precedence.

Changes

  1. DB: New forced_args column on tool table (Alembic migration)
  2. Backend: MCPTool.run() merges {**llm_kwargs, **self._forced_args} before calling the MCP server
  3. API: New PATCH /api/admin/tool/{tool_id}/forced-args endpoint (admin-only)
  4. Frontend: Settings button per MCP tool to configure forced args via key-value editor

Key Design Decisions

  • forced_args works on any tool type (MCP, custom, built-in), not just custom tools
  • Admin-only access enforced via admin_router + current_curator_or_admin_user
  • Backward compatible — nullable field, tools without forced_args work unchanged

PR

Implementation: #10496

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions