MALDA™ Reference Manual

The AI-First Programming Language - Version 1.0.11

20. MCP Server

MCP (Model Context Protocol) lets an AI host — Claude Desktop, Cursor, ChatGPT, or a MALDA MCPClient — launch your process and talk JSON-RPC 2.0 over STDIO (stdin/stdout). Decorate ordinary functions with @MCPTool, call new MCPServer().start(), and the host can list and call them. Same file: Examples/MCP/mcp_tools_server.malda.

20.1 A minimal server

@MCPTool("add", "Adds two numbers together")
function add(a, b) {
    return int(a) + int(b);
}

@MCPTool("reverse_string", "Reverses a string")
function reverseString(text) {
    var reversed = "";
    var i = length(text) - 1;
    while (i >= 0) {
        reversed = reversed + substring(text, i, 1);
        i = i - 1;
    }
    return reversed;
}

var server = new MCPServer();
server.start();

while (server.isRunning) {
    sleep(1000);
}

Run it as a normal MALDA program. The host, not you, should start that process when it wants the tools:

malda Examples/MCP/mcp_tools_server.malda

An MCP host config (Claude Desktop claude_desktop_config.json, Cursor mcp.json) looks like this — point command at a malda executable on PATH, or a full path:

{
  "mcpServers": {
    "malda-tools": {
      "command": "malda",
      "args": ["C:/path/to/Examples/MCP/mcp_tools_server.malda"]
    }
  }
}
Do not print banners on stdout after start() if a host is connected: STDIO is the protocol. Log to stderr or a file. The example server in Examples/MCP/ prints before the host handshake in a demo loop; a production server should stay quiet on stdout.

20.2 @MCPTool and schemas

@MCPTool("tool_name", "Tool description")
function myTool(param1, param2) {
    return param1 + param2;
}

If you omit a schema, MALDA builds JSON Schema from the parameter names: every property is type "string" and required. Pass a JSON schema string as the third argument when you need enums, numbers, or optional fields:

@MCPTool("tool_name", "Tool description", "{\"type\":\"object\",\"properties\":{...}}")
function myTool(param1) {
    // ...
}

20.3 MCPServer

var server = new MCPServer();                    // STDIO transport (default)
var server = new MCPServer("stdio");            // Explicit STDIO transport

JSON-RPC methods implemented: initialize, tools/list, tools/call, notifications/initialized.

20.4 MCPClient: call another server

MCPClient starts a child process and speaks the same STDIO protocol. Same file: Examples/MCP/mcp_client_example.malda. Run the client from the repo root so malda can find the server script.

var client = new MCPClient("example-server");
var connected = client.connect("malda", ["Examples/MCP/mcp_tools_server.malda"]);
if (!connected) {
    print("Failed to connect");
    return;
}

var tools = client.getTools();
print("Tool count: " + string(tools.length));

var sum = client.callTool("add", {"a": 5, "b": 3});
print(string(sum));

client.disconnect();

connect(command, args?, env?) returns true on success. callTool(name, arguments?) converts the JSON result to MALDA values. Each tool from getTools() has name, description, and schema.

var client = new MCPClient("my-server");
var connected = client.connect("python", ["-m", "mcp_server"], {"API_KEY": "secret"});

20.5 Wrapper agent (optional)

createWrapperAgent builds an Agent with every tool from the connected server already attached. If you omit llmClient, MALDA uses a local GGUF model (downloaded on first use). Prefer the callTool example above until you need an LLM in the loop.

var mcpClient = new MCPClient("example-server");
mcpClient.connect("malda", ["Examples/MCP/mcp_tools_server.malda"]);

var agent = mcpClient.createWrapperAgent(
    "Helper",
    "assistant",
    "You use MCP tools to answer questions."
);

var response = agent.think("Add 5 and 3");
print(response.content);
mcpClient.disconnect();

20.6 Advanced: generate a script

createMcpAgentScript(agentName, agentRole, agentInstructions, tools, outputPath, model?) writes a .malda file that exposes an agent as MCP tools. That is a code generator, not a live STDIO session — prefer callTool or createWrapperAgent until you need to emit a file. Pair it with MALDACodingAgent in 18. Agent Orchestration and compileMALDA in 13. Built-in Functions only when an agent should generate and compile MALDA.

See Also