grix-connector
Version:
Connect local AI coding agents (Claude, Codex, Gemini, Qwen, DeepSeek, Cursor, OpenCode, Pi, OpenHuman, Reasonix) to the Grix scheduling platform. Also serves as an OpenClaw plugin for Grix channel transport.
6 lines (5 loc) • 2.4 kB
JavaScript
import N from"node:http";import i from"node:process";import{TOOLS as y,toolCallToInvoke as O}from"../core/mcp/tools.js";function v(){const n=i.argv.slice(2);for(let r=0;r<n.length;r++)if(n[r]==="--api-url"&&n[r+1])return n[r+1];const t=i.env.GRIX_CONNECTOR_INTERNAL_API;if(t)return t;i.stderr.write(`FATAL: --api-url <url> required (or set GRIX_CONNECTOR_INTERNAL_API)
`),i.exit(1)}const w=v();function u(n,t){return{jsonrpc:"2.0",id:n,result:t}}function f(n,t,r){return{jsonrpc:"2.0",id:n,error:{code:t,message:r}}}async function S(n,t){const r=new URL(w),o=new URL("/api/invoke",r);o.search=r.search;const d=JSON.stringify({action:n,params:t,timeout_ms:15e3});return new Promise((e,s)=>{const p=N.request(o,{method:"POST",headers:{"content-type":"application/json","content-length":Buffer.byteLength(d)}},c=>{const g=[];c.on("data",l=>g.push(l)),c.on("end",()=>{const l=Buffer.concat(g).toString("utf8");try{const m=JSON.parse(l);m.ok?e(m.data??null):s(new Error(m.error??"invoke failed"))}catch{s(new Error(`invalid response: ${l.slice(0,200)}`))}})});p.on("error",c=>s(c)),p.write(d),p.end()})}function E(n){return u(n.id??null,{protocolVersion:"2024-11-05",capabilities:{tools:{}},serverInfo:{name:"grix-connector-tools",version:"1.0.0"}})}function I(n){return u(n.id??null,{tools:y})}async function L(n){const t=n.params??{},r=String(t.name??""),o=t.arguments??{};if(!y.find(e=>e.name===r))return f(n.id??null,-32602,`Unknown tool: ${r}`);try{const e=O(r,o),s=await S(e.action,e.params);return u(n.id??null,{content:[{type:"text",text:JSON.stringify(s,null,2)}]})}catch(e){const s=e instanceof Error?e.message:String(e);return u(n.id??null,{content:[{type:"text",text:JSON.stringify({error:s})}],isError:!0})}}let h="";i.stdin.setEncoding("utf8"),i.stdin.on("data",n=>{h+=n;const t=h.split(`
`);h=t.pop()??"";for(const r of t){const o=r.trim();o&&R(o)}}),i.stdin.on("end",()=>{i.exit(0)});async function R(n){let t;try{t=JSON.parse(n)}catch{a(f(null,-32700,"Parse error"));return}try{switch(t.method){case"initialize":a(E(t));return;case"notifications/initialized":return;case"tools/list":a(I(t));return;case"tools/call":a(await L(t));return;default:a(f(t.id??null,-32601,`Method not found: ${t.method}`))}}catch(r){const o=r instanceof Error?r.message:String(r);a(f(t.id??null,-32603,`Internal error: ${o}`))}}function a(n){n&&i.stdout.write(`${JSON.stringify(n)}
`)}