{"_id":"@capitalthought/agent-feedback","name":"@capitalthought/agent-feedback","dist-tags":{"latest":"0.1.0"},"versions":{"0.1.0":{"name":"@capitalthought/agent-feedback","version":"0.1.0","description":"Operator feedback + error reporting for agent-first MCP products. Drop-in tool factory + error-wrap middleware.","type":"module","main":"./dist/index.js","types":"./dist/index.d.ts","exports":{".":{"import":"./dist/index.js","types":"./dist/index.d.ts"}},"scripts":{"build":"tsc","test":"vitest run","type-check":"tsc --noEmit"},"dependencies":{"zod":"^3.23.0"},"devDependencies":{"typescript":"^5.6.0","vitest":"^2.1.0","@types/node":"^22.0.0"},"publishConfig":{"access":"public"},"repository":{"type":"git","url":"git+https://github.com/capitalthought/agent-feedback.git"},"keywords":["mcp","agent-first","feedback","capitalthought"],"author":{"name":"Capital Thought"},"license":"UNLICENSED","_id":"@capitalthought/agent-feedback@0.1.0","gitHead":"e1419c40f87d976164aa2f65b049a32dbc7430d4","bugs":{"url":"https://github.com/capitalthought/agent-feedback/issues"},"homepage":"https://github.com/capitalthought/agent-feedback#readme","_nodeVersion":"20.20.2","_npmVersion":"10.8.2","dist":{"integrity":"sha512-S+K+MVTeDOEs0xkSmqQcjifbY3546RuJeTFCUgqFLO/8s/mSF9cY25Eqq3g53gMdX9HuXN14fnZ7jn+ZicUx7g==","shasum":"16401dff7f2c6383f53476136e317aa0f1a19310","tarball":"https://registry.npmjs.org/@capitalthought/agent-feedback/-/agent-feedback-0.1.0.tgz","fileCount":35,"unpackedSize":39276,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEQCIBiCA6hF2bNATywETd988kd06CcPs+u+m9F3HwCnEr7YAiAswrUSirFRga2a/dCN2DwEJ9YQFQJu8GOlw6y8BT/HNQ=="}]},"_npmUser":{"name":"joshuabaer","email":"npmjs@joshspam.com"},"directories":{},"maintainers":[{"name":"joshuabaer","email":"npmjs@joshspam.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/agent-feedback_0.1.0_1777907306257_0.3557430320049664"},"_hasShrinkwrap":false}},"time":{"created":"2026-05-04T15:08:26.173Z","0.1.0":"2026-05-04T15:08:26.404Z","modified":"2026-05-04T15:08:26.582Z"},"maintainers":[{"name":"joshuabaer","email":"npmjs@joshspam.com"}],"description":"Operator feedback + error reporting for agent-first MCP products. Drop-in tool factory + error-wrap middleware.","homepage":"https://github.com/capitalthought/agent-feedback#readme","keywords":["mcp","agent-first","feedback","capitalthought"],"repository":{"type":"git","url":"git+https://github.com/capitalthought/agent-feedback.git"},"author":{"name":"Capital Thought"},"bugs":{"url":"https://github.com/capitalthought/agent-feedback/issues"},"license":"UNLICENSED","readme":"# @capitalthought/agent-feedback\n\nOperator feedback + error reporting for agent-first MCP products. Drop-in tool factory + error-wrap middleware for capturing feedback from inside Claude/Mikey conversations.\n\n## Why\n\nIn agent-first products, operators interact through an LLM (Mikey, Claude) — not a UI. When an operator says \"this is weird\" or hits a tool error, that signal evaporates the moment the conversation ends. This package gives you:\n\n1. An explicit MCP tool (`<product>_feedback`) the agent calls when the operator signals friction.\n2. A middleware (`wrapWithFeedback`) that auto-captures user-facing tool errors with a structured `feedback_id` returned to the LLM.\n\nBoth paths use the operator's existing JWT — no new shared secrets, no impersonation vector.\n\n## Install\n\n```bash\nnpm install @capitalthought/agent-feedback\n```\n\n## Usage\n\n### 1. Implement `FeedbackStorage` against your backend\n\n```ts\nimport type { FeedbackStorage, FeedbackInput, FeedbackRecord } from '@capitalthought/agent-feedback';\n\nexport class MyFeedbackStorage implements FeedbackStorage {\n  async create(input: FeedbackInput): Promise<FeedbackRecord> { /* INSERT into your DB */ }\n  async getById(id: string): Promise<FeedbackRecord | null> { /* SELECT */ }\n}\n```\n\n### 2. Register the explicit tool in your MCP server\n\n```ts\nimport { createFeedbackTool } from '@capitalthought/agent-feedback';\n\nconst feedbackTool = createFeedbackTool({\n  apiBaseUrl: 'https://yourproduct.com',\n  productName: 'yourproduct',\n  getAuthToken: async () => operatorJwt,  // your existing operator JWT cache\n});\n\nserver.registerTool(feedbackTool);\n```\n\n### 3. Wrap your existing tool handlers with the middleware\n\n```ts\nimport { wrapWithFeedback, defaultClassifier } from '@capitalthought/agent-feedback';\n\nconst userFacingErrors = new Set(['mfa_required', 'address_required', /* ... */]);\nconst infraNoise = new Set(['rate_limited', 'transient_5xx']);\n\nconst sessionId = `${operatorEmail}-${Date.now()}`;\n\nconst wrapped = wrapWithFeedback('yourproduct_launch', originalHandler, {\n  apiBaseUrl: 'https://yourproduct.com',\n  productName: 'yourproduct',\n  getAuthToken: async () => operatorJwt,\n  classifier: (code, tool) => defaultClassifier(code, tool, {\n    userFacingErrorCodes: userFacingErrors,\n    infraNoiseErrorCodes: infraNoise,\n  }),\n  sessionId,\n  skipToolNames: new Set(['yourproduct_feedback']), // never wrap the feedback tool itself\n});\n```\n\n### 4. Implement `POST /api/feedback` server-side\n\nThe middleware POSTs to `${apiBaseUrl}/api/feedback` with the operator JWT in the Authorization header. Your server should:\n\n- Validate the JWT and derive `operator_email` from it (NOT from the request body)\n- Validate `summary` + `context` for PII (no emails, phones, SSNs, URLs with querystrings, HTML)\n- Insert via your `FeedbackStorage`\n- Return `{ short_id: 'fb_XXXXXXXXXX' }`\n\nSee `AGENTS.md` for the full agent contract.\n\n## Default classifier\n\n`defaultClassifier(errorCode, toolName, options)` is **default-suppress** on unknown error codes. Only codes in `userFacingErrorCodes` are captured. This avoids polluting the triage queue with novel infra noise.\n\n## Per-session rate limit\n\nThe middleware caps feedback creates at 3 per session (configurable via `cap` option). Beyond the cap, captures are silently dropped — the original tool response is returned untouched.\n\n## Recursion guard\n\nPass the explicit feedback tool's name in `skipToolNames` to prevent the middleware from trying to record feedback about a failed feedback create.\n\n## License\n\nUNLICENSED — internal Capital Thought tooling. Open-sourced for transparency only.\n","readmeFilename":"README.md","_rev":"1-402654f3d5c0570499fa916d2ef92909"}