Metadata-Version: 2.4
Name: instana-fix-wrapper
Version: 1.0.2
Summary: Wrapper MCP server that fixes WatsonX parameter stringification bug for Instana MCP
Author-email: Your Name <your.email@example.com>
Requires-Python: >=3.10
Requires-Dist: mcp-instana==0.9.6
Requires-Dist: mcp>=1.0.0
Provides-Extra: dev
Requires-Dist: pytest-asyncio>=0.21.0; extra == 'dev'
Requires-Dist: pytest>=7.0.0; extra == 'dev'
Description-Content-Type: text/markdown

# Instana Fix Wrapper - MCP Server

A wrapper MCP server that fixes the WatsonX Orchestrator parameter stringification bug for Instana MCP v0.9.6.

## Problem It Solves

WatsonX Orchestrator has a bug where it converts nested JSON dictionaries to strings before sending them to MCP servers:

**What WatsonX Sends** (Wrong):
```python
{
  "selections": "{'entity_type': 'host', 'metrics': ['cpu', 'memory']}"  # STRING!
}
```

**What MCP Server Expects** (Correct):
```python
{
  "selections": {"entity_type": "host", "metrics": ["cpu", "memory"]}  # DICT!
}
```

This wrapper intercepts the calls, parses the stringified JSON back to proper dicts, and forwards to the real Instana MCP server.

## Features

✅ **Wraps All 8 Instana MCP Tools** (v0.9.6 Smart Router):
1. `analyze_infrastructure` - Infrastructure metrics and analysis
2. `manage_applications` - Application performance monitoring
3. `get_incidents` - Incident event monitoring
4. `get_issues` - Issue tracking
5. `get_websites` - Website monitoring
6. `manage_custom_dashboards` - Dashboard management
7. `get_actions` - Automation actions
8. `get_agent_monitoring_events` - Agent health monitoring

✅ **Fixes Stringification Bug** - Automatically parses strings back to dicts
✅ **Transparent** - Same interface as original Instana MCP
✅ **Logging** - Logs when fixes are applied for debugging

## Installation

### From PyPI (After Publishing)

```bash
pip install instana-fix-wrapper
```

### From Source (Development)

```bash
cd instana-fix-wrapper
pip install -e .
```

## Usage

### 1. Set Environment Variables

```bash
export INSTANA_BASE_URL="https://your-instana-instance.instana.io"
export INSTANA_API_TOKEN="your_instana_api_token"
```

### 2. Run the Wrapper Server

```bash
instana-fix-wrapper
```

Or with uvx:

```bash
uvx instana-fix-wrapper
```

### 3. Configure in WatsonX

Import the wrapper instead of the original Instana MCP:

```bash
orchestrate toolkits import \
  --name instana-fixed \
  --mcp-server "uvx instana-fix-wrapper"
```

## How It Works

```
┌─────────────┐
│  WatsonX    │
│ Orchestrator│
└──────┬──────┘
       │ Sends stringified JSON
       │ {"selections": "{'entity_type': 'host'}"}
       ▼
┌─────────────────────┐
│  Wrapper MCP Server │
│  (This Package)     │
│                     │
│  1. Receives call   │
│  2. Detects string  │
│  3. Parses to dict  │
│  4. Forwards fixed  │
└──────┬──────────────┘
       │ Sends proper dict
       │ {"selections": {"entity_type": "host"}}
       ▼
┌─────────────────┐
│  Instana MCP    │
│  (v0.9.6)       │
│                 │
│  Processes      │
│  Returns data   │
└─────────────────┘
```

## Example

### Before (Direct Instana MCP - Fails)

```python
# WatsonX sends:
{
  "entity": "host",
  "intent": "CPU usage",
  "selections": "{'entity_type': 'host', 'metrics': ['cpu']}"  # STRING!
}

# Instana MCP receives STRING and fails:
# Error: Input should be a valid dictionary
```

### After (With Wrapper - Works)

```python
# WatsonX sends (same):
{
  "entity": "host",
  "intent": "CPU usage",
  "selections": "{'entity_type': 'host', 'metrics': ['cpu']}"  # STRING
}

# Wrapper fixes it:
{
  "entity": "host",
  "intent": "CPU usage",
  "selections": {"entity_type": "host", "metrics": ["cpu"]}  # DICT!
}

# Instana MCP receives DICT and succeeds:
# Returns: CPU metrics data
```

## Testing

### Test the Wrapper Locally

```bash
# Set credentials
export INSTANA_BASE_URL="https://your-instana.instana.io"
export INSTANA_API_TOKEN="your_token"

# Run wrapper
instana-fix-wrapper

# In another terminal, test with MCP client
# (wrapper will log when it fixes stringified parameters)
```

### Test in WatsonX

1. Import wrapper toolkit
2. Create agent with wrapper tools
3. Test query:
   ```
   Get CPU usage for host t3992-dev1-db-node01-par01-dev
   ```
4. Should work without stringification errors!

## Logging

The wrapper logs when it fixes parameters:

```
[WRAPPER] Fixed stringified parameters for tool: analyze_infrastructure
[WRAPPER] Original: {'selections': "{'entity_type': 'host'}"}
[WRAPPER] Fixed: {'selections': {'entity_type': 'host'}}
```

## Comparison: Before vs After

| Metric | Without Wrapper | With Wrapper |
|--------|----------------|--------------|
| **Stringification Errors** | ✅ YES (fails) | ❌ NO (fixed) |
| **Retry Attempts** | 10-14 | 1-3 |
| **Success Rate** | Low | High |
| **Tool Count** | 8 tools | 8 tools |
| **Performance** | Slow (retries) | Fast |

## Architecture

### Wrapper Components

1. **Parameter Fixer** (`fix_stringified_json`)
   - Detects stringified JSON
   - Parses back to dict/list
   - Handles both single and double quotes

2. **Tool Definitions** (`list_tools`)
   - Exposes all 8 Instana tools
   - Same schemas as original
   - Transparent to WatsonX

3. **Call Handler** (`call_tool`)
   - Receives calls from WatsonX
   - Fixes parameters
   - Forwards to Instana MCP
   - Returns results

### Data Flow

```
WatsonX → Wrapper → Fix Parameters → Instana MCP → Results → Wrapper → WatsonX
```

## Limitations

- **Adds Latency**: Small overhead for parameter parsing (~1-5ms)
- **Requires Credentials**: Must set INSTANA_BASE_URL and INSTANA_API_TOKEN
- **Stdio Only**: Currently only supports stdio transport

## Troubleshooting

### Error: "INSTANA_BASE_URL and INSTANA_API_TOKEN must be set"

**Solution**: Set environment variables:
```bash
export INSTANA_BASE_URL="https://your-instana.instana.io"
export INSTANA_API_TOKEN="your_token"
```

### Error: "Import mcp could not be resolved"

**Solution**: Install dependencies:
```bash
pip install mcp mcp-instana==0.9.6
```

### Wrapper Not Fixing Parameters

**Check logs**: The wrapper logs when it fixes parameters. If you don't see logs, the parameters might already be correct.

## Development

### Project Structure

```
instana-fix-wrapper/
├── instana_fix_wrapper/
│   ├── __init__.py
│   └── server.py          # Main wrapper logic
├── pyproject.toml         # Package configuration
├── README.md              # This file
└── DEPLOYMENT_GUIDE.md    # Deployment instructions
```

### Running Tests

```bash
# Install dev dependencies
pip install -e ".[dev]"

# Run tests
pytest
```

### Building Package

```bash
# Install build tools
pip install build twine

# Build package
python -m build

# Upload to PyPI
twine upload dist/*
```

## Contributing

Contributions welcome! Please:
1. Fork the repository
2. Create a feature branch
3. Make your changes
4. Add tests
5. Submit a pull request

## License

MIT License - See LICENSE file for details

## Support

For issues or questions:
- GitHub Issues: [your-repo-url]
- Email: your.email@example.com

## Acknowledgments

- Built on top of [mcp-instana](https://pypi.org/project/mcp-instana/) v0.9.6
- Uses [MCP Python SDK](https://github.com/modelcontextprotocol/python-sdk)