atom-mcp-server 1.1.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/Dockerfile +18 -0
- package/README.md +184 -0
- package/claude_desktop_config.json +8 -0
- package/dist/auth.d.ts +38 -0
- package/dist/auth.d.ts.map +1 -0
- package/dist/auth.js +75 -0
- package/dist/auth.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +92 -0
- package/dist/index.js.map +1 -0
- package/dist/server.d.ts +3 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +234 -0
- package/dist/server.js.map +1 -0
- package/dist/supabase.d.ts +18 -0
- package/dist/supabase.d.ts.map +1 -0
- package/dist/supabase.js +86 -0
- package/dist/supabase.js.map +1 -0
- package/dist/tools/compare-prices.d.ts +16 -0
- package/dist/tools/compare-prices.d.ts.map +1 -0
- package/dist/tools/compare-prices.js +152 -0
- package/dist/tools/compare-prices.js.map +1 -0
- package/dist/tools/get-index-benchmarks.d.ts +14 -0
- package/dist/tools/get-index-benchmarks.d.ts.map +1 -0
- package/dist/tools/get-index-benchmarks.js +99 -0
- package/dist/tools/get-index-benchmarks.js.map +1 -0
- package/dist/tools/get-kpis.d.ts +10 -0
- package/dist/tools/get-kpis.d.ts.map +1 -0
- package/dist/tools/get-kpis.js +45 -0
- package/dist/tools/get-kpis.js.map +1 -0
- package/dist/tools/get-market-stats.d.ts +12 -0
- package/dist/tools/get-market-stats.d.ts.map +1 -0
- package/dist/tools/get-market-stats.js +95 -0
- package/dist/tools/get-market-stats.js.map +1 -0
- package/dist/tools/get-model-detail.d.ts +12 -0
- package/dist/tools/get-model-detail.d.ts.map +1 -0
- package/dist/tools/get-model-detail.js +96 -0
- package/dist/tools/get-model-detail.js.map +1 -0
- package/dist/tools/get-vendor-catalog.d.ts +15 -0
- package/dist/tools/get-vendor-catalog.d.ts.map +1 -0
- package/dist/tools/get-vendor-catalog.js +102 -0
- package/dist/tools/get-vendor-catalog.js.map +1 -0
- package/dist/tools/list-vendors.d.ts +13 -0
- package/dist/tools/list-vendors.d.ts.map +1 -0
- package/dist/tools/list-vendors.js +49 -0
- package/dist/tools/list-vendors.js.map +1 -0
- package/dist/tools/search-models.d.ts +22 -0
- package/dist/tools/search-models.d.ts.map +1 -0
- package/dist/tools/search-models.js +128 -0
- package/dist/tools/search-models.js.map +1 -0
- package/dist/types.d.ts +119 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +5 -0
- package/dist/types.js.map +1 -0
- package/env.example +17 -0
- package/package.json +52 -0
- package/railway.json +13 -0
- package/smithery.yaml +36 -0
- package/src/auth.ts +101 -0
- package/src/index.ts +94 -0
- package/src/server.ts +278 -0
- package/src/supabase.ts +125 -0
- package/src/tools/compare-prices.ts +175 -0
- package/src/tools/get-index-benchmarks.ts +122 -0
- package/src/tools/get-kpis.ts +62 -0
- package/src/tools/get-market-stats.ts +112 -0
- package/src/tools/get-model-detail.ts +119 -0
- package/src/tools/get-vendor-catalog.ts +121 -0
- package/src/tools/list-vendors.ts +60 -0
- package/src/tools/search-models.ts +146 -0
- package/src/types.ts +145 -0
- package/tsconfig.json +19 -0
package/Dockerfile
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
FROM node:22-alpine
|
|
2
|
+
|
|
3
|
+
WORKDIR /app
|
|
4
|
+
|
|
5
|
+
COPY package*.json ./
|
|
6
|
+
RUN npm install
|
|
7
|
+
|
|
8
|
+
COPY tsconfig.json ./
|
|
9
|
+
COPY src/ ./src/
|
|
10
|
+
|
|
11
|
+
RUN npm run build
|
|
12
|
+
|
|
13
|
+
ENV TRANSPORT=http
|
|
14
|
+
ENV PORT=3000
|
|
15
|
+
|
|
16
|
+
EXPOSE 3000
|
|
17
|
+
|
|
18
|
+
CMD ["node", "dist/index.js"]
|
package/README.md
ADDED
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
<p align="center">
|
|
2
|
+
<img src="https://raw.githubusercontent.com/StamatiosKanellakis/A7OM/main/ATOM_Logo_Gray.png" alt="ATOM" width="200" />
|
|
3
|
+
</p>
|
|
4
|
+
|
|
5
|
+
<h1 align="center">ATOM MCP Server</h1>
|
|
6
|
+
|
|
7
|
+
<p align="center">
|
|
8
|
+
<strong>AI Inference Pricing Intelligence — delivered as a native tool for AI agents.</strong><br/>
|
|
9
|
+
1,600+ SKUs · 40+ vendors · 6 modalities · 25 AIPI indexes · Updated weekly
|
|
10
|
+
</p>
|
|
11
|
+
|
|
12
|
+
<p align="center">
|
|
13
|
+
<a href="https://a7om.com">Website</a> ·
|
|
14
|
+
<a href="https://a7om.com/mcp">ATOM MCP Pro</a> ·
|
|
15
|
+
<a href="https://smithery.ai/server/@a7om/atom-mcp-server">Smithery</a>
|
|
16
|
+
</p>
|
|
17
|
+
|
|
18
|
+
---
|
|
19
|
+
|
|
20
|
+
## What Is This?
|
|
21
|
+
|
|
22
|
+
ATOM MCP Server lets any MCP-compatible AI agent (Claude, GPT, Cursor, Windsurf, VS Code Copilot) query real-time AI inference pricing data programmatically. Think of it as **the Bloomberg Terminal for AI pricing**, accessible via the Model Context Protocol.
|
|
23
|
+
|
|
24
|
+
Ask your AI assistant a question like *"What's the cheapest way to run GPT-4o?"* and it calls ATOM's tools behind the scenes, returning a data-backed answer from 1,600+ pricing SKUs across 40+ vendors globally.
|
|
25
|
+
|
|
26
|
+
Built by [ATOM (A7OM)](https://a7om.com) — the world's first methodological inference pricing index.
|
|
27
|
+
|
|
28
|
+
---
|
|
29
|
+
|
|
30
|
+
## Tools
|
|
31
|
+
|
|
32
|
+
| Tool | Tier | Description |
|
|
33
|
+
|------|------|-------------|
|
|
34
|
+
| `list_vendors` | Free | All 41 tracked vendors with country, region, and pricing page URLs |
|
|
35
|
+
| `get_kpis` | Free | 6 market KPIs: output premium, caching savings, open-source advantage, context cost curve, caching availability, size spread |
|
|
36
|
+
| `get_index_benchmarks` | Free | AIPI price benchmarks across 25 indexes — text, image, audio, video, multimodal by geography and tier |
|
|
37
|
+
| `get_market_stats` | Tiered | Aggregate market intelligence: medians, quartiles, distributions, modality breakdown |
|
|
38
|
+
| `search_models` | Tiered | Multi-filter search: modality, vendor, creator, open-source, price range, context window, parameters |
|
|
39
|
+
| `get_model_detail` | Tiered | Full specs + pricing across all vendors for a single model |
|
|
40
|
+
| `compare_prices` | Tiered | Cross-vendor price comparison for a model or model family |
|
|
41
|
+
| `get_vendor_catalog` | Tiered | Complete catalog for a specific vendor: all models, modalities, and pricing |
|
|
42
|
+
|
|
43
|
+
---
|
|
44
|
+
|
|
45
|
+
## Pricing Tiers
|
|
46
|
+
|
|
47
|
+
| | ATOM MCP (Free) | ATOM MCP Pro ($49/mo) |
|
|
48
|
+
|---|---|---|
|
|
49
|
+
| Vendors, KPIs, AIPI indexes | ✅ Full data | ✅ Full data |
|
|
50
|
+
| Market stats | Aggregates only | + Vendor-level breakdown |
|
|
51
|
+
| Model search & comparison | Counts + price ranges | Full granular SKU data |
|
|
52
|
+
| Model detail | Specs only | + Per-vendor pricing |
|
|
53
|
+
| Vendor catalog | Summary only | Full SKU listing |
|
|
54
|
+
|
|
55
|
+
**Free tier** (no API key): Enough to understand the market — counts, ranges, distributions, benchmarks.
|
|
56
|
+
|
|
57
|
+
**ATOM MCP Pro** ($49/mo): Full granular data — every vendor, model, price, and spec. → [a7om.com/mcp](https://a7om.com/mcp)
|
|
58
|
+
|
|
59
|
+
---
|
|
60
|
+
|
|
61
|
+
## Quick Start
|
|
62
|
+
|
|
63
|
+
### Option 1: Remote URL — Claude.ai / Claude Desktop (recommended)
|
|
64
|
+
|
|
65
|
+
No install required. Connect directly to ATOM's hosted server:
|
|
66
|
+
|
|
67
|
+
**Claude.ai (web):** Settings → Connectors → Add custom connector
|
|
68
|
+
```
|
|
69
|
+
Name: ATOM Pricing Intelligence
|
|
70
|
+
URL: https://atom-mcp-server-production.up.railway.app/mcp
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
**Claude Desktop:** Settings → Developer → Edit Config
|
|
74
|
+
```json
|
|
75
|
+
{
|
|
76
|
+
"mcpServers": {
|
|
77
|
+
"atom-pricing": {
|
|
78
|
+
"url": "https://atom-mcp-server-production.up.railway.app/mcp"
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
> Note: Remote URL support requires a recent Claude Desktop version. If it doesn't work, use the npx method below.
|
|
85
|
+
|
|
86
|
+
**Claude Desktop (via npx proxy):**
|
|
87
|
+
```json
|
|
88
|
+
{
|
|
89
|
+
"mcpServers": {
|
|
90
|
+
"atom-pricing": {
|
|
91
|
+
"command": "npx",
|
|
92
|
+
"args": ["mcp-remote", "https://atom-mcp-server-production.up.railway.app/mcp"]
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
### Option 2: Local (stdio) — for Cursor, Windsurf, etc.
|
|
99
|
+
|
|
100
|
+
```bash
|
|
101
|
+
git clone https://github.com/A7OM-AI/atom-mcp-server.git
|
|
102
|
+
cd atom-mcp-server
|
|
103
|
+
npm install && npm run build
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
Add to your MCP client config:
|
|
107
|
+
```json
|
|
108
|
+
{
|
|
109
|
+
"mcpServers": {
|
|
110
|
+
"atom-pricing": {
|
|
111
|
+
"command": "node",
|
|
112
|
+
"args": ["/path/to/atom-mcp-server/dist/index.js"],
|
|
113
|
+
"env": {
|
|
114
|
+
"SUPABASE_URL": "https://jonncmzxvxzwyaznokba.supabase.co",
|
|
115
|
+
"SUPABASE_ANON_KEY": "your-anon-key"
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
### Option 3: Deploy your own (Railway)
|
|
123
|
+
|
|
124
|
+
[](https://railway.app/template)
|
|
125
|
+
|
|
126
|
+
Set environment variables in Railway dashboard:
|
|
127
|
+
- `SUPABASE_URL`
|
|
128
|
+
- `SUPABASE_ANON_KEY`
|
|
129
|
+
- `ATOM_API_KEYS` (comma-separated, for paid tier validation)
|
|
130
|
+
- `TRANSPORT=http`
|
|
131
|
+
|
|
132
|
+
---
|
|
133
|
+
|
|
134
|
+
## Example Queries
|
|
135
|
+
|
|
136
|
+
Once connected, just ask your AI assistant naturally:
|
|
137
|
+
|
|
138
|
+
- *"What's the cheapest way to run GPT-4o?"*
|
|
139
|
+
- *"Compare Claude Sonnet 4.5 pricing across all vendors"*
|
|
140
|
+
- *"Find open-source text models under $0.50 per million tokens"*
|
|
141
|
+
- *"Show me Google's full model catalog"*
|
|
142
|
+
- *"What are the AIPI benchmark prices for text inference?"*
|
|
143
|
+
- *"Give me a market overview of AI inference pricing"*
|
|
144
|
+
- *"What are the key market KPIs for AI inference?"*
|
|
145
|
+
|
|
146
|
+
---
|
|
147
|
+
|
|
148
|
+
## Environment Variables
|
|
149
|
+
|
|
150
|
+
| Variable | Required | Description |
|
|
151
|
+
|----------|----------|-------------|
|
|
152
|
+
| `SUPABASE_URL` | Yes | Supabase project URL |
|
|
153
|
+
| `SUPABASE_ANON_KEY` | Yes | Supabase anonymous/public key |
|
|
154
|
+
| `ATOM_API_KEYS` | No | Comma-separated valid API keys for paid tier |
|
|
155
|
+
| `TRANSPORT` | No | `stdio` (default) or `http` |
|
|
156
|
+
| `PORT` | No | HTTP port (default 3000) |
|
|
157
|
+
|
|
158
|
+
---
|
|
159
|
+
|
|
160
|
+
## Tech Stack
|
|
161
|
+
|
|
162
|
+
- TypeScript / Node.js
|
|
163
|
+
- MCP SDK (`@modelcontextprotocol/sdk`)
|
|
164
|
+
- Supabase (PostgreSQL) via REST API
|
|
165
|
+
- Express (HTTP transport)
|
|
166
|
+
- Zod (schema validation)
|
|
167
|
+
|
|
168
|
+
---
|
|
169
|
+
|
|
170
|
+
## About ATOM
|
|
171
|
+
|
|
172
|
+
ATOM tracks 1,600+ AI inference pricing SKUs from 40+ vendors globally through the AIPI (ATOM Inference Price Index) system — the first methodological price benchmark for AI inference. Updated weekly using chained matched-model methodology to eliminate composition bias.
|
|
173
|
+
|
|
174
|
+
**Products:** [ATOM MCP](https://a7om.com/mcp) · [ATOM Terminal](https://a7om.com/terminal) · [ATOM Feed](https://a7om.com/feed)
|
|
175
|
+
|
|
176
|
+
---
|
|
177
|
+
|
|
178
|
+
## License
|
|
179
|
+
|
|
180
|
+
MIT
|
|
181
|
+
|
|
182
|
+
---
|
|
183
|
+
|
|
184
|
+
<p align="center"><strong>ATOM</strong> — <em>The Global Price Benchmark for AI Inference.</em></p>
|
package/dist/auth.d.ts
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import type { Tier } from "./types.js";
|
|
2
|
+
/**
|
|
3
|
+
* Determine the access tier from an API key.
|
|
4
|
+
* No key or invalid key = free tier.
|
|
5
|
+
*/
|
|
6
|
+
export declare function resolveTier(apiKey?: string): Tier;
|
|
7
|
+
/**
|
|
8
|
+
* Redact sensitive pricing fields for free-tier users.
|
|
9
|
+
* Shows structure but hides vendor, model, and price.
|
|
10
|
+
*/
|
|
11
|
+
export declare function redactForFreeTier(rows: Record<string, unknown>[], fieldsToRedact?: string[]): Record<string, unknown>[];
|
|
12
|
+
/**
|
|
13
|
+
* Build a free-tier summary: count + price range (no individual records).
|
|
14
|
+
*/
|
|
15
|
+
export declare function buildFreeTierSummary(rows: Record<string, unknown>[]): {
|
|
16
|
+
total_results: number;
|
|
17
|
+
price_range: {
|
|
18
|
+
min: number | null;
|
|
19
|
+
max: number | null;
|
|
20
|
+
};
|
|
21
|
+
modalities: string[];
|
|
22
|
+
directions: string[];
|
|
23
|
+
upgrade_message: string;
|
|
24
|
+
};
|
|
25
|
+
/**
|
|
26
|
+
* Returns an additional content block for free-tier responses.
|
|
27
|
+
* This plain-text note ensures the AI assistant surfaces the upgrade path.
|
|
28
|
+
*/
|
|
29
|
+
export declare function freeTierNote(toolContext: string): {
|
|
30
|
+
type: "text";
|
|
31
|
+
text: string;
|
|
32
|
+
};
|
|
33
|
+
/**
|
|
34
|
+
* Gate a full result set based on tier.
|
|
35
|
+
* Paid tier gets everything. Free tier gets redacted + summary.
|
|
36
|
+
*/
|
|
37
|
+
export declare function gateResults(rows: Record<string, unknown>[], tier: Tier): unknown;
|
|
38
|
+
//# sourceMappingURL=auth.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../src/auth.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAQvC;;;GAGG;AACH,wBAAgB,WAAW,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAGjD;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAC/B,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,EAC/B,cAAc,GAAE,MAAM,EAA0G,GAC/H,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAW3B;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,GAAG;IACrE,aAAa,EAAE,MAAM,CAAC;IACtB,WAAW,EAAE;QAAE,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;QAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,CAAC;IACxD,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,eAAe,EAAE,MAAM,CAAC;CACzB,CAmBA;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,WAAW,EAAE,MAAM,GAAG;IACjD,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;CACd,CAKA;AAED;;;GAGG;AACH,wBAAgB,WAAW,CACzB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,EAC/B,IAAI,EAAE,IAAI,GACT,OAAO,CAQT"}
|
package/dist/auth.js
ADDED
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
// ============================================================
|
|
2
|
+
// ATOM MCP Server — Authentication & Tier Gating
|
|
3
|
+
// ============================================================
|
|
4
|
+
// Valid API keys are loaded from environment.
|
|
5
|
+
// In production, these would be validated against a database.
|
|
6
|
+
const VALID_API_KEYS = new Set((process.env.ATOM_API_KEYS || "").split(",").filter(Boolean));
|
|
7
|
+
/**
|
|
8
|
+
* Determine the access tier from an API key.
|
|
9
|
+
* No key or invalid key = free tier.
|
|
10
|
+
*/
|
|
11
|
+
export function resolveTier(apiKey) {
|
|
12
|
+
if (!apiKey)
|
|
13
|
+
return "free";
|
|
14
|
+
return VALID_API_KEYS.has(apiKey.trim()) ? "paid" : "free";
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Redact sensitive pricing fields for free-tier users.
|
|
18
|
+
* Shows structure but hides vendor, model, and price.
|
|
19
|
+
*/
|
|
20
|
+
export function redactForFreeTier(rows, fieldsToRedact = ["vendor_name", "model_name", "normalized_price", "sku_id", "model_id", "vendor_id", "sku_plan_name"]) {
|
|
21
|
+
const REDACTED = "[UPGRADE TO ATOM MCP Pro — $49/mo]";
|
|
22
|
+
return rows.map((row) => {
|
|
23
|
+
const redacted = { ...row };
|
|
24
|
+
for (const field of fieldsToRedact) {
|
|
25
|
+
if (field in redacted) {
|
|
26
|
+
redacted[field] = REDACTED;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
return redacted;
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Build a free-tier summary: count + price range (no individual records).
|
|
34
|
+
*/
|
|
35
|
+
export function buildFreeTierSummary(rows) {
|
|
36
|
+
const prices = rows
|
|
37
|
+
.map((r) => r.normalized_price)
|
|
38
|
+
.filter((p) => p !== null && p > 0);
|
|
39
|
+
const modalities = [...new Set(rows.map((r) => r.modality).filter(Boolean))];
|
|
40
|
+
const directions = [...new Set(rows.map((r) => r.direction).filter(Boolean))];
|
|
41
|
+
return {
|
|
42
|
+
total_results: rows.length,
|
|
43
|
+
price_range: {
|
|
44
|
+
min: prices.length > 0 ? Math.min(...prices) : null,
|
|
45
|
+
max: prices.length > 0 ? Math.max(...prices) : null,
|
|
46
|
+
},
|
|
47
|
+
modalities,
|
|
48
|
+
directions,
|
|
49
|
+
upgrade_message: "Full vendor, model, and pricing details require an ATOM MCP Pro ($49/mo). Visit https://a7om.com/mcp",
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Returns an additional content block for free-tier responses.
|
|
54
|
+
* This plain-text note ensures the AI assistant surfaces the upgrade path.
|
|
55
|
+
*/
|
|
56
|
+
export function freeTierNote(toolContext) {
|
|
57
|
+
return {
|
|
58
|
+
type: "text",
|
|
59
|
+
text: `Note: The data above is summary-level only (counts, ranges, and redacted samples). ${toolContext} — including exact vendor names, model names, and per-SKU pricing — is available exclusively through ATOM MCP Pro ($49/mo). Learn more and subscribe at https://a7om.com/mcp`,
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Gate a full result set based on tier.
|
|
64
|
+
* Paid tier gets everything. Free tier gets redacted + summary.
|
|
65
|
+
*/
|
|
66
|
+
export function gateResults(rows, tier) {
|
|
67
|
+
if (tier === "paid") {
|
|
68
|
+
return rows;
|
|
69
|
+
}
|
|
70
|
+
return {
|
|
71
|
+
summary: buildFreeTierSummary(rows),
|
|
72
|
+
sample: redactForFreeTier(rows.slice(0, 5)),
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
//# sourceMappingURL=auth.js.map
|
package/dist/auth.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth.js","sourceRoot":"","sources":["../src/auth.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// ============================================================
|
|
3
|
+
// ATOM MCP Server — Entry Point
|
|
4
|
+
// ============================================================
|
|
5
|
+
// Dual transport: stdio (local) and Streamable HTTP (remote).
|
|
6
|
+
// Set TRANSPORT=http for HTTP mode, default is stdio.
|
|
7
|
+
// ============================================================
|
|
8
|
+
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
9
|
+
import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
|
|
10
|
+
import express from "express";
|
|
11
|
+
import { createServer } from "./server.js";
|
|
12
|
+
// ----------------------------------------------------------
|
|
13
|
+
// stdio transport (for Cursor, Claude Desktop, etc.)
|
|
14
|
+
// ----------------------------------------------------------
|
|
15
|
+
async function runStdio() {
|
|
16
|
+
const server = createServer();
|
|
17
|
+
const transport = new StdioServerTransport();
|
|
18
|
+
await server.connect(transport);
|
|
19
|
+
console.error("ATOM MCP Server running via stdio");
|
|
20
|
+
}
|
|
21
|
+
// ----------------------------------------------------------
|
|
22
|
+
// Streamable HTTP transport (for hosted / remote access)
|
|
23
|
+
// ----------------------------------------------------------
|
|
24
|
+
async function runHTTP() {
|
|
25
|
+
const app = express();
|
|
26
|
+
app.use(express.json());
|
|
27
|
+
// CORS — allow browser-based MCP clients and test tools
|
|
28
|
+
app.use((req, res, next) => {
|
|
29
|
+
res.header('Access-Control-Allow-Origin', '*');
|
|
30
|
+
res.header('Access-Control-Allow-Headers', 'Content-Type');
|
|
31
|
+
res.header('Access-Control-Allow-Methods', 'POST, GET, OPTIONS');
|
|
32
|
+
if (req.method === 'OPTIONS') {
|
|
33
|
+
res.sendStatus(200);
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
next();
|
|
37
|
+
});
|
|
38
|
+
// Health check
|
|
39
|
+
app.get("/health", (_req, res) => {
|
|
40
|
+
res.json({
|
|
41
|
+
status: "ok",
|
|
42
|
+
server: "atom-mcp-server",
|
|
43
|
+
version: "1.0.0",
|
|
44
|
+
});
|
|
45
|
+
});
|
|
46
|
+
// MCP endpoint — stateless mode (new transport per request)
|
|
47
|
+
app.post("/mcp", async (req, res) => {
|
|
48
|
+
const server = createServer();
|
|
49
|
+
const transport = new StreamableHTTPServerTransport({
|
|
50
|
+
sessionIdGenerator: undefined, // stateless
|
|
51
|
+
enableJsonResponse: true,
|
|
52
|
+
});
|
|
53
|
+
res.on("close", () => {
|
|
54
|
+
transport.close();
|
|
55
|
+
});
|
|
56
|
+
await server.connect(transport);
|
|
57
|
+
await transport.handleRequest(req, res, req.body);
|
|
58
|
+
});
|
|
59
|
+
// Handle GET and DELETE for MCP protocol completeness
|
|
60
|
+
app.get("/mcp", (_req, res) => {
|
|
61
|
+
res.status(405).json({
|
|
62
|
+
error: "Method Not Allowed. Use POST for MCP requests.",
|
|
63
|
+
});
|
|
64
|
+
});
|
|
65
|
+
app.delete("/mcp", (_req, res) => {
|
|
66
|
+
res.status(405).json({
|
|
67
|
+
error: "Method Not Allowed. Stateless server — no sessions to delete.",
|
|
68
|
+
});
|
|
69
|
+
});
|
|
70
|
+
const port = parseInt(process.env.PORT || "3000", 10);
|
|
71
|
+
app.listen(port, () => {
|
|
72
|
+
console.error(`ATOM MCP Server running on http://localhost:${port}/mcp`);
|
|
73
|
+
console.error(`Health check: http://localhost:${port}/health`);
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
// ----------------------------------------------------------
|
|
77
|
+
// Transport selection
|
|
78
|
+
// ----------------------------------------------------------
|
|
79
|
+
const transport = process.env.TRANSPORT || "stdio";
|
|
80
|
+
if (transport === "http") {
|
|
81
|
+
runHTTP().catch((error) => {
|
|
82
|
+
console.error("ATOM MCP Server HTTP error:", error);
|
|
83
|
+
process.exit(1);
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
else {
|
|
87
|
+
runStdio().catch((error) => {
|
|
88
|
+
console.error("ATOM MCP Server stdio error:", error);
|
|
89
|
+
process.exit(1);
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/server.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAsBpE,wBAAgB,YAAY,IAAI,SAAS,CAuPxC"}
|