Custom MCP Clients
Goal: Build your own MCP client to query OpenIndustrial data.
MCP Protocol Basics
MCP uses JSON-RPC 2.0 over stdio or HTTP:
{
"jsonrpc": "2.0",
"method": "tools/call",
"params": {
"name": "query_temperature_avg",
"arguments": {
"timeRange": "1h"
}
},
"id": 1
}
Response:
{
"jsonrpc": "2.0",
"result": {
"content": [
{
"type": "text",
"text": "{\"avg_temp\": 72.5, \"min\": 68.2, \"max\": 76.1}"
}
]
},
"id": 1
}
Option 1: Use the SDK
Install the OpenIndustrial MCP SDK:
npm install @openindustrial/mcp-client
TypeScript Example
import { OpenIndustrialMCP } from '@openindustrial/mcp-client';
const client = new OpenIndustrialMCP({
workspaceId: 'your-workspace-id',
token: process.env.OI_API_TOKEN
});
// List available tools
const tools = await client.listTools();
console.log('Available queries:', tools.map(t => t.name));
// Call a tool
const result = await client.callTool('query_temperature_avg', {
timeRange: '1h'
});
console.log('Result:', result);
Python Example
from openindustrial import MCPClient
client = MCPClient(
workspace_id='your-workspace-id',
token=os.environ['OI_API_TOKEN']
)
# List available tools
tools = client.list_tools()
print('Available queries:', [t.name for t in tools])
# Call a tool
result = client.call_tool('query_temperature_avg', {'timeRange': '1h'})
print('Result:', result)
Option 2: Direct HTTP
If you can't use the SDK, call the MCP HTTP endpoint directly:
List Tools
curl -X POST https://mcp.openindustrial.co/{workspace-id}/rpc \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{"jsonrpc": "2.0", "method": "tools/list", "id": 1}'
Call Tool
curl -X POST https://mcp.openindustrial.co/{workspace-id}/rpc \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"jsonrpc": "2.0",
"method": "tools/call",
"params": {
"name": "query_temperature_avg",
"arguments": {"timeRange": "1h"}
},
"id": 2
}'
Option 3: Stdio Transport
For subprocess-based integrations:
npx @openindustrial/mcp-server \
--workspace YOUR_WORKSPACE_ID \
--token YOUR_TOKEN
Send JSON-RPC over stdin, receive over stdout.
Tool Discovery
Every warm query exposes its schema:
{
"name": "query_temperature_avg",
"description": "Get average temperature for a time range",
"inputSchema": {
"type": "object",
"properties": {
"timeRange": {
"type": "string",
"description": "Time range (e.g., '1h', '24h', '7d')"
},
"deviceId": {
"type": "string",
"description": "Optional device filter"
}
},
"required": ["timeRange"]
}
}
Thinking Tip:
Tool schemas are auto-generated from your warm query definitions. Change the query, the schema updates.
Building an AI Agent
Example: Autonomous monitoring agent
import { OpenIndustrialMCP } from '@openindustrial/mcp-client';
import { ChatOpenAI } from 'langchain/chat_models/openai';
import { AgentExecutor } from 'langchain/agents';
// Connect to OpenIndustrial
const mcp = new OpenIndustrialMCP({
workspaceId: 'your-workspace-id',
token: process.env.OI_API_TOKEN
});
// Get tools as LangChain format
const tools = await mcp.asLangChainTools();
// Create agent
const agent = AgentExecutor.fromAgentAndTools({
agent: new ChatOpenAI({ model: 'gpt-4' }),
tools: tools
});
// Run autonomous monitoring
const result = await agent.invoke({
input: 'Check all temperature sensors and alert if any are above threshold'
});
Your agent queries governed data. Every call is authenticated, authorized, and audited—even for autonomous operations.
Error Handling
MCP errors follow JSON-RPC conventions:
{
"jsonrpc": "2.0",
"error": {
"code": -32600,
"message": "Invalid Request",
"data": {"detail": "Missing required parameter: timeRange"}
},
"id": 1
}
| Code | Meaning |
|---|---|
| -32600 | Invalid request |
| -32601 | Method not found |
| -32602 | Invalid params |
| -32603 | Internal error |
| -32001 | Authentication failed |
| -32002 | Authorization denied |
Rate Limiting
MCP endpoints are rate-limited:
| Tier | Requests/minute |
|---|---|
| Standard | 60 |
| Professional | 300 |
| Enterprise | Custom |
Handle 429 responses with exponential backoff.
Next Steps
| If you want to... | Go to... |
|---|---|
| Use pre-built integrations | App Makers → |
| Connect Claude Desktop | Claude Desktop → |
| Manage API keys | Secrets → |