GuidesDiscussions
Guides

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

  1. 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}
  1. 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}
  1. 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


Next Steps: Explore available tools → | See use case examples →