Skip to content

MCP (Model Context Protocol)

MCP tools implement the Model Context Protocol — a standard that lets AI agents discover and invoke capabilities at runtime. When you publish an MCP tool, any agent that speaks JSON-RPC 2.0 can list what your tool exposes and call it without needing a custom integration.

MCP tools can be written in Python, JavaScript, or Lua.


How it works

An MCP tool receives a JSON-RPC 2.0 request as its event and must return a JSON-RPC 2.0 response. Your handler is responsible for routing all methods — including initialize.

The platform passes the entire JSON-RPC request to your handler:

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

Your handler must return a matching JSON-RPC response:

{
"jsonrpc": "2.0",
"id": 1,
"result": { ... }
}

Supported methods

Implement whichever methods your MCP server needs:

MethodDescription
initializeHandshake — must be implemented
pingHealth check
tools/listReturn available tools and their schemas
tools/callExecute a specific tool
resources/listList available resources
resources/readRead a specific resource
resources/templates/listList resource templates
prompts/listList available prompts
prompts/getGet a specific prompt
completion/completeHandle completion requests

At minimum implement initialize, tools/list, and tools/call.


Python example

import json
def ok(_id, result):
return {"jsonrpc": "2.0", "id": _id, "result": result}
def err(_id, code, message):
return {"jsonrpc": "2.0", "id": _id, "error": {"code": code, "message": message}}
TOOLS_SPEC = [
{
"name": "echo",
"description": "Echo back the input string.",
"inputSchema": {
"type": "object",
"properties": {"text": {"type": "string"}},
"required": ["text"]
}
}
]
def handle_initialize(req):
return ok(req.get("id"), {
"protocolVersion": "2024-11-05",
"capabilities": {"tools": {}},
"serverInfo": {"name": "my-mcp-server", "version": "1.0.0"}
})
def handle_tools_list(req):
return ok(req.get("id"), {"tools": TOOLS_SPEC})
def handle_tools_call(req):
params = req.get("params", {})
name = params.get("name")
args = params.get("arguments", {})
if name == "echo":
return ok(req.get("id"), {
"content": [{"type": "text", "text": args.get("text", "")}]
})
return err(req.get("id"), -32602, f"Unknown tool: {name}")
METHODS = {
"initialize": handle_initialize,
"tools/list": handle_tools_list,
"tools/call": handle_tools_call,
}
def cortexone_handler(event, context=None):
req = json.loads(event) if isinstance(event, str) else event
if req.get("jsonrpc") != "2.0":
return err(req.get("id"), -32600, "Invalid Request")
handler = METHODS.get(req.get("method"))
if not handler:
return err(req.get("id"), -32601, f"Method not found: {req.get('method')}")
return handler(req)

JavaScript example

function ok(id, result) {
return { jsonrpc: "2.0", id: id, result: result };
}
function err(id, code, message) {
return { jsonrpc: "2.0", id: id, error: { code: code, message: message } };
}
var TOOLS_SPEC = [
{
name: "echo",
description: "Echo back the input string.",
inputSchema: {
type: "object",
properties: { text: { type: "string" } },
required: ["text"]
}
}
];
function handle_initialize(req) {
return ok(req.id, {
protocolVersion: "2024-11-05",
capabilities: { tools: {} },
serverInfo: { name: "my-mcp-server", version: "1.0.0" }
});
}
function handle_tools_list(req) {
return ok(req.id, { tools: TOOLS_SPEC });
}
function handle_tools_call(req) {
var name = req.params.name;
var args = req.params.arguments;
if (name === "echo") {
return ok(req.id, { content: [{ type: "text", text: args.text }] });
}
return err(req.id, -32602, "Unknown tool: " + name);
}
var METHODS = {
"initialize": handle_initialize,
"tools/list": handle_tools_list,
"tools/call": handle_tools_call
};
function cortexone_handler(event) {
var req = typeof event === "string" ? JSON.parse(event) : event;
var handler = METHODS[req.method];
if (!handler) return err(req.id, -32601, "Method not found: " + req.method);
return handler(req);
}

Lua example

local function ok(id, result)
return { jsonrpc = "2.0", id = id, result = result }
end
local function err(id, code, message)
return { jsonrpc = "2.0", id = id, error = { code = code, message = message } }
end
local TOOLS_SPEC = {
{
name = "echo",
description = "Echo back the input string.",
inputSchema = {
type = "object",
properties = { text = { type = "string" } },
required = { "text" }
}
}
}
local function handle_initialize(req)
return ok(req.id, {
protocolVersion = "2024-11-05",
capabilities = { tools = {} },
serverInfo = { name = "my-mcp-server", version = "1.0.0" }
})
end
local function handle_tools_list(req)
return ok(req.id, { tools = TOOLS_SPEC })
end
local function handle_tools_call(req)
local name = req.params.name
local args = req.params.arguments
if name == "echo" then
return ok(req.id, { content = {{ type = "text", text = args.text }} })
end
return err(req.id, -32602, "Unknown tool: " .. tostring(name))
end
local METHODS = {
["initialize"] = handle_initialize,
["tools/list"] = handle_tools_list,
["tools/call"] = handle_tools_call
}
function cortexone_handler(event, context)
local req = type(event) == "string" and json.decode(event) or event
local handler = METHODS[req.method]
if not handler then
return err(req.id, -32601, "Method not found: " .. tostring(req.method))
end
return handler(req)
end

Invoking an MCP tool

MCP tools use the same invoke endpoint as all other tools:

Terminal window
curl 'https://cortexconnect.rival.io/api/v1/functions/{function_id}/{version}/invoke' \
--header 'Authorization: <your_api_key>' \
--header 'Content-Type: application/json' \
--data '{
"event": {
"jsonrpc": "2.0",
"id": 1,
"method": "tools/list",
"params": {}
}
}'

Error codes

CodeMeaning
-32700Parse error — invalid JSON
-32600Invalid request
-32601Method not found
-32602Invalid params
-32603Internal error

Notes

  • Your handler must implement initialize — the platform does not handle it automatically.
  • Return a JSON-RPC error (not an HTTP error) for unknown methods or bad params.
  • MCP tools follow the same pricing, versioning, and publishing workflow as function tools.
  • JavaScript restriction applies: synchronous only, no async/await.