#!/usr/bin/env python3 """Minimal JSON-RPC client for the installed VCC Plus public STDIO MCP helper. No grant contents, private sockets, memory mutation or emulator internals used. """ import json,subprocess,sys from pathlib import Path HELPER='/Applications/VCC Plus.app/Contents/Helpers/vcc-mcp' class VCC: def __init__(self,grant): self.p=subprocess.Popen([HELPER,'--grant',str(grant)],stdin=subprocess.PIPE,stdout=subprocess.PIPE,stderr=subprocess.PIPE,text=True,bufsize=1) self.i=0 self.request('initialize',{'protocolVersion':'2024-11-05','capabilities':{},'clientInfo':{'name':'capital-quiz-tests','version':'1.0'}}) self.p.stdin.write(json.dumps({'jsonrpc':'2.0','method':'notifications/initialized'})+'\n');self.p.stdin.flush() def request(self,method,params): self.i+=1 self.p.stdin.write(json.dumps({'jsonrpc':'2.0','id':self.i,'method':method,'params':params})+'\n');self.p.stdin.flush() while True: line=self.p.stdout.readline() if not line:raise RuntimeError(self.p.stderr.read()) reply=json.loads(line) if reply.get('id')==self.i: if 'error' in reply:raise RuntimeError(reply['error']) return reply['result'] def call(self,name,args=None): r=self.request('tools/call',{'name':name,'arguments':args or {}}) for b in r.get('content',[]): if b.get('type')=='text': try:return json.loads(b['text']) except ValueError:pass return r def close(self): self.p.stdin.close();self.p.terminate();self.p.wait() if __name__=='__main__': v=VCC(sys.argv[1]) try: if len(sys.argv)<3:result=v.request('tools/list',{}) else:result=v.call(sys.argv[2],json.loads(sys.argv[3]) if len(sys.argv)>3 else {}) print(json.dumps(result,indent=2)) finally:v.close()