SimpleSallap:SimpleMCP:Move towards post json based flow

This commit is contained in:
hanishkvc 2025-12-06 19:46:19 +05:30
parent 1db3a80f40
commit 0a445c875b
2 changed files with 33 additions and 43 deletions

View File

@ -60,6 +60,7 @@ class Network(DictyDataclassMixin):
""" """
port: int = 3128 port: int = 3128
addr: str = '' addr: str = ''
maxReadBytes: int = 1*1024*1024
def server_address(self): def server_address(self):
return (self.addr, self.port) return (self.addr, self.port)

View File

@ -1,20 +1,13 @@
# A simple proxy server # A simple mcp server with a bunch of bundled tool calls
# by Humans for All # by Humans for All
# #
# Listens on the specified port (defaults to squids 3128) # Listens on the specified port (defaults to squids 3128)
# * if a url query is got wrt urlraw path # * return the supported tool calls meta data when requested
# http://localhost:3128/urlraw?url=http://site.of.interest/path/of/interest # * execute the requested tool call and return the results
# fetches the contents of the specified url and returns the same to the requester
# * if a url query is got wrt urltext path
# http://localhost:3128/urltext?url=http://site.of.interest/path/of/interest
# fetches the contents of the specified url and returns the same to the requester
# after removing html tags in general as well as contents of tags like style
# script, header, footer, nav ...
# * any request to aum path is used to respond with a predefined text response # * any request to aum path is used to respond with a predefined text response
# which can help identify this server, in a simple way. # which can help identify this server, in a simple way.
# #
# Expects a Bearer authorization line in the http header of the requests got. # Expects a Bearer authorization line in the http header of the requests got.
# HOWEVER DO KEEP IN MIND THAT ITS A VERY INSECURE IMPLEMENTATION, AT BEST
# #
@ -24,9 +17,11 @@ import urllib.parse
import time import time
import ssl import ssl
import traceback import traceback
import json
from typing import Callable from typing import Callable
import pdfmagic as mPdf import tcpdf as mTCPdf
import webmagic as mWeb import tcweb as mTCWeb
import toolcall as mTC
import config as mConfig import config as mConfig
@ -89,60 +84,56 @@ class ProxyHandler(http.server.BaseHTTPRequestHandler):
bearer_transform() bearer_transform()
authline = self.headers['Authorization'] authline = self.headers['Authorization']
if authline == None: if authline == None:
return { 'AllOk': False, 'Msg': "No auth line" } return mTC.TCOutResponse(False, 400, "WARN:No auth line")
authlineA = authline.strip().split(' ') authlineA = authline.strip().split(' ')
if len(authlineA) != 2: if len(authlineA) != 2:
return { 'AllOk': False, 'Msg': "Invalid auth line" } return mTC.TCOutResponse(False, 400, "WARN:Invalid auth line")
if authlineA[0] != 'Bearer': if authlineA[0] != 'Bearer':
return { 'AllOk': False, 'Msg': "Invalid auth type" } return mTC.TCOutResponse(False, 400, "WARN:Invalid auth type")
if authlineA[1] != gMe.op.bearerTransformed: if authlineA[1] != gMe.op.bearerTransformed:
return { 'AllOk': False, 'Msg': "Invalid auth" } return mTC.TCOutResponse(False, 400, "WARN:Invalid auth")
return { 'AllOk': True, 'Msg': "Auth Ok" } return mTC.TCOutResponse(True, 200, "Auth Ok")
def auth_and_run(self, pr:urllib.parse.ParseResult, handler:Callable[['ProxyHandler', urllib.parse.ParseResult], None]): def auth_and_run(self, pr:urllib.parse.ParseResult, handler:Callable[['ProxyHandler', urllib.parse.ParseResult], None]):
""" """
If authorisation is ok for the request, run the specified handler. If authorisation is ok for the request, run the specified handler.
""" """
acGot = self.auth_check() acGot = self.auth_check()
if not acGot['AllOk']: if not acGot.callOk:
self.send_error(400, f"WARN:{acGot['Msg']}") self.send_error(acGot.statusCode, acGot.statusMsg)
else: else:
try: try:
handler(self, pr) handler(self, pr)
except Exception as e: except Exception as e:
self.send_error(400, f"ERRR:ProxyHandler:{e}") self.send_error(400, f"ERRR:ProxyHandler:{e}")
def _do_GET(self): def _do_POST(self):
""" """
Handle GET requests Handle POST requests
""" """
print(f"DBUG:ProxyHandler:GET:{self.address_string()}:{self.path}") print(f"DBUG:PH:Post:{self.address_string()}:{self.path}")
print(f"DBUG:PH:Get:Headers:{self.headers}") print(f"DBUG:PH:Post:Headers:{self.headers}")
acGot = self.auth_check()
if not acGot.callOk:
self.send_error(acGot.statusCode, acGot.statusMsg)
pr = urllib.parse.urlparse(self.path) pr = urllib.parse.urlparse(self.path)
print(f"DBUG:ProxyHandler:GET:{pr}") print(f"DBUG:ProxyHandler:GET:{pr}")
match pr.path: if pr.path != '/mcp':
case '/urlraw': self.send_error(400, f"WARN:UnknownPath:{pr.path}")
self.auth_and_run(pr, mWeb.handle_urlraw) body = self.rfile.read(gMe.nw.maxReadBytes)
case '/htmltext': if len(body) == gMe.nw.maxReadBytes:
self.auth_and_run(pr, mWeb.handle_htmltext) self.send_error(400, f"WARN:RequestOverflow:{pr.path}")
case '/xmlfiltered': oRPC = json.loads(body)
self.auth_and_run(pr, mWeb.handle_xmlfiltered)
case '/pdftext':
self.auth_and_run(pr, mPdf.handle_pdftext)
case '/aum':
handle_aum(self, pr)
case _:
print(f"WARN:ProxyHandler:GET:UnknownPath{pr.path}")
self.send_error(400, f"WARN:UnknownPath:{pr.path}")
def do_GET(self):
def do_POST(self):
""" """
Catch all / trap any exceptions wrt actual get based request handling. Catch all / trap any exceptions wrt actual post based request handling.
""" """
try: try:
self._do_GET() self._do_POST()
except: except:
print(f"ERRR:PH:TheGET:{traceback.format_exception_only(sys.exception())}") print(f"ERRR:PH:ThePOST:{traceback.format_exception_only(sys.exception())}")
self.send_error(500, f"ERRR: handling request") self.send_error(500, f"ERRR: handling request")
def do_OPTIONS(self): def do_OPTIONS(self):
@ -162,8 +153,6 @@ class ProxyHandler(http.server.BaseHTTPRequestHandler):
if (gMe.op.sslContext): if (gMe.op.sslContext):
self.request = gMe.op.sslContext.wrap_socket(self.request, server_side=True) self.request = gMe.op.sslContext.wrap_socket(self.request, server_side=True)
self.setup() self.setup()
#self.rfile = self.request.makefile('rb', self.rbufsize)
#self.wfile = self.request.makefile('wb', self.wbufsize)
except: except:
print(f"ERRR:ProxyHandler:SSLHS:{traceback.format_exception_only(sys.exception())}") print(f"ERRR:ProxyHandler:SSLHS:{traceback.format_exception_only(sys.exception())}")
return return