Alteryx MCP
by thinhdao276
README.md
# Alteryx MCP
An MCP server that exposes comprehensive Alteryx workflow manipulation tools over stdio, enabling AI assistants to:
- **Read & Analyze**: Summarize workflows into Markdown (containers, connections, SQL, diagrams)
- **Find Tools**: Search for tools by ID, type, or annotation patterns
- **Edit Configurations**: Modify tool settings, field selections, annotations
- **Update SQL**: Change database queries with OCI compliance (auto-removes `--` comments)
- **Manage Connections**: Update DCM connection identifiers
- **Create Workflows**: Build new `.yxmd` files programmatically
It wraps `alteryx_mcp/alteryx_mcp.py` from this repository.
## Demo
[Watch the demo video](summarize_test.mov)
## Features
### 1. Workflow Analysis
- Parse and summarize entire workflows
- Extract container hierarchies, tool types, database connections
- Generate Mermaid diagrams for data flow visualization
### 2. Tool Discovery
- Find tools by ToolID, plugin type (e.g., `AlteryxSelect`, `DbFileInput`)
- **NEW**: `find_tools_fast()` - Optimized regex-based search (10-100x faster for specific ToolID lookups)
- Search by annotation text patterns
- Get complete tool configuration details
### 3. Direct Editing
- **Select Tools**: Update field selections (`selected: true/false`) and rename fields
- **Annotations**: Change tool annotations/labels
- **SQL Queries**: Update DbFileInput queries with automatic comment removal for OCI
- **Connections**: Swap DCM connection IDs across tools
- **NEW**: **Row Limits**: Get, update, and batch-modify row limits for Sample/Filter tools
- All edits support dry-run mode for safe previewing
### 4. Connection Management
- **Batch Update Connections**: Update multiple tools with the same connection ID
- Copy connection from reference tool or use provided connection ID
- Update entire workflow at once
### 5. Row Limit Management (NEW)
- **Get Row Limits**: Read current First N, Last N, Sample N settings
- **Update Single Tool**: Change row limit for specific tool
- **Batch Update**: Mass-modify row limits across entire workflow
- Update by specific tool IDs or by plugin type (e.g., all Sample tools)
### 6. Workflow Creation
- Build workflows from scratch with JSON configuration
- Define tools, positions, connections programmatically
- Specify custom metadata
## Install (editable dev)
```bash
# From repo root
pip install -e .
```
## Run (stdio)
```bash
alteryx-mcp
```
## Tools Reference
### Analysis Tools
#### `summarize_workflow`
```python
summarize_workflow(
workflow: str, # Path to .yxmd file
mapping: str | None # Optional JSON mapping for connection aliases
) -> str # Returns Markdown summary
```
**Example**:
```json
{
"workflow": "c:/projects/VCI/VCIProjectionBaseLine.yxmd",
"mapping": "c:/projects/connections.json"
}
```
Returns comprehensive Markdown with:
- Metadata (WorkflowId, Description)
- Container hierarchy
- Top tool types
- Database connections with queries
- Output destinations
- Mermaid flowcharts
---
#### `find_tools`
```python
find_tools(
workflow: str, # Path to .yxmd file
tool_id: int | None = None, # Find specific tool ID
plugin_type: str | None = None, # e.g., 'AlteryxSelect', 'DbFileInput'
annotation_pattern: str | None = None # Search in annotations
) -> str # Returns JSON with matching tools
```
**Examples**:
```json
// Find all Select tools
{
"workflow": "path/to/workflow.yxmd",
"plugin_type": "AlteryxSelect"
}
// Find tools mentioning "v12Live" in annotations
{
"workflow": "path/to/workflow.yxmd",
"annotation_pattern": "v12Live"
}
// Find specific tool
{
"workflow": "path/to/workflow.yxmd",
"tool_id": 375
}
```
Supported plugin types:
- `AlteryxSelect`, `DbFileInput`, `DbFileOutput`
- `Filter`, `Join`, `Sort`, `Formula`
- `Browse`, `TextBox`, `ToolContainer`
- `Union`, `Summarize`, `Sample`, `Unique`
- `RecordID`, `MultiRowFormula`, `TextInput`, `DateTimeInput`
---
### Editing Tools
#### `update_select_tool`
```python
update_select_tool(
workflow: str, # Path to .yxmd file
tool_id: int, # Tool ID of Select tool
field_updates: str, # JSON string with field updates
dry_run: bool = False
) -> str # Status message
```
**Example - Update field selections**:
```json
{
"workflow": "path/to/workflow.yxmd",
"tool_id": 375,
"field_updates": "{\"SCM37_CTRA22_IBCONO\": {\"selected\": false}, \"SCM37_CTRA22_IBFACI\": {\"selected\": true, \"rename\": \"FACILITY_CODE\"}}",
"dry_run": true
}
```
Field update options:
- `selected`: `true` or `false`
- `rename`: New field name
---
#### `update_annotation`
```python
update_annotation(
workflow: str, # Path to .yxmd file
tool_id: int, # Tool ID to update
new_annotation: str, # New annotation text
dry_run: bool = False
) -> str
```
**Example**:
```json
{
"workflow": "path/to/workflow.yxmd",
"tool_id": 12,
"new_annotation": "dcm:prod-oracle\nQuery=SELECT * FROM MPHEAD WHERE CONO=1",
"dry_run": false
}
```
---
#### `update_sql_query`
```python
update_sql_query(
workflow: str, # Path to .yxmd file
tool_id: int, # Tool ID of DbFileInput
new_query: str, # New SQL query
remove_comments: bool = True, # Strip -- comments for OCI
dry_run: bool = False
) -> str
```
**Example - Update query with OCI compliance**:
```json
{
"workflow": "path/to/workflow.yxmd",
"tool_id": 12,
"new_query": "SELECT IACONO, IAPUNO, IACUCD -- Company info\nFROM MVXCDTA.MPHEAD\nWHERE IACONO = 1",
"remove_comments": true,
"dry_run": false
}
```
Result (after comment removal):
```sql
SELECT IACONO, IAPUNO, IACUCD
FROM MVXCDTA.MPHEAD
WHERE IACONO = 1
```
---
#### `update_connection_id`
```python
update_connection_id(
workflow: str, # Path to .yxmd file
tool_id: int, # Tool ID to update
new_connection_id: str, # New DCM connection ID (UUID)
dry_run: bool = False
) -> str
```
**Example**:
```json
{
"workflow": "path/to/workflow.yxmd",
"tool_id": 12,
"new_connection_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"dry_run": false
}
```
---
#### `batch_update_connections`
```python
batch_update_connections(
workflow: str,
tool_ids: List[int],
source_connection_id: str | None = None,
source_tool_id: int | None = None,
dry_run: bool = False
) -> str
```
**Example**:
```json
{
"workflow": "path/to/workflow.yxmd",
"tool_ids": [12, 14, 16],
"source_tool_id": 13,
"dry_run": true
}
```
---
#### `rewrite_connections`
```python
rewrite_connections(
workflow: str, # Path to .yxmd file
config: str, # Path to JSON config
dry_run: bool = False
) -> str
```
Config JSON format:
```json
{
"connections": {
"old-uuid-1": {
"new_id": "new-uuid-1",
"old_label": "dev-db",
"new_label": "prod-db"
}
}
}
```
---
### Row Limit Tools
#### `get_row_limit`
```python
get_row_limit(
workflow: str,
tool_id: int
) -> str
```
**Example**:
```json
{
"workflow": "path/to/workflow.yxmd",
"tool_id": 10
}
```
#### `update_row_limit`
```python
update_row_limit(
workflow: str,
tool_id: int,
first_n: int | None = None,
last_n: int | None = None,
sample_n: int | None = None,
dry_run: bool = False
) -> str
```
**Example**:
```json
{
"workflow": "path/to/workflow.yxmd",
"tool_id": 10,
"first_n": 500,
"dry_run": false
}
```
#### `batch_update_row_limits`
```python
batch_update_row_limits(
workflow: str,
tool_ids: List[int] | None = None,
plugin_type: str | None = None,
first_n: int | None = None,
last_n: int | None = None,
sample_n: int | None = None,
dry_run: bool = False
) -> str
```
**Example**:
```json
{
"workflow": "path/to/workflow.yxmd",
"plugin_type": "Sample",
"first_n": 1000,
"dry_run": false
}
```
---
### Creation Tools
#### `create_workflow`
```python
create_workflow(
output_path: str, # Where to save .yxmd
tools_config: str, # JSON array of tool configs
connections: str | None, # Optional JSON array of connections
metadata: str | None # Optional JSON dict of metadata
) -> str
```
**Example - Create simple workflow**:
```json
{
"output_path": "c:/temp/new_workflow.yxmd",
"tools_config": "[{\"tool_id\": 1, \"plugin\": \"TextInput\", \"position\": {\"x\": 100, \"y\": 100}, \"configuration\": {\"Text\": \"Hello World\"}, \"annotation\": \"Data source\"}, {\"tool_id\": 2, \"plugin\": \"Browse\", \"position\": {\"x\": 300, \"y\": 100}, \"annotation\": \"View output\"}]",
"connections": "[{\"origin\": 1, \"destination\": 2}]",
"metadata": "{\"Name\": \"My Workflow\", \"Description\": \"Auto-generated test workflow\"}"
}
```
Tool configuration structure:
```typescript
{
tool_id?: number, // Optional, defaults to index
plugin: string, // Plugin type name
position: {x: number, y: number},
configuration: object, // Tool-specific config
annotation?: string // Optional annotation
}
```
Connection structure:
```typescript
{
origin: number, // Source tool ID
destination: number, // Target tool ID
origin_connection?: string, // Default: "Output"
destination_connection?: string // Default: "Input"
}
```
---
## MCP Client Configuration
Point your MCP client (e.g., GitHub Copilot, Claude Desktop) to launch the script on stdio:
```json
{
"mcpServers": {
"alteryx": {
"command": "alteryx-mcp",
"args": []
}
}
}
```
Or with full path:
```json
{
"mcpServers": {
"alteryx": {
"command": "python",
"args": ["-m", "alteryx_mcp.server"]
}
}
}
```
---
## Usage Patterns
### Pattern 1: Find and Update Field Selections
```
1. User: "Find all Select tools in the workflow"
→ find_tools(workflow="...", plugin_type="AlteryxSelect")
2. User: "In tool 375, deselect field IBCONO and rename IBFACI to FACILITY"
→ update_select_tool(workflow="...", tool_id=375,
field_updates='{"IBCONO": {"selected": false},
"IBFACI": {"rename": "FACILITY"}}')
```
### Pattern 2: Update SQL for OCI Compliance
```
1. User: "Show me all database input tools"
→ find_tools(workflow="...", plugin_type="DbFileInput")
2. User: "Update the SQL in tool 12 and remove all comments"
→ update_sql_query(workflow="...", tool_id=12,
new_query="SELECT...", remove_comments=true)
```
### Pattern 3: Change Annotations
```
1. User: "Find tools connected to v12Live"
→ find_tools(workflow="...", annotation_pattern="v12Live")
2. User: "Update annotation for tool 12 to show production connection"
→ update_annotation(workflow="...", tool_id=12,
new_annotation="dcm:prod-oracle\\nQuery=...")
```
### Pattern 4: Create New Workflow
```
User: "Create a workflow that reads from TextInput and shows Browse output"
→ create_workflow(output_path="...",
tools_config='[{"plugin": "TextInput", ...},
{"plugin": "Browse", ...}]',
connections='[{"origin": 1, "destination": 2}]')
```
---
## Advanced Features
### OCI Compliance
All SQL operations automatically handle Oracle Instant Client requirements:
- Removes `--` style comments (not supported in OCI)
- Preserves multi-line queries
- Maintains query formatting
### Dry Run Mode
All editing tools support `dry_run=true` to preview changes without writing to disk.
### Pattern Matching
The MCP uses efficient XML pattern matching to locate tools:
- By Plugin type (partial match supported)
- By ToolID (exact match)
- By annotation text (case-insensitive substring)
### Container Support
Tools within containers are fully supported:
- Search recurses into nested containers
- Container paths preserved in results
- Edits work on tools at any depth
---
## Architecture
```
alteryx-mcp/
├── alteryx_mcp/
│ ├── server.py # MCP FastMCP server exposing 8 tools
│ └── __init__.py
├── pyproject.toml # Package metadata
└── README.md # This file
```
The server is a thin wrapper around `alteryx_mcp.py` which provides:
- XML parsing and manipulation
- Tool configuration updates
- Workflow creation
- Safe file writing with proper encoding
---
## Troubleshooting
**Tool not found**: Verify ToolID exists using `find_tools()`
**SQL comments not removed**: Ensure `remove_comments=true` is set
**Workflow won't open in Alteryx**: Check XML formatting; use dry_run first
**Connection update failed**: Verify UUID format for connection IDs
**Field not updated**: Check exact field name spelling (case-sensitive)
---
## Contributing
This MCP server is part of the Alteryx MCP project. To extend:
1. Add new functions to `alteryx_mcp/alteryx_mcp.py`
2. Expose via `@mcp.tool()` decorators in `server.py`
3. Update this README with examples
4. Test with real workflows
---
## License
Internal tool for Alteryx MCP project use.
This server cannot be deployed
Maintenance
ActivityInactive
ResponsivenessNo issues