char-fork/llama.cpp
git clone https://git.t4t.associates/char-fork/llama.cpp
20455a4ad
char/aliceai-t5-moe
1#!/usr/bin/env python3 2""" 3Minimal MCP server for testing. 4Implements JSON-RPC 2.0 over stdio (line-delimited JSON). 5""" 6import json 7import sys 8import os 9 10# Ensure we use python3 from the current environment 11if sys .platform == "win32" : 12# On Windows, we need to use the same python interpreter 13pass 14 15TOOLS = [ 16 { 17"name" :"echo" , 18"description" :"Echo back the input message" , 19"inputSchema" : { 20"type" :"object" , 21"properties" : { 22"message" : {"type" :"string" ,"description" :"Message to echo" } 23 }, 24"required" : ["message" ] 25 } 26 }, 27 { 28"name" :"add" , 29"description" :"Add two numbers" , 30"inputSchema" : { 31"type" :"object" , 32"properties" : { 33"a" : {"type" :"number" }, 34"b" : {"type" :"number" } 35 }, 36"required" : ["a" ,"b" ] 37 } 38 }, 39 { 40"name" :"fail_once" , 41"description" :"Fails on first call, succeeds on subsequent calls" , 42"inputSchema" : { 43"type" :"object" , 44"properties" : {} 45 } 46 } 47] 48 49_state = {"fail_once_called" :False } 50 51def handle_initialize (params ,req_id ): 52return { 53"jsonrpc" :"2.0" , 54"id" :req_id , 55"result" : { 56"protocolVersion" :"2024-11-05" , 57"capabilities" : {"tools" : {}}, 58"serverInfo" : {"name" :"echo-test" ,"version" :"1.0" } 59 } 60 } 61 62def handle_tools_list (params ,req_id ): 63return { 64"jsonrpc" :"2.0" , 65"id" :req_id , 66"result" : {"tools" :TOOLS } 67 } 68 69def handle_tools_call (params ,req_id ): 70tool_name = params .get ("name" ) 71arguments = params .get ("arguments" , {}) 72 73if tool_name == "echo" : 74message = arguments .get ("message" ,"" ) 75return { 76"jsonrpc" :"2.0" , 77"id" :req_id , 78"result" : { 79"content" : [{"type" :"text" ,"text" :f"echo: { message } " }] 80 } 81 } 82elif tool_name == "add" : 83a = arguments .get ("a" ,0 ) 84b = arguments .get ("b" ,0 ) 85return { 86"jsonrpc" :"2.0" , 87"id" :req_id , 88"result" : { 89"content" : [{"type" :"text" ,"text" :str (a + b )}] 90 } 91 } 92elif tool_name == "fail_once" : 93if not _state ["fail_once_called" ]: 94_state ["fail_once_called" ]= True 95return { 96"jsonrpc" :"2.0" , 97"id" :req_id , 98"error" : {"code" :- 32000 ,"message" :"transient error" } 99 } 100return { 101"jsonrpc" :"2.0" , 102"id" :req_id , 103"result" : { 104"content" : [{"type" :"text" ,"text" :"ok" }] 105 } 106 } 107else : 108return { 109"jsonrpc" :"2.0" , 110"id" :req_id , 111"error" : {"code" :- 32602 ,"message" :f"Unknown tool: { tool_name } " } 112 } 113 114def handle_ping (params ,req_id ): 115return { 116"jsonrpc" :"2.0" , 117"id" :req_id , 118"result" : {} 119 } 120 121HANDLERS = { 122"initialize" :handle_initialize , 123"tools/list" :handle_tools_list , 124"tools/call" :handle_tools_call , 125"ping" :handle_ping , 126} 127 128def main (): 129# Use unbuffered output 130sys .stdout = os .fdopen (sys .stdout .fileno (),"w" ,buffering = 1 ) 131sys .stderr = os .fdopen (sys .stderr .fileno (),"w" ,buffering = 1 ) 132 133for line in sys .stdin : 134line = line .strip () 135if not line : 136continue 137try : 138request = json .loads (line ) 139except json .JSONDecodeError : 140continue 141 142method = request .get ("method" ) 143req_id = request .get ("id" ) 144params = request .get ("params" , {}) 145 146# JSON-RPC 2.0: a message without an id is a notification and must not receive a response 147if req_id is None : 148continue 149 150handler = HANDLERS .get (method ) 151if handler : 152response = handler (params ,req_id ) 153else : 154response = { 155"jsonrpc" :"2.0" , 156"id" :req_id , 157"error" : {"code" :- 32601 ,"message" :f"Method not found: { method } " } 158 } 159 160sys .stdout .write (json .dumps (response )+ "\n" ) 161sys .stdout .flush () 162 163if __name__ == "__main__" : 164main ()