User GuidesConsuming MCP via REST API

Consuming MCP via REST API

Learn how to consume MCP endpoints as REST APIs from any programming language or platform.

Overview

MA²D MCP servers expose HTTP endpoints that follow the JSON-RPC 2.0 specification. You can call these endpoints from any language or tool that supports HTTP requests.

Basic Concepts

Endpoint Structure

https://ma2d.vercel.app/api/platform/{serverId}/mcp

Request Format

All requests use:

  • Method: POST
  • Content-Type: application/json
  • Body: JSON-RPC 2.0 format

Response Format

Responses follow JSON-RPC 2.0:

  • Success: Contains result field
  • Error: Contains error field with code and message

Quick Start Examples

Choose your language to see how to call MCP endpoints:

cURL

curl -X POST https://ma2d.vercel.app/api/platform/YOUR_SERVER_ID/mcp \
  -H "Content-Type: application/json" \
  -d '{
    "jsonrpc": "2.0",
    "id": 1,
    "method": "tools/list"
  }'

JavaScript / TypeScript

const response = await fetch(
  'https://ma2d.vercel.app/api/platform/YOUR_SERVER_ID/mcp',
  {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({
      jsonrpc: '2.0',
      id: 1,
      method: 'tools/list'
    })
  }
)
 
const data = await response.json()
console.log(data.result)

Python

import requests
 
response = requests.post(
    'https://ma2d.vercel.app/api/platform/YOUR_SERVER_ID/mcp',
    json={
        'jsonrpc': '2.0',
        'id': 1,
        'method': 'tools/list'
    }
)
 
data = response.json()
print(data['result'])

Go

import (
    "bytes"
    "encoding/json"
    "net/http"
)
 
body, _ := json.Marshal(map[string]interface{}{
    "jsonrpc": "2.0",
    "id":      1,
    "method":  "tools/list",
})
 
resp, _ := http.Post(
    "https://ma2d.vercel.app/api/platform/YOUR_SERVER_ID/mcp",
    "application/json",
    bytes.NewBuffer(body),
)

Java

import java.net.http.*;
 
var request = HttpRequest.newBuilder()
    .uri(URI.create("https://ma2d.vercel.app/api/platform/YOUR_SERVER_ID/mcp"))
    .header("Content-Type", "application/json")
    .POST(HttpRequest.BodyPublishers.ofString("""
        {
          "jsonrpc": "2.0",
          "id": 1,
          "method": "tools/list"
        }
    """))
    .build();
 
var response = HttpClient.newHttpClient()
    .send(request, HttpResponse.BodyHandlers.ofString());

Available Methods

List Tools

Get all available tools:

Request:

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/list"
}

Response:

{
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    "tools": [
      {
        "name": "get_weather",
        "description": "Get current weather...",
        "inputSchema": { /* JSON Schema */ }
      }
    ]
  }
}

Call a Tool

Execute a specific tool:

Request:

{
  "jsonrpc": "2.0",
  "id": 2,
  "method": "tools/call",
  "params": {
    "name": "get_weather",
    "arguments": {
      "city": "San Francisco"
    }
  }
}

Response:

{
  "jsonrpc": "2.0",
  "id": 2,
  "result": {
    "content": [{
      "type": "text",
      "text": "{\"temperature\": 65, ...}"
    }]
  }
}

List Resources

Get available resources:

{
  "jsonrpc": "2.0",
  "id": 3,
  "method": "resources/list"
}

Read a Resource

Access resource content:

{
  "jsonrpc": "2.0",
  "id": 4,
  "method": "resources/read",
  "params": {
    "uri": "weather://cities/supported"
  }
}

Complete Examples

JavaScript/TypeScript Client

class MCPClient {
  private endpoint: string
  private requestId: number = 1
 
  constructor(serverId: string) {
    this.endpoint = `https://ma2d.vercel.app/api/platform/${serverId}/mcp`
  }
 
  private async request(method: string, params?: any) {
    const response = await fetch(this.endpoint, {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({
        jsonrpc: '2.0',
        id: this.requestId++,
        method,
        params
      })
    })
 
    const data = await response.json()
    
    if (data.error) {
      throw new Error(`MCP Error: ${data.error.message}`)
    }
    
    return data.result
  }
 
  async listTools() {
    return await this.request('tools/list')
  }
 
  async callTool(name: string, arguments: any) {
    return await this.request('tools/call', { name, arguments })
  }
 
  async listResources() {
    return await this.request('resources/list')
  }
 
  async readResource(uri: string) {
    return await this.request('resources/read', { uri })
  }
}
 
// Usage
const client = new MCPClient('YOUR_SERVER_ID')
const tools = await client.listTools()
const result = await client.callTool('get_weather', { city: 'San Francisco' })

Python Client

import requests
from typing import Any, Dict, Optional
 
class MCPClient:
    def __init__(self, server_id: str):
        self.endpoint = f'https://ma2d.vercel.app/api/platform/{server_id}/mcp'
        self.request_id = 1
 
    def _request(self, method: str, params: Optional[Dict] = None) -> Any:
        payload = {
            'jsonrpc': '2.0',
            'id': self.request_id,
            'method': method
        }
        
        if params:
            payload['params'] = params
        
        self.request_id += 1
        
        response = requests.post(self.endpoint, json=payload)
        data = response.json()
        
        if 'error' in data:
            raise Exception(f"MCP Error: {data['error']['message']}")
        
        return data['result']
 
    def list_tools(self):
        return self._request('tools/list')
 
    def call_tool(self, name: str, arguments: Dict):
        return self._request('tools/call', {'name': name, 'arguments': arguments})
 
    def list_resources(self):
        return self._request('resources/list')
 
    def read_resource(self, uri: str):
        return self._request('resources/read', {'uri': uri})
 
# Usage
client = MCPClient('YOUR_SERVER_ID')
tools = client.list_tools()
result = client.call_tool('get_weather', {'city': 'San Francisco'})

Go Client

package main
 
import (
    "bytes"
    "encoding/json"
    "fmt"
    "io"
    "net/http"
)
 
type MCPClient struct {
    endpoint  string
    requestID int
}
 
type Request struct {
    JSONRPC string      `json:"jsonrpc"`
    ID      int         `json:"id"`
    Method  string      `json:"method"`
    Params  interface{} `json:"params,omitempty"`
}
 
type Response struct {
    JSONRPC string      `json:"jsonrpc"`
    ID      int         `json:"id"`
    Result  interface{} `json:"result,omitempty"`
    Error   *RPCError   `json:"error,omitempty"`
}
 
type RPCError struct {
    Code    int    `json:"code"`
    Message string `json:"message"`
}
 
func NewMCPClient(serverID string) *MCPClient {
    return &MCPClient{
        endpoint:  fmt.Sprintf("https://ma2d.vercel.app/api/platform/%s/mcp", serverID),
        requestID: 1,
    }
}
 
func (c *MCPClient) request(method string, params interface{}) (interface{}, error) {
    req := Request{
        JSONRPC: "2.0",
        ID:      c.requestID,
        Method:  method,
        Params:  params,
    }
    c.requestID++
 
    body, _ := json.Marshal(req)
    resp, err := http.Post(c.endpoint, "application/json", bytes.NewBuffer(body))
    if err != nil {
        return nil, err
    }
    defer resp.Body.Close()
 
    var result Response
    json.NewDecoder(resp.Body).Decode(&result)
 
    if result.Error != nil {
        return nil, fmt.Errorf("MCP Error: %s", result.Error.Message)
    }
 
    return result.Result, nil
}
 
func (c *MCPClient) ListTools() (interface{}, error) {
    return c.request("tools/list", nil)
}
 
func (c *MCPClient) CallTool(name string, arguments map[string]interface{}) (interface{}, error) {
    return c.request("tools/call", map[string]interface{}{
        "name":      name,
        "arguments": arguments,
    })
}
 
// Usage
func main() {
    client := NewMCPClient("YOUR_SERVER_ID")
    tools, _ := client.ListTools()
    result, _ := client.CallTool("get_weather", map[string]interface{}{
        "city": "San Francisco",
    })
}

Error Handling

Handle errors properly in each language:

JavaScript

try {
  const result = await client.callTool('get_weather', { city: 'SF' })
} catch (error) {
  if (error.code === -32602) {
    console.error('Invalid parameters')
  } else if (error.code === -32601) {
    console.error('Method not found')
  } else {
    console.error('Unknown error:', error)
  }
}

Python

try:
    result = client.call_tool('get_weather', {'city': 'SF'})
except Exception as e:
    if '-32602' in str(e):
        print('Invalid parameters')
    elif '-32601' in str(e):
        print('Method not found')
    else:
        print(f'Unknown error: {e}')

Go

result, err := client.CallTool("get_weather", map[string]interface{}{
    "city": "SF",
})
if err != nil {
    if strings.Contains(err.Error(), "-32602") {
        fmt.Println("Invalid parameters")
    } else if strings.Contains(err.Error(), "-32601") {
        fmt.Println("Method not found")
    } else {
        fmt.Printf("Unknown error: %v\n", err)
    }
}

Authentication

If your MCP server requires authentication:

const response = await fetch(endpoint, {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'Authorization': 'Bearer YOUR_TOKEN'
  },
  body: JSON.stringify(request)
})

Best Practices

  1. Reuse Connections - Keep HTTP client instances
  2. Handle Errors - Always check for error field
  3. Validate Inputs - Check against tool schemas
  4. Set Timeouts - Prevent hanging requests
  5. Log Requests - Debug easier with logs

Next Steps


Start consuming MCP endpoints from any platform or language! 🚀