@agentkarma/sdk 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tools.js","sourceRoot":"","sources":["../src/tools.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAGH,OAAO,EAAE,yBAAyB,EAAE,MAAM,aAAa,CAAC;AACxD,OAAO,EAAE,aAAa,EAAoB,MAAM,aAAa,CAAC;AAsC9D,MAAM,SAAS,GAA8B;IAC3C,YAAY,EAAE,IAAI;IAClB,cAAc,EAAE,IAAI;IACpB,aAAa,EAAE,IAAI;CACpB,CAAC;AAEF,MAAM,gBAAgB,GAAG,CAAC,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,KAAK,CAAU,CAAC;AAEvE,+EAA+E;AAE/E,MAAM,UAAU,GAAe;IAC7B,IAAI,EAAE,QAAQ;IACd,WAAW,EACT,sFAAsF;CACzF,CAAC;AAEF,6EAA6E;AAC7E,MAAM,gBAAgB,GAAe;IACnC,IAAI,EAAE,QAAQ;IACd,WAAW,EACT,kFAAkF;CACrF,CAAC;AAEF,MAAM,iBAAiB,GAAe;IACpC,IAAI,EAAE,QAAQ;IACd,IAAI,EAAE,CAAC,GAAG,gBAAgB,CAAC;IAC3B,WAAW,EACT,gFAAgF;CACnF,CAAC;AAEF,MAAM,iBAAiB,GAAe;IACpC,IAAI,EAAE,QAAQ;IACd,IAAI,EAAE,CAAC,GAAG,gBAAgB,CAAC;IAC3B,WAAW,EAAE,iEAAiE;CAC/E,CAAC;AAEF,MAAM,QAAQ,GAAe;IAC3B,IAAI,EAAE,QAAQ;IACd,IAAI,EAAE,CAAC,UAAU,EAAE,UAAU,EAAE,MAAM,CAAC;IACtC,WAAW,EACT,oGAAoG;CACvG,CAAC;AAEF,SAAS,YAAY,CACnB,UAAsC,EACtC,QAAkB;IAElB,OAAO;QACL,IAAI,EAAE,QAAQ;QACd,UAAU;QACV,QAAQ;QACR,oBAAoB,EAAE,KAAK;KAC5B,CAAC;AACJ,CAAC;AAED,gFAAgF;AAEhF,SAAS,QAAQ,CAAC,KAAc;IAC9B,OAAO,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC;AACjE,CAAC;AAED,iGAAiG;AACjG,SAAS,gBAAgB,CAAC,KAAc;IACtC,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,EAAE;QAAE,OAAO,SAAS,CAAC;IAC5E,MAAM,CAAC,GAAG,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IAC5D,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;AACzC,CAAC;AAED,SAAS,iBAAiB,CAAC,KAAc;IACvC,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,EAAE;QAAE,OAAO,SAAS,CAAC;IAC5E,IAAI,OAAO,KAAK,KAAK,SAAS;QAAE,OAAO,KAAK,CAAC;IAC7C,IAAI,KAAK,KAAK,MAAM,IAAI,KAAK,KAAK,GAAG;QAAE,OAAO,IAAI,CAAC;IACnD,IAAI,KAAK,KAAK,OAAO,IAAI,KAAK,KAAK,GAAG;QAAE,OAAO,KAAK,CAAC;IACrD,OAAO,OAAO,CAAC,KAAK,CAAC,CAAC;AACxB,CAAC;AAED,SAAS,OAAO,CAAC,KAAc;IAC7B,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAK,gBAAsC,CAAC,QAAQ,CAAC,KAAK,CAAC;QACzF,CAAC,CAAE,KAAe;QAClB,CAAC,CAAC,SAAS,CAAC;AAChB,CAAC;AAED,SAAS,MAAM,CAAC,KAAc;IAC5B,OAAO,KAAK,KAAK,UAAU,IAAI,KAAK,KAAK,UAAU,IAAI,KAAK,KAAK,MAAM;QACrE,CAAC,CAAC,KAAK;QACP,CAAC,CAAC,SAAS,CAAC;AAChB,CAAC;AAED;;;;;GAKG;AACH,SAAS,oBAAoB,CAAC,KAAc;IAC1C,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,EAAE;QAAE,OAAO,SAAS,CAAC;IAC5E,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC;IAC7B,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,MAAM,IAAI,yBAAyB,CACjC,wBAAwB,gBAAgB,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CACtD,CAAC;IACJ,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,uEAAuE;AACvE,SAAS,UAAU,CAAC,KAAc,EAAE,GAAW;IAC7C,MAAM,CAAC,GAAG,gBAAgB,CAAC,KAAK,CAAC,CAAC;IAClC,IAAI,CAAC,KAAK,SAAS;QAAE,OAAO,SAAS,CAAC;IACtC,OAAO,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;AACnD,CAAC;AAED,gFAAgF;AAEhF,MAAM,CAAC,MAAM,eAAe,GAA+B;IACzD;QACE,IAAI,EAAE,WAAW;QACjB,KAAK,EAAE,wBAAwB;QAC/B,WAAW,EACT,8LAA8L;QAChM,WAAW,EAAE,YAAY,CACvB,EAAE,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,iBAAiB,EAAE,IAAI,EAAE,QAAQ,EAAE,EAChE,CAAC,QAAQ,CAAC,CACX;QACD,WAAW,EAAE,SAAS;QACtB,OAAO,EAAE,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE,CACzB,MAAM,CAAC,QAAQ,CAAC,QAAQ,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE;YACtC,KAAK,EAAE,oBAAoB,CAAC,KAAK,CAAC,KAAK,CAAC;YACxC,IAAI,EAAE,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,MAAM;SACnC,CAAC;KACL;IACD;QACE,IAAI,EAAE,gBAAgB;QACtB,KAAK,EAAE,2BAA2B;QAClC,WAAW,EACT,4JAA4J;QAC9J,WAAW,EAAE,YAAY,CACvB;YACE,QAAQ,EAAE;gBACR,IAAI,EAAE,SAAS;gBACf,OAAO,EAAE,CAAC;gBACV,WAAW,EAAE,sDAAsD;aACpE;SACF,EACD,CAAC,UAAU,CAAC,CACb;QACD,WAAW,EAAE,SAAS;QACtB,OAAO,EAAE,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE,CAAC,MAAM,CAAC,YAAY,CAAC,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;KACxE;IACD;QACE,IAAI,EAAE,eAAe;QACrB,KAAK,EAAE,eAAe;QACtB,WAAW,EACT,wIAAwI;QAC1I,WAAW,EAAE,YAAY,CACvB;YACE,KAAK,EAAE;gBACL,IAAI,EAAE,QAAQ;gBACd,SAAS,EAAE,CAAC;gBACZ,WAAW,EAAE,8CAA8C;aAC5D;YACD,KAAK,EAAE;gBACL,IAAI,EAAE,SAAS;gBACf,OAAO,EAAE,CAAC;gBACV,OAAO,EAAE,EAAE;gBACX,WAAW,EAAE,oCAAoC;aAClD;SACF,EACD,CAAC,OAAO,CAAC,CACV;QACD,WAAW,EAAE,SAAS;QACtB,OAAO,EAAE,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE,CACzB,MAAM,CAAC,YAAY,CAAC,QAAQ,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE;YACzC,KAAK,EAAE,UAAU,CAAC,KAAK,CAAC,KAAK,EAAE,EAAE,CAAC;SACnC,CAAC;KACL;IACD;QACE,IAAI,EAAE,mBAAmB;QACzB,KAAK,EAAE,2BAA2B;QAClC,WAAW,EACT,gIAAgI;QAClI,WAAW,EAAE,YAAY,CACvB;YACE,MAAM,EAAE,gBAAgB;YACxB,KAAK,EAAE;gBACL,IAAI,EAAE,SAAS;gBACf,OAAO,EAAE,CAAC;gBACV,OAAO,EAAE,GAAG;gBACZ,WAAW,EAAE,oCAAoC;aAClD;YACD,MAAM,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,CAAC,EAAE,WAAW,EAAE,cAAc,EAAE;SACrE,EACD,CAAC,QAAQ,CAAC,CACX;QACD,WAAW,EAAE,SAAS;QACtB,OAAO,EAAE,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE,CACzB,MAAM,CAAC,eAAe,CAAC,QAAQ,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE;YAC7C,KAAK,EAAE,UAAU,CAAC,KAAK,CAAC,KAAK,EAAE,GAAG,CAAC;YACnC,MAAM,EAAE,gBAAgB,CAAC,KAAK,CAAC,MAAM,CAAC;SACvC,CAAC;KACL;IACD;QACE,IAAI,EAAE,sBAAsB;QAC5B,KAAK,EAAE,sBAAsB;QAC7B,WAAW,EACT,gFAAgF;QAClF,WAAW,EAAE,YAAY,CAAC,EAAE,MAAM,EAAE,gBAAgB,EAAE,EAAE,CAAC,QAAQ,CAAC,CAAC;QACnE,WAAW,EAAE,SAAS;QACtB,OAAO,EAAE,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE,CAAC,MAAM,CAAC,kBAAkB,CAAC,QAAQ,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;KAC9E;IACD;QACE,IAAI,EAAE,gBAAgB;QACtB,KAAK,EAAE,yCAAyC;QAChD,WAAW,EACT,0QAA0Q;QAC5Q,WAAW,EAAE,YAAY,CACvB,EAAE,KAAK,EAAE,iBAAiB,EAAE,MAAM,EAAE,UAAU,EAAE,EAChD,CAAC,OAAO,EAAE,QAAQ,CAAC,CACpB;QACD,WAAW,EAAE,SAAS;QACtB,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,EAAE;YAC/B,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;YACnC,IAAI,CAAC,KAAK,EAAE,CAAC;gBACX,MAAM,IAAI,yBAAyB,CACjC,wBAAwB,gBAAgB,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CACtD,CAAC;YACJ,CAAC;YACD,OAAO,MAAM,CAAC,mBAAmB,CAAC,KAAK,EAAE,QAAQ,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC;QACnE,CAAC;KACF;IACD;QACE,IAAI,EAAE,UAAU;QAChB,KAAK,EAAE,oBAAoB;QAC3B,WAAW,EACT,2NAA2N;QAC7N,WAAW,EAAE,YAAY,CACvB,EAAE,KAAK,EAAE,iBAAiB,EAAE,MAAM,EAAE,UAAU,EAAE,EAChD,CAAC,OAAO,EAAE,QAAQ,CAAC,CACpB;QACD,WAAW,EAAE,SAAS;QACtB,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,EAAE;YAC/B,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;YACnC,IAAI,CAAC,KAAK,EAAE,CAAC;gBACX,MAAM,IAAI,yBAAyB,CACjC,wBAAwB,gBAAgB,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CACtD,CAAC;YACJ,CAAC;YACD,OAAO,MAAM,CAAC,aAAa,CAAC,KAAK,EAAE,QAAQ,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC;QAC7D,CAAC;KACF;IACD;QACE,IAAI,EAAE,YAAY;QAClB,KAAK,EAAE,kBAAkB;QACzB,WAAW,EACT,+NAA+N;QACjO,WAAW,EAAE,YAAY,CACvB,EAAE,KAAK,EAAE,iBAAiB,EAAE,MAAM,EAAE,UAAU,EAAE,EAChD,CAAC,OAAO,EAAE,QAAQ,CAAC,CACpB;QACD,WAAW,EAAE,SAAS;QACtB,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,EAAE;YAC/B,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;YACnC,IAAI,CAAC,KAAK,EAAE,CAAC;gBACX,MAAM,IAAI,yBAAyB,CACjC,wBAAwB,gBAAgB,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CACtD,CAAC;YACJ,CAAC;YACD,OAAO,MAAM,CAAC,cAAc,CAAC,KAAK,EAAE,QAAQ,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC;QAC9D,CAAC;KACF;IACD;QACE,IAAI,EAAE,aAAa;QACnB,KAAK,EAAE,8BAA8B;QACrC,WAAW,EACT,kPAAkP;QACpP,WAAW,EAAE,YAAY,CACvB;YACE,MAAM,EAAE,UAAU;YAClB,KAAK,EAAE,iBAAiB;YACxB,IAAI,EAAE;gBACJ,IAAI,EAAE,QAAQ;gBACd,IAAI,EAAE,CAAC,UAAU,EAAE,UAAU,CAAC;gBAC9B,WAAW,EAAE,mDAAmD;aACjE;YACD,SAAS,EAAE;gBACT,IAAI,EAAE,SAAS;gBACf,OAAO,EAAE,CAAC;gBACV,OAAO,EAAE,GAAG;gBACZ,WAAW,EAAE,2CAA2C;aACzD;YACD,sBAAsB,EAAE;gBACtB,IAAI,EAAE,SAAS;gBACf,WAAW,EAAE,oDAAoD;aAClE;YACD,YAAY,EAAE;gBACZ,IAAI,EAAE,SAAS;gBACf,OAAO,EAAE,CAAC;gBACV,WAAW,EAAE,kDAAkD;aAChE;YACD,kBAAkB,EAAE;gBAClB,IAAI,EAAE,SAAS;gBACf,OAAO,EAAE,CAAC;gBACV,OAAO,EAAE,GAAG;gBACZ,WAAW,EAAE,0CAA0C;aACxD;YACD,uBAAuB,EAAE;gBACvB,IAAI,EAAE,SAAS;gBACf,WAAW,EAAE,iDAAiD;aAC/D;SACF,EACD,CAAC,QAAQ,CAAC,CACX;QACD,WAAW,EAAE,SAAS;QACtB,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,EAAE;YAC/B,MAAM,MAAM,GAAG,QAAQ,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;YACtC,MAAM,KAAK,GAAG,oBAAoB,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;YAChD,MAAM,MAAM,GAAgB,EAAE,CAAC;YAC/B,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC;YACxB,IAAI,IAAI,KAAK,UAAU,IAAI,IAAI,KAAK,UAAU;gBAAE,MAAM,CAAC,IAAI,GAAG,IAAI,CAAC;YACnE,MAAM,QAAQ,GAAG,gBAAgB,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;YACnD,IAAI,QAAQ,KAAK,SAAS;gBAAE,MAAM,CAAC,QAAQ,GAAG,QAAQ,CAAC;YACvD,MAAM,cAAc,GAAG,iBAAiB,CAAC,KAAK,CAAC,sBAAsB,CAAC,CAAC;YACvE,IAAI,cAAc,KAAK,SAAS;gBAAE,MAAM,CAAC,oBAAoB,GAAG,cAAc,CAAC;YAC/E,MAAM,KAAK,GAAG,gBAAgB,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC;YACnD,IAAI,KAAK,KAAK,SAAS;gBAAE,MAAM,CAAC,UAAU,GAAG,KAAK,CAAC;YACnD,MAAM,WAAW,GAAG,gBAAgB,CAAC,KAAK,CAAC,kBAAkB,CAAC,CAAC;YAC/D,IAAI,WAAW,KAAK,SAAS;gBAAE,MAAM,CAAC,gBAAgB,GAAG,WAAW,CAAC;YACrE,MAAM,WAAW,GAAG,iBAAiB,CAAC,KAAK,CAAC,uBAAuB,CAAC,CAAC;YACrE,IAAI,WAAW,KAAK,SAAS;gBAAE,MAAM,CAAC,qBAAqB,GAAG,WAAW,CAAC;YAE1E,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,QAAQ,CAAC,MAAM,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC;YACxE,MAAM,QAAQ,GAAG,aAAa,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;YACjD,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,IAAI,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,CAAC;QAClE,CAAC;KACF;CACF,CAAC;AAEF,yCAAyC;AACzC,MAAM,UAAU,iBAAiB,CAC/B,IAAY;IAEZ,OAAO,eAAe,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,CAAC;AACtD,CAAC;AAED,sCAAsC;AACtC,MAAM,UAAU,mBAAmB;IACjC,OAAO,eAAe,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;AAC5C,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,iBAAiB,CACrC,MAAwB,EACxB,IAAY,EACZ,QAAiC,EAAE;IAEnC,MAAM,IAAI,GAAG,iBAAiB,CAAC,IAAI,CAAC,CAAC;IACrC,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,MAAM,IAAI,yBAAyB,CAAC,4BAA4B,IAAI,EAAE,CAAC,CAAC;IAC1E,CAAC;IACD,OAAO,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;AACrC,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agentkarma/sdk",
3
- "version": "0.1.0",
3
+ "version": "0.2.0",
4
4
  "description": "TypeScript SDK for AgentKarma — the reputation layer for autonomous on-chain agents.",
5
5
  "license": "MIT",
6
6
  "author": "Kerem Noras <kerem@noras.tech>",
@@ -20,8 +20,19 @@
20
20
  ".": {
21
21
  "types": "./dist/index.d.ts",
22
22
  "import": "./dist/index.js"
23
+ },
24
+ "./tools": {
25
+ "types": "./dist/tools.d.ts",
26
+ "import": "./dist/tools.js"
27
+ },
28
+ "./mcp": {
29
+ "types": "./dist/mcp.d.ts",
30
+ "import": "./dist/mcp.js"
23
31
  }
24
32
  },
33
+ "bin": {
34
+ "agentkarma-mcp": "./dist/mcp-cli.js"
35
+ },
25
36
  "files": [
26
37
  "dist",
27
38
  "src",
@@ -32,11 +43,15 @@
32
43
  "engines": {
33
44
  "node": ">=18"
34
45
  },
46
+ "publishConfig": {
47
+ "access": "public"
48
+ },
35
49
  "scripts": {
36
- "build": "tsc -p tsconfig.json",
50
+ "build": "tsc -p tsconfig.json && chmod +x dist/mcp-cli.js",
37
51
  "typecheck": "tsc -p tsconfig.json --noEmit",
38
52
  "test": "bun test",
39
- "clean": "rm -rf dist"
53
+ "clean": "rm -rf dist",
54
+ "prepublishOnly": "npm run build"
40
55
  },
41
56
  "keywords": [
42
57
  "agentkarma",
@@ -47,9 +62,20 @@
47
62
  "x402",
48
63
  "solana",
49
64
  "celo",
50
- "preflight"
65
+ "preflight",
66
+ "mcp",
67
+ "model-context-protocol"
51
68
  ],
69
+ "peerDependencies": {
70
+ "@modelcontextprotocol/sdk": ">=1.0.0 <2"
71
+ },
72
+ "peerDependenciesMeta": {
73
+ "@modelcontextprotocol/sdk": {
74
+ "optional": true
75
+ }
76
+ },
52
77
  "devDependencies": {
78
+ "@modelcontextprotocol/sdk": "^1.29.0",
53
79
  "@types/node": "^25.5.2",
54
80
  "bun-types": "^1.3.13",
55
81
  "typescript": "^6.0.2"
package/src/mcp-cli.ts ADDED
@@ -0,0 +1,34 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * `agentkarma-mcp` — run the AgentKarma MCP server over stdio.
4
+ *
5
+ * Backed by the public AgentKarma API (read-only, non-routing). Point it at a
6
+ * different host with AGENTKARMA_BASE_URL.
7
+ *
8
+ * npx agentkarma-mcp
9
+ * AGENTKARMA_BASE_URL=https://staging.agentkarma.io npx agentkarma-mcp
10
+ *
11
+ * Requires the optional peer dependency `@modelcontextprotocol/sdk`.
12
+ */
13
+
14
+ import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
15
+ import { createAgentKarmaMcpServer } from './mcp.js';
16
+
17
+ const baseUrl = process.env.AGENTKARMA_BASE_URL;
18
+ const server = createAgentKarmaMcpServer({
19
+ config: baseUrl ? { baseUrl } : undefined,
20
+ });
21
+
22
+ try {
23
+ await server.connect(new StdioServerTransport());
24
+ // stderr only — stdout is the JSON-RPC channel and must stay clean.
25
+ console.error(
26
+ `agentkarma-mcp ready (${baseUrl ?? 'https://agentkarma.io'}) over stdio`,
27
+ );
28
+ } catch (err) {
29
+ console.error(
30
+ 'agentkarma-mcp failed to start:',
31
+ err instanceof Error ? err.message : err,
32
+ );
33
+ process.exit(1);
34
+ }
package/src/mcp.ts ADDED
@@ -0,0 +1,146 @@
1
+ /**
2
+ * @agentkarma/sdk/mcp — a turnkey AgentKarma MCP server, built from the
3
+ * `@agentkarma/sdk/tools` catalog and backed by the public AgentKarma client.
4
+ *
5
+ * This is the OPTIONAL server layer. It depends on `@modelcontextprotocol/sdk`
6
+ * (declared as an optional peer dependency) — install it only if you use this
7
+ * module. The core client (`@agentkarma/sdk`) and the tool catalog
8
+ * (`@agentkarma/sdk/tools`) stay dependency-free.
9
+ *
10
+ * The server is read-only and non-routing: it exposes the read catalog, never
11
+ * signs, and never proxies a call on the caller's behalf.
12
+ *
13
+ * import { createAgentKarmaMcpServer } from '@agentkarma/sdk/mcp';
14
+ * import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
15
+ * const server = createAgentKarmaMcpServer();
16
+ * await server.connect(new StdioServerTransport());
17
+ */
18
+
19
+ // Low-level `Server` (not the high-level `McpServer`) is deliberate: `McpServer`
20
+ // requires Zod for every tool's `inputSchema`, whereas this catalog ships plain
21
+ // JSON Schema (zero-dep, portable). The SDK documents `Server` as the path for
22
+ // exactly this "advanced use case", so the @deprecated hint is acknowledged and
23
+ // intentional — we want JSON Schema on the wire without a Zod dependency.
24
+ import { Server } from '@modelcontextprotocol/sdk/server/index.js';
25
+ import {
26
+ CallToolRequestSchema,
27
+ ListToolsRequestSchema,
28
+ type CallToolResult,
29
+ type Tool,
30
+ } from '@modelcontextprotocol/sdk/types.js';
31
+
32
+ import { createAgentKarmaClient, type AgentKarmaClient } from './client.js';
33
+ import {
34
+ AgentKarmaError,
35
+ AgentKarmaNotFoundError,
36
+ AgentKarmaValidationError,
37
+ } from './errors.js';
38
+ import { agentKarmaTools, getAgentKarmaTool } from './tools.js';
39
+ import type { ClientConfig } from './types.js';
40
+
41
+ const MCP_SERVER_NAME = 'agentkarma';
42
+ const MCP_SERVER_VERSION = '0.1.0';
43
+
44
+ const SERVER_INSTRUCTIONS = [
45
+ 'AgentKarma is the reputation layer for autonomous on-chain agents.',
46
+ 'Use these read-only tools to look up trust signals BEFORE paying or',
47
+ 'delegating to a wallet — every response carries two-faced karma (provider +',
48
+ 'consumer) and a confidence badge. `check_trust` runs a local allow/deny',
49
+ 'policy. AgentKarma does not proxy paid calls (non-routing).',
50
+ ].join(' ');
51
+
52
+ /** The tool advertisements (MCP `tools/list` shape), derived from the catalog. */
53
+ export function agentKarmaMcpTools(): Tool[] {
54
+ return agentKarmaTools.map((t) => ({
55
+ name: t.name,
56
+ title: t.title,
57
+ description: t.description,
58
+ inputSchema: t.inputSchema as Tool['inputSchema'],
59
+ annotations: { title: t.title, ...t.annotations },
60
+ }));
61
+ }
62
+
63
+ /**
64
+ * Run a catalog tool and shape the result as an MCP `CallToolResult`. Errors
65
+ * are converted to clean, non-leaky tool errors — raw network/stack detail is
66
+ * NEVER echoed to the caller.
67
+ */
68
+ export async function callAgentKarmaTool(
69
+ client: AgentKarmaClient,
70
+ name: string,
71
+ args: Record<string, unknown> = {},
72
+ ): Promise<CallToolResult> {
73
+ const tool = getAgentKarmaTool(name);
74
+ if (!tool) {
75
+ return toolError('unknown_tool', `Unknown tool: ${name}`);
76
+ }
77
+ try {
78
+ const data = await tool.handler(client, args);
79
+ return { content: [{ type: 'text', text: JSON.stringify(data, null, 2) }] };
80
+ } catch (err) {
81
+ if (err instanceof AgentKarmaNotFoundError) {
82
+ return toolError('not_found', `No record found for this ${name} lookup.`);
83
+ }
84
+ if (err instanceof AgentKarmaValidationError) {
85
+ // Validation messages describe the caller's own bad argument — safe to echo.
86
+ // INVARIANT: AgentKarmaValidationError messages MUST stay caller-facing —
87
+ // never interpolate a host, URL, response body, or any upstream/network
88
+ // detail into one, because this branch echoes err.message verbatim to a
89
+ // public MCP caller. Upstream/network errors take the non-echoing branches
90
+ // below instead.
91
+ return toolError('invalid_input', err.message);
92
+ }
93
+ if (err instanceof AgentKarmaError && typeof err.status === 'number') {
94
+ return toolError('upstream_error', `AgentKarma returned ${err.status}.`);
95
+ }
96
+ // Unknown/network error: log server-side, return a generic message.
97
+ console.error(`[agentkarma-mcp:${name}]`, err);
98
+ return toolError(
99
+ 'tool_error',
100
+ `${name} encountered an unexpected error. Verify the arguments and try again.`,
101
+ );
102
+ }
103
+ }
104
+
105
+ function toolError(error: string, message: string): CallToolResult {
106
+ return {
107
+ isError: true,
108
+ content: [{ type: 'text', text: JSON.stringify({ error, message }) }],
109
+ };
110
+ }
111
+
112
+ /** Options for {@link createAgentKarmaMcpServer}. */
113
+ export interface CreateAgentKarmaMcpServerOptions {
114
+ /** Pre-built client. Takes precedence over `config`. */
115
+ client?: AgentKarmaClient;
116
+ /** Client config (baseUrl, timeout, fetch, …) when no `client` is supplied. */
117
+ config?: ClientConfig;
118
+ }
119
+
120
+ /**
121
+ * Build a low-level MCP `Server` exposing the AgentKarma read catalog. Connect
122
+ * it to any transport (`StdioServerTransport`, an HTTP transport, …).
123
+ */
124
+ export function createAgentKarmaMcpServer(
125
+ options: CreateAgentKarmaMcpServerOptions = {},
126
+ ): Server {
127
+ const client = options.client ?? createAgentKarmaClient(options.config);
128
+ const server = new Server(
129
+ { name: MCP_SERVER_NAME, version: MCP_SERVER_VERSION },
130
+ { capabilities: { tools: {} }, instructions: SERVER_INSTRUCTIONS },
131
+ );
132
+
133
+ server.setRequestHandler(ListToolsRequestSchema, async () => ({
134
+ tools: agentKarmaMcpTools(),
135
+ }));
136
+
137
+ server.setRequestHandler(CallToolRequestSchema, async (request) =>
138
+ callAgentKarmaTool(
139
+ client,
140
+ request.params.name,
141
+ (request.params.arguments ?? {}) as Record<string, unknown>,
142
+ ),
143
+ );
144
+
145
+ return server;
146
+ }
package/src/tools.ts ADDED
@@ -0,0 +1,423 @@
1
+ /**
2
+ * @agentkarma/sdk/tools — framework-agnostic MCP tool catalog.
3
+ *
4
+ * One canonical, dependency-free description of AgentKarma's read surface as
5
+ * MCP-style tools. Each descriptor carries a JSON Schema (draft-07) input
6
+ * contract and a `handler` that runs against an `AgentKarmaClient` — so the
7
+ * SAME catalog can be mounted on any MCP server (`@agentkarma/sdk/mcp`), wired
8
+ * into another agent framework, or called directly.
9
+ *
10
+ * These are READ tools only. They never sign, never execute a transaction,
11
+ * never proxy a call (non-routing, RFC §12). The one write in the SDK —
12
+ * `submitFeedback` — needs a wallet signature and is intentionally NOT exposed
13
+ * here, so an MCP server built from this catalog requires no keys.
14
+ *
15
+ * Zero runtime dependencies: schemas are plain JSON Schema objects, not Zod, so
16
+ * importing this module pulls nothing extra into a client-only consumer.
17
+ */
18
+
19
+ import type { AgentKarmaClient } from './client.js';
20
+ import { AgentKarmaValidationError } from './errors.js';
21
+ import { evaluateTrust, type TrustPolicy } from './policy.js';
22
+ import type { Chain, KarmaFace } from './types.js';
23
+
24
+ /** MCP tool annotations (subset of the MCP spec) describing tool behaviour. */
25
+ export interface AgentKarmaToolAnnotations {
26
+ /** The tool does not modify state. Always true here. */
27
+ readOnlyHint: true;
28
+ /** Repeated calls with the same args yield the same result. Always true here. */
29
+ idempotentHint: true;
30
+ /** The tool reads from an external service (agentkarma.io). Always true here. */
31
+ openWorldHint: true;
32
+ }
33
+
34
+ /** A JSON Schema (draft-07) object — kept loose to avoid a schema-lib dependency. */
35
+ export type JSONSchema = Record<string, unknown>;
36
+
37
+ /**
38
+ * A single AgentKarma tool: its MCP advertisement (name/title/description/schema)
39
+ * plus a handler that executes it against an `AgentKarmaClient`.
40
+ */
41
+ export interface AgentKarmaToolDescriptor {
42
+ /** Stable tool name (snake_case), e.g. `get_karma`. */
43
+ name: string;
44
+ /** Human-readable title for tool pickers. */
45
+ title: string;
46
+ /** What the tool does and when to use it. */
47
+ description: string;
48
+ /** JSON Schema (draft-07) for the tool's arguments. */
49
+ inputSchema: JSONSchema;
50
+ /** MCP behaviour hints. */
51
+ annotations: AgentKarmaToolAnnotations;
52
+ /** Execute the tool against a client. Returns plain JSON-serializable data. */
53
+ handler: (
54
+ client: AgentKarmaClient,
55
+ input: Record<string, unknown>,
56
+ ) => Promise<unknown>;
57
+ }
58
+
59
+ const READ_ONLY: AgentKarmaToolAnnotations = {
60
+ readOnlyHint: true,
61
+ idempotentHint: true,
62
+ openWorldHint: true,
63
+ };
64
+
65
+ const SUPPORTED_CHAINS = ['solana', 'celo', 'stellar', 'arc'] as const;
66
+
67
+ // ─── Reusable schema fragments ──────────────────────────────────────────────
68
+
69
+ const walletProp: JSONSchema = {
70
+ type: 'string',
71
+ description:
72
+ 'On-chain agent wallet address (Solana base58, Stellar G-address, or EVM 0x address).',
73
+ };
74
+
75
+ /** Solana-only endpoints (history, feedback) reject non-base58 addresses. */
76
+ const solanaWalletProp: JSONSchema = {
77
+ type: 'string',
78
+ description:
79
+ 'Solana agent wallet address (base58, 32–44 chars). This endpoint is Solana-only.',
80
+ };
81
+
82
+ const optionalChainProp: JSONSchema = {
83
+ type: 'string',
84
+ enum: [...SUPPORTED_CHAINS],
85
+ description:
86
+ "Chain for the lookup. Defaults to 'solana'. Pass for celo/arc/stellar wallets.",
87
+ };
88
+
89
+ const requiredChainProp: JSONSchema = {
90
+ type: 'string',
91
+ enum: [...SUPPORTED_CHAINS],
92
+ description: 'Chain the wallet lives on (spans all chains; must be explicit).',
93
+ };
94
+
95
+ const faceProp: JSONSchema = {
96
+ type: 'string',
97
+ enum: ['provider', 'consumer', 'both'],
98
+ description:
99
+ "Karma face: 'provider' (will it deliver?), 'consumer' (will it pay cleanly?), or 'both' (default).",
100
+ };
101
+
102
+ function objectSchema(
103
+ properties: Record<string, JSONSchema>,
104
+ required: string[],
105
+ ): JSONSchema {
106
+ return {
107
+ type: 'object',
108
+ properties,
109
+ required,
110
+ additionalProperties: false,
111
+ };
112
+ }
113
+
114
+ // ─── Input coercion helpers (handlers receive raw, possibly-stringy args) ────
115
+
116
+ function asString(value: unknown): string {
117
+ return typeof value === 'string' ? value : String(value ?? '');
118
+ }
119
+
120
+ /** Coerce an MCP arg to a number, tolerating JSON-string numbers. `undefined` passes through. */
121
+ function asOptionalNumber(value: unknown): number | undefined {
122
+ if (value === undefined || value === null || value === '') return undefined;
123
+ const n = typeof value === 'number' ? value : Number(value);
124
+ return Number.isNaN(n) ? undefined : n;
125
+ }
126
+
127
+ function asOptionalBoolean(value: unknown): boolean | undefined {
128
+ if (value === undefined || value === null || value === '') return undefined;
129
+ if (typeof value === 'boolean') return value;
130
+ if (value === 'true' || value === '1') return true;
131
+ if (value === 'false' || value === '0') return false;
132
+ return Boolean(value);
133
+ }
134
+
135
+ function asChain(value: unknown): Chain | undefined {
136
+ return typeof value === 'string' && (SUPPORTED_CHAINS as readonly string[]).includes(value)
137
+ ? (value as Chain)
138
+ : undefined;
139
+ }
140
+
141
+ function asFace(value: unknown): KarmaFace | 'both' | undefined {
142
+ return value === 'provider' || value === 'consumer' || value === 'both'
143
+ ? value
144
+ : undefined;
145
+ }
146
+
147
+ /**
148
+ * Resolve an OPTIONAL chain argument: `undefined` when absent, the validated
149
+ * chain otherwise. Unlike a bare `asChain`, a present-but-invalid value throws
150
+ * rather than silently downgrading to the client's 'solana' default — so
151
+ * `chain: 'polygon'` fails loudly instead of returning a wrong Solana lookup.
152
+ */
153
+ function resolveOptionalChain(value: unknown): Chain | undefined {
154
+ if (value === undefined || value === null || value === '') return undefined;
155
+ const chain = asChain(value);
156
+ if (!chain) {
157
+ throw new AgentKarmaValidationError(
158
+ `chain must be one of ${SUPPORTED_CHAINS.join(', ')}`,
159
+ );
160
+ }
161
+ return chain;
162
+ }
163
+
164
+ /** Clamp an optional limit to the tool's advertised [1, max] bound. */
165
+ function clampLimit(value: unknown, max: number): number | undefined {
166
+ const n = asOptionalNumber(value);
167
+ if (n === undefined) return undefined;
168
+ return Math.min(Math.max(1, Math.trunc(n)), max);
169
+ }
170
+
171
+ // ─── The catalog ─────────────────────────────────────────────────────────────
172
+
173
+ export const agentKarmaTools: AgentKarmaToolDescriptor[] = [
174
+ {
175
+ name: 'get_karma',
176
+ title: 'Get Karma (both faces)',
177
+ description:
178
+ 'Look up the full two-faced Karma snapshot for an agent wallet — provider score, consumer score, confidence badge, autonomy, identity. Use BEFORE paying an agent or accepting work from one.',
179
+ inputSchema: objectSchema(
180
+ { wallet: walletProp, chain: optionalChainProp, face: faceProp },
181
+ ['wallet'],
182
+ ),
183
+ annotations: READ_ONLY,
184
+ handler: (client, input) =>
185
+ client.getKarma(asString(input.wallet), {
186
+ chain: resolveOptionalChain(input.chain),
187
+ face: asFace(input.face) ?? 'both',
188
+ }),
189
+ },
190
+ {
191
+ name: 'get_celo_agent',
192
+ title: 'Get Celo agent (ERC-8004)',
193
+ description:
194
+ 'Resolve a Celo ERC-8004 agent by numeric agentId: IdentityRegistry record (owner, agentURI, declared services) plus aggregate ReputationRegistry feedback.',
195
+ inputSchema: objectSchema(
196
+ {
197
+ agent_id: {
198
+ type: 'integer',
199
+ minimum: 1,
200
+ description: 'ERC-8004 agentId on Celo mainnet (positive integer).',
201
+ },
202
+ },
203
+ ['agent_id'],
204
+ ),
205
+ annotations: READ_ONLY,
206
+ handler: (client, input) => client.getCeloAgent(Number(input.agent_id)),
207
+ },
208
+ {
209
+ name: 'search_agents',
210
+ title: 'Search agents',
211
+ description:
212
+ 'Find agents by a substring of their display name or wallet address (case-insensitive), ranked by score. Returns up to `limit` results.',
213
+ inputSchema: objectSchema(
214
+ {
215
+ query: {
216
+ type: 'string',
217
+ minLength: 3,
218
+ description: 'Name or wallet-address substring (≥3 chars).',
219
+ },
220
+ limit: {
221
+ type: 'integer',
222
+ minimum: 1,
223
+ maximum: 50,
224
+ description: 'Max results (1–50, clamped to 50).',
225
+ },
226
+ },
227
+ ['query'],
228
+ ),
229
+ annotations: READ_ONLY,
230
+ handler: (client, input) =>
231
+ client.searchAgents(asString(input.query), {
232
+ limit: clampLimit(input.limit, 50),
233
+ }),
234
+ },
235
+ {
236
+ name: 'get_agent_history',
237
+ title: 'Get agent payment history',
238
+ description:
239
+ "Paginated x402 payment history for a Solana agent wallet, with each transaction's consumer feedback rating. Solana-only today.",
240
+ inputSchema: objectSchema(
241
+ {
242
+ wallet: solanaWalletProp,
243
+ limit: {
244
+ type: 'integer',
245
+ minimum: 1,
246
+ maximum: 200,
247
+ description: 'Page size (1–200, clamped to 200).',
248
+ },
249
+ offset: { type: 'integer', minimum: 0, description: 'Page offset.' },
250
+ },
251
+ ['wallet'],
252
+ ),
253
+ annotations: READ_ONLY,
254
+ handler: (client, input) =>
255
+ client.getAgentHistory(asString(input.wallet), {
256
+ limit: clampLimit(input.limit, 200),
257
+ offset: asOptionalNumber(input.offset),
258
+ }),
259
+ },
260
+ {
261
+ name: 'get_feedback_summary',
262
+ title: 'Get feedback summary',
263
+ description:
264
+ 'Aggregate delivered/failed counts and delivery rate for a Solana agent wallet.',
265
+ inputSchema: objectSchema({ wallet: solanaWalletProp }, ['wallet']),
266
+ annotations: READ_ONLY,
267
+ handler: (client, input) => client.getFeedbackSummary(asString(input.wallet)),
268
+ },
269
+ {
270
+ name: 'get_succession',
271
+ title: "Get succession plan (Dead Man's Switch)",
272
+ description:
273
+ "Return the agent's declared succession plan plus AgentKarma's OBSERVED heartbeat liveness (derived status, heir count, deadline). A continuity/trust signal. AgentKarma never holds a key or executes the will (non-custody). Throws not-found when no plan is declared.",
274
+ inputSchema: objectSchema(
275
+ { chain: requiredChainProp, wallet: walletProp },
276
+ ['chain', 'wallet'],
277
+ ),
278
+ annotations: READ_ONLY,
279
+ handler: async (client, input) => {
280
+ const chain = asChain(input.chain);
281
+ if (!chain) {
282
+ throw new AgentKarmaValidationError(
283
+ `chain must be one of ${SUPPORTED_CHAINS.join(', ')}`,
284
+ );
285
+ }
286
+ return client.getSuccessionStatus(chain, asString(input.wallet));
287
+ },
288
+ },
289
+ {
290
+ name: 'get_bond',
291
+ title: 'Get bonding status',
292
+ description:
293
+ 'Return surety bonds taken out ON this agent (open vs resolved, total bonded USDC, demo flag). A bond lifts confidence/Tier-1 presence only — never the trust ceiling. Returns an empty block when the agent has no bonds.',
294
+ inputSchema: objectSchema(
295
+ { chain: requiredChainProp, wallet: walletProp },
296
+ ['chain', 'wallet'],
297
+ ),
298
+ annotations: READ_ONLY,
299
+ handler: async (client, input) => {
300
+ const chain = asChain(input.chain);
301
+ if (!chain) {
302
+ throw new AgentKarmaValidationError(
303
+ `chain must be one of ${SUPPORTED_CHAINS.join(', ')}`,
304
+ );
305
+ }
306
+ return client.getBondStatus(chain, asString(input.wallet));
307
+ },
308
+ },
309
+ {
310
+ name: 'get_surety',
311
+ title: 'Get Surety Karma',
312
+ description:
313
+ "Return this wallet's ORTHOGONAL Surety Karma from underwriting OTHER agents' bonds (score, settled/success/in-flight counts). Never folded into Provider/Consumer karma. Returns null when the wallet has never underwritten.",
314
+ inputSchema: objectSchema(
315
+ { chain: requiredChainProp, wallet: walletProp },
316
+ ['chain', 'wallet'],
317
+ ),
318
+ annotations: READ_ONLY,
319
+ handler: async (client, input) => {
320
+ const chain = asChain(input.chain);
321
+ if (!chain) {
322
+ throw new AgentKarmaValidationError(
323
+ `chain must be one of ${SUPPORTED_CHAINS.join(', ')}`,
324
+ );
325
+ }
326
+ return client.getSuretyKarma(chain, asString(input.wallet));
327
+ },
328
+ },
329
+ {
330
+ name: 'check_trust',
331
+ title: 'Check trust before executing',
332
+ description:
333
+ 'Fetch an agent\'s Karma and evaluate a local trust policy against it — the "should I trust this agent before paying?" gate. Returns an explainable allow/deny decision plus the snapshot it read. Pure local evaluation: no routing, no signing.',
334
+ inputSchema: objectSchema(
335
+ {
336
+ wallet: walletProp,
337
+ chain: optionalChainProp,
338
+ face: {
339
+ type: 'string',
340
+ enum: ['provider', 'consumer'],
341
+ description: 'Face to score the decision on (default provider).',
342
+ },
343
+ min_score: {
344
+ type: 'integer',
345
+ minimum: 0,
346
+ maximum: 100,
347
+ description: 'Reject when the face score is below this.',
348
+ },
349
+ require_receipt_backed: {
350
+ type: 'boolean',
351
+ description: 'Require at least one Tier-1 receipt-backed signal.',
352
+ },
353
+ min_tx_count: {
354
+ type: 'integer',
355
+ minimum: 0,
356
+ description: 'Require at least this many indexed transactions.',
357
+ },
358
+ min_autonomy_score: {
359
+ type: 'integer',
360
+ minimum: 0,
361
+ maximum: 100,
362
+ description: 'Require autonomy score at or above this.',
363
+ },
364
+ require_live_succession: {
365
+ type: 'boolean',
366
+ description: 'Require a live (declared/live) succession plan.',
367
+ },
368
+ },
369
+ ['wallet'],
370
+ ),
371
+ annotations: READ_ONLY,
372
+ handler: async (client, input) => {
373
+ const wallet = asString(input.wallet);
374
+ const chain = resolveOptionalChain(input.chain);
375
+ const policy: TrustPolicy = {};
376
+ const face = input.face;
377
+ if (face === 'provider' || face === 'consumer') policy.face = face;
378
+ const minScore = asOptionalNumber(input.min_score);
379
+ if (minScore !== undefined) policy.minScore = minScore;
380
+ const requireReceipt = asOptionalBoolean(input.require_receipt_backed);
381
+ if (requireReceipt !== undefined) policy.requireReceiptBacked = requireReceipt;
382
+ const minTx = asOptionalNumber(input.min_tx_count);
383
+ if (minTx !== undefined) policy.minTxCount = minTx;
384
+ const minAutonomy = asOptionalNumber(input.min_autonomy_score);
385
+ if (minAutonomy !== undefined) policy.minAutonomyScore = minAutonomy;
386
+ const requireLive = asOptionalBoolean(input.require_live_succession);
387
+ if (requireLive !== undefined) policy.requireLiveSuccession = requireLive;
388
+
389
+ const snapshot = await client.getKarma(wallet, { chain, face: 'both' });
390
+ const decision = evaluateTrust(snapshot, policy);
391
+ return { wallet, chain: chain ?? 'solana', decision, snapshot };
392
+ },
393
+ },
394
+ ];
395
+
396
+ /** Look up a tool descriptor by name. */
397
+ export function getAgentKarmaTool(
398
+ name: string,
399
+ ): AgentKarmaToolDescriptor | undefined {
400
+ return agentKarmaTools.find((t) => t.name === name);
401
+ }
402
+
403
+ /** Every tool name in the catalog. */
404
+ export function agentKarmaToolNames(): string[] {
405
+ return agentKarmaTools.map((t) => t.name);
406
+ }
407
+
408
+ /**
409
+ * Run a catalog tool by name against a client. Throws
410
+ * `AgentKarmaValidationError` for an unknown tool; the client's own validation
411
+ * governs the arguments.
412
+ */
413
+ export async function runAgentKarmaTool(
414
+ client: AgentKarmaClient,
415
+ name: string,
416
+ input: Record<string, unknown> = {},
417
+ ): Promise<unknown> {
418
+ const tool = getAgentKarmaTool(name);
419
+ if (!tool) {
420
+ throw new AgentKarmaValidationError(`Unknown AgentKarma tool: ${name}`);
421
+ }
422
+ return tool.handler(client, input);
423
+ }