{"_id":"@anaisbetts/kubera-3p-mcp","name":"@anaisbetts/kubera-3p-mcp","dist-tags":{"latest":"0.1.0"},"versions":{"0.1.0":{"name":"@anaisbetts/kubera-3p-mcp","version":"0.1.0","module":"index.ts","type":"module","license":"MIT","bin":{"kubera-3p-mcp":"dist/kubera-3p-mcp.js"},"scripts":{"build":"bun build ./src/cli.ts --outfile dist/kubera-3p-mcp.js --target node --banner \"#!/usr/bin/env node\"","prepare":"git clean -xdf dist && bun run build","start":"bun run src/cli.ts","typecheck":"tsc --noEmit","capture":"bun run scripts/capture-fixtures.ts"},"dependencies":{"@modelcontextprotocol/sdk":"^1.30.0","zod":"^4.4.3"},"devDependencies":{"@types/bun":"latest","typescript":"5.8.3"},"gitHead":"09448c58baacd302cf99bccc6b205469d22768aa","_id":"@anaisbetts/kubera-3p-mcp@0.1.0","description":"Typed TypeScript client for the Kubera (`api.kubera.com`) REST API, plus an MCP server that exposes those endpoints as tools.","_nodeVersion":"25.0.0","_npmVersion":"11.6.2","dist":{"integrity":"sha512-o11aYZPWLlllvrE3eVLrvi1N8QJKY66cYpXZy2QdouoaJjiF7bMV14z5eOKg90vhku/qtiDVcIRakgxFEmbyEg==","shasum":"b1a4b4d4daa6d9a51cbc7edda679b610844c4416","tarball":"https://registry.npmjs.org/@anaisbetts/kubera-3p-mcp/-/kubera-3p-mcp-0.1.0.tgz","fileCount":3,"unpackedSize":1042716,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEYCIQCN2w4xG2rsFzIL7+uNCLFzOflYcbJSDyGA0KMXQbCxaQIhAImd9zuNTIG6KgIBMfB5uQLMxF0SWLkfh/Jt1aOT9awb"}]},"_npmUser":{"name":"anaisbetts","email":"anais@anaisbetts.org"},"directories":{},"maintainers":[{"name":"anaisbetts","email":"anais@anaisbetts.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/kubera-3p-mcp_0.1.0_1785780130641_0.6457245535253331"},"_hasShrinkwrap":false}},"time":{"created":"2026-08-03T18:02:10.424Z","0.1.0":"2026-08-03T18:02:10.846Z","modified":"2026-08-03T18:02:11.082Z"},"maintainers":[{"name":"anaisbetts","email":"anais@anaisbetts.org"}],"description":"Typed TypeScript client for the Kubera (`api.kubera.com`) REST API, plus an MCP server that exposes those endpoints as tools.","license":"MIT","readme":"# kubera-3p-mcp\n\nTyped TypeScript client for the Kubera (`api.kubera.com`) REST API, plus an MCP server that exposes those endpoints as tools.\n\n## Why does this exist?\n\nKubera has decided that if you have a white-label account (i.e. run by your financial advisor), you're not allowed to use their MCP Server to access your own financial data. So instead, we make our own and tell them to fly a kite.\n\n## Requirements\n\n- [Bun](https://bun.sh) 1.1+ (for local development / `prepare` build)\n- Node.js 18+ (to run the published `bin` bundle)\n\n## Install\n\n```bash\nbun install\n```\n\n## Auth: `cognito-session.json`\n\nKubera API calls use:\n\n```http\nAuthorization: Bearer <Cognito AccessToken>\n```\n\nAccessTokens expire in about an hour. You provide a Cognito **session file** (refresh token, device fields, and your white-label `baseUrl`). Derived AccessTokens are cached on disk — same pattern as stonex-mcp — so Cognito refresh is not called on every tool use.\n\nThe session file also carries:\n\n| Field | Purpose |\n|-------|---------|\n| `baseUrl` | White-label host used for `Origin` / `Referer` (required) |\n| `apiBaseUrl` | API root (optional; defaults to `https://api.kubera.com/api/v1`) |\n| `clientId` | Cognito app client id (from Amplify localStorage) |\n| `userPoolId` | Cognito user pool id (from access/id token `iss`) |\n\n### Export session (one paste)\n\n1. Log into your Kubera white-label host in the browser.\n2. Open DevTools → **Console**.\n3. Paste the contents of [`scripts/export-cognito-session.js`](scripts/export-cognito-session.js) and press Enter.\n4. Save the downloaded `cognito-session.json`.\n5. Run:\n\n```bash\nkubera-3p-mcp --session /path/to/cognito-session.json\n```\n\n### AccessToken cache\n\n| OS | Path |\n|----|------|\n| Windows | `%LOCALAPPDATA%\\kubera-3p-mcp\\access-token.json` |\n| macOS | `~/Library/Caches/kubera-3p-mcp/access-token.json` |\n| Linux | `${XDG_CACHE_HOME:-~/.cache}/kubera-3p-mcp/access-token.json` |\n\nStartup / request flow:\n\n1. Prefer a still-valid cached AccessToken.\n2. Else, if the session export still has a valid AccessToken, cache that.\n3. Else call Cognito `REFRESH_TOKEN_AUTH` once and write the new AccessToken to the cache.\n4. On API `401`, clear cache, refresh once, retry; if that fails, re-export the session file.\n\nTreat the session file and cached token like passwords. Do not commit them.\n\n## Run the MCP server\n\n```bash\nbun start -- --session /path/to/cognito-session.json\n# or after build:\nnode dist/kubera-3p-mcp.js --session /path/to/cognito-session.json\n```\n\n### Cursor / Claude Desktop config\n\n```json\n{\n  \"mcpServers\": {\n    \"kubera\": {\n      \"command\": \"npx\",\n      \"args\": [\n        \"-y\",\n        \"kubera-3p-mcp\",\n        \"--session\",\n        \"C:/Users/YOU/cognito-session.json\"\n      ]\n    }\n  }\n}\n```\n\nLocal equivalent: `\"command\": \"bun\", \"args\": [\"run\", \"/path/to/kubera-3p-mcp/src/cli.ts\", \"--session\", \"/path/to/cognito-session.json\"]`.\n\n## Typed client\n\n```ts\nimport { KuberaClient } from \"./src/client/index.ts\";\nimport { resolveAuth } from \"./src/auth/resolveAuth.ts\";\nimport { writeTokenCache } from \"./src/auth/tokenCache.ts\";\n\nconst { accessToken, session } = await resolveAuth(\n  \"/path/to/cognito-session.json\",\n);\n\nconst client = new KuberaClient({\n  accessToken,\n  session,\n  onAccessToken: (token) => writeTokenCache(token),\n});\n\nconst user = await client.getUser();\nconst portfolios = await client.getPortfolios();\nconst portfolioId = portfolios.data.portfolio[0]!.id;\nconst chart = await client.getChartAndCagr({ portfolioId });\n```\n\n## Capture fixtures\n\n```bash\nbun run capture -- --session ./cognito-session.json\n```\n\n## Security note\n\nLocal capture files (`kubera-fetch.js`, `kubera-har.json`, `kubera-urls.txt`), `cognito-session.json`, and `fixtures/` can contain live secrets and portfolio data. They are gitignored. Rotate credentials if those files were shared.\n","readmeFilename":"README.md","_rev":"1-47f8b4ba77126430cf4e5259b4591bcf"}