adaptive-memory-multi-model-router 2.15.4 → 2.16.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.
Files changed (129) hide show
  1. package/AGENT_COUNCIL_FINDINGS.md +123 -98
  2. package/CAMPAIGN_SUMMARY.md +87 -0
  3. package/CHANGELOG.md +7 -1
  4. package/ENTERPRISE_INTEGRATIONS.md +94 -0
  5. package/INTEGRATION_PROGRESS.md +96 -0
  6. package/OPPORTUNITIES_100.md +277 -0
  7. package/POPULARITY_BOOSTERS.md +1 -1
  8. package/README.md +147 -275
  9. package/README_ja.md +17 -21
  10. package/README_zh.md +13 -17
  11. package/TODO_BROWSER_AUTOMATION.md +87 -0
  12. package/a3m-integrations-summary.md +73 -0
  13. package/apps/cost-calculator/README.md +72 -0
  14. package/apps/cost-calculator/calculator.css +280 -0
  15. package/apps/cost-calculator/calculator.js +150 -0
  16. package/apps/cost-calculator/index.html +321 -0
  17. package/apps/cost-calculator/package.json +13 -0
  18. package/articles/ANNOUNCEMENT_reddit_ml.md +76 -0
  19. package/articles/ANNOUNCEMENT_vc/347/244/276/345/214/272.md +71 -0
  20. package/articles/ANNOUNCEMENT_vercel.md +85 -0
  21. package/articles/CHINESE_DIRECTORIES.md +2 -2
  22. package/articles/CHINESE_SUBMISSIONS_READY.md +5 -5
  23. package/articles/HN_POST_READY.md +16 -20
  24. package/articles/INDIEHACKERS_READY.md +19 -34
  25. package/dist/analytics/costAnalytics.d.ts +0 -1
  26. package/dist/benchmark/reproducible.d.ts +0 -1
  27. package/dist/cache/semanticCache.d.ts +0 -1
  28. package/dist/cost/budgetEnforcer.d.ts +0 -1
  29. package/dist/cost/costTracker.d.ts +0 -1
  30. package/dist/ensemble/multiRoundDialog.d.ts +0 -1
  31. package/dist/ensemble/shapleyValue.d.ts +0 -1
  32. package/dist/ensemble.d.ts +0 -1
  33. package/dist/index.d.ts +0 -1
  34. package/dist/integrations/oauth.d.ts +0 -1
  35. package/dist/integrations/scienceAdapter.d.ts +0 -1
  36. package/dist/memory/autoFetch.d.ts +0 -1
  37. package/dist/memory/hybridMemory.d.ts +0 -1
  38. package/dist/memory/memoryTree.d.ts +0 -1
  39. package/dist/memory/obsidianVault.d.ts +0 -1
  40. package/dist/memory/reasoningBank.d.ts +0 -1
  41. package/dist/observability/changeWatch.d.ts +0 -1
  42. package/dist/observability/fatigueDetector.d.ts +0 -1
  43. package/dist/observability/index.d.ts +0 -1
  44. package/dist/observability/metrics.d.ts +0 -1
  45. package/dist/observability/middleware.d.ts +0 -1
  46. package/dist/observability/tracer.d.ts +0 -1
  47. package/dist/observability/types.d.ts +0 -1
  48. package/dist/providers/providerConfig.d.ts +5 -2
  49. package/dist/providers/providerConfig.js +1006 -1
  50. package/dist/providers/providerConfig.js.map +1 -1
  51. package/dist/routing/advancedRouter.d.ts +1 -2
  52. package/dist/routing/advancedRouter.js +84 -0
  53. package/dist/routing/advancedRouter.js.map +1 -1
  54. package/dist/routing/crossModelValidation.d.ts +0 -1
  55. package/dist/routing/providerHealth.d.ts +77 -2
  56. package/dist/routing/providerHealth.js +190 -4
  57. package/dist/routing/providerHealth.js.map +1 -1
  58. package/dist/routing/providerRetry.d.ts +0 -1
  59. package/dist/routing/shadowSampler.d.ts +187 -0
  60. package/dist/routing/shadowSampler.js +306 -0
  61. package/dist/routing/shadowSampler.js.map +1 -0
  62. package/dist/sdk.d.ts +0 -1
  63. package/dist/security/guardrails.d.ts +0 -1
  64. package/dist/server/dashboard.d.ts +0 -1
  65. package/dist/server/handlers/chatHandler.d.ts +0 -1
  66. package/dist/server/handlers/completionsHandler.d.ts +0 -1
  67. package/dist/server/handlers/embeddingsHandler.d.ts +0 -1
  68. package/dist/server/handlers/healthHandler.d.ts +0 -1
  69. package/dist/server/handlers/metricsHandler.d.ts +0 -1
  70. package/dist/server/handlers/modelsHandler.d.ts +0 -1
  71. package/dist/server/metrics.d.ts +0 -1
  72. package/dist/server/modelMapper.d.ts +0 -1
  73. package/dist/server/proxyServer.d.ts +0 -1
  74. package/dist/server/router.d.ts +0 -1
  75. package/dist/server/state.d.ts +0 -1
  76. package/dist/tui/dashboard.d.ts +0 -1
  77. package/dist/utils/costUtils.d.ts +0 -1
  78. package/dist/utils/sorting.d.ts +0 -1
  79. package/dist/utils/tokenUtils.d.ts +0 -1
  80. package/docs/llms-full.txt +153 -286
  81. package/docs/llms.txt +71 -112
  82. package/integrations/browser-use/README.md +155 -0
  83. package/integrations/browser-use/examples/form-filling.ts +179 -0
  84. package/integrations/browser-use/index.ts +145 -0
  85. package/integrations/browser-use/package.json +34 -0
  86. package/integrations/browser-use/tsconfig.json +17 -0
  87. package/integrations/mcp-browser/README.md +177 -0
  88. package/integrations/mcp-browser/package.json +38 -0
  89. package/integrations/mcp-browser/src/index.ts +297 -0
  90. package/integrations/sota-browser/README.md +191 -0
  91. package/integrations/sota-browser/package.json +34 -0
  92. package/llms-full.txt +6 -6
  93. package/llms.txt +62 -112
  94. package/package.json +92 -13
  95. package/packages/a3m-vercel-ai/README.md +161 -0
  96. package/packages/a3m-vercel-ai/dist/a3m-language-model.d.ts +12 -0
  97. package/packages/a3m-vercel-ai/dist/a3m-language-model.d.ts.map +1 -0
  98. package/packages/a3m-vercel-ai/dist/a3m-language-model.js +289 -0
  99. package/packages/a3m-vercel-ai/dist/a3m-language-model.js.map +1 -0
  100. package/packages/a3m-vercel-ai/dist/index.d.ts +82 -0
  101. package/packages/a3m-vercel-ai/dist/index.d.ts.map +1 -0
  102. package/packages/a3m-vercel-ai/dist/index.js +79 -0
  103. package/packages/a3m-vercel-ai/dist/index.js.map +1 -0
  104. package/packages/a3m-vercel-ai/dist/types.d.ts +97 -0
  105. package/packages/a3m-vercel-ai/dist/types.d.ts.map +1 -0
  106. package/packages/a3m-vercel-ai/dist/types.js +5 -0
  107. package/packages/a3m-vercel-ai/dist/types.js.map +1 -0
  108. package/packages/a3m-vercel-ai/package-lock.json +969 -0
  109. package/packages/a3m-vercel-ai/package.json +46 -0
  110. package/packages/a3m-vercel-ai/src/a3m-language-model.ts +381 -0
  111. package/packages/a3m-vercel-ai/src/index.ts +104 -0
  112. package/packages/a3m-vercel-ai/src/types.ts +116 -0
  113. package/packages/a3m-vercel-ai/tsconfig.json +20 -0
  114. package/src/providers/providerConfig.ts +1053 -1
  115. package/summary.txt +38 -0
  116. package/.github/ISSUE_TEMPLATE/bug_report.md +0 -94
  117. package/.github/ISSUE_TEMPLATE/config.yml +0 -17
  118. package/.github/ISSUE_TEMPLATE/feature_request.md +0 -71
  119. package/.well-known/ai-plugin.json +0 -16
  120. package/adapters/README.md +0 -36
  121. package/adapters/__init__.py +0 -25
  122. package/adapters/a3m_adapter/__init__.py +0 -15
  123. package/adapters/a3m_adapter/adapter/__init__.py +0 -7
  124. package/adapters/a3m_adapter/adapter/config.py +0 -100
  125. package/adapters/a3m_adapter/adapter/langchain.py +0 -155
  126. package/adapters/a3m_adapter/adapter/llamaindex.py +0 -162
  127. package/adapters/a3m_adapter/tests/__init__.py +0 -1
  128. package/adapters/a3m_adapter/tests/test_adapters.py +0 -120
  129. package/adapters/setup.py +0 -23
@@ -0,0 +1,34 @@
1
+ {
2
+ "name": "a3m-browser-use",
3
+ "version": "1.0.0",
4
+ "description": "A3M Router integration for browser-use - cost-optimized browser automation",
5
+ "main": "dist/index.js",
6
+ "types": "dist/index.d.ts",
7
+ "scripts": {
8
+ "build": "tsc",
9
+ "prepublishOnly": "npm run build"
10
+ },
11
+ "dependencies": {
12
+ "adaptive-memory-multi-model-router": "^2.14.0",
13
+ "browser-use": "^0.12.0"
14
+ },
15
+ "peerDependencies": {
16
+ "browser-use": "^0.12.0"
17
+ },
18
+ "keywords": [
19
+ "browser-use",
20
+ "a3m",
21
+ "llm",
22
+ "router",
23
+ "browser-automation",
24
+ "cost-optimization",
25
+ "stealth",
26
+ "anti-detection"
27
+ ],
28
+ "repository": {
29
+ "type": "git",
30
+ "url": "https://github.com/Das-rebel/a3m-router"
31
+ },
32
+ "author": "Subhojit Das",
33
+ "license": "MIT"
34
+ }
@@ -0,0 +1,17 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2022",
4
+ "module": "NodeNext",
5
+ "moduleResolution": "NodeNext",
6
+ "outDir": "./dist",
7
+ "rootDir": "./src",
8
+ "strict": true,
9
+ "esModuleInterop": true,
10
+ "skipLibCheck": true,
11
+ "declaration": true,
12
+ "declarationMap": true,
13
+ "sourceMap": true
14
+ },
15
+ "include": ["src/**/*"],
16
+ "exclude": ["node_modules", "dist", "examples"]
17
+ }
@@ -0,0 +1,177 @@
1
+ # A3M Router MCP Server for Browser Automation
2
+
3
+ **Use A3M's intelligent routing as an MCP server for AI agents.**
4
+
5
+ This integration exposes A3M Router's capabilities via the Model Context Protocol (MCP), enabling AI agents (Claude Desktop, Cursor, Codex, n8n, etc.) to use intelligent LLM routing for browser automation tasks.
6
+
7
+ ## What is MCP?
8
+
9
+ The [Model Context Protocol](https://modelcontextprotocol.io/) is an open standard for connecting AI assistants to external tools and data sources. MCP servers expose capabilities as "tools" that AI agents can call.
10
+
11
+ ## Installation
12
+
13
+ ```bash
14
+ npm install a3m-mcp-browser
15
+ # or
16
+ npx a3m-mcp-browser
17
+ ```
18
+
19
+ ## Setup
20
+
21
+ ### Claude Desktop
22
+
23
+ Add to `~/Library/Application Support/Claude/claude_desktop_config.json`:
24
+
25
+ ```json
26
+ {
27
+ "mcpServers": {
28
+ "a3m-browser": {
29
+ "command": "npx",
30
+ "args": ["a3m-mcp-browser"]
31
+ }
32
+ }
33
+ }
34
+ ```
35
+
36
+ ### Cursor
37
+
38
+ Settings → MCP → Add new server:
39
+
40
+ ```json
41
+ {
42
+ "name": "a3m-browser",
43
+ "command": "npx",
44
+ "args": ["a3m-mcp-browser"]
45
+ }
46
+ ```
47
+
48
+ ### n8n
49
+
50
+ Add MCP Trigger node with server config above.
51
+
52
+ ## Available Tools
53
+
54
+ ### `route_for_browser_task`
55
+
56
+ Route a browser task to the optimal LLM provider.
57
+
58
+ ```json
59
+ {
60
+ "task": "Extract all job listings from this page including title, company, and apply URL",
61
+ "context": "web_scraping"
62
+ }
63
+ ```
64
+
65
+ **Context options:**
66
+ - `web_scraping` - Data extraction from web pages
67
+ - `form_filling` - Filling out web forms
68
+ - `form_analysis` - Analyzing form structure
69
+ - `content_generation` - Generating content for web
70
+ - `decision_making` - Making decisions based on page content
71
+
72
+ ### `extract_form_data`
73
+
74
+ Extract structured data from a web page.
75
+
76
+ ```json
77
+ {
78
+ "page_html": "<html>...</html>",
79
+ "schema": {
80
+ "name": "string",
81
+ "email": "string",
82
+ "jobs": "array"
83
+ }
84
+ }
85
+ ```
86
+
87
+ ### `fill_form_intelligently`
88
+
89
+ Get optimal values to fill a form field.
90
+
91
+ ```json
92
+ {
93
+ "field_name": "email",
94
+ "field_type": "email",
95
+ "user_profile": {
96
+ "email": "user@example.com"
97
+ }
98
+ }
99
+ ```
100
+
101
+ ### `get_stealth_routing`
102
+
103
+ Get routing configuration optimized for stealth.
104
+
105
+ ```json
106
+ {
107
+ "minimize_detection": true,
108
+ "provider_rotation": true
109
+ }
110
+ ```
111
+
112
+ ## Example Workflow
113
+
114
+ ### Claude Desktop
115
+
116
+ ```
117
+ You: Use A3M to extract all job listings from linkedin.com/jobs/search?q=marketing
118
+
119
+ Claude: I'll use the A3M router to extract the job data...
120
+
121
+ [Calls route_for_browser_task with task="Extract all job listings..."]
122
+
123
+ Claude: I found 25 jobs. Here's the first few:
124
+
125
+ 1. **Head of Marketing** @ TechCorp
126
+ - URL: https://linkedin.com/jobs/view/123
127
+ - Location: Bengaluru
128
+ - Posted: 2 days ago
129
+
130
+ 2. **VP Growth** @ StartupXYZ
131
+ - URL: https://linkedin.com/jobs/view/456
132
+ - Location: Mumbai
133
+ - Posted: 5 days ago
134
+ ```
135
+
136
+ ### Cursor
137
+
138
+ ```
139
+ User: Fill out this job application form using my resume data
140
+
141
+ Cursor: I'll use A3M to intelligently fill the form...
142
+
143
+ [Calls fill_form_intelligently for each field]
144
+
145
+ [Calls route_for_browser_task to verify form completion]
146
+ ```
147
+
148
+ ## Cost Savings
149
+
150
+ | Task Type | Without A3M | With A3M | Savings |
151
+ |-----------|-------------|----------|---------|
152
+ | Form filling | $0.03/task | $0.002/task | 93% |
153
+ | Data extraction | $0.01/task | $0.003/task | 70% |
154
+ | Page analysis | $0.02/task | $0.005/task | 75% |
155
+
156
+ ## Features
157
+
158
+ - **Automatic routing** - Routes to cheapest capable model
159
+ - **Stealth mode** - Minimize bot detection
160
+ - **Parallel ensemble** - Run multiple providers for reliability
161
+ - **Fallback handling** - Automatic retry on failure
162
+ - **Cost tracking** - Monitor spending per task
163
+
164
+ ## Configuration
165
+
166
+ ```json
167
+ {
168
+ "model": "auto",
169
+ "stealth": true,
170
+ "parallelEnsemble": 3,
171
+ "providers": ["openai", "anthropic", "google", "groq"]
172
+ }
173
+ ```
174
+
175
+ ## License
176
+
177
+ MIT - Same as A3M Router
@@ -0,0 +1,38 @@
1
+ {
2
+ "name": "a3m-mcp-browser",
3
+ "version": "1.0.0",
4
+ "description": "A3M Router MCP server for browser automation",
5
+ "main": "dist/index.js",
6
+ "types": "dist/index.d.ts",
7
+ "bin": {
8
+ "a3m-mcp-browser": "dist/index.js"
9
+ },
10
+ "scripts": {
11
+ "build": "tsc",
12
+ "start": "node dist/index.js",
13
+ "dev": "tsc && node dist/index.js"
14
+ },
15
+ "dependencies": {
16
+ "adaptive-memory-multi-model-router": "^2.14.0",
17
+ "@modelcontextprotocol/sdk": "^0.5.0"
18
+ },
19
+ "engines": {
20
+ "node": ">=18.0.0"
21
+ },
22
+ "keywords": [
23
+ "mcp",
24
+ "model-context-protocol",
25
+ "a3m",
26
+ "browser-automation",
27
+ "llm-routing",
28
+ "claude",
29
+ "cursor",
30
+ "n8n"
31
+ ],
32
+ "repository": {
33
+ "type": "git",
34
+ "url": "https://github.com/Das-rebel/a3m-router"
35
+ },
36
+ "author": "Subhojit Das",
37
+ "license": "MIT"
38
+ }
@@ -0,0 +1,297 @@
1
+ /**
2
+ * A3M Router MCP Server for Browser Automation
3
+ *
4
+ * Exposes A3M's intelligent LLM routing as MCP tools for AI agents.
5
+ */
6
+
7
+ import { Server } from '@modelcontextprotocol/sdk/server/index.js';
8
+ import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
9
+ import {
10
+ CallToolRequestSchema,
11
+ ListToolsRequestSchema,
12
+ } from '@modelcontextprotocol/sdk/types.js';
13
+ import { A3MRouter } from 'adaptive-memory-multi-model-router';
14
+
15
+ // Initialize A3M Router
16
+ const router = new A3MRouter({
17
+ model: 'auto',
18
+ stealth: true,
19
+ parallelEnsemble: 3,
20
+ browserOptimized: true,
21
+ providers: ['openai', 'anthropic', 'google', 'groq'],
22
+ });
23
+
24
+ // Create MCP server
25
+ const server = new Server(
26
+ {
27
+ name: 'a3m-browser',
28
+ version: '1.0.0',
29
+ },
30
+ {
31
+ capabilities: {
32
+ tools: {},
33
+ },
34
+ }
35
+ );
36
+
37
+ // Define available tools
38
+ const tools = [
39
+ {
40
+ name: 'route_for_browser_task',
41
+ description: 'Route a browser automation task to the optimal LLM provider. Best for: web scraping, form filling, content extraction, page analysis.',
42
+ inputSchema: {
43
+ type: 'object',
44
+ properties: {
45
+ task: {
46
+ type: 'string',
47
+ description: 'The browser automation task to route',
48
+ },
49
+ context: {
50
+ type: 'string',
51
+ enum: ['web_scraping', 'form_filling', 'form_analysis', 'content_generation', 'decision_making'],
52
+ description: 'Type of browser task',
53
+ default: 'web_scraping',
54
+ },
55
+ },
56
+ required: ['task'],
57
+ },
58
+ },
59
+ {
60
+ name: 'extract_form_data',
61
+ description: 'Extract structured data from a web page HTML.',
62
+ inputSchema: {
63
+ type: 'object',
64
+ properties: {
65
+ page_html: {
66
+ type: 'string',
67
+ description: 'The HTML content of the page',
68
+ },
69
+ schema: {
70
+ type: 'object',
71
+ description: 'JSON schema describing what to extract',
72
+ },
73
+ },
74
+ required: ['page_html', 'schema'],
75
+ },
76
+ },
77
+ {
78
+ name: 'fill_form_intelligently',
79
+ description: 'Determine the best value to fill a form field with, based on user profile.',
80
+ inputSchema: {
81
+ type: 'object',
82
+ properties: {
83
+ field_name: {
84
+ type: 'string',
85
+ description: 'Name of the form field',
86
+ },
87
+ field_type: {
88
+ type: 'string',
89
+ description: 'Type of field (text, email, phone, etc.)',
90
+ },
91
+ user_profile: {
92
+ type: 'object',
93
+ description: 'User profile data to fill from',
94
+ },
95
+ },
96
+ required: ['field_name', 'field_type', 'user_profile'],
97
+ },
98
+ },
99
+ {
100
+ name: 'get_stealth_routing',
101
+ description: 'Get routing configuration optimized for stealth (minimizing bot detection).',
102
+ inputSchema: {
103
+ type: 'object',
104
+ properties: {
105
+ minimize_detection: {
106
+ type: 'boolean',
107
+ description: 'Enable stealth mode',
108
+ default: true,
109
+ },
110
+ },
111
+ },
112
+ },
113
+ {
114
+ name: 'get_cost_stats',
115
+ description: 'Get cost statistics for routing decisions.',
116
+ inputSchema: {
117
+ type: 'object',
118
+ properties: {},
119
+ },
120
+ },
121
+ ];
122
+
123
+ // List tools handler
124
+ server.setRequestHandler(ListToolsRequestSchema, async () => {
125
+ return { tools };
126
+ });
127
+
128
+ // Call tool handler
129
+ server.setRequestHandler(CallToolRequestSchema, async (request) => {
130
+ const { name, arguments: args } = request.params;
131
+
132
+ try {
133
+ switch (name) {
134
+ case 'route_for_browser_task': {
135
+ const { task, context = 'web_scraping' } = args as {
136
+ task: string;
137
+ context?: string;
138
+ };
139
+
140
+ const result = await router.route({
141
+ task,
142
+ context: context as any,
143
+ });
144
+
145
+ return {
146
+ content: [
147
+ {
148
+ type: 'text',
149
+ text: JSON.stringify({
150
+ content: result.content,
151
+ provider: result.provider,
152
+ model: result.model,
153
+ cost: result.cost,
154
+ }, null, 2),
155
+ },
156
+ ],
157
+ };
158
+ }
159
+
160
+ case 'extract_form_data': {
161
+ const { page_html, schema } = args as {
162
+ page_html: string;
163
+ schema: any;
164
+ };
165
+
166
+ const result = await router.route({
167
+ task: `Extract structured data from this HTML matching the schema: ${JSON.stringify(schema)}`,
168
+ context: 'data_extraction',
169
+ });
170
+
171
+ return {
172
+ content: [
173
+ {
174
+ type: 'text',
175
+ text: result.content,
176
+ },
177
+ ],
178
+ };
179
+ }
180
+
181
+ case 'fill_form_intelligently': {
182
+ const { field_name, field_type, user_profile } = args as {
183
+ field_name: string;
184
+ field_type: string;
185
+ user_profile: any;
186
+ };
187
+
188
+ // Map field types to profile keys
189
+ const fieldMappings: Record<string, string> = {
190
+ 'first name': 'firstName',
191
+ 'last name': 'lastName',
192
+ 'email': 'email',
193
+ 'phone': 'phone',
194
+ 'name': 'fullName',
195
+ };
196
+
197
+ const profileKey = fieldMappings[field_name.toLowerCase()] || field_name.toLowerCase();
198
+ let value = user_profile[profileKey];
199
+
200
+ if (!value) {
201
+ // Try common variations
202
+ const variations = [
203
+ field_name.replace(/\s+/g, ''),
204
+ field_name.replace(/\s+/g, '_'),
205
+ field_name.toLowerCase(),
206
+ ];
207
+ for (const v of variations) {
208
+ if (user_profile[v]) {
209
+ value = user_profile[v];
210
+ break;
211
+ }
212
+ }
213
+ }
214
+
215
+ return {
216
+ content: [
217
+ {
218
+ type: 'text',
219
+ text: JSON.stringify({
220
+ field: field_name,
221
+ suggested_value: value || '',
222
+ provider: 'profile_lookup',
223
+ }, null, 2),
224
+ },
225
+ ],
226
+ };
227
+ }
228
+
229
+ case 'get_stealth_routing': {
230
+ return {
231
+ content: [
232
+ {
233
+ type: 'text',
234
+ text: JSON.stringify({
235
+ stealth: true,
236
+ proxy_rotation: true,
237
+ humanize_timing: true,
238
+ randomize_user_agent: true,
239
+ recommended_providers: ['anthropic', 'google'],
240
+ avoid_providers: ['openai-gpt4'], // Rate limited sites
241
+ }, null, 2),
242
+ },
243
+ ],
244
+ };
245
+ }
246
+
247
+ case 'get_cost_stats': {
248
+ const stats = router.getStats();
249
+ const cost = router.getCost();
250
+
251
+ return {
252
+ content: [
253
+ {
254
+ type: 'text',
255
+ text: JSON.stringify({
256
+ total_requests: stats.totalRequests,
257
+ total_cost: cost.total,
258
+ average_cost_per_request: cost.total / (stats.totalRequests || 1),
259
+ by_provider: cost.byProvider,
260
+ }, null, 2),
261
+ },
262
+ ],
263
+ };
264
+ }
265
+
266
+ default:
267
+ return {
268
+ content: [
269
+ {
270
+ type: 'text',
271
+ text: `Unknown tool: ${name}`,
272
+ },
273
+ ],
274
+ isError: true,
275
+ };
276
+ }
277
+ } catch (error) {
278
+ return {
279
+ content: [
280
+ {
281
+ type: 'text',
282
+ text: `Error: ${error instanceof Error ? error.message : String(error)}`,
283
+ },
284
+ ],
285
+ isError: true,
286
+ };
287
+ }
288
+ });
289
+
290
+ // Start server
291
+ async function main() {
292
+ const transport = new StdioServerTransport();
293
+ await server.connect(transport);
294
+ console.error('A3M Browser MCP Server running on stdio');
295
+ }
296
+
297
+ main().catch(console.error);