Skip to content

Agents/tools#351

Open
pankhuri-mt wants to merge 7 commits intoagents/devfrom
agents/tools
Open

Agents/tools#351
pankhuri-mt wants to merge 7 commits intoagents/devfrom
agents/tools

Conversation

@pankhuri-mt
Copy link
Collaborator

Tools Subsystem: Toolkit Management and MCP Serving

Summary

This PR introduces a complete, production-grade tools subsystem for the Mindtrace platform that enables modular tool organization, discovery, and serving over remote MCP (Model Context Protocol) using FastMCP. The system supports both built-in and external toolkits with full lifecycle management, registry tracking, and automatic logging.

Architecture

Core Components

  1. ToolkitLoader (toolkit.py)

    • Dynamic discovery and loading of toolkits
    • Support for built-in toolkits and external packages via entry points
    • Metadata extraction and tool registration
    • Tag-based filtering
  2. MCPServer (server/mcp_server.py)

    • FastMCP-based server for serving tools over remote MCP
    • Type-safe parameter handling with Pydantic
    • Automatic tool registration from toolkits
    • Tag-based tool filtering
  3. ToolService (server/tool_service.py)

    • Production-grade Service subclass for serving toolkits
    • Full infrastructure support: Gunicorn/Uvicorn workers, structured logging, PID tracking
    • Graceful shutdown handling
    • Status and heartbeat endpoints
    • Background launch capability
    • Automatic operation logging via track_operation
  4. CLI Interface (cli/tools.py)

    • Comprehensive command-line interface using Typer
    • Server lifecycle management with registry integration
    • Toolkit discovery and verification

Features

Toolkit Management

  • Built-in Toolkits: Organized in mindtrace/agents/tools/ with metadata
  • External Toolkit Support:
    • Entry point registration for automatic discovery
    • Manual package specification with --package flag
    • Installation support via --install flag
  • Tag-based Filtering: Filter tools by tags when serving
  • Metadata System: Name, description, version, tags for each toolkit

CLI Commands

  • mindtrace tools list - List available toolkits and tools
  • mindtrace tools pull - Verify and inspect toolkits (with optional package installation)
  • mindtrace tools serve - Launch production servers with registry tracking
  • mindtrace tools stop - Stop servers by name, port, host/port, or URL
  • mindtrace tools list-servers - List all registered servers with status
  • mindtrace tools info - Get detailed information about toolkits and tools

Server Management

  • Registry Integration: All servers are registered in mindtrace.registry with unique names
  • Lifecycle Management:
    • Automatic cleanup of stopped servers
    • Process verification using psutil
    • Port availability checking
    • Server startup verification
  • Unique Logging: Each server instance logs to its own file based on server name
  • Background Execution: Servers run as detached processes with proper signal handling

Production Features

  • Multiple Workers: Support for Gunicorn/Uvicorn workers for production scaling
  • Automatic Logging: All tool executions are automatically logged with:
    • Start/completion timestamps
    • Duration metrics
    • Error tracking
    • System metrics (CPU, memory)
  • Structured Logging: JSON-formatted logs with full context
  • Graceful Shutdown: HTTP shutdown endpoint for clean termination

Usage Examples

Python API

from mindtrace.agents.tools import basler_camera_tools

# Use tools directly
result = await basler_camera_tools.discover_available_cameras()

# Serve programmatically
from mindtrace.agents.server import create_mcp_server
server = create_mcp_server(
    toolkits=["basler_camera_tools"],
    tags={"camera"},
    name="camera-tools"
)
server.run(host="0.0.0.0", port=8000)

CLI Usage

# List toolkits
mindtrace tools list

# Serve with registry tracking (name is required)
mindtrace tools serve basler_camera_tools --name camera-server --workers 4

# List active servers
mindtrace tools list-servers

# Stop server
mindtrace tools stop --name camera-server

External Toolkit Integration

External packages can register toolkits via entry points:

# pyproject.toml
[project.entry-points."mindtrace.agents.toolkits"]
my_tools = "my_package.tools:get_toolkit_info"

Testing

The system includes:

  • Example toolkit (basler_camera_tools) demonstrating the pattern
  • CLI commands for verification and testing
  • Server lifecycle management with proper cleanup

Documentation

Comprehensive README includes:

  • Quick start guide
  • CLI command reference
  • External toolkit integration guide
  • Tool creation guide
  • Best practices
  • API reference

@pankhuri-mt
Copy link
Collaborator Author

Hi @Yasserelhaddar could you please provide feedback on changes to hardware component, (there is one failing test on mockplc to be fixed, as I have added ip_address to be returned in details of camera), would like to get any feedback for camera related changes.

@pankhuri-mt pankhuri-mt linked an issue Jan 27, 2026 that may be closed by this pull request
Comment on lines +20 to +21
from mindtrace.agents import __version__
typer.echo(f"mindtrace version {__version__}")
Copy link
Contributor

Choose a reason for hiding this comment

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

__version__ doesn't seem to exist

Comment on lines +13 to +29
dependencies = [
"mindtrace-core>=0.7.1",
"mindtrace-registry>=0.7.1",
"mindtrace-database>=0.7.1",
"mindtrace-services>=0.7.1",
"mindtrace-datalake>=0.7.1",
"mindtrace-models>=0.7.1",
"mindtrace-cluster>=0.7.1",
"mindtrace-jobs>=0.7.1",
"mindtrace-hardware>=0.7.1",
"fastmcp>=2.13.0",
"typer>=0.9.0",
"uvicorn>=0.25.0",
"pydantic>=2.0.0",
"rich>=13.0.0",
"httpx>=0.25.0"
]
Copy link
Contributor

Choose a reason for hiding this comment

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

are all these dependencies required currently?
also, some like fastmcp, uvicorn, pydantic, httpx will anyway be included when importing, say, mindtrace-services

Comment on lines +10 to +28
# List all toolkits
mindtrace tools list

# List tools in a specific toolkit
mindtrace tools list basler_camera_tools

# Verbose output with descriptions
mindtrace tools list basler_camera_tools --verbose
```

#### Get Information

```bash
# Get toolkit information
mindtrace tools info basler_camera_tools

# Get specific tool information
mindtrace tools info basler_camera_tools --tool discover_camera_parameters
```
Copy link
Contributor

Choose a reason for hiding this comment

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

list and info seem very similar:

$ mindtrace tools list basler_camera_tools

Toolkit: basler_camera_tools
Description: Tools for controlling and configuring Basler cameras
Version: 0.7.1
Tags: camera, hardware, basler

Tools (4):

┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━┓
┃ Tool Name                  ┃ Type  ┃
┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━┩
│ discover_available_cameras │ async │
│ discover_camera_parameters │ async │
│ set_camera_parameter       │ async │
│ get_camera_status          │ async │
└────────────────────────────┴───────┘

$ mindtrace tools info basler_camera_tools

Toolkit: basler_camera_tools
Version: 0.7.1
Tags: camera, hardware, basler
Module: mindtrace.agents.tools.basler_camera_tools

Description:
Tools for controlling and configuring Basler cameras

Tools (4):
  - discover_available_cameras (async)
  - discover_camera_parameters (async)
  - set_camera_parameter (async)
  - get_camera_status (async)


```bash
# Serve all tools from a toolkit (name is required for registry tracking)
mindtrace tools serve basler_camera_tools --name camera-server
Copy link
Contributor

Choose a reason for hiding this comment

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

serving the tools outputs an error:

$ mindtrace tools serve basler_camera_tools --name camera-server

Mindtrace Tool Service
Launching with toolkits: basler_camera_tools

Initializing LocalBackend with uri: /home/vik/.cache/mindtrace/registry
Registering default materializers...
Default materializers registered successfully.
Warmed materializer cache with 33 entries
[2026-02-09 17:38:29,909] ERROR: mindtrace.registry.core.registry.Registry: Object toolservers:camera-server version 1 does not exist.
Object toolservers:camera-server version 1 does not exist.
Launching detached process...
Verifying server is up at 0.0.0.0:8000...
⚠ Server process is running but not responding on port 8000
The server may still be starting. Check logs or try:
  mindtrace tools list-servers

the service did seem to start at 8000.

Comment on lines +88 to +104
# Override logger with unique name per server instance
# This ensures each server instance logs to its own file
from mindtrace.core.logging.logger import get_logger

# Create unique logger name based on server_id or server_name
if server_name:
unique_logger_name = f"mindtrace.agents.server.tool_service.ToolService.{server_name}"
else:
# Use server_id to make it unique
unique_logger_name = f"mindtrace.agents.server.tool_service.ToolService.{self.id}"

# Set up unique logger for this instance
self.logger = get_logger(
unique_logger_name,
use_structlog=use_structlog,
structlog_bind={"tool_service_name": server_name if server_name else self.id},
)
Copy link
Contributor

Choose a reason for hiding this comment

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

Mindtrace.__init__ already accepts logger_kwargs but all instance-level logs go to the same file because self.unique_name happens to just stop at the class name.
Would it help to introduce a param logger_name in Mindtrace.__init__ so that deriving objects can just pass an additional param to super().__init__.
It can then be useful for any class where instance-level log files need to be spearated.



@tools_app.command("serve")
def serve_tools(
Copy link
Contributor

Choose a reason for hiding this comment

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

this function can definitely use some helper functions. it currently does registry ops, liveness checks, http shutdown requests, subprocess launching, output formatting. this will be difficult to test.
speaking of which, let's add tests please. this is a new package being added and the process of getting tests up can help shape the library bits into better units.

Comment on lines +408 to +436
cmd = [
sys.executable,
"-m",
"mindtrace.agents.server.tool_service_launcher",
"--host", host,
"--port", str(port),
"--workers", str(workers),
"--toolkits", ",".join(toolkits),
]

if tag_set:
cmd.extend(["--tags", ",".join(tag_set)])

if name:
cmd.extend(["--server-name", name])

# Launch launcher module in a detached subprocess (following hardware pattern)
# Redirect stdout/stderr to /dev/null since Service handles its own logging
devnull = os.open(os.devnull, os.O_RDWR)
try:
process = subprocess.Popen(
cmd,
stdout=devnull,
stderr=devnull,
start_new_session=True, # Detach from terminal session (like hardware)
cwd=os.getcwd(),
)
finally:
os.close(devnull)
Copy link
Contributor

Choose a reason for hiding this comment

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

there is an existing mindtrace.services.core.Launcher. Can it be used (or modified appropriately if not)?

Comment on lines +13 to +14
parser.add_argument("--host", default=os.getenv("TOOL_SERVICE_HOST", "0.0.0.0"), help="Service host")
parser.add_argument("--port", type=int, default=int(os.getenv("TOOL_SERVICE_PORT", "8000")), help="Service port")
Copy link
Contributor

Choose a reason for hiding this comment

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

os.getenvs with a TOOL_SERVICE prefix. Can mindtrace.core.Config be used here?
all packages try to use the MINDTRACE_* pattern for config items, helps to group into a single namespace.

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.

Mindtrace Toolkit

2 participants