Feature/react call mcp (#428)

Key Features

  - MCP Tool Integration: Added core MCP tool support with ToolClientSpec and ToolClient classes
  - API Enhancement: New mcp_tool method for flow-specific tool invocation
  - CLI Tooling: New tg-invoke-mcp-tool command for testing MCP integration
  - React Agent Enhancement: Fixed and improved multi-tool invocation capabilities
  - Tool Management: Enhanced CLI for tool configuration and management

Changes

  - Added MCP tool invocation to API with flow-specific integration
  - Implemented ToolClientSpec and ToolClient for tool call handling
  - Updated agent-manager-react to invoke MCP tools with configurable types
  - Enhanced CLI with new commands and improved help text
  - Added comprehensive documentation for new CLI commands
  - Improved tool configuration management

Testing

  - Added tg-invoke-mcp-tool CLI command for isolated MCP integration testing
  - Enhanced agent capability to invoke multiple tools simultaneously
This commit is contained in:
cybermaggedon 2025-07-08 16:19:19 +01:00 committed by GitHub
parent e56186054a
commit 9c7a070681
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
22 changed files with 2718 additions and 9 deletions

View file

@ -210,6 +210,51 @@ Request schema:
Response schema: Response schema:
`trustgraph.schema.FlowResponse` `trustgraph.schema.FlowResponse`
## Flow Service Methods
Flow instances provide access to various TrustGraph services through flow-specific endpoints:
### MCP Tool Service - Invoke MCP Tools
The `mcp_tool` method allows invoking MCP (Model Control Protocol) tools within a flow context.
Request:
```json
{
"name": "file-reader",
"parameters": {
"path": "/path/to/file.txt"
}
}
```
Response:
```json
{
"object": {"content": "file contents here", "size": 1024}
}
```
Or for text responses:
```json
{
"text": "plain text response"
}
```
### Other Service Methods
Flow instances also provide access to:
- `text_completion` - LLM text completion
- `agent` - Agent question answering
- `graph_rag` - Graph-based RAG queries
- `document_rag` - Document-based RAG queries
- `embeddings` - Text embeddings
- `prompt` - Prompt template processing
- `triples_query` - Knowledge graph queries
- `load_document` - Document loading
- `load_text` - Text loading
## Python SDK ## Python SDK
The Python SDK provides convenient access to the Flow API: The Python SDK provides convenient access to the Flow API:
@ -233,6 +278,10 @@ flows = await client.list_flows()
# Stop a flow instance # Stop a flow instance
await client.stop_flow("flow-123") await client.stop_flow("flow-123")
# Use flow instance services
flow = client.id("flow-123")
result = await flow.mcp_tool("file-reader", {"path": "/path/to/file.txt"})
``` ```
## Features ## Features

137
docs/apis/api-mcp-tool.md Normal file
View file

@ -0,0 +1,137 @@
# TrustGraph MCP Tool API
This is a higher-level interface to the MCP (Model Control Protocol) tool service. The input
specifies an MCP tool by name and parameters to pass to the tool.
## Request/response
### Request
The request contains the following fields:
- `name`: The MCP tool name
- `parameters`: A set of key/values describing the tool parameters
### Response
The response contains either of these fields:
- `text`: A plain text response
- `object`: A structured object response
## REST service
The REST service accepts `name` and `parameters` fields, with parameters
encoded as a JSON object.
e.g.
In this example, the MCP tool takes parameters and returns a
structured response in the `object` field.
Request:
```
{
"name": "file-reader",
"parameters": {
"path": "/path/to/file.txt"
}
}
```
Response:
```
{
"object": {"content": "file contents here", "size": 1024}
}
```
## Websocket
Requests have `name` and `parameters` fields.
e.g.
Request:
```
{
"id": "akshfkiehfkseffh-142",
"service": "mcp-tool",
"flow": "default",
"request": {
"name": "file-reader",
"parameters": {
"path": "/path/to/file.txt"
}
}
}
```
Responses:
```
{
"id": "akshfkiehfkseffh-142",
"response": {
"object": {"content": "file contents here", "size": 1024}
},
"complete": true
}
```
e.g.
An example which returns plain text
Request:
```
{
"id": "akshfkiehfkseffh-141",
"service": "mcp-tool",
"request": {
"name": "calculator",
"parameters": {
"expression": "2 + 2"
}
}
}
```
Response:
```
{
"id": "akshfkiehfkseffh-141",
"response": {
"text": "4"
},
"complete": true
}
```
## Pulsar
The Pulsar schema for the MCP Tool API is defined in Python code here:
https://github.com/trustgraph-ai/trustgraph/blob/master/trustgraph-base/trustgraph/schema/mcp_tool.py
Default request queue:
`non-persistent://tg/request/mcp-tool`
Default response queue:
`non-persistent://tg/response/mcp-tool`
Request schema:
`trustgraph.schema.McpToolRequest`
Response schema:
`trustgraph.schema.McpToolResponse`
## Pulsar Python client
The client class is
`trustgraph.clients.McpToolClient`
https://github.com/trustgraph-ai/trustgraph/blob/master/trustgraph-base/trustgraph/clients/mcp_tool_client.py

View file

@ -0,0 +1,374 @@
# tg-delete-mcp-tool
## Synopsis
```
tg-delete-mcp-tool [OPTIONS] --name NAME
```
## Description
The `tg-delete-mcp-tool` command deletes MCP (Model Control Protocol) tools from the TrustGraph system. It removes MCP tool configurations by name from the 'mcp' configuration group. Once deleted, MCP tools are no longer available for agent use.
This command is useful for:
- Removing obsolete or deprecated MCP tools
- Cleaning up MCP tool configurations
- Managing MCP tool registry maintenance
- Updating MCP tool deployments by removing old versions
The command removes MCP tool configurations from the 'mcp' configuration group in the TrustGraph API.
## Options
- `-u, --api-url URL`
- TrustGraph API URL for configuration management
- Default: `http://localhost:8088/` (or `TRUSTGRAPH_URL` environment variable)
- Should point to a running TrustGraph API instance
- `--name NAME`
- **Required.** MCP tool name to delete
- Must match an existing MCP tool name in the registry
- MCP tool will be completely removed from the system
- `-h, --help`
- Show help message and exit
## Examples
### Basic MCP Tool Deletion
Delete a weather MCP tool:
```bash
tg-delete-mcp-tool --name weather
```
### Calculator MCP Tool Deletion
Delete a calculator MCP tool:
```bash
tg-delete-mcp-tool --name calculator
```
### Custom API URL
Delete an MCP tool from a specific TrustGraph instance:
```bash
tg-delete-mcp-tool --api-url http://trustgraph.example.com:8088/ --name custom-mcp
```
### Batch MCP Tool Deletion
Delete multiple MCP tools in a script:
```bash
#!/bin/bash
# Delete obsolete MCP tools
tg-delete-mcp-tool --name old-search
tg-delete-mcp-tool --name deprecated-calc
tg-delete-mcp-tool --name unused-mcp
```
### Conditional Deletion
Delete an MCP tool only if it exists:
```bash
#!/bin/bash
# Check if MCP tool exists before deletion
if tg-show-mcp-tools | grep -q "test-mcp"; then
tg-delete-mcp-tool --name test-mcp
echo "MCP tool deleted"
else
echo "MCP tool not found"
fi
```
## Deletion Process
The deletion process involves:
1. **Existence Check**: Verify the MCP tool exists in the configuration
2. **Configuration Removal**: Delete the MCP tool configuration from the 'mcp' group
The command performs validation before deletion to ensure the tool exists.
## Error Handling
The command handles various error conditions:
- **Tool not found**: If the specified MCP tool name doesn't exist
- **API connection errors**: If the TrustGraph API is unavailable
- **Configuration errors**: If the MCP tool configuration cannot be removed
Common error scenarios:
```bash
# MCP tool not found
tg-delete-mcp-tool --name nonexistent-mcp
# Output: MCP tool 'nonexistent-mcp' not found.
# Missing required field
tg-delete-mcp-tool
# Output: Exception: Must specify --name for MCP tool to delete
# API connection error
tg-delete-mcp-tool --api-url http://invalid-host:8088/ --name tool1
# Output: Exception: [Connection error details]
```
## Verification
The command provides feedback on the deletion process:
- **Success**: `MCP tool 'tool-name' deleted successfully.`
- **Not found**: `MCP tool 'tool-name' not found.`
- **Error**: `Error deleting MCP tool 'tool-name': [error details]`
## Advanced Usage
### Safe Deletion with Verification
Verify MCP tool exists before deletion:
```bash
#!/bin/bash
MCP_NAME="weather"
# Check if MCP tool exists
if tg-show-mcp-tools | grep -q "^$MCP_NAME"; then
echo "Deleting MCP tool: $MCP_NAME"
tg-delete-mcp-tool --name "$MCP_NAME"
# Verify deletion
if ! tg-show-mcp-tools | grep -q "^$MCP_NAME"; then
echo "MCP tool successfully deleted"
else
echo "MCP tool deletion failed"
fi
else
echo "MCP tool $MCP_NAME not found"
fi
```
### Backup Before Deletion
Backup MCP tool configuration before deletion:
```bash
#!/bin/bash
MCP_NAME="important-mcp"
# Export MCP tool configuration
echo "Backing up MCP tool configuration..."
tg-show-mcp-tools | grep -A 10 "^$MCP_NAME" > "${MCP_NAME}_backup.txt"
# Delete MCP tool
echo "Deleting MCP tool..."
tg-delete-mcp-tool --name "$MCP_NAME"
echo "MCP tool deleted, backup saved to ${MCP_NAME}_backup.txt"
```
### Cleanup Script
Clean up multiple MCP tools based on patterns:
```bash
#!/bin/bash
# Delete all test MCP tools
echo "Cleaning up test MCP tools..."
# Get list of test MCP tools
TEST_MCPS=$(tg-show-mcp-tools | grep "^test-" | cut -d: -f1)
for mcp in $TEST_MCPS; do
echo "Deleting $mcp..."
tg-delete-mcp-tool --name "$mcp"
done
echo "Cleanup complete"
```
### Environment-Specific Deletion
Delete MCP tools from specific environments:
```bash
#!/bin/bash
# Delete development MCP tools from production
export TRUSTGRAPH_URL="http://prod.trustgraph.com:8088/"
DEV_MCPS=("dev-mcp" "debug-mcp" "test-helper")
for mcp in "${DEV_MCPS[@]}"; do
echo "Removing development MCP tool: $mcp"
tg-delete-mcp-tool --name "$mcp"
done
```
### MCP Service Shutdown
Remove MCP tools when services are decommissioned:
```bash
#!/bin/bash
# Remove MCP tools for decommissioned service
SERVICE_NAME="old-service"
# Find MCP tools for this service
MCP_TOOLS=$(tg-show-mcp-tools | grep "$SERVICE_NAME" | cut -d: -f1)
for tool in $MCP_TOOLS; do
echo "Removing MCP tool for decommissioned service: $tool"
tg-delete-mcp-tool --name "$tool"
done
```
## Integration with Other Commands
### With MCP Tool Management
List and delete MCP tools:
```bash
# List all MCP tools
tg-show-mcp-tools
# Delete specific MCP tool
tg-delete-mcp-tool --name unwanted-mcp
# Verify deletion
tg-show-mcp-tools | grep unwanted-mcp
```
### With Configuration Management
Manage MCP tool configurations:
```bash
# View current configuration
tg-show-config
# Delete MCP tool
tg-delete-mcp-tool --name old-mcp
# View updated configuration
tg-show-config
```
### With MCP Tool Invocation
Ensure MCP tools can't be invoked after deletion:
```bash
# Delete MCP tool
tg-delete-mcp-tool --name deprecated-mcp
# Verify tool is no longer available
tg-invoke-mcp-tool --name deprecated-mcp
# Should fail with tool not found error
```
## Best Practices
1. **Verification**: Always verify MCP tool exists before deletion
2. **Backup**: Backup important MCP tool configurations before deletion
3. **Dependencies**: Check for MCP tool dependencies before deletion
4. **Service Coordination**: Coordinate with MCP service owners before deletion
5. **Testing**: Test system functionality after MCP tool deletion
6. **Documentation**: Document reasons for MCP tool deletion
7. **Gradual Removal**: Remove MCP tools gradually in production environments
8. **Monitoring**: Monitor for errors after MCP tool deletion
## Troubleshooting
### MCP Tool Not Found
If MCP tool deletion reports "not found":
1. Verify the MCP tool name is correct
2. Check MCP tool exists with `tg-show-mcp-tools`
3. Ensure you're connected to the correct TrustGraph instance
4. Check for case sensitivity in MCP tool name
### Deletion Errors
If deletion fails:
1. Check TrustGraph API connectivity
2. Verify API permissions
3. Check for configuration corruption
4. Retry the deletion operation
5. Check MCP service status
### Permission Errors
If deletion fails due to permissions:
1. Verify API access credentials
2. Check TrustGraph API permissions
3. Ensure proper authentication
4. Contact system administrator if needed
## Recovery
### Restore Deleted MCP Tool
If an MCP tool was accidentally deleted:
1. Use backup configuration if available
2. Re-register the MCP tool with `tg-set-mcp-tool`
3. Restore from version control if MCP tool definitions are tracked
4. Contact system administrator for recovery options
### Verify System State
After deletion, verify system state:
```bash
# Check MCP tool registry
tg-show-mcp-tools
# Verify no orphaned configurations
tg-show-config | grep "mcp\."
# Test MCP tool functionality
tg-invoke-mcp-tool --name remaining-tool
```
## MCP Tool Lifecycle
### Development to Production
Manage MCP tool lifecycle:
```bash
#!/bin/bash
# Promote MCP tool from dev to production
# Remove development version
tg-delete-mcp-tool --name dev-tool
# Add production version
tg-set-mcp-tool --name prod-tool --tool-url "http://prod.mcp.com/api"
```
### Version Management
Manage MCP tool versions:
```bash
#!/bin/bash
# Update MCP tool to new version
# Remove old version
tg-delete-mcp-tool --name tool-v1
# Add new version
tg-set-mcp-tool --name tool-v2 --tool-url "http://new.mcp.com/api"
```
## Security Considerations
When deleting MCP tools:
1. **Access Control**: Ensure proper authorization for deletion
2. **Audit Trail**: Log MCP tool deletions for security auditing
3. **Impact Assessment**: Assess security impact of tool removal
4. **Credential Cleanup**: Remove associated credentials if applicable
5. **Network Security**: Update firewall rules if MCP endpoints are no longer needed
## Related Commands
- [`tg-show-mcp-tools`](tg-show-mcp-tools.md) - Display registered MCP tools
- [`tg-set-mcp-tool`](tg-set-mcp-tool.md) - Configure and register MCP tools
- [`tg-invoke-mcp-tool`](tg-invoke-mcp-tool.md) - Execute MCP tools
- [`tg-delete-tool`](tg-delete-tool.md) - Delete regular agent tools
## See Also
- MCP Protocol Documentation
- TrustGraph MCP Integration Guide
- MCP Tool Management Manual

317
docs/cli/tg-delete-tool.md Normal file
View file

@ -0,0 +1,317 @@
# tg-delete-tool
## Synopsis
```
tg-delete-tool [OPTIONS] --id ID
```
## Description
The `tg-delete-tool` command deletes tools from the TrustGraph system. It removes tool configurations by ID from the agent configuration and updates the tool index accordingly. Once deleted, tools are no longer available for agent use.
This command is useful for:
- Removing obsolete or deprecated tools
- Cleaning up tool configurations
- Managing tool registry maintenance
- Updating tool deployments by removing old versions
The command removes both the tool from the tool index and deletes the complete tool configuration from the TrustGraph API.
## Options
- `-u, --api-url URL`
- TrustGraph API URL for configuration management
- Default: `http://localhost:8088/` (or `TRUSTGRAPH_URL` environment variable)
- Should point to a running TrustGraph API instance
- `--id ID`
- **Required.** Tool ID to delete
- Must match an existing tool ID in the registry
- Tool will be completely removed from the system
- `-h, --help`
- Show help message and exit
## Examples
### Basic Tool Deletion
Delete a weather tool:
```bash
tg-delete-tool --id weather
```
### Calculator Tool Deletion
Delete a calculator tool:
```bash
tg-delete-tool --id calculator
```
### Custom API URL
Delete a tool from a specific TrustGraph instance:
```bash
tg-delete-tool --api-url http://trustgraph.example.com:8088/ --id custom-tool
```
### Batch Tool Deletion
Delete multiple tools in a script:
```bash
#!/bin/bash
# Delete obsolete tools
tg-delete-tool --id old-search
tg-delete-tool --id deprecated-calc
tg-delete-tool --id unused-tool
```
### Conditional Deletion
Delete a tool only if it exists:
```bash
#!/bin/bash
# Check if tool exists before deletion
if tg-show-tools | grep -q "test-tool"; then
tg-delete-tool --id test-tool
echo "Tool deleted"
else
echo "Tool not found"
fi
```
## Deletion Process
The deletion process involves two steps:
1. **Index Update**: Remove the tool ID from the tool index
2. **Configuration Removal**: Delete the tool configuration data
Both operations must succeed for the deletion to be complete.
## Error Handling
The command handles various error conditions:
- **Tool not found**: If the specified tool ID doesn't exist
- **Missing configuration**: If tool is in index but configuration is missing
- **API connection errors**: If the TrustGraph API is unavailable
- **Partial deletion**: If index update or configuration removal fails
Common error scenarios:
```bash
# Tool not found
tg-delete-tool --id nonexistent-tool
# Output: Tool 'nonexistent-tool' not found in tool index.
# Missing required field
tg-delete-tool
# Output: Exception: Must specify --id for tool to delete
# API connection error
tg-delete-tool --api-url http://invalid-host:8088/ --id tool1
# Output: Exception: [Connection error details]
```
## Verification
The command provides feedback on the deletion process:
- **Success**: `Tool 'tool-id' deleted successfully.`
- **Not found**: `Tool 'tool-id' not found in tool index.`
- **Configuration missing**: `Tool configuration for 'tool-id' not found.`
- **Error**: `Error deleting tool 'tool-id': [error details]`
## Advanced Usage
### Safe Deletion with Verification
Verify tool exists before deletion:
```bash
#!/bin/bash
TOOL_ID="weather"
# Check if tool exists
if tg-show-tools | grep -q "^$TOOL_ID:"; then
echo "Deleting tool: $TOOL_ID"
tg-delete-tool --id "$TOOL_ID"
# Verify deletion
if ! tg-show-tools | grep -q "^$TOOL_ID:"; then
echo "Tool successfully deleted"
else
echo "Tool deletion failed"
fi
else
echo "Tool $TOOL_ID not found"
fi
```
### Backup Before Deletion
Backup tool configuration before deletion:
```bash
#!/bin/bash
TOOL_ID="important-tool"
# Export tool configuration
echo "Backing up tool configuration..."
tg-show-tools | grep -A 20 "^$TOOL_ID:" > "${TOOL_ID}_backup.txt"
# Delete tool
echo "Deleting tool..."
tg-delete-tool --id "$TOOL_ID"
echo "Tool deleted, backup saved to ${TOOL_ID}_backup.txt"
```
### Cleanup Script
Clean up multiple tools based on patterns:
```bash
#!/bin/bash
# Delete all test tools
echo "Cleaning up test tools..."
# Get list of test tools
TEST_TOOLS=$(tg-show-tools | grep "^test-" | cut -d: -f1)
for tool in $TEST_TOOLS; do
echo "Deleting $tool..."
tg-delete-tool --id "$tool"
done
echo "Cleanup complete"
```
### Environment-Specific Deletion
Delete tools from specific environments:
```bash
#!/bin/bash
# Delete development tools from production
export TRUSTGRAPH_URL="http://prod.trustgraph.com:8088/"
DEV_TOOLS=("dev-tool" "debug-tool" "test-helper")
for tool in "${DEV_TOOLS[@]}"; do
echo "Removing development tool: $tool"
tg-delete-tool --id "$tool"
done
```
## Integration with Other Commands
### With Tool Management
List and delete tools:
```bash
# List all tools
tg-show-tools
# Delete specific tool
tg-delete-tool --id unwanted-tool
# Verify deletion
tg-show-tools | grep unwanted-tool
```
### With Configuration Management
Manage tool configurations:
```bash
# View current configuration
tg-show-config
# Delete tool
tg-delete-tool --id old-tool
# View updated configuration
tg-show-config
```
### With Agent Workflows
Ensure agents don't use deleted tools:
```bash
# Delete tool
tg-delete-tool --id deprecated-tool
# Check agent configuration
tg-show-config | grep deprecated-tool
```
## Best Practices
1. **Verification**: Always verify tool exists before deletion
2. **Backup**: Backup important tool configurations before deletion
3. **Dependencies**: Check for tool dependencies before deletion
4. **Testing**: Test system functionality after tool deletion
5. **Documentation**: Document reasons for tool deletion
6. **Gradual Removal**: Remove tools gradually in production environments
7. **Monitoring**: Monitor for errors after tool deletion
## Troubleshooting
### Tool Not Found
If tool deletion reports "not found":
1. Verify the tool ID is correct
2. Check tool exists with `tg-show-tools`
3. Ensure you're connected to the correct TrustGraph instance
4. Check for case sensitivity in tool ID
### Partial Deletion
If deletion partially fails:
1. Check TrustGraph API connectivity
2. Verify API permissions
3. Check for configuration corruption
4. Retry the deletion operation
5. Manual cleanup may be required
### Permission Errors
If deletion fails due to permissions:
1. Verify API access credentials
2. Check TrustGraph API permissions
3. Ensure proper authentication
4. Contact system administrator if needed
## Recovery
### Restore Deleted Tool
If a tool was accidentally deleted:
1. Use backup configuration if available
2. Re-register the tool with `tg-set-tool`
3. Restore from version control if tool definitions are tracked
4. Contact system administrator for recovery options
### Verify System State
After deletion, verify system state:
```bash
# Check tool index consistency
tg-show-tools
# Verify no orphaned configurations
tg-show-config | grep "tool\."
# Test agent functionality
tg-invoke-agent --prompt "Test prompt"
```
## Related Commands
- [`tg-show-tools`](tg-show-tools.md) - Display registered tools
- [`tg-set-tool`](tg-set-tool.md) - Configure and register tools
- [`tg-delete-mcp-tool`](tg-delete-mcp-tool.md) - Delete MCP tools
- [`tg-show-config`](tg-show-config.md) - View system configuration
## See Also
- TrustGraph Tool Management Guide
- Agent Configuration Documentation
- System Administration Manual

View file

@ -0,0 +1,448 @@
# tg-invoke-mcp-tool
Invokes MCP (Model Control Protocol) tools through the TrustGraph API with parameter support.
## Synopsis
```bash
tg-invoke-mcp-tool [options] -n tool-name [-P parameters]
```
## Description
The `tg-invoke-mcp-tool` command invokes MCP (Model Control Protocol) tools through the TrustGraph API. MCP tools are external services that provide standardized interfaces for AI model interactions within the TrustGraph ecosystem.
MCP tools offer extensible functionality with consistent APIs, stateful interactions, and built-in security mechanisms. They can be used for various purposes including file operations, calculations, web requests, database queries, and custom integrations.
## Options
### Required Arguments
- `-n, --name TOOL_NAME`: MCP tool name to invoke
### Optional Arguments
- `-u, --url URL`: TrustGraph API URL (default: `$TRUSTGRAPH_URL` or `http://localhost:8088/`)
- `-f, --flow-id ID`: Flow instance ID to use (default: `default`)
- `-P, --parameters JSON`: Tool parameters as JSON-encoded dictionary
## Examples
### Basic Tool Invocation
```bash
tg-invoke-mcp-tool -n weather
```
### Tool with Parameters
```bash
tg-invoke-mcp-tool -n calculator -P '{"expression": "2 + 2"}'
```
### File Operations
```bash
tg-invoke-mcp-tool -n file-reader -P '{"path": "/path/to/file.txt"}'
```
### Web Request Tool
```bash
tg-invoke-mcp-tool -n http-client -P '{"url": "https://api.example.com/data", "method": "GET"}'
```
### Database Query
```bash
tg-invoke-mcp-tool -n database -P '{"query": "SELECT * FROM users LIMIT 10", "database": "main"}'
```
### Custom Flow and API URL
```bash
tg-invoke-mcp-tool -u http://custom-api:8088/ -f my-flow -n weather -P '{"location": "London"}'
```
## Parameter Format
### Simple Parameters
```bash
tg-invoke-mcp-tool -n calculator -P '{"operation": "add", "a": 10, "b": 5}'
```
### Complex Parameters
```bash
tg-invoke-mcp-tool -n data-processor -P '{
"input_data": [1, 2, 3, 4, 5],
"operations": ["sum", "average", "max"],
"output_format": "json"
}'
```
### File Input Parameters
```bash
tg-invoke-mcp-tool -n text-analyzer -P "{\"text\": \"$(cat document.txt)\", \"analysis_type\": \"sentiment\"}"
```
### Multiple Parameters
```bash
tg-invoke-mcp-tool -n report-generator -P '{
"template": "monthly-report",
"data_source": "sales_database",
"period": "2024-01",
"format": "pdf",
"recipients": ["admin@example.com"]
}'
```
## Common MCP Tools
### File Operations
```bash
# Read file content
tg-invoke-mcp-tool -n file-reader -P '{"path": "/path/to/file.txt"}'
# Write file content
tg-invoke-mcp-tool -n file-writer -P '{"path": "/path/to/output.txt", "content": "Hello World"}'
# List directory contents
tg-invoke-mcp-tool -n directory-lister -P '{"path": "/home/user", "recursive": false}'
```
### Data Processing
```bash
# JSON processing
tg-invoke-mcp-tool -n json-processor -P '{"data": "{\"key\": \"value\"}", "operation": "validate"}'
# CSV analysis
tg-invoke-mcp-tool -n csv-analyzer -P '{"file": "data.csv", "columns": ["name", "age"], "operation": "statistics"}'
# Text transformation
tg-invoke-mcp-tool -n text-transformer -P '{"text": "Hello World", "operation": "uppercase"}'
```
### Web and API
```bash
# HTTP requests
tg-invoke-mcp-tool -n http-client -P '{"url": "https://api.github.com/users/octocat", "method": "GET"}'
# Web scraping
tg-invoke-mcp-tool -n web-scraper -P '{"url": "https://example.com", "selector": "h1"}'
# API testing
tg-invoke-mcp-tool -n api-tester -P '{"endpoint": "/api/v1/users", "method": "POST", "payload": {"name": "John"}}'
```
### Database Operations
```bash
# Query execution
tg-invoke-mcp-tool -n database -P '{"query": "SELECT COUNT(*) FROM users", "database": "production"}'
# Schema inspection
tg-invoke-mcp-tool -n db-inspector -P '{"database": "main", "operation": "list_tables"}'
# Data migration
tg-invoke-mcp-tool -n db-migrator -P '{"source": "old_db", "target": "new_db", "table": "users"}'
```
## Output Formats
### String Response
```bash
tg-invoke-mcp-tool -n calculator -P '{"expression": "10 + 5"}'
# Output: "15"
```
### JSON Response
```bash
tg-invoke-mcp-tool -n weather -P '{"location": "New York"}'
# Output:
# {
# "location": "New York",
# "temperature": 22,
# "conditions": "sunny",
# "humidity": 45
# }
```
### Complex Object Response
```bash
tg-invoke-mcp-tool -n data-analyzer -P '{"dataset": "sales.csv"}'
# Output:
# {
# "summary": {
# "total_records": 1000,
# "columns": ["date", "product", "amount"],
# "date_range": "2024-01-01 to 2024-12-31"
# },
# "statistics": {
# "total_sales": 50000,
# "average_transaction": 50.0,
# "top_product": "Widget A"
# }
# }
```
## Error Handling
### Tool Not Found
```bash
Exception: MCP tool 'nonexistent-tool' not found
```
**Solution**: Check available tools with `tg-show-mcp-tools`.
### Invalid Parameters
```bash
Exception: Invalid JSON in parameters: Expecting property name enclosed in double quotes
```
**Solution**: Verify JSON parameter format and escape special characters.
### Missing Required Parameters
```bash
Exception: Required parameter 'input_data' not provided
```
**Solution**: Check tool documentation for required parameters.
### Flow Not Found
```bash
Exception: Flow instance 'invalid-flow' not found
```
**Solution**: Verify flow ID exists with `tg-show-flows`.
### Tool Execution Error
```bash
Exception: Tool execution failed: Connection timeout
```
**Solution**: Check network connectivity and tool service availability.
## Advanced Usage
### Batch Processing
```bash
# Process multiple files
for file in *.txt; do
echo "Processing $file..."
tg-invoke-mcp-tool -n text-analyzer -P "{\"file\": \"$file\", \"analysis\": \"sentiment\"}"
done
```
### Error Handling in Scripts
```bash
#!/bin/bash
# robust-tool-invoke.sh
tool_name="$1"
parameters="$2"
if ! result=$(tg-invoke-mcp-tool -n "$tool_name" -P "$parameters" 2>&1); then
echo "Error invoking tool: $result" >&2
exit 1
fi
echo "Success: $result"
```
### Pipeline Processing
```bash
# Chain multiple tools
data=$(tg-invoke-mcp-tool -n data-loader -P '{"source": "database"}')
processed=$(tg-invoke-mcp-tool -n data-processor -P "{\"data\": \"$data\", \"operation\": \"clean\"}")
tg-invoke-mcp-tool -n report-generator -P "{\"data\": \"$processed\", \"format\": \"pdf\"}"
```
### Configuration-Driven Invocation
```bash
# Use configuration file
config_file="tool-config.json"
tool_name=$(jq -r '.tool' "$config_file")
parameters=$(jq -c '.parameters' "$config_file")
tg-invoke-mcp-tool -n "$tool_name" -P "$parameters"
```
### Interactive Tool Usage
```bash
#!/bin/bash
# interactive-mcp-tool.sh
echo "Available tools:"
tg-show-mcp-tools
read -p "Enter tool name: " tool_name
read -p "Enter parameters (JSON): " parameters
echo "Invoking tool..."
tg-invoke-mcp-tool -n "$tool_name" -P "$parameters"
```
### Parallel Tool Execution
```bash
# Execute multiple tools in parallel
tools=("weather" "calculator" "file-reader")
params=('{"location": "NYC"}' '{"expression": "2+2"}' '{"path": "file.txt"}')
for i in "${!tools[@]}"; do
(
echo "Executing ${tools[$i]}..."
tg-invoke-mcp-tool -n "${tools[$i]}" -P "${params[$i]}" > "result-${tools[$i]}.json"
) &
done
wait
```
## Tool Management
### List Available Tools
```bash
# Show all registered MCP tools
tg-show-mcp-tools
```
### Register New Tools
```bash
# Register a new MCP tool
tg-set-mcp-tool weather-service "http://weather-api:8080/mcp" "Weather data provider"
```
### Remove Tools
```bash
# Remove an MCP tool
tg-delete-mcp-tool weather-service
```
## Use Cases
### Data Processing Workflows
```bash
# Extract, transform, and load data
raw_data=$(tg-invoke-mcp-tool -n data-extractor -P '{"source": "external_api"}')
clean_data=$(tg-invoke-mcp-tool -n data-cleaner -P "{\"data\": \"$raw_data\"}")
tg-invoke-mcp-tool -n data-loader -P "{\"data\": \"$clean_data\", \"target\": \"warehouse\"}"
```
### Automation Scripts
```bash
# Automated system monitoring
status=$(tg-invoke-mcp-tool -n system-monitor -P '{"checks": ["cpu", "memory", "disk"]}')
if echo "$status" | grep -q "warning"; then
tg-invoke-mcp-tool -n alert-system -P "{\"message\": \"System warning detected\", \"severity\": \"medium\"}"
fi
```
### Integration Testing
```bash
# Test API endpoints
endpoints=("/api/users" "/api/orders" "/api/products")
for endpoint in "${endpoints[@]}"; do
result=$(tg-invoke-mcp-tool -n api-tester -P "{\"endpoint\": \"$endpoint\", \"method\": \"GET\"}")
echo "Testing $endpoint: $result"
done
```
### Content Generation
```bash
# Generate documentation
code_analysis=$(tg-invoke-mcp-tool -n code-analyzer -P '{"directory": "./src", "language": "python"}')
tg-invoke-mcp-tool -n doc-generator -P "{\"analysis\": \"$code_analysis\", \"format\": \"markdown\"}"
```
## Performance Optimization
### Caching Tool Results
```bash
# Cache expensive tool operations
cache_dir="mcp-cache"
mkdir -p "$cache_dir"
invoke_with_cache() {
local tool="$1"
local params="$2"
local cache_key=$(echo "$tool-$params" | md5sum | cut -d' ' -f1)
local cache_file="$cache_dir/$cache_key.json"
if [ -f "$cache_file" ]; then
echo "Cache hit for $tool"
cat "$cache_file"
else
echo "Cache miss, invoking $tool..."
tg-invoke-mcp-tool -n "$tool" -P "$params" | tee "$cache_file"
fi
}
```
### Asynchronous Processing
```bash
# Non-blocking tool execution
async_invoke() {
local tool="$1"
local params="$2"
local output_file="$3"
tg-invoke-mcp-tool -n "$tool" -P "$params" > "$output_file" 2>&1 &
echo $! # Return process ID
}
# Execute multiple tools asynchronously
pid1=$(async_invoke "data-processor" '{"file": "data1.csv"}' "result1.json")
pid2=$(async_invoke "data-processor" '{"file": "data2.csv"}' "result2.json")
# Wait for completion
wait $pid1 $pid2
```
## Environment Variables
- `TRUSTGRAPH_URL`: Default API URL
## Related Commands
- [`tg-show-mcp-tools`](tg-show-mcp-tools.md) - List available MCP tools
- [`tg-set-mcp-tool`](tg-set-mcp-tool.md) - Register MCP tools
- [`tg-delete-mcp-tool`](tg-delete-mcp-tool.md) - Remove MCP tools
- [`tg-show-flows`](tg-show-flows.md) - List available flow instances
- [`tg-invoke-prompt`](tg-invoke-prompt.md) - Invoke prompt templates
## API Integration
This command uses the TrustGraph API flow interface to execute MCP tools within the context of specified flows. MCP tools are external services that implement the Model Control Protocol for standardized AI tool interactions.
## Best Practices
1. **Parameter Validation**: Always validate JSON parameters before execution
2. **Error Handling**: Implement robust error handling for production use
3. **Tool Discovery**: Use `tg-show-mcp-tools` to discover available tools
4. **Resource Management**: Consider performance implications of long-running tools
5. **Security**: Avoid passing sensitive data in parameters; use secure tool configurations
6. **Documentation**: Document custom tool parameters and expected responses
7. **Testing**: Test tool integrations thoroughly before production deployment
## Troubleshooting
### Tool Not Available
```bash
# Check tool registration
tg-show-mcp-tools | grep "tool-name"
# Verify tool service is running
curl -f http://tool-service:8080/health
```
### Parameter Issues
```bash
# Validate JSON format
echo '{"key": "value"}' | jq .
# Test with minimal parameters
tg-invoke-mcp-tool -n tool-name -P '{}'
```
### Flow Problems
```bash
# Check flow status
tg-show-flows | grep "flow-id"
# Verify flow supports MCP tools
tg-get-flow-class -n "flow-class" | jq '.interfaces.mcp_tool'
```
### Connection Issues
```bash
# Test API connectivity
curl -f http://localhost:8088/health
# Check environment variables
echo $TRUSTGRAPH_URL
```

267
docs/cli/tg-set-mcp-tool.md Normal file
View file

@ -0,0 +1,267 @@
# tg-set-mcp-tool
## Synopsis
```
tg-set-mcp-tool [OPTIONS] --name NAME --tool-url URL
```
## Description
The `tg-set-mcp-tool` command configures and registers MCP (Model Control Protocol) tools in the TrustGraph system. It allows defining MCP tool configurations with name and URL. Tools are stored in the 'mcp' configuration group for discovery and execution.
This command is useful for:
- Registering MCP tool endpoints for agent use
- Configuring external MCP server connections
- Managing MCP tool registry for agent workflows
- Integrating third-party MCP tools into TrustGraph
The command stores MCP tool configurations in the 'mcp' configuration group, separate from regular agent tools.
## Options
- `-u, --api-url URL`
- TrustGraph API URL for configuration storage
- Default: `http://localhost:8088/` (or `TRUSTGRAPH_URL` environment variable)
- Should point to a running TrustGraph API instance
- `--name NAME`
- **Required.** MCP tool name identifier
- Used to reference the MCP tool in configurations
- Must be unique within the MCP tool registry
- `--tool-url URL`
- **Required.** MCP tool URL endpoint
- Should point to the MCP server endpoint providing the tool functionality
- Must be a valid URL accessible by the TrustGraph system
- `-h, --help`
- Show help message and exit
## Examples
### Basic MCP Tool Registration
Register a weather service MCP tool:
```bash
tg-set-mcp-tool --name weather --tool-url "http://localhost:3000/weather"
```
### Calculator MCP Tool
Register a calculator MCP tool:
```bash
tg-set-mcp-tool --name calculator --tool-url "http://mcp-tools.example.com/calc"
```
### Remote MCP Service
Register a remote MCP service:
```bash
tg-set-mcp-tool --name document-processor \
--tool-url "https://api.example.com/mcp/documents"
```
### Custom API URL
Register MCP tool with custom TrustGraph API:
```bash
tg-set-mcp-tool -u http://trustgraph.example.com:8088/ \
--name custom-mcp --tool-url "http://custom.mcp.com/api"
```
### Local Development Setup
Register MCP tools for local development:
```bash
tg-set-mcp-tool --name dev-tool --tool-url "http://localhost:8080/mcp"
```
## MCP Tool Configuration
MCP tools are configured with minimal metadata:
- **name**: Unique identifier for the tool
- **url**: Endpoint URL for the MCP server
The configuration is stored as JSON in the 'mcp' configuration group:
```json
{
"name": "weather",
"url": "http://localhost:3000/weather"
}
```
## Advanced Usage
### Updating Existing MCP Tools
Update an existing MCP tool configuration:
```bash
# Update MCP tool URL
tg-set-mcp-tool --name weather --tool-url "http://new-weather-server:3000/api"
```
### Batch MCP Tool Registration
Register multiple MCP tools in a script:
```bash
#!/bin/bash
# Register a suite of MCP tools
tg-set-mcp-tool --name search --tool-url "http://search-mcp:3000/api"
tg-set-mcp-tool --name translate --tool-url "http://translate-mcp:3000/api"
tg-set-mcp-tool --name summarize --tool-url "http://summarize-mcp:3000/api"
```
### Environment-Specific Configuration
Configure MCP tools for different environments:
```bash
# Development environment
export TRUSTGRAPH_URL="http://dev.trustgraph.com:8088/"
tg-set-mcp-tool --name dev-mcp --tool-url "http://dev.mcp.com/api"
# Production environment
export TRUSTGRAPH_URL="http://prod.trustgraph.com:8088/"
tg-set-mcp-tool --name prod-mcp --tool-url "http://prod.mcp.com/api"
```
### MCP Tool Validation
Verify MCP tool registration:
```bash
# Register MCP tool and verify
tg-set-mcp-tool --name test-mcp --tool-url "http://test.mcp.com/api"
# Check if MCP tool was registered
tg-show-mcp-tools | grep test-mcp
```
## Error Handling
The command handles various error conditions:
- **Missing required arguments**: Both name and tool-url must be provided
- **Invalid URLs**: Tool URLs must be valid and accessible
- **API connection errors**: If the TrustGraph API is unavailable
- **Configuration errors**: If MCP tool data cannot be stored
Common error scenarios:
```bash
# Missing required field
tg-set-mcp-tool --name tool1
# Output: Exception: Must specify --tool-url for MCP tool
# Missing name
tg-set-mcp-tool --tool-url "http://example.com/mcp"
# Output: Exception: Must specify --name for MCP tool
# Invalid API URL
tg-set-mcp-tool -u "invalid-url" --name tool1 --tool-url "http://mcp.com"
# Output: Exception: [API connection error]
```
## Integration with Other Commands
### With MCP Tool Management
View registered MCP tools:
```bash
# Register MCP tool
tg-set-mcp-tool --name new-mcp --tool-url "http://new.mcp.com/api"
# View all MCP tools
tg-show-mcp-tools
```
### With Agent Workflows
Use MCP tools in agent workflows:
```bash
# Register MCP tool
tg-set-mcp-tool --name weather --tool-url "http://weather.mcp.com/api"
# Invoke MCP tool directly
tg-invoke-mcp-tool --name weather --input "location=London"
```
### With Configuration Management
MCP tools integrate with configuration management:
```bash
# Register MCP tool
tg-set-mcp-tool --name config-mcp --tool-url "http://config.mcp.com/api"
# View configuration including MCP tools
tg-show-config
```
## Best Practices
1. **Clear Naming**: Use descriptive, unique MCP tool names
2. **Reliable URLs**: Ensure MCP endpoints are stable and accessible
3. **Health Checks**: Verify MCP endpoints are operational before registration
4. **Documentation**: Document MCP tool capabilities and usage
5. **Error Handling**: Implement proper error handling for MCP endpoints
6. **Security**: Use secure URLs (HTTPS) when possible
7. **Monitoring**: Monitor MCP tool availability and performance
## Troubleshooting
### MCP Tool Not Appearing
If a registered MCP tool doesn't appear in listings:
1. Verify the MCP tool was registered successfully
2. Check MCP tool registry with `tg-show-mcp-tools`
3. Ensure the API URL is correct
4. Verify TrustGraph API is running
### MCP Tool Registration Errors
If MCP tool registration fails:
1. Check all required arguments are provided
2. Verify the tool URL is accessible
3. Ensure the MCP endpoint is operational
4. Check API connectivity
5. Review error messages for specific issues
### MCP Tool Connectivity Issues
If MCP tools aren't working as expected:
1. Verify MCP endpoint is accessible from TrustGraph
2. Check MCP server logs for errors
3. Ensure MCP protocol compatibility
4. Review network connectivity and firewall rules
5. Test MCP endpoint directly
## MCP Protocol
The Model Control Protocol (MCP) is a standardized interface for AI model tools:
- **Standardized API**: Consistent interface across different tools
- **Extensible**: Support for complex tool interactions
- **Stateful**: Can maintain state across multiple interactions
- **Secure**: Built-in security and authentication mechanisms
## Security Considerations
When registering MCP tools:
1. **URL Validation**: Ensure URLs are legitimate and secure
2. **Network Security**: Use HTTPS when possible
3. **Access Control**: Implement proper authentication for MCP endpoints
4. **Input Validation**: Validate all inputs to MCP tools
5. **Error Handling**: Don't expose sensitive information in error messages
## Related Commands
- [`tg-show-mcp-tools`](tg-show-mcp-tools.md) - Display registered MCP tools
- [`tg-delete-mcp-tool`](tg-delete-mcp-tool.md) - Remove MCP tool configurations
- [`tg-invoke-mcp-tool`](tg-invoke-mcp-tool.md) - Execute MCP tools
- [`tg-set-tool`](tg-set-tool.md) - Configure regular agent tools
## See Also
- MCP Protocol Documentation
- TrustGraph MCP Integration Guide
- Agent Tool Configuration Guide

321
docs/cli/tg-set-tool.md Normal file
View file

@ -0,0 +1,321 @@
# tg-set-tool
## Synopsis
```
tg-set-tool [OPTIONS] --id ID --name NAME --type TYPE --description DESCRIPTION [--argument ARG...]
```
## Description
The `tg-set-tool` command configures and registers tools in the TrustGraph system. It allows defining tool metadata including ID, name, description, type, and argument specifications. Tools are stored in the agent configuration and indexed for discovery and execution.
This command is useful for:
- Registering new tools for agent use
- Updating existing tool configurations
- Defining tool arguments and parameter types
- Managing the tool registry for agent workflows
The command updates both the tool index and stores the complete tool configuration in the TrustGraph API.
## Options
- `-u, --api-url URL`
- TrustGraph API URL for configuration storage
- Default: `http://localhost:8088/` (or `TRUSTGRAPH_URL` environment variable)
- Should point to a running TrustGraph API instance
- `--id ID`
- **Required.** Unique identifier for the tool
- Used to reference the tool in configurations and agent workflows
- Must be unique within the tool registry
- `--name NAME`
- **Required.** Human-readable name for the tool
- Displayed in tool listings and user interfaces
- Should be descriptive and clear
- `--type TYPE`
- **Required.** Tool type defining its functionality
- Valid types:
- `knowledge-query` - Query knowledge bases
- `text-completion` - Text completion/generation
- `mcp-tool` - Model Control Protocol tool
- `--description DESCRIPTION`
- **Required.** Detailed description of what the tool does
- Used by agents to understand tool capabilities
- Should clearly explain the tool's purpose and function
- `--argument ARG`
- Tool argument specification in format: `name:type:description`
- Can be specified multiple times for multiple arguments
- Valid argument types:
- `string` - String/text parameter
- `number` - Numeric parameter
- `-h, --help`
- Show help message and exit
## Examples
### Basic Tool Registration
Register a simple weather lookup tool:
```bash
tg-set-tool --id weather --name "Weather Lookup" \
--type knowledge-query \
--description "Get current weather information" \
--argument location:string:"Location to query" \
--argument units:string:"Temperature units (C/F)"
```
### Calculator Tool
Register a calculator tool with MCP type:
```bash
tg-set-tool --id calculator --name "Calculator" --type mcp-tool \
--description "Perform mathematical calculations" \
--argument expression:string:"Mathematical expression to evaluate"
```
### Text Completion Tool
Register a text completion tool:
```bash
tg-set-tool --id text-generator --name "Text Generator" \
--type text-completion \
--description "Generate text based on prompts" \
--argument prompt:string:"Text prompt for generation" \
--argument max_tokens:number:"Maximum tokens to generate"
```
### Custom API URL
Register a tool with custom API endpoint:
```bash
tg-set-tool -u http://trustgraph.example.com:8088/ \
--id custom-tool --name "Custom Tool" \
--type knowledge-query \
--description "Custom tool functionality"
```
### Tool Without Arguments
Register a simple tool with no arguments:
```bash
tg-set-tool --id status-check --name "Status Check" \
--type knowledge-query \
--description "Check system status"
```
## Tool Types
### knowledge-query
Tools that query knowledge bases, databases, or information systems:
- Used for information retrieval
- Typically return structured data or search results
- Examples: web search, document lookup, database queries
### text-completion
Tools that generate or complete text:
- Used for text generation tasks
- Process prompts and return generated content
- Examples: language models, text generators, summarizers
### mcp-tool
Model Control Protocol tools:
- Standardized tool interface for AI models
- Support complex interactions and state management
- Examples: external API integrations, complex workflows
## Argument Types
### string
Text or string parameters:
- Accept any text input
- Used for queries, prompts, identifiers
- Should include clear description of expected format
### number
Numeric parameters:
- Accept integer or floating-point values
- Used for limits, thresholds, quantities
- Should specify valid ranges when applicable
## Configuration Storage
The tool configuration is stored in two parts:
1. **Tool Index** (`agent.tool-index`)
- List of all registered tool IDs
- Updated to include new tools
- Used for tool discovery
2. **Tool Configuration** (`agent.tool.{id}`)
- Complete tool definition as JSON
- Includes metadata and argument specifications
- Used for tool execution and validation
## Advanced Usage
### Updating Existing Tools
Update an existing tool configuration:
```bash
# Update tool description
tg-set-tool --id weather --name "Weather Lookup" \
--type knowledge-query \
--description "Updated weather information service" \
--argument location:string:"Location to query"
```
### Batch Tool Registration
Register multiple tools in a script:
```bash
#!/bin/bash
# Register a suite of tools
tg-set-tool --id search --name "Web Search" --type knowledge-query \
--description "Search the web" \
--argument query:string:"Search query"
tg-set-tool --id summarize --name "Text Summarizer" --type text-completion \
--description "Summarize text content" \
--argument text:string:"Text to summarize"
tg-set-tool --id translate --name "Translator" --type mcp-tool \
--description "Translate text between languages" \
--argument text:string:"Text to translate" \
--argument target_lang:string:"Target language"
```
### Tool Validation
Verify tool registration:
```bash
# Register tool and verify
tg-set-tool --id test-tool --name "Test Tool" \
--type knowledge-query \
--description "Test tool for validation"
# Check if tool was registered
tg-show-tools | grep test-tool
```
## Error Handling
The command handles various error conditions:
- **Missing required arguments**: All required fields must be provided
- **Invalid tool types**: Only valid types are accepted
- **Invalid argument format**: Arguments must follow `name:type:description` format
- **API connection errors**: If the TrustGraph API is unavailable
- **Configuration errors**: If tool data cannot be stored
Common error scenarios:
```bash
# Missing required field
tg-set-tool --id tool1 --name "Tool 1"
# Output: Exception: Must specify --type for tool
# Invalid tool type
tg-set-tool --id tool1 --name "Tool 1" --type invalid-type
# Output: Exception: Type must be one of: knowledge-query, text-completion, mcp-tool
# Invalid argument format
tg-set-tool --id tool1 --name "Tool 1" --type knowledge-query \
--argument "bad-format"
# Output: Exception: Arguments should be form name:type:description
```
## Integration with Other Commands
### With Tool Management
View registered tools:
```bash
# Register tool
tg-set-tool --id new-tool --name "New Tool" \
--type knowledge-query \
--description "Newly registered tool"
# View all tools
tg-show-tools
```
### With Agent Invocation
Use registered tools with agents:
```bash
# Register tool
tg-set-tool --id weather --name "Weather" \
--type knowledge-query \
--description "Weather lookup"
# Use tool in agent workflow
tg-invoke-agent --prompt "What's the weather in London?"
```
### With Flow Configuration
Tools can be used in flow configurations:
```bash
# Register tool for flow use
tg-set-tool --id data-processor --name "Data Processor" \
--type mcp-tool \
--description "Process data in flows"
# View flows that might use the tool
tg-show-flows
```
## Best Practices
1. **Clear Naming**: Use descriptive, unique tool IDs and names
2. **Detailed Descriptions**: Provide comprehensive tool descriptions
3. **Argument Documentation**: Clearly describe each argument's purpose
4. **Type Selection**: Choose appropriate tool types for functionality
5. **Validation**: Test tools after registration
6. **Version Management**: Track tool configuration changes
7. **Documentation**: Document custom tools and their usage
## Troubleshooting
### Tool Not Appearing
If a registered tool doesn't appear in listings:
1. Verify the tool was registered successfully
2. Check the tool index with `tg-show-tools`
3. Ensure the API URL is correct
4. Verify TrustGraph API is running
### Tool Registration Errors
If tool registration fails:
1. Check all required arguments are provided
2. Verify argument format is correct
3. Ensure tool type is valid
4. Check API connectivity
5. Review error messages for specific issues
### Tool Configuration Issues
If tools aren't working as expected:
1. Verify tool arguments are correctly specified
2. Check tool type matches intended functionality
3. Ensure tool implementation is available
4. Review agent logs for tool execution errors
## Related Commands
- [`tg-show-tools`](tg-show-tools.md) - Display registered tools
- [`tg-delete-tool`](tg-delete-tool.md) - Remove tool configurations
- [`tg-set-mcp-tool`](tg-set-mcp-tool.md) - Configure MCP tools
- [`tg-invoke-agent`](tg-invoke-agent.md) - Use tools with agents
## See Also
- TrustGraph Tool Development Guide
- Agent Configuration Documentation
- MCP Tool Integration Guide

View file

@ -49,6 +49,19 @@ class Config:
self.request(input) self.request(input)
def delete(self, keys):
# The input consists of system and prompt strings
input = {
"operation": "delete",
"keys": [
{ "type": v.type, "key": v.key }
for v in keys
]
}
self.request(input)
def list(self, type): def list(self, type):
# The input consists of system and prompt strings # The input consists of system and prompt strings
@ -67,7 +80,7 @@ class Config:
"type": type, "type": type,
} }
object = self.request(input)["directory"] object = self.request(input)
try: try:
return [ return [

View file

@ -4,6 +4,7 @@ import base64
from .. knowledge import hash, Uri, Literal from .. knowledge import hash, Uri, Literal
from . types import Triple from . types import Triple
from . exceptions import ProtocolException
def to_value(x): def to_value(x):
if x["e"]: return Uri(x["v"]) if x["e"]: return Uri(x["v"])
@ -197,7 +198,6 @@ class FlowInstance:
def prompt(self, id, variables): def prompt(self, id, variables):
# The input consists of system and prompt strings
input = { input = {
"id": id, "id": id,
"variables": variables "variables": variables
@ -221,12 +221,37 @@ class FlowInstance:
raise ProtocolException("Response not formatted correctly") raise ProtocolException("Response not formatted correctly")
def mcp_tool(self, name, parameters={}):
# The input consists of name and parameters
input = {
"name": name,
"parameters": parameters,
}
object = self.request(
"service/mcp-tool",
input
)
if "text" in object:
return object["text"]
if "object" in object:
try:
return object["object"]
except Exception as e:
raise ProtocolException(
"Returned object not well-formed JSON"
)
raise ProtocolException("Response not formatted correctly")
def triples_query( def triples_query(
self, s=None, p=None, o=None, self, s=None, p=None, o=None,
user=None, collection=None, limit=10000 user=None, collection=None, limit=10000
): ):
# The input consists of system and prompt strings
input = { input = {
"limit": limit "limit": limit
} }

View file

@ -29,4 +29,5 @@ from . document_embeddings_client import DocumentEmbeddingsClientSpec
from . agent_service import AgentService from . agent_service import AgentService
from . graph_rag_client import GraphRagClientSpec from . graph_rag_client import GraphRagClientSpec
from . tool_service import ToolService from . tool_service import ToolService
from . tool_client import ToolClientSpec

View file

@ -0,0 +1,40 @@
import json
from . request_response_spec import RequestResponse, RequestResponseSpec
from .. schema import ToolRequest, ToolResponse
class ToolClient(RequestResponse):
async def invoke(self, name, parameters={}, timeout=600):
if parameters is None:
parameters = {}
resp = await self.request(
ToolRequest(
name = name,
parameters = json.dumps(parameters),
),
timeout=timeout
)
if resp.error:
raise RuntimeError(resp.error.message)
if resp.text: return resp.text
return json.loads(resp.object)
class ToolClientSpec(RequestResponseSpec):
def __init__(
self, request_name, response_name,
):
super(ToolClientSpec, self).__init__(
request_name = request_name,
request_schema = ToolRequest,
response_name = response_name,
response_schema = ToolResponse,
impl = ToolClient,
)

View file

@ -0,0 +1,94 @@
#!/usr/bin/env python3
"""
Deletes MCP (Model Control Protocol) tools from the TrustGraph system.
Removes MCP tool configurations by name from the 'mcp' configuration group.
"""
import argparse
import os
from trustgraph.api import Api, ConfigKey
import textwrap
default_url = os.getenv("TRUSTGRAPH_URL", 'http://localhost:8088/')
def delete_mcp_tool(
url : str,
name : str,
):
api = Api(url).config()
# Check if the tool exists first
try:
values = api.get([
ConfigKey(type="mcp", key=name)
])
if not values or not values[0].value:
print(f"MCP tool '{name}' not found.")
return False
except Exception as e:
print(f"MCP tool '{name}' not found.")
return False
# Delete the MCP tool configuration from the 'mcp' group
try:
api.delete([
ConfigKey(type="mcp", key=name)
])
print(f"MCP tool '{name}' deleted successfully.")
return True
except Exception as e:
print(f"Error deleting MCP tool '{name}': {e}")
return False
def main():
parser = argparse.ArgumentParser(
prog='tg-delete-mcp-tool',
description=__doc__,
epilog=textwrap.dedent('''
This utility removes MCP tool configurations from the TrustGraph system.
Once deleted, the tool will no longer be available for use.
Examples:
%(prog)s --name weather
%(prog)s --name calculator
%(prog)s --api-url http://localhost:9000/ --name file-reader
''').strip(),
formatter_class=argparse.RawDescriptionHelpFormatter
)
parser.add_argument(
'-u', '--api-url',
default=default_url,
help=f'API URL (default: {default_url})',
)
parser.add_argument(
'--name',
required=True,
help='MCP tool name to delete',
)
args = parser.parse_args()
try:
if not args.name:
raise RuntimeError("Must specify --name for MCP tool to delete")
delete_mcp_tool(
url=args.api_url,
name=args.name
)
except Exception as e:
print("Exception:", e, flush=True)
main()

View file

@ -0,0 +1,127 @@
#!/usr/bin/env python3
"""
Deletes tools from the TrustGraph system.
Removes tool configurations by ID from the agent configuration
and updates the tool index accordingly.
"""
import argparse
import os
from trustgraph.api import Api, ConfigKey, ConfigValue
import json
import textwrap
default_url = os.getenv("TRUSTGRAPH_URL", 'http://localhost:8088/')
def delete_tool(
url : str,
id : str,
):
api = Api(url).config()
# Get the current tool index
try:
values = api.get([
ConfigKey(type="agent", key="tool-index")
])
ix = json.loads(values[0].value)
except Exception as e:
print(f"Error reading tool index: {e}")
return False
# Check if the tool exists in the index
if id not in ix:
print(f"Tool '{id}' not found in tool index.")
return False
# Check if the tool configuration exists
try:
tool_values = api.get([
ConfigKey(type="agent", key=f"tool.{id}")
])
if not tool_values or not tool_values[0].value:
print(f"Tool configuration for '{id}' not found.")
return False
except Exception as e:
print(f"Tool configuration for '{id}' not found.")
return False
# Remove the tool ID from the index
ix.remove(id)
# Delete the tool configuration and update the index
try:
# Update the tool index
api.put([
ConfigValue(
type="agent", key="tool-index", value=json.dumps(ix)
)
])
# Delete the tool configuration
api.delete([
ConfigKey(type="agent", key=f"tool.{id}")
])
print(f"Tool '{id}' deleted successfully.")
return True
except Exception as e:
print(f"Error deleting tool '{id}': {e}")
return False
def main():
parser = argparse.ArgumentParser(
prog='tg-delete-tool',
description=__doc__,
epilog=textwrap.dedent('''
This utility removes tool configurations from the TrustGraph system.
It removes the tool from both the tool index and deletes the tool
configuration. Once deleted, the tool will no longer be available for use.
Examples:
%(prog)s --id weather
%(prog)s --id calculator
%(prog)s --api-url http://localhost:9000/ --id file-reader
''').strip(),
formatter_class=argparse.RawDescriptionHelpFormatter
)
parser.add_argument(
'-u', '--api-url',
default=default_url,
help=f'API URL (default: {default_url})',
)
parser.add_argument(
'--id',
required=True,
help='Tool ID to delete',
)
args = parser.parse_args()
try:
if not args.id:
raise RuntimeError("Must specify --id for tool to delete")
delete_tool(
url=args.api_url,
id=args.id
)
except Exception as e:
print("Exception:", e, flush=True)
main()

View file

@ -0,0 +1,80 @@
#!/usr/bin/env python3
"""
Invokes MCP (Model Control Protocol) tools through the TrustGraph API.
Allows calling MCP tools by specifying the tool name and providing
parameters as a JSON-encoded dictionary. The tool is executed within
the context of a specified flow.
"""
import argparse
import os
import json
from trustgraph.api import Api
default_url = os.getenv("TRUSTGRAPH_URL", 'http://localhost:8088/')
def query(url, flow_id, name, parameters):
api = Api(url).flow().id(flow_id)
resp = api.mcp_tool(name=name, parameters=parameters)
if isinstance(resp, str):
print(resp)
else:
print(json.dumps(resp, indent=4))
def main():
parser = argparse.ArgumentParser(
prog='tg-invoke-mcp-tool',
description=__doc__,
)
parser.add_argument(
'-u', '--url',
default=default_url,
help=f'API URL (default: {default_url})',
)
parser.add_argument(
'-f', '--flow-id',
default="default",
help=f'Flow ID (default: default)'
)
parser.add_argument(
'-n', '--name',
metavar='tool-name',
help=f'MCP tool name',
)
parser.add_argument(
'-P', '--parameters',
help='''Tool parameters, should be JSON-encoded dict.''',
)
args = parser.parse_args()
if args.parameters:
parameters = json.loads(args.parameters)
else:
parameters = {}
try:
query(
url = args.url,
flow_id = args.flow_id,
name = args.name,
parameters = parameters,
)
except Exception as e:
print("Exception:", e, flush=True)
main()

View file

@ -0,0 +1,93 @@
#!/usr/bin/env python3
"""
Configures and registers MCP (Model Control Protocol) tools in the
TrustGraph system. Allows defining MCP tool configurations with name and
URL. Tools are stored in the 'mcp' configuration group for discovery and
execution.
"""
import argparse
import os
from trustgraph.api import Api, ConfigValue
import textwrap
import json
default_url = os.getenv("TRUSTGRAPH_URL", 'http://localhost:8088/')
def set_mcp_tool(
url : str,
name : str,
tool_url : str,
):
api = Api(url).config()
# Store the MCP tool configuration in the 'mcp' group
values = api.put([
ConfigValue(
type="mcp", key=name, value=json.dumps({
"name": name,
"url": tool_url,
})
)
])
print(f"MCP tool '{name}' set with URL: {tool_url}")
def main():
parser = argparse.ArgumentParser(
prog='tg-set-mcp-tool',
description=__doc__,
epilog=textwrap.dedent('''
MCP tools are configured with just a name and URL. The URL should point
to the MCP server endpoint that provides the tool functionality.
Examples:
%(prog)s --name weather --tool-url "http://localhost:3000/weather"
%(prog)s --name calculator --tool-url "http://mcp-tools.example.com/calc"
''').strip(),
formatter_class=argparse.RawDescriptionHelpFormatter
)
parser.add_argument(
'-u', '--api-url',
default=default_url,
help=f'API URL (default: {default_url})',
)
parser.add_argument(
'--name',
required=True,
help='MCP tool name',
)
parser.add_argument(
'--tool-url',
required=True,
help='MCP tool URL endpoint',
)
args = parser.parse_args()
try:
if not args.name:
raise RuntimeError("Must specify --name for MCP tool")
if not args.tool_url:
raise RuntimeError("Must specify --url for MCP tool")
set_mcp_tool(
url=args.api_url,
name=args.name,
tool_url=args.tool_url
)
except Exception as e:
print("Exception:", e, flush=True)
main()

View file

@ -0,0 +1,195 @@
#!/usr/bin/env python3
"""
Configures and registers tools in the TrustGraph system.
Allows defining tool metadata including ID, name, description, type,
and argument specifications. Tools are stored in the agent configuration
and indexed for discovery and execution.
"""
from typing import List
import argparse
import os
from trustgraph.api import Api, ConfigKey, ConfigValue
import json
import tabulate
import textwrap
import dataclasses
default_url = os.getenv("TRUSTGRAPH_URL", 'http://localhost:8088/')
@dataclasses.dataclass
class Argument:
name : str
type : str
description : str
@staticmethod
def parse(s):
parts = s.split(":")
if len(parts) != 3:
raise RuntimeError(
"Arguments should be form name:type:description"
)
valid_types = [
"string", "number",
]
if parts[1] not in valid_types:
raise RuntimeError(
f"Type {parts[1]} invalid, use: " +
", ".join(valid_types)
)
return Argument(name=parts[0], type=parts[1], description=parts[2])
def set_tool(
url : str,
id : str,
name : str,
description : str,
type : str,
arguments : List[Argument],
):
api = Api(url).config()
values = api.get([
ConfigKey(type="agent", key="tool-index")
])
ix = json.loads(values[0].value)
object = {
"id": id,
"name": name,
"description": description,
"type": type,
"arguments": [
{
"name": a.name,
"type": a.type,
"description": a.description,
}
for a in arguments
]
}
if id not in ix:
ix.append(id)
values = api.put([
ConfigValue(
type="agent", key="tool-index", value=json.dumps(ix)
),
ConfigValue(
type="agent", key=f"tool.{id}", value=json.dumps(object)
)
])
print("Tool set.")
def main():
parser = argparse.ArgumentParser(
prog='tg-set-tool',
description=__doc__,
epilog=textwrap.dedent('''
Valid tool types:
knowledge-query - Query knowledge bases
text-completion - Text completion/generation
mcp-tool - Model Control Protocol tool
Valid argument types:
string - String/text parameter
number - Numeric parameter
Examples:
%(prog)s --id weather --name "Weather lookup" \\
--type knowledge-query \\
--description "Get weather information" \\
--argument location:string:"Location to query" \\
--argument units:string:"Temperature units (C/F)"
%(prog)s --id calculator --name "Calculator" --type mcp-tool \\
--description "Perform calculations" \\
--argument expression:string:"Mathematical expression"
''').strip(),
formatter_class=argparse.RawDescriptionHelpFormatter
)
parser.add_argument(
'-u', '--api-url',
default=default_url,
help=f'API URL (default: {default_url})',
)
parser.add_argument(
'--id',
help=f'Tool ID',
)
parser.add_argument(
'--name',
help=f'Tool name',
)
parser.add_argument(
'--description',
help=f'Tool description',
)
parser.add_argument(
'--type',
help=f'Tool type, one of: knowledge-query, text-completion, mcp-tool',
)
parser.add_argument(
'--argument',
nargs="*",
help=f'Arguments, form: name:type:description',
)
args = parser.parse_args()
try:
valid_types = [
"knowledge-query", "text-completion", "mcp-tool"
]
if args.id is None:
raise RuntimeError("Must specify --id for prompt")
if args.name is None:
raise RuntimeError("Must specify --name for prompt")
if args.type:
if args.type not in valid_types:
raise RuntimeError(
"Type must be one of: " + ", ".join(valid_types)
)
if args.argument:
arguments = [
Argument.parse(a)
for a in args.argument
]
else:
arguments = []
set_tool(
url=args.api_url, id=args.id, name=args.name,
description=args.description,
type=args.type,
arguments=arguments
)
except Exception as e:
print("Exception:", e, flush=True)
main()

View file

@ -0,0 +1,70 @@
#!/usr/bin/env python3
"""
Dumps out the current agent tool configuration
"""
import argparse
import os
from trustgraph.api import Api, ConfigKey
import json
import tabulate
import textwrap
default_url = os.getenv("TRUSTGRAPH_URL", 'http://localhost:8088/')
def show_config(url):
api = Api(url).config()
values = api.get_values(type="mcp")
for n, value in enumerate(values):
data = json.loads(value.value)
table = []
table.append(("id", value.key))
table.append(("name", data["name"]))
table.append(("url", data["url"]))
print()
print(value.key + ":")
print(tabulate.tabulate(
table,
tablefmt="pretty",
maxcolwidths=[None, 70],
stralign="left"
))
print()
def main():
parser = argparse.ArgumentParser(
prog='tg-show-mcp-tools',
description=__doc__,
)
parser.add_argument(
'-u', '--api-url',
default=default_url,
help=f'API URL (default: {default_url})',
)
args = parser.parse_args()
try:
show_config(
url=args.api_url,
)
except Exception as e:
print("Exception:", e, flush=True)
main()

View file

@ -37,6 +37,7 @@ def show_config(url):
table.append(("id", data["id"])) table.append(("id", data["id"]))
table.append(("name", data["name"])) table.append(("name", data["name"]))
table.append(("description", data["description"])) table.append(("description", data["description"]))
table.append(("type", data["type"]))
for n, arg in enumerate(data["arguments"]): for n, arg in enumerate(data["arguments"]):
table.append(( table.append((

View file

@ -46,7 +46,9 @@ setuptools.setup(
scripts=[ scripts=[
"scripts/tg-add-library-document", "scripts/tg-add-library-document",
"scripts/tg-delete-flow-class", "scripts/tg-delete-flow-class",
"scripts/tg-delete-mcp-tool",
"scripts/tg-delete-kg-core", "scripts/tg-delete-kg-core",
"scripts/tg-delete-tool",
"scripts/tg-dump-msgpack", "scripts/tg-dump-msgpack",
"scripts/tg-get-flow-class", "scripts/tg-get-flow-class",
"scripts/tg-get-kg-core", "scripts/tg-get-kg-core",
@ -56,6 +58,7 @@ setuptools.setup(
"scripts/tg-invoke-document-rag", "scripts/tg-invoke-document-rag",
"scripts/tg-invoke-graph-rag", "scripts/tg-invoke-graph-rag",
"scripts/tg-invoke-llm", "scripts/tg-invoke-llm",
"scripts/tg-invoke-mcp-tool",
"scripts/tg-invoke-prompt", "scripts/tg-invoke-prompt",
"scripts/tg-load-doc-embeds", "scripts/tg-load-doc-embeds",
"scripts/tg-load-kg-core", "scripts/tg-load-kg-core",
@ -67,8 +70,10 @@ setuptools.setup(
"scripts/tg-put-kg-core", "scripts/tg-put-kg-core",
"scripts/tg-remove-library-document", "scripts/tg-remove-library-document",
"scripts/tg-save-doc-embeds", "scripts/tg-save-doc-embeds",
"scripts/tg-set-mcp-tool",
"scripts/tg-set-prompt", "scripts/tg-set-prompt",
"scripts/tg-set-token-costs", "scripts/tg-set-token-costs",
"scripts/tg-set-tool",
"scripts/tg-show-config", "scripts/tg-show-config",
"scripts/tg-show-flow-classes", "scripts/tg-show-flow-classes",
"scripts/tg-show-flow-state", "scripts/tg-show-flow-state",
@ -77,6 +82,7 @@ setuptools.setup(
"scripts/tg-show-kg-cores", "scripts/tg-show-kg-cores",
"scripts/tg-show-library-documents", "scripts/tg-show-library-documents",
"scripts/tg-show-library-processing", "scripts/tg-show-library-processing",
"scripts/tg-show-mcp-tools",
"scripts/tg-show-processor-state", "scripts/tg-show-processor-state",
"scripts/tg-show-prompts", "scripts/tg-show-prompts",
"scripts/tg-show-token-costs", "scripts/tg-show-token-costs",

View file

@ -14,12 +14,19 @@ class AgentManager:
async def reason(self, question, history, context): async def reason(self, question, history, context):
print(f"calling reason: {question}", flush=True)
tools = self.tools tools = self.tools
print(f"in reason", flush=True)
print(tools, flush=True)
tool_names = ",".join([ tool_names = ",".join([
t for t in self.tools.keys() t for t in self.tools.keys()
]) ])
print("Tool names:", tool_names, flush=True)
variables = { variables = {
"question": question, "question": question,
"tools": [ "tools": [
@ -83,6 +90,9 @@ class AgentManager:
async def react(self, question, history, think, observe, context): async def react(self, question, history, think, observe, context):
logger.info(f"question: {question}")
print(f"question: {question}", flush=True)
act = await self.reason( act = await self.reason(
question = question, question = question,
history = history, history = history,
@ -104,13 +114,12 @@ class AgentManager:
else: else:
raise RuntimeError(f"No action for {act.name}!") raise RuntimeError(f"No action for {act.name}!")
print("TOOL>>>", act) print("TOOL>>>", act, flush=True)
resp = await action.implementation(context).invoke( resp = await action.implementation(context).invoke(
**act.arguments **act.arguments
) )
print("RSETUL", resp)
resp = resp.strip() resp = resp.strip()
logger.info(f"resp: {resp}") logger.info(f"resp: {resp}")

View file

@ -5,13 +5,14 @@ Simple agent infrastructure broadly implements the ReAct flow.
import json import json
import re import re
import sys import sys
import functools
from ... base import AgentService, TextCompletionClientSpec, PromptClientSpec from ... base import AgentService, TextCompletionClientSpec, PromptClientSpec
from ... base import GraphRagClientSpec from ... base import GraphRagClientSpec, ToolClientSpec
from ... schema import AgentRequest, AgentResponse, AgentStep, Error from ... schema import AgentRequest, AgentResponse, AgentStep, Error
from . tools import KnowledgeQueryImpl, TextCompletionImpl from . tools import KnowledgeQueryImpl, TextCompletionImpl, McpToolImpl
from . agent_manager import AgentManager from . agent_manager import AgentManager
from . types import Final, Action, Tool, Argument from . types import Final, Action, Tool, Argument
@ -67,6 +68,13 @@ class Processor(AgentService):
) )
) )
self.register_specification(
ToolClientSpec(
request_name = "mcp-tool-request",
response_name = "mcp-tool-response",
)
)
async def on_tools_config(self, config, version): async def on_tools_config(self, config, version):
print("Loading configuration version", version) print("Loading configuration version", version)
@ -102,17 +110,21 @@ class Processor(AgentService):
impl_id = data.get("type") impl_id = data.get("type")
name = data.get("name")
if impl_id == "knowledge-query": if impl_id == "knowledge-query":
impl = KnowledgeQueryImpl impl = KnowledgeQueryImpl
elif impl_id == "text-completion": elif impl_id == "text-completion":
impl = TextCompletionImpl impl = TextCompletionImpl
elif impl_id == "mcp-tool":
impl = functools.partial(McpToolImpl, name=k)
else: else:
raise RuntimeError( raise RuntimeError(
f"Tool-kind {impl_id} not known" f"Tool-kind {impl_id} not known"
) )
tools[data.get("name")] = Tool( tools[data.get("name")] = Tool(
name = data.get("name"), name = name,
description = data.get("description"), description = data.get("description"),
implementation = impl, implementation = impl,
config=data.get("config", {}), config=data.get("config", {}),
@ -181,6 +193,8 @@ class Processor(AgentService):
await respond(r) await respond(r)
print("Call React", flush=True)
act = await self.agent.react( act = await self.agent.react(
question = request.question, question = request.question,
history = history, history = history,

View file

@ -1,4 +1,6 @@
import json
# This tool implementation knows how to put a question to the graph RAG # This tool implementation knows how to put a question to the graph RAG
# service # service
class KnowledgeQueryImpl: class KnowledgeQueryImpl:
@ -23,3 +25,29 @@ class TextCompletionImpl:
arguments.get("question") arguments.get("question")
) )
# This tool implementation knows how to do MCP tool invocation. This uses
# the mcp-tool service.
class McpToolImpl:
def __init__(self, context, name):
self.context = context
self.name = name
async def invoke(self, **arguments):
client = self.context("mcp-tool-request")
print(f"MCP tool invocation: {self.name}...", flush=True)
output = await client.invoke(
name = self.name,
parameters = {},
)
print(output)
if isinstance(output, str):
return output
else:
return json.dumps(output)