1 - How to Create a Custom MCP Tool
Build your own Model Context Protocol (MCP) compatible tools
This guide shows you how to create a new custom tool that’s compatible with the Model Context Protocol (MCP) in gomcptest.
Prerequisites
- A working installation of gomcptest
- Go programming knowledge
- Understanding of the MCP protocol basics
mkdir -p tools/YourToolName/cmd
2. Create the README.md file
Create a README.md in the tool directory with documentation:
touch tools/YourToolName/README.md
Include the following sections:
- Tool description
- Parameters
- Usage notes
- Example
3. Create the main.go file
Create a main.go file in the cmd directory:
touch tools/YourToolName/cmd/main.go
Here’s a template to start with:
package main
import (
	"encoding/json"
	"fmt"
	"log"
	"os"
	"github.com/mark3labs/mcp-go"
)
// Define your tool's parameters structure
type Params struct {
	// Add your parameters here
	// Example:
	InputParam string `json:"input_param"`
}
func main() {
	server := mcp.NewServer()
	// Register your tool function
	server.RegisterFunction("YourToolName", func(params json.RawMessage) (any, error) {
		var p Params
		if err := json.Unmarshal(params, &p); err != nil {
			return nil, fmt.Errorf("failed to parse parameters: %w", err)
		}
		// Implement your tool's logic here
		result := doSomethingWithParams(p)
		return result, nil
	})
	if err := server.Run(os.Stdin, os.Stdout); err != nil {
		log.Fatalf("Server error: %v", err)
	}
}
func doSomethingWithParams(p Params) interface{} {
	// Your tool's core functionality
	// ...
	
	// Return the result
	return map[string]interface{}{
		"result": "Your processed result",
	}
}
Open the Makefile in the root directory and add your tool:
YourToolName:
	go build -o bin/YourToolName tools/YourToolName/cmd/main.go
Also add it to the all target.
Test the tool directly:
echo '{"name":"YourToolName","params":{"input_param":"test"}}' | ./bin/YourToolName
8. Use with the CLI
Add your tool to the CLI command:
./bin/cliGCP -mcpservers "./GlobTool;./GrepTool;./LS;./View;./YourToolName;./dispatch_agent;./Bash;./Replace"
- Focus on a single, well-defined purpose
- Provide clear error messages
- Include meaningful response formatting
- Implement proper parameter validation
- Handle edge cases gracefully
- Consider adding unit tests in a _test.go file
2 - How to Configure the OpenAI-Compatible Server
Customize the OpenAI-compatible server with AgentFlow UI for different use cases, including tool selection, event monitoring, and production deployment
This guide shows you how to configure and customize the OpenAI-compatible server in gomcptest with the AgentFlow web interface for different use cases.
Prerequisites
- A working installation of gomcptest
- Basic familiarity with the OpenAI server from the tutorial
- Understanding of environment variables and configuration
Environment Variables Configuration
Basic Server Configuration
The OpenAI server can be configured using the following environment variables:
# Server port (default: 8080)
export PORT=8080
# Log level: DEBUG, INFO, WARN, ERROR (default: INFO)
export LOG_LEVEL=INFO
# Artifact storage path (default: ~/openaiserver/artifacts)
export ARTIFACT_PATH=~/openaiserver/artifacts
# Maximum upload size in bytes (default: 52428800 = 50MB)
export MAX_UPLOAD_SIZE=52428800
GCP Configuration
Configure the Google Cloud Platform integration:
# GCP Project ID (required)
export GCP_PROJECT=your-gcp-project-id
# GCP Region (default: us-central1)
export GCP_REGION=us-central1
# Comma-separated list of Gemini models (default: gemini-1.5-pro,gemini-2.0-flash)
export GEMINI_MODELS=gemini-1.5-pro,gemini-2.0-flash
Note: IMAGEN_MODELS and IMAGE_DIR environment variables are no longer needed for the openaiserver. Image generation is now handled by the independent tools/imagen MCP server.
Enable additional Vertex AI built-in tools:
# Enable code execution capabilities
export VERTEX_AI_CODE_EXECUTION=true
# Enable Google Search integration
export VERTEX_AI_GOOGLE_SEARCH=true
# Enable Google Search with retrieval and grounding
export VERTEX_AI_GOOGLE_SEARCH_RETRIEVAL=true
Artifact Storage Configuration
The OpenAI server includes a built-in artifact storage API for managing file uploads and downloads.
Artifact Storage Features
- Generic File Support: Store any type of file (text, binary, images, documents)
- UUID-based Storage: Each uploaded file gets a unique UUID identifier
- Metadata Tracking: Automatically tracks original filename, content type, size, and upload timestamp
- Configurable Storage: Set custom storage directory and size limits
- RESTful API: Simple HTTP endpoints for upload and retrieval
Artifact API Endpoints
Upload Artifact:
POST /artifact/
Headers required:
- Content-Type: The MIME type of the file
- X-Original-Filename: The original name of the file
Response:
{
  "artifactId": "7f33ee3d-b589-4b3c-b8c8-a9a3ee04eacf"
}
Retrieve Artifact:
GET /artifact/{artifactId}
Returns the file with appropriate headers:
- Content-Type: Original MIME type
- Content-Disposition: Original filename
- Content-Length: File size
Example Usage
Upload a file:
curl -X POST http://localhost:8080/artifact/ \
  -H "Content-Type: text/plain" \
  -H "X-Original-Filename: example.txt" \
  --data-binary @example.txt
Download a file:
curl http://localhost:8080/artifact/7f33ee3d-b589-4b3c-b8c8-a9a3ee04eacf
Storage Directory Structure
Files are stored using the following structure:
~/openaiserver/artifacts/
├── 7f33ee3d-b589-4b3c-b8c8-a9a3ee04eacf           # The actual file
└── 7f33ee3d-b589-4b3c-b8c8-a9a3ee04eacf.meta.json # Metadata file
The metadata file contains:
{
  "originalFilename": "example.txt",
  "contentType": "text/plain",
  "size": 49,
  "uploadTimestamp": "2025-09-19T12:01:11.277651Z"
}
AgentFlow UI Configuration
The AgentFlow web interface provides several configuration options for enhanced user experience.
Accessing AgentFlow
Once your server is running, access AgentFlow at:
http://localhost:8080/ui
AgentFlow allows granular control over tool availability:
- Default Behavior: All tools are available by default
- Tool Filtering: Use the tool selection dropdown to choose specific tools
- Model String Format: Selected tools are encoded as model|tool1|tool2|tool3
Example tool selection scenarios:
- Development: Enable only Edit,View,GlobTool, andGrepToolfor code editing tasks
- File Management: Enable only LS,View,Bashfor system administration
- Content Creation: Enable View,Replace,Editfor document editing
Event Monitoring Configuration
AgentFlow provides real-time tool event monitoring:
- Tool Call Events: See when AI decides to use tools
- Tool Response Events: Monitor tool execution results
- Event Persistence: All events are saved in conversation history
- Event Details: Click notifications for detailed argument/response information
Mobile and PWA Configuration
For mobile deployment, AgentFlow supports Progressive Web App features:
- Apple Touch Icons: Pre-configured for iOS web app installation
- Responsive Design: Optimized for mobile devices
- Web App Manifest: Supports “Add to Home Screen” functionality
- Offline Capability: Conversations persist offline
UI Customization
You can customize AgentFlow by modifying the template file:
host/openaiserver/simpleui/chat-ui.html.tmpl
Key customization areas:
- Color Scheme: Modify CSS gradient backgrounds
- Tool Notification Styling: Customize event notification appearance
- Mobile Behavior: Adjust responsive breakpoints
- Branding: Update titles, icons, and metadata
Setting Up a Production Environment
For a production environment, create a proper systemd service file:
sudo nano /etc/systemd/system/gomcptest-openai.service
Add the following content:
[Unit]
Description=gomcptest OpenAI Server
After=network.target
[Service]
User=yourusername
WorkingDirectory=/path/to/gomcptest/host/openaiserver
ExecStart=/path/to/gomcptest/host/openaiserver/openaiserver -mcpservers "/path/to/gomcptest/bin/GlobTool;/path/to/gomcptest/bin/GrepTool;/path/to/gomcptest/bin/LS;/path/to/gomcptest/bin/View;/path/to/gomcptest/bin/Bash;/path/to/gomcptest/bin/Replace"
Environment=PORT=8080
Environment=LOG_LEVEL=INFO
Environment=GCP_PROJECT=your-gcp-project-id
Environment=GCP_REGION=us-central1
Environment=GEMINI_MODELS=gemini-1.5-pro,gemini-2.0-flash
Environment=ARTIFACT_PATH=/var/lib/gomcptest/artifacts
Environment=MAX_UPLOAD_SIZE=52428800
Restart=on-failure
[Install]
WantedBy=multi-user.target
Then enable and start the service:
sudo systemctl enable gomcptest-openai
sudo systemctl start gomcptest-openai
To add custom MCP tools to the server, include them in the -mcpservers parameter when starting the server:
go run . -mcpservers "../bin/GlobTool;../bin/GrepTool;../bin/LS;../bin/View;../bin/YourCustomTool;../bin/Bash;../bin/Replace"
Some tools require additional parameters. You can specify these after the tool path:
go run . -mcpservers "../bin/GlobTool;../bin/dispatch_agent -glob-path ../bin/GlobTool -grep-path ../bin/GrepTool -ls-path ../bin/LS -view-path ../bin/View"
API Usage Configuration
Enabling CORS
For web applications, you may need to enable CORS. Add a middleware to the main.go file:
package main
import (
    "net/http"
    // other imports
)
// CORS middleware
func corsMiddleware(next http.Handler) http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        w.Header().Set("Access-Control-Allow-Origin", "*")
        w.Header().Set("Access-Control-Allow-Methods", "GET, POST, OPTIONS")
        w.Header().Set("Access-Control-Allow-Headers", "Content-Type, Authorization")
        
        if r.Method == "OPTIONS" {
            w.WriteHeader(http.StatusOK)
            return
        }
        
        next.ServeHTTP(w, r)
    })
}
func main() {
    // existing code...
    
    http.Handle("/", corsMiddleware(openAIHandler))
    
    // existing code...
}
Setting Rate Limits
Add a simple rate limiting middleware:
package main
import (
    "net/http"
    "sync"
    "time"
    // other imports
)
type RateLimiter struct {
    requests     map[string][]time.Time
    maxRequests  int
    timeWindow   time.Duration
    mu           sync.Mutex
}
func NewRateLimiter(maxRequests int, timeWindow time.Duration) *RateLimiter {
    return &RateLimiter{
        requests:    make(map[string][]time.Time),
        maxRequests: maxRequests,
        timeWindow:  timeWindow,
    }
}
func (rl *RateLimiter) Middleware(next http.Handler) http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        ip := r.RemoteAddr
        
        rl.mu.Lock()
        
        // Clean up old requests
        now := time.Now()
        if reqs, exists := rl.requests[ip]; exists {
            var validReqs []time.Time
            for _, req := range reqs {
                if now.Sub(req) <= rl.timeWindow {
                    validReqs = append(validReqs, req)
                }
            }
            rl.requests[ip] = validReqs
        }
        
        // Check if rate limit is exceeded
        if len(rl.requests[ip]) >= rl.maxRequests {
            rl.mu.Unlock()
            http.Error(w, "Rate limit exceeded", http.StatusTooManyRequests)
            return
        }
        
        // Add current request
        rl.requests[ip] = append(rl.requests[ip], now)
        rl.mu.Unlock()
        
        next.ServeHTTP(w, r)
    })
}
func main() {
    // existing code...
    
    rateLimiter := NewRateLimiter(10, time.Minute) // 10 requests per minute
    http.Handle("/", rateLimiter.Middleware(corsMiddleware(openAIHandler)))
    
    // existing code...
}
Adjusting Memory Usage
For high-load scenarios, adjust Go’s garbage collector:
export GOGC=100  # Default is 100, lower values lead to more frequent GC
Increasing Concurrency
If handling many concurrent requests, adjust the server’s concurrency limits:
package main
import (
    "net/http"
    // other imports
)
func main() {
    // existing code...
    
    server := &http.Server{
        Addr:         ":" + strconv.Itoa(cfg.Port),
        Handler:      openAIHandler,
        ReadTimeout:  30 * time.Second,
        WriteTimeout: 120 * time.Second,
        IdleTimeout:  120 * time.Second,
        MaxHeaderBytes: 1 << 20,
    }
    
    err = server.ListenAndServe()
    
    // existing code...
}
Troubleshooting Common Issues
Debugging Connection Problems
If you’re experiencing connection issues, set the log level to DEBUG:
Common Error Messages
- Failed to create MCP client: Ensure the tool path is correct and the tool is executable
- Failed to load GCP config: Check your GCP environment variables
- Error in LLM request: Verify your GCP credentials and project access
To verify tools are registered correctly, look for log messages like:
INFO server0 Registering command=../bin/GlobTool
INFO server1 Registering command=../bin/GrepTool
3 - How to Configure the cliGCP Command Line Interface
Customize the cliGCP tool with environment variables and command-line options
This guide shows you how to configure and customize the cliGCP command line interface for various use cases.
Prerequisites
- A working installation of gomcptest
- Basic familiarity with the cliGCP tool from the tutorial
- Understanding of environment variables and configuration
Command Line Arguments
The cliGCP tool accepts the following command line arguments:
# Specify the MCP servers to use (required)
-mcpservers "tool1;tool2;tool3"
# Example with tool arguments
./cliGCP -mcpservers "./GlobTool;./GrepTool;./dispatch_agent -glob-path ./GlobTool -grep-path ./GrepTool -ls-path ./LS -view-path ./View;./Bash"
Environment Variables Configuration
GCP Configuration
Configure the Google Cloud Platform integration with these environment variables:
# GCP Project ID (required)
export GCP_PROJECT=your-gcp-project-id
# GCP Region (default: us-central1)
export GCP_REGION=us-central1
# Comma-separated list of Gemini models (required)
export GEMINI_MODELS=gemini-1.5-pro,gemini-2.0-flash
# Directory to store images (required for image generation)
export IMAGE_DIR=/path/to/image/directory
Advanced Configuration
You can customize the behavior of the cliGCP tool with these additional environment variables:
# Set a custom system instruction for the model
export SYSTEM_INSTRUCTION="You are a helpful assistant specialized in Go programming."
# Adjust the model's temperature (0.0-1.0, default is 0.2)
# Lower values make output more deterministic, higher values more creative
export MODEL_TEMPERATURE=0.3
# Set a maximum token limit for responses
export MAX_OUTPUT_TOKENS=2048
Creating Shell Aliases
To simplify usage, create shell aliases in your .bashrc or .zshrc:
# Add to ~/.bashrc or ~/.zshrc
alias gpt='cd /path/to/gomcptest/bin && ./cliGCP -mcpservers "./GlobTool;./GrepTool;./LS;./View;./Bash;./Replace"'
# Create specialized aliases for different tasks
alias code-assistant='cd /path/to/gomcptest/bin && GCP_PROJECT=your-project GEMINI_MODELS=gemini-2.0-flash ./cliGCP -mcpservers "./GlobTool;./GrepTool;./LS;./View;./Bash;./Replace"'
alias security-scanner='cd /path/to/gomcptest/bin && SYSTEM_INSTRUCTION="You are a security expert focused on finding vulnerabilities in code" ./cliGCP -mcpservers "./GlobTool;./GrepTool;./LS;./View;./Bash"'
Customizing the System Instruction
To modify the default system instruction, edit the agent.go file:
// In host/cliGCP/cmd/agent.go
genaimodels[model].SystemInstruction = &genai.Content{
    Role: "user",
    Parts: []genai.Part{
        genai.Text("You are a helpful agent with access to tools. " +
            "Your job is to help the user by performing tasks using these tools. " +
            "You should not make up information. " +
            "If you don't know something, say so and explain what you would need to know to help. " +
            "If not indication, use the current working directory which is " + cwd),
    },
}
Creating Task-Specific Configurations
For different use cases, you can create specialized configuration scripts:
Code Review Helper
Create a file called code-reviewer.sh:
#!/bin/bash
export GCP_PROJECT=your-gcp-project-id
export GCP_REGION=us-central1
export GEMINI_MODELS=gemini-2.0-flash
export IMAGE_DIR=/tmp/images
export SYSTEM_INSTRUCTION="You are a code review expert. Analyze code for bugs, security issues, and areas for improvement. Focus on providing constructive feedback and detailed explanations."
cd /path/to/gomcptest/bin
./cliGCP -mcpservers "./GlobTool;./GrepTool;./LS;./View;./Bash"
Make it executable:
chmod +x code-reviewer.sh
Documentation Generator
Create a file called doc-generator.sh:
#!/bin/bash
export GCP_PROJECT=your-gcp-project-id
export GCP_REGION=us-central1
export GEMINI_MODELS=gemini-2.0-flash
export IMAGE_DIR=/tmp/images
export SYSTEM_INSTRUCTION="You are a documentation specialist. Your task is to help create clear, comprehensive documentation for code. Analyze code structure and create appropriate documentation following best practices."
cd /path/to/gomcptest/bin
./cliGCP -mcpservers "./GlobTool;./GrepTool;./LS;./View;./Bash;./Replace"
Configuring dispatch_agent
When using the dispatch_agent tool, you can configure its behavior with additional arguments:
./cliGCP -mcpservers "./GlobTool;./GrepTool;./LS;./View;./dispatch_agent -glob-path ./GlobTool -grep-path ./GrepTool -ls-path ./LS -view-path ./View -timeout 30s;./Bash;./Replace"
You can create specialized tool combinations for different tasks:
# Web development toolset
./cliGCP -mcpservers "./GlobTool -include '*.{html,css,js}';./GrepTool;./LS;./View;./Bash;./Replace"
# Go development toolset
./cliGCP -mcpservers "./GlobTool -include '*.go';./GrepTool;./LS;./View;./Bash;./Replace"
Troubleshooting Common Issues
Model Connection Issues
If you’re having trouble connecting to the Gemini model:
- Verify your GCP credentials:
gcloud auth application-default print-access-token
- Check that the Vertex AI API is enabled:
gcloud services list --enabled | grep aiplatform
- Verify your project has access to the models you’re requesting
If tools are failing to execute:
- Ensure the tool paths are correct
- Verify the tools are executable
- Check for permission issues in the directories you’re accessing
For better performance:
- Use more specific tool patterns to reduce search scope
- Consider creating specialized agents for different tasks
- Set a lower temperature for more deterministic responses
4 - How to Query OpenAI Server with Tool Events
Learn how to programmatically query the OpenAI-compatible server and monitor tool execution events using curl, Python, or shell commands
This guide shows you how to programmatically interact with the gomcptest OpenAI-compatible server to execute tools and monitor their execution events in real-time.
Prerequisites
- A running gomcptest OpenAI server with tools registered
- Basic familiarity with HTTP requests and Server-Sent Events
- curlcommand-line tool or Python with- requestslibrary
The gomcptest server supports two streaming modes:
- Standard Mode (default): Only chat completion chunks (OpenAI compatible)
- Enhanced Mode: Includes tool execution events (tool_callandtool_response)
Tool events are only visible when the server is configured with enhanced streaming or when using the AgentFlow web UI.
Method 1: Using curl with Streaming
First, let’s execute a simple tool like sleep with streaming enabled:
curl -X POST http://localhost:8080/v1/chat/completions \
  -H "Content-Type: application/json" \
  -H "Accept: text/event-stream" \
  -N \
  -d '{
    "model": "gemini-2.0-flash",
    "messages": [
      {
        "role": "user", 
        "content": "Please use the sleep tool to pause for 2 seconds, then tell me you are done"
      }
    ],
    "stream": true
  }'
Expected Output (Standard Mode)
In standard mode, you’ll see only chat completion chunks:
data: {"id":"chatcmpl-abc123","object":"chat.completion.chunk","created":1704067200,"model":"gemini-2.0-flash","choices":[{"index":0,"delta":{"role":"assistant","content":"I'll"},"finish_reason":null}]}
data: {"id":"chatcmpl-abc123","object":"chat.completion.chunk","created":1704067200,"model":"gemini-2.0-flash","choices":[{"index":0,"delta":{"content":" use the sleep tool to pause for 2 seconds."},"finish_reason":null}]}
data: {"id":"chatcmpl-abc123","object":"chat.completion.chunk","created":1704067200,"model":"gemini-2.0-flash","choices":[{"index":0,"delta":{"content":" Done! I have completed the 2-second pause."},"finish_reason":"stop"}]}
data: [DONE]
Here’s a Python script that demonstrates how to capture and parse tool events:
import requests
import json
import time
def stream_with_tool_monitoring(prompt, model="gemini-2.0-flash"):
    """
    Send a streaming request and monitor tool events
    """
    url = "http://localhost:8080/v1/chat/completions"
    
    payload = {
        "model": model,
        "messages": [{"role": "user", "content": prompt}],
        "stream": True
    }
    
    headers = {
        "Content-Type": "application/json",
        "Accept": "text/event-stream"
    }
    
    print(f"🚀 Sending request: {prompt}")
    print("=" * 60)
    
    with requests.post(url, json=payload, headers=headers, stream=True) as response:
        if response.status_code != 200:
            print(f"❌ Error: {response.status_code} - {response.text}")
            return
            
        content_buffer = ""
        tool_calls = {}
        
        for line in response.iter_lines(decode_unicode=True):
            if line.startswith("data: "):
                data = line[6:]  # Remove "data: " prefix
                
                if data == "[DONE]":
                    print("\n✅ Stream completed")
                    break
                    
                try:
                    event = json.loads(data)
                    
                    # Handle different event types
                    if event.get("event_type") == "tool_call":
                        tool_info = event.get("tool_call", {})
                        tool_id = tool_info.get("id")
                        tool_name = tool_info.get("name")
                        tool_args = tool_info.get("arguments", {})
                        
                        print(f"🔧 Tool Call: {tool_name}")
                        print(f"   ID: {tool_id}")
                        print(f"   Arguments: {json.dumps(tool_args, indent=2)}")
                        
                        tool_calls[tool_id] = {
                            "name": tool_name,
                            "args": tool_args,
                            "start_time": time.time()
                        }
                        
                    elif event.get("event_type") == "tool_response":
                        tool_info = event.get("tool_response", {})
                        tool_id = tool_info.get("id")
                        tool_name = tool_info.get("name")
                        response_data = tool_info.get("response")
                        error = tool_info.get("error")
                        
                        if tool_id in tool_calls:
                            duration = time.time() - tool_calls[tool_id]["start_time"]
                            print(f"📥 Tool Response: {tool_name} (took {duration:.2f}s)")
                        else:
                            print(f"📥 Tool Response: {tool_name}")
                            
                        print(f"   ID: {tool_id}")
                        if error:
                            print(f"   ❌ Error: {error}")
                        else:
                            print(f"   ✅ Response: {response_data}")
                        
                    elif event.get("choices") and event["choices"][0].get("delta"):
                        # Handle chat completion chunks
                        delta = event["choices"][0]["delta"]
                        if delta.get("content"):
                            content_buffer += delta["content"]
                            print(delta["content"], end="", flush=True)
                            
                except json.JSONDecodeError:
                    continue
                    
        if content_buffer:
            print(f"\n💬 Complete Response: {content_buffer}")
# Example usage
if __name__ == "__main__":
    # Test with sleep tool
    stream_with_tool_monitoring(
        "Use the sleep tool to pause for 3 seconds, then tell me the current time"
    )
    
    print("\n" + "=" * 60)
    
    # Test with file operations
    stream_with_tool_monitoring(
        "List the files in the current directory using the LS tool"
    )
The sleep tool is perfect for demonstrating tool events because it has a measurable duration:
# Test sleep tool with timing
curl -X POST http://localhost:8080/v1/chat/completions \
  -H "Content-Type: application/json" \
  -N \
  -d '{
    "model": "gemini-2.0-flash",
    "messages": [
      {
        "role": "user", 
        "content": "Please use the sleep tool to pause for exactly 5 seconds and confirm when complete"
      }
    ],
    "stream": true
  }' | while IFS= read -r line; do
    echo "$(date '+%H:%M:%S') - $line"
  done
This will show timestamps for each event, helping you verify the tool execution timing.
Method 4: Advanced Event Filtering with jq
If you have jq installed, you can filter and format the events:
curl -X POST http://localhost:8080/v1/chat/completions \
  -H "Content-Type: application/json" \
  -N \
  -d '{
    "model": "gemini-2.0-flash",
    "messages": [{"role": "user", "content": "Use the sleep tool for 3 seconds"}],
    "stream": true
  }' | grep "^data: " | sed 's/^data: //' | while read line; do
    if [ "$line" != "[DONE]" ]; then
      echo "$line" | jq -r '
        if .event_type == "tool_call" then
          "🔧 TOOL CALL: " + .tool_call.name + " with args: " + (.tool_call.arguments | tostring)
        elif .event_type == "tool_response" then
          "📥 TOOL RESPONSE: " + .tool_response.name + " -> " + (.tool_response.response | tostring)
        elif .choices and .choices[0].delta.content then
          "💬 CONTENT: " + .choices[0].delta.content
        else
          "📊 OTHER: " + (.object // "unknown")
        end'
    fi
  done
When you execute a tool, you should see this event sequence:
- Tool Call Event: AI decides to use a tool - {
  "event_type": "tool_call",
  "object": "tool.call",
  "tool_call": {
    "id": "call_abc123",
    "name": "sleep",
    "arguments": {"seconds": 3}
  }
}
 
- Tool Response Event: Tool execution completes - {
  "event_type": "tool_response", 
  "object": "tool.response",
  "tool_response": {
    "id": "call_abc123",
    "name": "sleep",
    "response": "Slept for 3 seconds"
  }
}
 
- Chat Completion Chunks: AI generates response based on tool result 
Troubleshooting
If you’re not seeing tool events in your stream:
- Check Server Configuration: Tool events require the withAllEventsflag to be enabled
- Verify Tool Registration: Ensure tools are properly registered with the server
- Test with AgentFlow UI: The web UI at http://localhost:8080/uialways shows tool events
If the AI isn’t using your requested tool:
- Be Explicit: Clearly request the specific tool by name
- Check Tool Availability: Use /v1/toolsendpoint to verify tool registration
- Use Simple Examples: Start with basic tools like sleeporLS
# Check which tools are registered
curl http://localhost:8080/v1/tools | jq '.tools[] | .name'
Next Steps
This approach gives you programmatic access to the same tool execution visibility that the AgentFlow web interface provides, enabling automation, monitoring, and integration with other systems.
5 - How to Use the OpenAI Server with big-AGI
Configure the gomcptest OpenAI-compatible server as a backend for big-AGI
This guide shows you how to set up and configure the gomcptest OpenAI-compatible server to work with big-AGI, a popular open-source web client for AI assistants.
Prerequisites
Why Use big-AGI with gomcptest?
big-AGI provides a polished, feature-rich web interface for interacting with AI models. By connecting it to the gomcptest OpenAI-compatible server, you get:
- A professional web interface for your AI interactions
- Support for tools/function calling
- Conversation history management
- Persona management
- Image generation capabilities
- Multiple user support
Setting Up big-AGI
- Clone the big-AGI repository: - git clone https://github.com/enricoros/big-agi.git
cd big-agi
 
- Install dependencies: 
- Create a - .env.localfile for configuration:
 - cp .env.example .env.local
 
- Edit the - .env.localfile to configure your gomcptest server connection:
 - # big-AGI configuration
# Your gomcptest OpenAI-compatible server URL
OPENAI_API_HOST=http://localhost:8080
# This can be any string since the gomcptest server doesn't use API keys
OPENAI_API_KEY=gomcptest-local-server
# Set this to true to enable the custom server
OPENAI_API_ENABLE_CUSTOM_PROVIDER=true
 
- Start big-AGI: 
- Open your browser and navigate to - http://localhost:3000to access the big-AGI interface.
 
Configuring big-AGI to Use Your Models
The gomcptest OpenAI-compatible server exposes Google Cloud models through an OpenAI-compatible API. In big-AGI, you’ll need to configure the models:
- Open big-AGI in your browser
- Click on the Settings icon (gear) in the top right
- Go to the Models tab
- Under “OpenAI Models”:- Click “Add Models”
- Add your models by ID (e.g., gemini-1.5-pro,gemini-2.0-flash)
- Set context length appropriately (8K-32K depending on the model)
- Set function calling capability to truefor models that support it
 
To use the MCP tools through big-AGI’s function calling interface:
- In big-AGI, click on the Settings icon
- Go to the Advanced tab
- Enable “Function Calling” under the “Experimental Features” section
- In a new chat, click on the “Functions” tab (plugin icon) in the chat interface
- The available tools from your gomcptest server should be listed
Configuring CORS for big-AGI
If you’re running big-AGI on a different domain or port than your gomcptest server, you’ll need to enable CORS on the server side. Edit the OpenAI server configuration:
- Create or edit a CORS middleware for the OpenAI server: - // CORS middleware with specific origin allowance
func corsMiddleware(next http.Handler) http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        // Allow requests from big-AGI origin
        w.Header().Set("Access-Control-Allow-Origin", "http://localhost:3000")
        w.Header().Set("Access-Control-Allow-Methods", "GET, POST, OPTIONS")
        w.Header().Set("Access-Control-Allow-Headers", "Content-Type, Authorization")
        if r.Method == "OPTIONS" {
            w.WriteHeader(http.StatusOK)
            return
        }
        next.ServeHTTP(w, r)
    })
}
 
- Apply this middleware to your server routes 
Troubleshooting Common Issues
Model Not Found
If big-AGI reports that models cannot be found:
- Verify your gomcptest server is running and accessible
- Check the server logs to ensure models are properly registered
- Make sure the model IDs in big-AGI match exactly the ones provided by your gomcptest server
Function Calling Not Working
If tools aren’t working properly:
- Ensure the tools are properly registered in your gomcptest server
- Check that function calling is enabled in big-AGI settings
- Verify the model you’re using supports function calling
Connection Issues
If big-AGI can’t connect to your server:
- Verify the OPENAI_API_HOSTvalue in your.env.localfile
- Check for CORS issues in your browser’s developer console
- Ensure your server is running and accessible from the browser
Production Deployment
For production use, consider:
- Securing your API: - Add proper authentication to your gomcptest OpenAI server
- Update the OPENAI_API_KEYin big-AGI accordingly
 
- Deploying big-AGI: 
- Setting up HTTPS: - For production, both big-AGI and your gomcptest server should use HTTPS
- Consider using a reverse proxy like Nginx with Let’s Encrypt certificates
 
Example: Basic Chat Interface
Once everything is set up, you can use big-AGI’s interface to interact with your AI models:
- Start a new chat
- Select your model from the model dropdown (e.g., gemini-1.5-pro)
- Enable function calling if you want to use tools
- Begin chatting with your AI assistant, powered by gomcptest
The big-AGI interface provides a much richer experience than a command-line interface, with features like conversation history, markdown rendering, code highlighting, and more.