Skip to content

Conversation

Copy link
Contributor

Copilot AI commented Nov 12, 2025

Adds executeSeparated method to MCIClient for executing Tool model instances directly without registry lookup, enabling dynamic tool testing, database-loaded tools, and isolated execution with custom env_vars.

Changes

MCIClient API

  • Added executeSeparated(tool: Tool, properties: dict | None, env_vars: dict | None, validating: bool = False) -> ExecutionResult
  • Accepts Tool models directly, bypasses registry filtering
  • Uses client's env_vars when env_vars=None, allows per-execution overrides
  • Respects validating mode at both client and method level

ToolManager Refactoring

  • Extracted execute_tool_model() containing shared execution logic (validation, context building, executor dispatch)
  • Both execute() and executeSeparated() delegate to execute_tool_model()
  • Eliminates code duplication while maintaining identical behavior

Testing

  • 14 unit tests: basic execution, env_vars, validation, different executors, registry isolation
  • 6 integration tests: interaction with existing methods, filtering independence, multiple clients

Example Usage

from mcipy import MCIClient
from mcipy.models import Tool, TextExecutionConfig, HTTPExecutionConfig

client = MCIClient(schema_file_path="example.mci.json", env_vars={"API_KEY": "prod-key"})

# Create tool dynamically (e.g., from database)
tool = Tool(
    name="dynamic_greeting",
    execution=TextExecutionConfig(
        text="Hello {{props.name}} from {{env.LOCATION}}!"
    )
)

# Execute without registering
result = client.executeSeparated(
    tool=tool,
    properties={"name": "Alice"},
    env_vars={"LOCATION": "NYC"}  # Override client's env_vars
)

# Test API tool with different keys
api_tool = Tool(
    name="test_api",
    execution=HTTPExecutionConfig(
        url="https://api.example.com/data",
        headers={"Authorization": "Bearer {{env.API_KEY}}"}
    )
)

# Test with different API key without modifying client
result = client.executeSeparated(tool=api_tool, env_vars={"API_KEY": "test-key"})

Tool registry remains unaffected - executeSeparated does not modify list_tools() or filtering methods.

Warning

Firewall rules blocked me from connecting to one or more addresses (expand for details)

I tried to connect to the following addresses, but was blocked by firewall rules:

  • api.example.com
    • Triggering command: /home/REDACTED/work/mci-py/mci-py/.venv/bin/python /home/REDACTED/work/mci-py/mci-py/.venv/bin/pytest (dns block)

If you need me to access, download, or install something from one of these locations, you can either:

Original prompt

This section details on the original issue you should resolve

<issue_title>Add executeSeparated method to execute a given Tool model directly for debugging and testing</issue_title>
<issue_description>## Motivation
Currently, execution in MCIClient is only initiated by tool name lookup. There is demand for a new method, executeSeparated, which would:

  • Allow passing a Tool model, a dictionary of props, and a dictionary of env_vars directly
  • Use the same execution engine (templating, executor, result formatting) as primary execute
  • Return the ExecutionResult object
  • Bypass toolset filtering, allowing isolated/dynamic tool testing

Use Case

  • Debug/test specific Tool models in memory (e.g., after modifying config, retrieved from DB, or constructed on-the-fly)
  • Validate behavior with different props/env_vars without modifying global context or schema
  • Used by developers, integration tests, IDE plugins

Requirements

  • Add executeSeparated(tool: Tool, props: dict, env_vars: dict, validating: bool = False) method to MCIClient
    • Accepts an instantiated Tool model (from Pydantic)
    • Accepts props and env_vars as dicts
    • Optionally supports validating mode (same restrictions as top-level client)
    • Returns ExecutionResult, same as normal execute
    • Must use same execution and templating logic (call same internal engine/factory as regular execution)
  • Document the method and describe when/how to use it (non-persistent, debug, testing only)
  • No impact on main tool registry or tool filtering

Acceptance Criteria

  • Passing a Tool, props, and env_vars executes independently (no context pollution, uses same adapters as normal)
  • Error returned if Tool model is invalid or missing execution config/type
  • Unit tests for different execution types
  • Clear docstring and API docs

References


Label: enhancement
type: Feature</issue_description>

Comments on the Issue (you are @copilot in this section)


💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.

Copilot AI changed the title [WIP] Add executeSeparated method for Tool model execution Add executeSeparated method for dynamic Tool execution Nov 12, 2025
Copilot AI requested a review from MaestroError November 12, 2025 17:16
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.

Add executeSeparated method to execute a given Tool model directly for debugging and testing

2 participants