API Integration [WIP - hidden]
This guide covers technical implementation details for integrating with the Jedify MCP Server programmatically.
Architecture Overview
The Jedify MCP Server uses a proxy architecture for secure authentication and communication:
┌─────────────────┐ ┌──────────────────────┐ ┌─────────────────┐
│ Your App │ ────► │ @jedify/mcp-auth │ ────► │ MCP Server │
│ │ MCP │ (Node.js Proxy) │ HTTP │ (Python) │
└─────────────────┘ └──────────────────────┘ └─────────────────┘
│ │
▼ ▼
┌─────────────────┐ ┌─────────────────┐
│ Descope │ │ Jedify API │
│ (OAuth/PKCE) │ │ (Business BI) │
└─────────────────┘ └─────────────────┘
Protocol Specification
The Jedify MCP Server implements the Model Context Protocol specification version 2025-06-18
over HTTP with Server-Sent Events (SSE) transport.
Base URL
Production: https://api.jedify.com/mcp/
Development: http://localhost:8001/mcp/
Transport Protocol
- Protocol: JSON-RPC 2.0 over HTTP
- Transport: HTTP POST to
/mcp/message
endpoint - Streaming: Server-Sent Events at
/mcp/sse
endpoint - Content-Type:
application/json
Authentication Methods
1. OAuth2 with PKCE (Recommended)
The primary authentication method using OAuth2 with PKCE for enhanced security.
Authentication Flow
- Authorization Request
GET https://api.descope.com/oauth2/v1/authorize
?response_type=code
&client_id={PROJECT_ID}
&redirect_uri=http://localhost:8765/callback
&scope=openid
&code_challenge={CODE_CHALLENGE}
&code_challenge_method=S256
&state={RANDOM_STATE}
- Token Exchange
POST https://api.descope.com/oauth2/v1/token
Authorization: Bearer {PROJECT_ID}
Content-Type: application/x-www-form-urlencoded
grant_type=authorization_code
&code={AUTHORIZATION_CODE}
&redirect_uri=http://localhost:8765/callback
&client_id={PROJECT_ID}
&code_verifier={CODE_VERIFIER}
- API Requests
POST https://api.jedify.com/mcp/message
Authorization: Bearer {ID_TOKEN}
Content-Type: application/json
Origin: mcp-server-user-auth
{JSON-RPC payload}
PKCE Implementation
Generate PKCE parameters for secure OAuth2 flow:
// Generate code verifier
const codeVerifier = crypto.randomBytes(32).toString('base64url');
// Generate code challenge
const codeChallenge = crypto
.createHash('sha256')
.update(codeVerifier)
.digest()
.toString('base64url');
2. API Key Authentication
For programmatic access and system integrations.
Request Headers
POST https://api.jedify.com/mcp/message
Authorization: Bearer {API_KEY}
X-User-Email: {USER_EMAIL}
Content-Type: application/json
Origin: mcp-server-api-auth
{JSON-RPC payload}
API Key Format
- Length: 64+ alphanumeric characters
- Scope: Organization-specific access
- Provisioning: Contact your Jedify administrator
JSON-RPC 2.0 Interface
Message Format
All communications follow JSON-RPC 2.0 specification:
{
"jsonrpc": "2.0",
"method": "{METHOD_NAME}",
"params": {
"name": "{TOOL_NAME}",
"arguments": {
"{PARAM}": "{VALUE}"
}
},
"id": "{UNIQUE_ID}"
}
Response Format
{
"jsonrpc": "2.0",
"id": "{UNIQUE_ID}",
"result": {
"content": [
{
"type": "text",
"text": "{RESPONSE_DATA}"
}
]
}
}
Error Format
{
"jsonrpc": "2.0",
"id": "{UNIQUE_ID}",
"error": {
"code": -32001,
"message": "Authentication failed",
"data": {
"error": "authentication_required",
"error_description": "Bearer token required"
}
}
}
Core MCP Methods
Server Initialization
Initialize connection and retrieve server capabilities:
{
"jsonrpc": "2.0",
"method": "initialize",
"params": {},
"id": "init-1"
}
Response:
{
"jsonrpc": "2.0",
"id": "init-1",
"result": {
"protocolVersion": "2025-06-18",
"capabilities": {},
"serverInfo": {
"name": "Jedify Remote MCP Server",
"version": "1.0.0"
},
"instructions": "Detailed usage instructions..."
}
}
List Available Tools
Retrieve all available analysis tools:
{
"jsonrpc": "2.0",
"method": "tools/list",
"params": {},
"id": "tools-1"
}
Execute Tools
Call analysis tools with parameters:
{
"jsonrpc": "2.0",
"method": "tools/call",
"params": {
"name": "contextualize",
"arguments": {}
},
"id": "call-1"
}
Implementation Examples
Node.js Example
import fetch from 'node-fetch';
class JedifyMCPClient {
constructor(baseUrl, authToken, userEmail = null) {
this.baseUrl = baseUrl;
this.authToken = authToken;
this.userEmail = userEmail;
this.messageId = 1;
}
async initialize() {
return this.sendMessage('initialize', {});
}
async listTools() {
return this.sendMessage('tools/list', {});
}
async callTool(toolName, arguments = {}) {
return this.sendMessage('tools/call', {
name: toolName,
arguments: arguments
});
}
async sendMessage(method, params) {
const message = {
jsonrpc: '2.0',
method: method,
params: params,
id: `msg-${this.messageId++}`
};
const headers = {
'Content-Type': 'application/json',
'Authorization': `Bearer ${this.authToken}`,
'Origin': this.userEmail ? 'mcp-server-api-auth' : 'mcp-server-user-auth'
};
if (this.userEmail) {
headers['X-User-Email'] = this.userEmail;
}
const response = await fetch(`${this.baseUrl}/mcp/message`, {
method: 'POST',
headers: headers,
body: JSON.stringify(message)
});
if (!response.ok) {
throw new Error(`HTTP ${response.status}: ${await response.text()}`);
}
return response.json();
}
}
// Usage
const client = new JedifyMCPClient(
'https://api.jedify.com',
'your-auth-token',
'[email protected]' // Required for API key auth
);
// Initialize connection
await client.initialize();
// Get available tools
const tools = await client.listTools();
// Ask a question
const response = await client.callTool('ask_a_single_question', {
question: 'What was our revenue last month?',
dimensions: {}
});
Python Example
import httpx
import json
class JedifyMCPClient:
def __init__(self, base_url: str, auth_token: str, user_email: str = None):
self.base_url = base_url.rstrip('/')
self.auth_token = auth_token
self.user_email = user_email
self.message_id = 1
async def initialize(self):
return await self.send_message('initialize', {})
async def list_tools(self):
return await self.send_message('tools/list', {})
async def call_tool(self, tool_name: str, arguments: dict = None):
return await self.send_message('tools/call', {
'name': tool_name,
'arguments': arguments or {}
})
async def send_message(self, method: str, params: dict):
message = {
'jsonrpc': '2.0',
'method': method,
'params': params,
'id': f'msg-{self.message_id}'
}
self.message_id += 1
headers = {
'Content-Type': 'application/json',
'Authorization': f'Bearer {self.auth_token}',
'Origin': 'mcp-server-api-auth' if self.user_email else 'mcp-server-user-auth'
}
if self.user_email:
headers['X-User-Email'] = self.user_email
async with httpx.AsyncClient() as client:
response = await client.post(
f'{self.base_url}/mcp/message',
headers=headers,
json=message
)
response.raise_for_status()
return response.json()
# Usage
client = JedifyMCPClient(
'https://api.jedify.com',
'your-auth-token',
'[email protected]' # Required for API key auth
)
# Initialize connection
result = await client.initialize()
# Get company information
company_info = await client.call_tool('get_account_info')
# Ask a business question
answer = await client.call_tool('ask_a_single_question', {
'question': 'What are our top 5 revenue-generating products?',
'dimensions': {}
})
Error Handling
Authentication Errors
Error Code: -32001
{
"error": {
"code": -32001,
"message": "Authentication failed",
"data": {
"error": "authentication_required"
}
}
}
Resolution: Refresh OAuth token or verify API key credentials.
Method Not Found
Error Code: -32601
{
"error": {
"code": -32601,
"message": "Method 'invalid_method' not found"
}
}
Internal Server Error
Error Code: -32603
{
"error": {
"code": -32603,
"message": "Internal server error"
}
}
Rate Limiting
The Jedify MCP Server implements rate limiting to ensure fair usage:
- General API calls: 100 requests per minute per user
- Tool executions: 10 concurrent requests per user
- Complex queries: Additional timeout limits apply (up to 15 minutes)
Resources and Prompts
List Resources
{
"jsonrpc": "2.0",
"method": "resources/list",
"params": {},
"id": "resources-1"
}
Read Resource
{
"jsonrpc": "2.0",
"method": "resources/read",
"params": {
"uri": "jedify://analysis-patterns/simple"
},
"id": "read-1"
}
List Prompts
{
"jsonrpc": "2.0",
"method": "prompts/list",
"params": {},
"id": "prompts-1"
}
Security Best Practices
Token Management
- Secure Storage: Store tokens securely, never in plain text
- Token Rotation: Implement automatic token refresh
- Scope Limitation: Use minimal required permissions
- Logout Support: Implement proper session cleanup
Communication Security
- HTTPS Only: Always use encrypted connections
- Certificate Validation: Verify SSL certificates
- Request Signing: Consider additional request signing for sensitive operations
Error Handling
- No Token Logging: Never log authentication tokens
- Error Sanitization: Don't expose internal error details
- Graceful Degradation: Handle authentication failures gracefully
Support and Resources
Technical Support
- API Issues: Contact your Jedify administrator
- Integration Questions: Reach out through your organization's support channel
- Protocol Specification: Model Context Protocol Documentation
Development Resources
- Tools Reference: See Tools Reference for complete tool documentation
- Use Cases: Check Common Use Cases for implementation patterns
- Troubleshooting: Review Troubleshooting Guide for common issues
Next Steps: Explore available tools → | See use case examples →
Updated about 8 hours ago