Model Context Protocol (MCP) server for KeeperHub that enables AI agents to create, manage, and execute blockchain automation workflows.
- Full CRUD operations for workflows (create, read, update, delete)
- AI-powered workflow generation via natural language prompts
- Async execution with status polling and log retrieval
- MCP Resources for exposing workflow definitions
- API Key authentication for secure access
# Build the Docker image
docker build -t keeperhub-mcp .
# Run the server
docker run -i --rm \
-e KEEPERHUB_API_KEY=your_api_key_here \
keeperhub-mcp# Install dependencies
pnpm install
# Build the project
pnpm build
# Run the server
KEEPERHUB_API_KEY=your_api_key_here pnpm start# Run with tsx for hot reloading
KEEPERHUB_API_KEY=your_api_key_here pnpm devThe server requires the following environment variables:
| Variable | Description | Required | Default |
|---|---|---|---|
KEEPERHUB_API_KEY |
Your KeeperHub API key | Yes | - |
KEEPERHUB_API_URL |
KeeperHub API base URL | No | https://app.keeperhub.com |
PORT |
Port for HTTP/SSE mode (leave unset for stdio) | No | - |
MCP_API_KEY |
API key for authenticating MCP requests (required if PORT is set) | No | - |
The server supports two transport modes:
- Stdio Mode (default): For local AI clients using stdin/stdout communication
- HTTP/SSE Mode: For remote AI agents using Server-Sent Events over HTTP
To enable HTTP mode, set the PORT environment variable. When running in HTTP mode, you must also set MCP_API_KEY for authentication.
Add this to your MCP client configuration (e.g., Claude Code config):
{
"mcpServers": {
"keeperhub": {
"command": "docker",
"args": [
"run",
"-i",
"--rm",
"-e",
"KEEPERHUB_API_KEY",
"keeperhub-mcp"
]
}
}
}Or for local development:
{
"mcpServers": {
"keeperhub": {
"command": "node",
"args": [
"/absolute/path/to/keeperhub-mcp/dist/index.js"
],
"env": {
"KEEPERHUB_API_KEY": "your_api_key_here"
}
}
}
}For remote AI agents, run the server in HTTP mode:
# Using Node.js
PORT=3000 \
MCP_API_KEY=your_secure_mcp_key \
KEEPERHUB_API_KEY=your_keeperhub_key \
pnpm startOr using Docker:
docker run -p 3000:3000 \
-e PORT=3000 \
-e MCP_API_KEY=your_secure_mcp_key \
-e KEEPERHUB_API_KEY=your_keeperhub_key \
keeperhub-mcpThe server will expose the following endpoints:
GET /health- Health check endpointGET /sse- Server-Sent Events endpoint for MCP protocolPOST /message- Message endpoint for client requests
All HTTP requests must include an Authorization header with a Bearer token:
Authorization: Bearer your_secure_mcp_keycurl -H "Authorization: Bearer your_secure_mcp_key" \
http://localhost:3000/healthList workflows in the organization.
Parameters:
limit(optional): Maximum number of workflows to returnoffset(optional): Number of workflows to skipproject_id(optional): Filter by project ID (uselist_projectsto discover IDs)tag_id(optional): Filter by tag ID (uselist_tagsto discover IDs)
Example:
{
"limit": 10,
"offset": 0,
"project_id": "proj_abc123",
"tag_id": "tag_xyz789"
}Get workflow details by ID.
Parameters:
workflow_id(required): The ID of the workflow to retrieve
Example:
{
"workflow_id": "wf_abc123"
}Create a new workflow.
Parameters:
name(required): Name of the workflowdescription(optional): Optional descriptionproject_id(optional): Project ID to assign (uselist_projectsto discover IDs)tag_id(optional): Tag ID to assign (uselist_tagsto discover IDs)nodes(optional): Workflow nodes arrayedges(optional): Workflow edges array
Example:
{
"name": "My Workflow",
"description": "A simple workflow",
"project_id": "proj_abc123",
"tag_id": "tag_xyz789",
"nodes": [
{
"id": "1",
"type": "trigger",
"data": { "type": "manual" }
}
],
"edges": []
}Update workflow nodes/edges.
Parameters:
workflow_id(required): The ID of the workflow to updatename(optional): New name for the workflowdescription(optional): New descriptionproject_id(optional): Project ID to assign (nullto unassign)tag_id(optional): Tag ID to assign (nullto unassign)nodes(optional): Updated workflow nodesedges(optional): Updated workflow edges
Example:
{
"workflow_id": "wf_abc123",
"name": "Updated Workflow Name",
"project_id": "proj_abc123",
"nodes": [...]
}Delete a workflow.
Parameters:
workflow_id(required): The ID of the workflow to delete
Example:
{
"workflow_id": "wf_abc123"
}AI-powered workflow generation from natural language.
Parameters:
prompt(required): Natural language description of the workflowexisting_workflow_id(optional): ID of an existing workflow to modify
Example:
{
"prompt": "Create a workflow that monitors Ethereum wallet balance and sends a Discord notification when it changes"
}Start async execution of a workflow.
Parameters:
workflow_id(required): The ID of the workflow to executeinput(optional): Input data for the workflow
Example:
{
"workflow_id": "wf_abc123",
"input": {
"walletAddress": "0x1234..."
}
}Poll execution status.
Parameters:
execution_id(required): The ID of the execution to check
Example:
{
"execution_id": "exec_xyz789"
}Get execution logs.
Parameters:
execution_id(required): The ID of the execution to get logs for
Example:
{
"execution_id": "exec_xyz789"
}List all projects in the organization.
Parameters: none
Example:
{}List all tags in the organization.
Parameters: none
Example:
{}Send ETH or ERC-20 tokens directly without creating a workflow.
Parameters:
network(required): Blockchain network (e.g., "ethereum", "polygon", "base")recipient_address(required): Destination wallet addressamount(required): Amount in human-readable units (e.g., "0.1")token_address(optional): ERC-20 contract address; omit for native transfers
Example:
{
"network": "sepolia",
"recipient_address": "0xRecipient...",
"amount": "0.01"
}Call any smart contract function directly. Auto-detects read vs write.
Parameters:
contract_address(required): Target contract addressnetwork(required): Blockchain networkfunction_name(required): Function to callfunction_args(optional): Arguments as JSON array stringabi(optional): ABI JSON string; auto-fetched if omitted
Read a contract value, evaluate a condition, and execute a write if met.
Parameters:
contract_address(required): Contract to readnetwork(required): Blockchain networkfunction_name(required): Read function for conditioncondition(required):{operator, value}— operators: eq, neq, gt, lt, gte, lteaction(required):{contract_address, function_name, ...}write to execute if condition is met
Check status of a direct execution. Returns tx hash and block explorer link.
Parameters:
execution_id(required): ID returned from a direct execution call
Returns a list of all workflows in the organization.
URI: keeperhub://workflows
MIME Type: application/json
Returns details for a specific workflow.
URI: keeperhub://workflows/{workflow_id}
MIME Type: application/json
To use this MCP server, you need to generate an API key from the KeeperHub application:
- Log in to app.keeperhub.com
- Navigate to Organization Settings
- Go to the API Keys section
- Click "Create API Key"
- Give it a name and copy the key (it will only be shown once)
- Use the key in the
KEEPERHUB_API_KEYenvironment variable
keeperhub-mcp/
├── src/
│ ├── index.ts # MCP server entry point
│ ├── http-server.ts # HTTP/SSE transport server
│ ├── tools/
│ │ ├── index.ts # Tool exports
│ │ ├── workflows.ts # Workflow CRUD tools
│ │ ├── executions.ts # Execution tools
│ │ └── generate.ts # AI generation tool
│ ├── resources/
│ │ ├── index.ts # Resource exports
│ │ └── workflows.ts # Workflow resources
│ ├── client/
│ │ └── keeperhub.ts # KeeperHub API client
│ └── types/
│ └── index.ts # Type definitions
├── Dockerfile
├── package.json
├── tsconfig.json
├── .gitignore
└── README.md
pnpm buildpnpm type-checkdocker build -t keeperhub-mcp .All tools return errors in the following format:
{
"content": [
{
"type": "text",
"text": "Error: <error message>"
}
],
"isError": true
}Common errors:
401 Unauthorized: Invalid or missing API key404 Not Found: Workflow or execution not found400 Bad Request: Invalid parameters500 Internal Server Error: Server error
- API keys are transmitted via Bearer authentication
- Keys are scoped to a single organization
- All communication with KeeperHub API is over HTTPS
- Keys are never logged or exposed in error messages
MIT
For issues or questions:
- GitHub Issues: techops-services/keeperhub-mcp
- Documentation: KeeperHub Docs