ai-cost-analyzer 1.0.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.
- package/README.md +228 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +219 -0
- package/dist/index.js.map +1 -0
- package/dist/tools/analyze.d.ts +6 -0
- package/dist/tools/analyze.d.ts.map +1 -0
- package/dist/tools/analyze.js +210 -0
- package/dist/tools/analyze.js.map +1 -0
- package/dist/tools/compare.d.ts +6 -0
- package/dist/tools/compare.d.ts.map +1 -0
- package/dist/tools/compare.js +212 -0
- package/dist/tools/compare.js.map +1 -0
- package/dist/tools/optimize.d.ts +6 -0
- package/dist/tools/optimize.d.ts.map +1 -0
- package/dist/tools/optimize.js +204 -0
- package/dist/tools/optimize.js.map +1 -0
- package/dist/tools/pricing.d.ts +16 -0
- package/dist/tools/pricing.d.ts.map +1 -0
- package/dist/tools/pricing.js +162 -0
- package/dist/tools/pricing.js.map +1 -0
- package/dist/tools/savings.d.ts +6 -0
- package/dist/tools/savings.d.ts.map +1 -0
- package/dist/tools/savings.js +193 -0
- package/dist/tools/savings.js.map +1 -0
- package/dist/types.d.ts +144 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +5 -0
- package/dist/types.js.map +1 -0
- package/package.json +41 -0
- package/src/index.ts +291 -0
- package/src/tools/analyze.ts +260 -0
- package/src/tools/compare.ts +282 -0
- package/src/tools/optimize.ts +291 -0
- package/src/tools/pricing.ts +197 -0
- package/src/tools/savings.ts +238 -0
- package/src/types.ts +183 -0
- package/tsconfig.json +19 -0
package/README.md
ADDED
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
# AI Cost Analyzer
|
|
2
|
+
|
|
3
|
+
An MCP (Model Context Protocol) server that helps developers understand and reduce their AI API costs. Stop wasting 30-40% of your token budget on unused tool definitions, redundant context, and cache misses.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- **Usage Analysis** -- Break down API costs by model, detect token waste, and track spending trends
|
|
8
|
+
- **Savings Estimation** -- Get dollar-amount projections for prompt caching, model routing, and context pruning
|
|
9
|
+
- **Prompt Optimization** -- Automatically detect and remove redundant content, verbose phrasing, and duplicate instructions
|
|
10
|
+
- **Model Comparison** -- Compare cost/quality tradeoffs across Claude, GPT-4o, and Gemini for any task
|
|
11
|
+
- **Live Pricing** -- Current pricing data for all major LLM APIs in one place
|
|
12
|
+
|
|
13
|
+
## Installation
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
# Clone or copy the server
|
|
17
|
+
cd ai-cost-analyzer
|
|
18
|
+
|
|
19
|
+
# Install dependencies
|
|
20
|
+
npm install
|
|
21
|
+
|
|
22
|
+
# Build
|
|
23
|
+
npm run build
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
### Configure with Claude Desktop
|
|
27
|
+
|
|
28
|
+
Add to your `claude_desktop_config.json`:
|
|
29
|
+
|
|
30
|
+
```json
|
|
31
|
+
{
|
|
32
|
+
"mcpServers": {
|
|
33
|
+
"ai-cost-analyzer": {
|
|
34
|
+
"command": "node",
|
|
35
|
+
"args": ["/path/to/ai-cost-analyzer/dist/index.js"]
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
### Configure with Claude Code
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
claude mcp add ai-cost-analyzer node /path/to/ai-cost-analyzer/dist/index.js
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
### Run with SSE transport
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
# Start the SSE server (default port 3000)
|
|
51
|
+
npm run start:sse
|
|
52
|
+
|
|
53
|
+
# Or specify a custom port
|
|
54
|
+
PORT=8080 npm run start:sse
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
## Tools
|
|
58
|
+
|
|
59
|
+
### `analyze_usage`
|
|
60
|
+
|
|
61
|
+
Accepts API usage data and returns detailed cost analysis.
|
|
62
|
+
|
|
63
|
+
**Input:**
|
|
64
|
+
```json
|
|
65
|
+
{
|
|
66
|
+
"usage_data": [
|
|
67
|
+
{
|
|
68
|
+
"model": "claude-sonnet",
|
|
69
|
+
"input_tokens": 15000,
|
|
70
|
+
"output_tokens": 3000,
|
|
71
|
+
"cached_tokens": 5000,
|
|
72
|
+
"timestamp": "2026-03-15T10:30:00Z",
|
|
73
|
+
"tool_definitions": 12,
|
|
74
|
+
"system_prompt_tokens": 3500
|
|
75
|
+
},
|
|
76
|
+
{
|
|
77
|
+
"model": "claude-opus",
|
|
78
|
+
"input_tokens": 8000,
|
|
79
|
+
"output_tokens": 4000,
|
|
80
|
+
"timestamp": "2026-03-15T11:00:00Z"
|
|
81
|
+
}
|
|
82
|
+
]
|
|
83
|
+
}
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
**Output includes:**
|
|
87
|
+
- Total cost breakdown by model
|
|
88
|
+
- Average cost per request
|
|
89
|
+
- Token waste estimation (unused tool definitions, oversized system prompts)
|
|
90
|
+
- Daily and weekly trend analysis
|
|
91
|
+
|
|
92
|
+
---
|
|
93
|
+
|
|
94
|
+
### `estimate_savings`
|
|
95
|
+
|
|
96
|
+
Estimates monthly savings from optimization strategies.
|
|
97
|
+
|
|
98
|
+
**Input:**
|
|
99
|
+
```json
|
|
100
|
+
{
|
|
101
|
+
"usage_data": [
|
|
102
|
+
{
|
|
103
|
+
"model": "claude-sonnet",
|
|
104
|
+
"input_tokens": 12000,
|
|
105
|
+
"output_tokens": 2500,
|
|
106
|
+
"cached_tokens": 0,
|
|
107
|
+
"timestamp": "2026-03-15T10:00:00Z",
|
|
108
|
+
"tool_definitions": 15
|
|
109
|
+
}
|
|
110
|
+
],
|
|
111
|
+
"monthly_multiplier": 30
|
|
112
|
+
}
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
**Output includes:**
|
|
116
|
+
- Current vs. optimized monthly cost
|
|
117
|
+
- Savings from prompt caching (up to 90% on cached tokens)
|
|
118
|
+
- Savings from model routing (use cheaper models for simple tasks)
|
|
119
|
+
- Savings from context pruning (remove unused tool definitions)
|
|
120
|
+
- Actionable recommendations
|
|
121
|
+
|
|
122
|
+
---
|
|
123
|
+
|
|
124
|
+
### `optimize_prompt`
|
|
125
|
+
|
|
126
|
+
Analyzes and optimizes a system prompt and tool definitions.
|
|
127
|
+
|
|
128
|
+
**Input:**
|
|
129
|
+
```json
|
|
130
|
+
{
|
|
131
|
+
"system_prompt": "You are a helpful assistant. Please make sure to always respond in a professional manner. It is important to note that you should be concise. You are a helpful assistant that responds professionally.",
|
|
132
|
+
"tool_definitions": [
|
|
133
|
+
"{\"name\": \"search\", \"description\": \"Search the web for information\"}",
|
|
134
|
+
"{\"name\": \"calculator\", \"description\": \"Perform mathematical calculations\"}"
|
|
135
|
+
],
|
|
136
|
+
"requests_per_month": 50000,
|
|
137
|
+
"model": "claude-sonnet"
|
|
138
|
+
}
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
**Output includes:**
|
|
142
|
+
- Token count before and after optimization
|
|
143
|
+
- Optimized system prompt with redundant content removed
|
|
144
|
+
- Estimated monthly cost reduction
|
|
145
|
+
- Specific recommendations (enable caching, split tool groups, etc.)
|
|
146
|
+
|
|
147
|
+
---
|
|
148
|
+
|
|
149
|
+
### `compare_models`
|
|
150
|
+
|
|
151
|
+
Compares models for a given task with cost/quality tradeoff analysis.
|
|
152
|
+
|
|
153
|
+
**Input:**
|
|
154
|
+
```json
|
|
155
|
+
{
|
|
156
|
+
"task_description": "Classify customer support tickets into categories",
|
|
157
|
+
"estimated_input_tokens": 800,
|
|
158
|
+
"estimated_output_tokens": 50
|
|
159
|
+
}
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
**Output includes:**
|
|
163
|
+
- Cost per request for each model
|
|
164
|
+
- Cost per 1,000 requests
|
|
165
|
+
- Monthly projection at 10K requests
|
|
166
|
+
- Quality tier classification
|
|
167
|
+
- Task-specific model recommendation
|
|
168
|
+
|
|
169
|
+
---
|
|
170
|
+
|
|
171
|
+
### `get_pricing`
|
|
172
|
+
|
|
173
|
+
Returns current LLM API pricing. No input required.
|
|
174
|
+
|
|
175
|
+
**Output includes:**
|
|
176
|
+
|
|
177
|
+
| Model | Input/1M | Output/1M | Cached Input/1M |
|
|
178
|
+
|-------|----------|-----------|-----------------|
|
|
179
|
+
| Claude Opus | $15.00 | $75.00 | $1.50 |
|
|
180
|
+
| Claude Sonnet | $3.00 | $15.00 | $0.30 |
|
|
181
|
+
| Claude Haiku | $0.25 | $1.25 | $0.025 |
|
|
182
|
+
| GPT-4o | $2.50 | $10.00 | $1.25 |
|
|
183
|
+
| GPT-4o Mini | $0.15 | $0.60 | $0.075 |
|
|
184
|
+
| Gemini 2.0 Flash | $0.10 | $0.40 | $0.025 |
|
|
185
|
+
|
|
186
|
+
## Pricing
|
|
187
|
+
|
|
188
|
+
| Plan | Price | Includes |
|
|
189
|
+
|------|-------|----------|
|
|
190
|
+
| **Indie** | $29/month | 1 seat, all tools, email support |
|
|
191
|
+
| **Team** | $99/month | 5 seats, all tools, priority support, shared dashboards |
|
|
192
|
+
| **Enterprise** | $299/month | Unlimited seats, all tools, dedicated support, SSO, custom integrations |
|
|
193
|
+
|
|
194
|
+
All plans include unlimited tool calls and full access to pricing data updates.
|
|
195
|
+
|
|
196
|
+
## Development
|
|
197
|
+
|
|
198
|
+
```bash
|
|
199
|
+
# Watch mode for development
|
|
200
|
+
npm run dev
|
|
201
|
+
|
|
202
|
+
# Build for production
|
|
203
|
+
npm run build
|
|
204
|
+
|
|
205
|
+
# Run with stdio transport
|
|
206
|
+
npm start
|
|
207
|
+
|
|
208
|
+
# Run with SSE transport
|
|
209
|
+
npm run start:sse
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
## Architecture
|
|
213
|
+
|
|
214
|
+
```
|
|
215
|
+
src/
|
|
216
|
+
index.ts Main server entry point, tool registration, transport setup
|
|
217
|
+
types.ts Shared TypeScript types and interfaces
|
|
218
|
+
tools/
|
|
219
|
+
analyze.ts analyze_usage: cost breakdown, waste detection, trends
|
|
220
|
+
savings.ts estimate_savings: caching, routing, pruning projections
|
|
221
|
+
optimize.ts optimize_prompt: prompt analysis and optimization
|
|
222
|
+
compare.ts compare_models: cross-model cost/quality comparison
|
|
223
|
+
pricing.ts get_pricing: pricing data and cost computation helpers
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
## License
|
|
227
|
+
|
|
228
|
+
MIT
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* AI Cost Analyzer -- MCP Server
|
|
4
|
+
*
|
|
5
|
+
* Helps developers understand and reduce their AI API costs through
|
|
6
|
+
* usage analysis, savings estimation, prompt optimization, and model comparison.
|
|
7
|
+
*/
|
|
8
|
+
export {};
|
|
9
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA;;;;;GAKG"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* AI Cost Analyzer -- MCP Server
|
|
4
|
+
*
|
|
5
|
+
* Helps developers understand and reduce their AI API costs through
|
|
6
|
+
* usage analysis, savings estimation, prompt optimization, and model comparison.
|
|
7
|
+
*/
|
|
8
|
+
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
9
|
+
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
10
|
+
import { SSEServerTransport } from "@modelcontextprotocol/sdk/server/sse.js";
|
|
11
|
+
import { z } from "zod";
|
|
12
|
+
import http from "node:http";
|
|
13
|
+
import { handleAnalyzeUsage } from "./tools/analyze.js";
|
|
14
|
+
import { handleEstimateSavings } from "./tools/savings.js";
|
|
15
|
+
import { handleOptimizePrompt } from "./tools/optimize.js";
|
|
16
|
+
import { handleCompareModels } from "./tools/compare.js";
|
|
17
|
+
import { handleGetPricing } from "./tools/pricing.js";
|
|
18
|
+
// ---------------------------------------------------------------------------
|
|
19
|
+
// Zod schemas for tool inputs
|
|
20
|
+
// ---------------------------------------------------------------------------
|
|
21
|
+
const UsageRecordSchema = z.object({
|
|
22
|
+
model: z.string().describe("Model identifier (e.g. 'claude-sonnet', 'gpt-4o')"),
|
|
23
|
+
input_tokens: z.number().int().min(0).describe("Number of input tokens"),
|
|
24
|
+
output_tokens: z.number().int().min(0).describe("Number of output tokens"),
|
|
25
|
+
cached_tokens: z.number().int().min(0).optional().describe("Number of cached input tokens"),
|
|
26
|
+
timestamp: z.string().describe("ISO-8601 timestamp of the request"),
|
|
27
|
+
tool_definitions: z.number().int().min(0).optional().describe("Number of tool definitions sent"),
|
|
28
|
+
system_prompt_tokens: z.number().int().min(0).optional().describe("Token count of the system prompt"),
|
|
29
|
+
});
|
|
30
|
+
// ---------------------------------------------------------------------------
|
|
31
|
+
// Server setup
|
|
32
|
+
// ---------------------------------------------------------------------------
|
|
33
|
+
const server = new McpServer({
|
|
34
|
+
name: "ai-cost-analyzer",
|
|
35
|
+
version: "1.0.0",
|
|
36
|
+
});
|
|
37
|
+
// ---------------------------------------------------------------------------
|
|
38
|
+
// Tool: analyze_usage
|
|
39
|
+
// ---------------------------------------------------------------------------
|
|
40
|
+
server.tool("analyze_usage", "Analyze AI API usage data and return cost breakdowns by model, average cost per request, token waste estimation, and daily/weekly trends.", {
|
|
41
|
+
usage_data: z.array(UsageRecordSchema).describe("Array of API usage records with model, tokens, and timestamps"),
|
|
42
|
+
}, async ({ usage_data }) => {
|
|
43
|
+
try {
|
|
44
|
+
const result = handleAnalyzeUsage(usage_data);
|
|
45
|
+
return {
|
|
46
|
+
content: [{ type: "text", text: result }],
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
catch (err) {
|
|
50
|
+
return {
|
|
51
|
+
content: [{
|
|
52
|
+
type: "text",
|
|
53
|
+
text: `Error analyzing usage: ${err instanceof Error ? err.message : String(err)}`,
|
|
54
|
+
}],
|
|
55
|
+
isError: true,
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
});
|
|
59
|
+
// ---------------------------------------------------------------------------
|
|
60
|
+
// Tool: estimate_savings
|
|
61
|
+
// ---------------------------------------------------------------------------
|
|
62
|
+
server.tool("estimate_savings", "Estimate potential monthly savings from prompt caching, model routing, and context pruning based on current usage patterns.", {
|
|
63
|
+
usage_data: z.array(UsageRecordSchema).describe("Array of API usage records representing current usage patterns"),
|
|
64
|
+
monthly_multiplier: z.number().min(1).optional().describe("If the usage_data is a sample, multiply costs by this factor to project monthly totals (default: 1)"),
|
|
65
|
+
}, async ({ usage_data, monthly_multiplier }) => {
|
|
66
|
+
try {
|
|
67
|
+
const result = handleEstimateSavings(usage_data, monthly_multiplier);
|
|
68
|
+
return {
|
|
69
|
+
content: [{ type: "text", text: result }],
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
catch (err) {
|
|
73
|
+
return {
|
|
74
|
+
content: [{
|
|
75
|
+
type: "text",
|
|
76
|
+
text: `Error estimating savings: ${err instanceof Error ? err.message : String(err)}`,
|
|
77
|
+
}],
|
|
78
|
+
isError: true,
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
});
|
|
82
|
+
// ---------------------------------------------------------------------------
|
|
83
|
+
// Tool: optimize_prompt
|
|
84
|
+
// ---------------------------------------------------------------------------
|
|
85
|
+
server.tool("optimize_prompt", "Analyze a system prompt and tool definitions, return an optimized version with redundant content removed, token counts before/after, and cost reduction estimates.", {
|
|
86
|
+
system_prompt: z.string().describe("The system prompt text to optimize"),
|
|
87
|
+
tool_definitions: z.array(z.string()).describe("Array of tool definition strings (JSON or plain text)"),
|
|
88
|
+
requests_per_month: z.number().int().min(1).optional().describe("Estimated requests per month for cost projection (default: 10,000)"),
|
|
89
|
+
model: z.string().optional().describe("Model name for pricing calculation (default: claude-sonnet)"),
|
|
90
|
+
}, async ({ system_prompt, tool_definitions, requests_per_month, model }) => {
|
|
91
|
+
try {
|
|
92
|
+
const result = handleOptimizePrompt(system_prompt, tool_definitions, requests_per_month, model);
|
|
93
|
+
return {
|
|
94
|
+
content: [{ type: "text", text: result }],
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
catch (err) {
|
|
98
|
+
return {
|
|
99
|
+
content: [{
|
|
100
|
+
type: "text",
|
|
101
|
+
text: `Error optimizing prompt: ${err instanceof Error ? err.message : String(err)}`,
|
|
102
|
+
}],
|
|
103
|
+
isError: true,
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
});
|
|
107
|
+
// ---------------------------------------------------------------------------
|
|
108
|
+
// Tool: compare_models
|
|
109
|
+
// ---------------------------------------------------------------------------
|
|
110
|
+
server.tool("compare_models", "Compare cost and quality tradeoffs across Claude, GPT-4o, GPT-4o-mini, and Gemini models for a given task. Returns cost per request, monthly projections, and recommendations.", {
|
|
111
|
+
task_description: z.string().describe("Description of the task to compare models for"),
|
|
112
|
+
estimated_input_tokens: z.number().int().min(1).optional().describe("Override estimated input tokens per request"),
|
|
113
|
+
estimated_output_tokens: z.number().int().min(1).optional().describe("Override estimated output tokens per request"),
|
|
114
|
+
}, async ({ task_description, estimated_input_tokens, estimated_output_tokens }) => {
|
|
115
|
+
try {
|
|
116
|
+
const result = handleCompareModels(task_description, estimated_input_tokens, estimated_output_tokens);
|
|
117
|
+
return {
|
|
118
|
+
content: [{ type: "text", text: result }],
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
catch (err) {
|
|
122
|
+
return {
|
|
123
|
+
content: [{
|
|
124
|
+
type: "text",
|
|
125
|
+
text: `Error comparing models: ${err instanceof Error ? err.message : String(err)}`,
|
|
126
|
+
}],
|
|
127
|
+
isError: true,
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
});
|
|
131
|
+
// ---------------------------------------------------------------------------
|
|
132
|
+
// Tool: get_pricing
|
|
133
|
+
// ---------------------------------------------------------------------------
|
|
134
|
+
server.tool("get_pricing", "Return current pricing for all major LLM APIs (Claude, OpenAI, Gemini) with input, output, and cached token rates per million tokens.", {}, async () => {
|
|
135
|
+
try {
|
|
136
|
+
const result = handleGetPricing();
|
|
137
|
+
return {
|
|
138
|
+
content: [{ type: "text", text: result }],
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
catch (err) {
|
|
142
|
+
return {
|
|
143
|
+
content: [{
|
|
144
|
+
type: "text",
|
|
145
|
+
text: `Error fetching pricing: ${err instanceof Error ? err.message : String(err)}`,
|
|
146
|
+
}],
|
|
147
|
+
isError: true,
|
|
148
|
+
};
|
|
149
|
+
}
|
|
150
|
+
});
|
|
151
|
+
// ---------------------------------------------------------------------------
|
|
152
|
+
// Transport: stdio or SSE
|
|
153
|
+
// ---------------------------------------------------------------------------
|
|
154
|
+
async function main() {
|
|
155
|
+
const useSSE = process.argv.includes("--sse");
|
|
156
|
+
if (useSSE) {
|
|
157
|
+
const port = parseInt(process.env.PORT ?? "3000", 10);
|
|
158
|
+
// Track active transports for cleanup
|
|
159
|
+
const transports = new Map();
|
|
160
|
+
const httpServer = http.createServer(async (req, res) => {
|
|
161
|
+
// CORS headers
|
|
162
|
+
res.setHeader("Access-Control-Allow-Origin", "*");
|
|
163
|
+
res.setHeader("Access-Control-Allow-Methods", "GET, POST, OPTIONS");
|
|
164
|
+
res.setHeader("Access-Control-Allow-Headers", "Content-Type");
|
|
165
|
+
if (req.method === "OPTIONS") {
|
|
166
|
+
res.writeHead(204);
|
|
167
|
+
res.end();
|
|
168
|
+
return;
|
|
169
|
+
}
|
|
170
|
+
const url = new URL(req.url ?? "/", `http://localhost:${port}`);
|
|
171
|
+
if (url.pathname === "/sse" && req.method === "GET") {
|
|
172
|
+
// Create a new SSE transport for this connection
|
|
173
|
+
const transport = new SSEServerTransport("/messages", res);
|
|
174
|
+
const sessionId = transport.sessionId;
|
|
175
|
+
transports.set(sessionId, transport);
|
|
176
|
+
res.on("close", () => {
|
|
177
|
+
transports.delete(sessionId);
|
|
178
|
+
});
|
|
179
|
+
await server.connect(transport);
|
|
180
|
+
return;
|
|
181
|
+
}
|
|
182
|
+
if (url.pathname === "/messages" && req.method === "POST") {
|
|
183
|
+
const sessionId = url.searchParams.get("sessionId");
|
|
184
|
+
if (!sessionId || !transports.has(sessionId)) {
|
|
185
|
+
res.writeHead(400, { "Content-Type": "application/json" });
|
|
186
|
+
res.end(JSON.stringify({ error: "Invalid or missing sessionId" }));
|
|
187
|
+
return;
|
|
188
|
+
}
|
|
189
|
+
const transport = transports.get(sessionId);
|
|
190
|
+
await transport.handlePostMessage(req, res);
|
|
191
|
+
return;
|
|
192
|
+
}
|
|
193
|
+
// Health check
|
|
194
|
+
if (url.pathname === "/health") {
|
|
195
|
+
res.writeHead(200, { "Content-Type": "application/json" });
|
|
196
|
+
res.end(JSON.stringify({ status: "ok", server: "ai-cost-analyzer", version: "1.0.0" }));
|
|
197
|
+
return;
|
|
198
|
+
}
|
|
199
|
+
res.writeHead(404, { "Content-Type": "application/json" });
|
|
200
|
+
res.end(JSON.stringify({ error: "Not found" }));
|
|
201
|
+
});
|
|
202
|
+
httpServer.listen(port, () => {
|
|
203
|
+
console.error(`AI Cost Analyzer MCP server (SSE) listening on port ${port}`);
|
|
204
|
+
console.error(` SSE endpoint: http://localhost:${port}/sse`);
|
|
205
|
+
console.error(` Messages endpoint: http://localhost:${port}/messages`);
|
|
206
|
+
console.error(` Health check: http://localhost:${port}/health`);
|
|
207
|
+
});
|
|
208
|
+
}
|
|
209
|
+
else {
|
|
210
|
+
const transport = new StdioServerTransport();
|
|
211
|
+
await server.connect(transport);
|
|
212
|
+
console.error("AI Cost Analyzer MCP server running on stdio");
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
main().catch((err) => {
|
|
216
|
+
console.error("Fatal error:", err);
|
|
217
|
+
process.exit(1);
|
|
218
|
+
});
|
|
219
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"analyze.d.ts","sourceRoot":"","sources":["../../src/tools/analyze.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EACV,WAAW,EAIZ,MAAM,aAAa,CAAC;AAgBrB,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,WAAW,EAAE,GAAG,MAAM,CAOjE"}
|