Basic Usage
This guide covers the essential patterns for working with the MCI Python adapter, from client initialization to tool execution and error handling.
Client Initialization
Basic Setup
from mcipy import MCIClient
# Initialize with your schema file
client = MCIClient( json_file_path = "my-tools.mci.json" )
With Environment Variables
Environment variables are crucial for handling secrets and configuration:
import os
from mcipy import MCIClient
client = MCIClient(
json_file_path = "tools.mci.json" ,
env_vars = {
"API_KEY" : os.getenv( "MY_API_KEY" ),
"DATABASE_URL" : os.getenv( "DATABASE_URL" ),
"ENVIRONMENT" : "production" ,
"USERNAME" : "demo_user"
}
)
Never hardcode API keys or passwords in your schema files. Always use
environment variables for sensitive information.
Multiple Clients
You can create multiple client instances for different schema files:
# Client for API tools
api_client = MCIClient(
json_file_path = "api-tools.mci.json" ,
env_vars = { "API_KEY" : "key1" }
)
# Client for CLI tools
cli_client = MCIClient(
json_file_path = "cli-tools.mci.json" ,
env_vars = { "WORKSPACE" : "/home/user" }
)
# Get tool names as a list
tool_names = client.list_tools()
print ( f "Available tools: { tool_names } " )
# Output: ['greet_user', 'get_weather', 'search_files']
# Get full tool objects
tools = client.tools()
for tool in tools:
print ( f "- { tool.name } : { tool.title } " )
print ( f " Description: { tool.description } " )
# Get input schema for a specific tool
schema = client.get_tool_schema( "greet_user" )
print ( f "Required properties: { schema.get( 'required' , []) } " )
print ( f "Properties: { list (schema.get( 'properties' , {}).keys()) } " )
# Example output:
# Required properties: ['username']
# Properties: ['username']
Filter tools to work with specific subsets:
# Include only specific tools
weather_client = client.only([ "get_weather" , "get_forecast" ])
print ( f "Weather tools: { weather_client.list_tools() } " )
# Exclude dangerous tools
safe_client = client.without([ "delete_data" , "admin_reset" ])
print ( f "Safe tools: { safe_client.list_tools() } " )
# Chain filtering
filtered_client = client.only([ "tool1" , "tool2" , "tool3" ]) \
.without([ "tool2" ])
Basic Execution
# Execute a tool with properties
result = client.execute(
tool_name = "greet_user" ,
properties = { "username" : "Alice" }
)
# The result object contains the execution outcome
print ( f "Success: {not result.isError } " )
print ( f "Content: { result.content } " )
Error Handling
Always check the isError
property before using results:
result = client.execute(
tool_name = "my_tool" ,
properties = { "param1" : "value" }
)
if result.isError:
print ( f "❌ Error occurred: { result.error } " )
# Handle error case - maybe retry, log, or return default
return None
else :
print ( f "✅ Success: { result.content } " )
# Process successful result
return result.content
Handling Different Result Types
Results can contain various types of content depending on the tool:
# Text execution results
text_result = client.execute( "generate_message" , { "name" : "John" })
if not text_result.isError:
message = text_result.content # String content
# CLI execution results
cli_result = client.execute( "list_files" , { "directory" : "/tmp" })
if not cli_result.isError:
file_list = cli_result.content.splitlines() # Parse command output
# HTTP execution results
api_result = client.execute( "get_user_data" , { "user_id" : "123" })
if not api_result.isError:
# Content might be JSON string from API response
import json
try :
user_data = json.loads(api_result.content)
except json.JSONDecodeError:
# Handle non-JSON response
raw_response = api_result.content
Understanding the tool definition structure helps you create and work with tools effectively:
{
"name" : "tool_identifier" ,
"title" : "Human-Readable Tool Name" ,
"description" : "What this tool does" ,
"inputSchema" : {
"type" : "object" ,
"properties" : {
"param1" : {
"type" : "string" ,
"description" : "Description of parameter 1"
},
"param2" : {
"type" : "number" ,
"description" : "Description of parameter 2"
}
},
"required" : [ "param1" ]
},
"execution" : {
"type" : "text|file|cli|http"
// ... execution-specific configuration
}
}
MCI supports standard JSON Schema types, just like the MCP:
{
"username" : {
"type" : "string" ,
"description" : "User's username" ,
"minLength" : 3 ,
"maxLength" : 20
}
}
{
"age" : {
"type" : "number" ,
"description" : "User's age in years" ,
"minimum" : 0 ,
"maximum" : 150
}
}
{
"include_metadata" : {
"type" : "boolean" ,
"description" : "Whether to include additional metadata"
}
}
{
"tags" : {
"type" : "array" ,
"items" : {
"type" : "string"
},
"description" : "List of tags to apply"
}
}
{
"config" : {
"type" : "object" ,
"properties" : {
"host" : { "type" : "string" },
"port" : { "type" : "number" }
},
"required" : [ "host" ],
"description" : "Server configuration"
}
}
Complete Example
Here’s a comprehensive example putting it all together:
#!/usr/bin/env python3
"""
Complete MCI basic usage example.
"""
import os
from datetime import datetime
from mcipy import MCIClient
def main ():
# Initialize client with environment variables
client = MCIClient(
json_file_path = "./tools.mci.json" ,
env_vars = {
"CURRENT_DATE" : datetime.now().strftime( "%Y-%m- %d " ),
"API_KEY" : os.getenv( "DEMO_API_KEY" , "demo-key-123" ),
"USERNAME" : "demo_user"
}
)
print ( "🚀 MCI Python Adapter Demo" )
print ( "=" * 40 )
# List all available tools
print ( " \n 📋 Available tools:" )
tools = client.tools()
for tool in tools:
required_params = tool.inputSchema.get( 'required' , [])
print ( f " • { tool.name } : { tool.title } " )
print ( f " Required: { required_params } " )
# Execute a simple text tool
print ( " \n 💬 Executing greeting tool..." )
result = client.execute(
tool_name = "greet_user" ,
properties = { "username" : "Alice" }
)
if result.isError:
print ( f " ❌ Error: { result.error } " )
else :
print ( f " ✅ Result: { result.content } " )
# Filter tools and show the difference
print ( " \n 🔍 Tool filtering example:" )
all_tools = client.list_tools()
safe_tools = client.without([ "dangerous_tool" ]).list_tools()
print ( f " All tools: { len (all_tools) } " )
print ( f " Safe tools: { len (safe_tools) } " )
# Get schema information
print ( " \n 📊 Tool schema example:" )
if "greet_user" in client.list_tools():
schema = client.get_tool_schema( "greet_user" )
print ( f " Properties: { list (schema.get( 'properties' , {}).keys()) } " )
print ( f " Required: { schema.get( 'required' , []) } " )
print ( " \n ✨ Demo completed successfully!" )
if __name__ == "__main__" :
main()
Best Practices
Environment Variables : Always use environment variables for API keys,
database URLs, and other sensitive configuration.
Error Handling : Check result.isError
before using result.content
to
avoid processing failed executions.
Tool Organization : Use descriptive names and group related tools in
separate schema files for better organization.
Schema Validation : Define clear input schemas with proper types and
descriptions to make tools easier to use.
Troubleshooting
Common Issues
FileNotFoundError: [Errno 2] No such file or directory: 'tools.mci.json'
Solution : Ensure the schema file path is correct and the file exists.import os
if os.path.exists( "tools.mci.json" ):
client = MCIClient( json_file_path = "tools.mci.json" )
else :
print ( "Schema file not found!" )
Missing Required Parameters
Missing required property: 'username'
Solution : Ensure all required parameters are provided:schema = client.get_tool_schema( "my_tool" )
required = schema.get( 'required' , [])
print ( f "Required parameters: { required } " )
Next Steps