@scavio/mcp-server 0.14.0 → 0.15.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 +36 -17
- package/dist/auth/cimd.d.ts +2 -0
- package/dist/auth/cimd.js +20 -0
- package/dist/auth/cimd.js.map +1 -0
- package/dist/auth/provider.d.ts +12 -0
- package/dist/auth/provider.js +43 -0
- package/dist/auth/provider.js.map +1 -0
- package/dist/auth/routes.d.ts +2 -0
- package/dist/auth/routes.js +214 -0
- package/dist/auth/routes.js.map +1 -0
- package/dist/auth/stores.d.ts +33 -0
- package/dist/auth/stores.js +69 -0
- package/dist/auth/stores.js.map +1 -0
- package/dist/index.js +20 -1
- package/dist/index.js.map +1 -1
- package/dist/lib/client.js +4 -1
- package/dist/lib/client.js.map +1 -1
- package/dist/lib/env.d.ts +3 -0
- package/dist/lib/env.js +4 -0
- package/dist/lib/env.js.map +1 -1
- package/dist/lib/errors.d.ts +5 -1
- package/dist/lib/errors.js +5 -1
- package/dist/lib/errors.js.map +1 -1
- package/dist/lib/tool-error.js +10 -0
- package/dist/lib/tool-error.js.map +1 -1
- package/dist/tools/index.d.ts +7 -6
- package/dist/tools/index.js +7 -6
- package/dist/tools/index.js.map +1 -1
- package/dist/tools/walmart.js +35 -5
- package/dist/tools/walmart.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -3,9 +3,9 @@
|
|
|
3
3
|

|
|
4
4
|

|
|
5
5
|
|
|
6
|
-
[Scavio](https://scavio.dev) is a unified [Web Search API](https://scavio.dev/docs/search-api) and MCP server that gives AI agents web search, page extraction, and structured data from e-commerce, social, travel, jobs, real-estate, app-store, ad-library and company-filing sources.
|
|
6
|
+
[Scavio](https://scavio.dev) is a unified [Web Search API](https://scavio.dev/docs/search-api) and MCP server that gives AI agents web search, page extraction, and structured data from e-commerce, social, travel, jobs, real-estate, app-store, ad-library and company-filing sources. 192 tools across 31 platforms plus Extract, one API key.
|
|
7
7
|
|
|
8
|
-
**The 22 platforms added in 0.13.0 are opt-in.** Registering all
|
|
8
|
+
**The 22 platforms added in 0.13.0 are opt-in.** Registering all 192 tools puts 138KB of tool definitions — roughly 35k tokens — into every session before you type anything. So the default is the surface 0.12.x already had, plus Extract: 107 tools, 65KB. Upgrading never removes a tool you were using. Everything else is one env var away: see [Choosing which tools load](#choosing-which-tools-load).
|
|
9
9
|
|
|
10
10
|
## Remote MCP Server
|
|
11
11
|
|
|
@@ -15,7 +15,10 @@ Connect directly to Scavio's remote MCP server without any local installation:
|
|
|
15
15
|
https://mcp.scavio.dev/mcp
|
|
16
16
|
```
|
|
17
17
|
|
|
18
|
-
|
|
18
|
+
Two ways to authenticate:
|
|
19
|
+
|
|
20
|
+
- **Sign in with OAuth, no key to copy.** Claude Desktop, claude.ai and Claude Code sign in to your Scavio account through the server. In Claude Desktop or claude.ai: Settings > Connectors > Add custom connector, name it Scavio, paste the URL, then Connect and Authorize. In Claude Code: `claude mcp add --transport http scavio https://mcp.scavio.dev/mcp`, then run `/mcp` and choose Authenticate.
|
|
21
|
+
- **API key.** Pass it in the `x-api-key` header. Get your key at [scavio.dev](https://scavio.dev).
|
|
19
22
|
|
|
20
23
|
---
|
|
21
24
|
|
|
@@ -53,13 +56,23 @@ Requires Node.js 20+. Get your API key at [scavio.dev](https://scavio.dev).
|
|
|
53
56
|
|
|
54
57
|
### Claude Code
|
|
55
58
|
|
|
59
|
+
Sign in with OAuth, then run `/mcp` inside Claude Code and choose Authenticate:
|
|
60
|
+
|
|
61
|
+
```bash
|
|
62
|
+
claude mcp add --transport http scavio https://mcp.scavio.dev/mcp
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
Or pass an API key:
|
|
66
|
+
|
|
56
67
|
```bash
|
|
57
|
-
claude mcp add
|
|
68
|
+
claude mcp add --transport http scavio https://mcp.scavio.dev/mcp --header "x-api-key: YOUR_SCAVIO_API_KEY"
|
|
58
69
|
```
|
|
59
70
|
|
|
60
71
|
### Claude Desktop
|
|
61
72
|
|
|
62
|
-
Add
|
|
73
|
+
No API key needed: Settings > Connectors > Add custom connector, name it Scavio, paste `https://mcp.scavio.dev/mcp`, then Connect and sign in to your Scavio account. The same steps work on claude.ai.
|
|
74
|
+
|
|
75
|
+
Or run the server locally. Add to `claude_desktop_config.json` (`~/Library/Application Support/Claude/claude_desktop_config.json` on macOS, `%APPDATA%\Claude\claude_desktop_config.json` on Windows):
|
|
63
76
|
|
|
64
77
|
```json
|
|
65
78
|
{
|
|
@@ -194,8 +207,8 @@ Add to settings (`Cmd+,`):
|
|
|
194
207
|
|
|
195
208
|
## Choosing which tools load
|
|
196
209
|
|
|
197
|
-
Scavio exposes
|
|
198
|
-
roughly
|
|
210
|
+
Scavio exposes 192 tools. Loading all of them costs 138KB of `tools/list` —
|
|
211
|
+
roughly 35k tokens of context in every session before the user has said anything,
|
|
199
212
|
and more tools than some clients will accept at all. So the server registers a
|
|
200
213
|
curated subset by default and lets you pick the rest. The sizes below are
|
|
201
214
|
measured, not estimated: `npm run toolslist` reproduces them.
|
|
@@ -204,10 +217,10 @@ measured, not estimated: `npm run toolslist` reproduces them.
|
|
|
204
217
|
|
|
205
218
|
| Value | Registers |
|
|
206
219
|
|-------|-----------|
|
|
207
|
-
| *(unset)* | Everything 0.12.x had, plus `extract` — **
|
|
208
|
-
| `all` | every platform — **
|
|
209
|
-
| `extract,sec,g2` | just those platforms — 11 tools,
|
|
210
|
-
| `default,
|
|
220
|
+
| *(unset)* or `default` | Everything 0.12.x had, plus `extract` — **107 tools, 65KB** |
|
|
221
|
+
| `all` | every platform — **192 tools, 138KB** |
|
|
222
|
+
| `extract,sec,g2` | just those platforms — 11 tools, 10KB |
|
|
223
|
+
| `default,zillow,metaads` | the default set plus two more — 113 tools, 72KB |
|
|
211
224
|
| `none` | no platform tools, only `get_usage` |
|
|
212
225
|
|
|
213
226
|
Keys are matched case- and punctuation-insensitively, so `meta-ads`, `metaads`
|
|
@@ -365,12 +378,18 @@ single page.
|
|
|
365
378
|
| `get_walmart_offers` | The buy-box offer for a product: price, seller, condition, buy-box flag |
|
|
366
379
|
| `get_walmart_seller` | Marketplace seller storefront: name, rating, Pro Seller badge, business details |
|
|
367
380
|
| `get_walmart_seller_products` | A seller's catalogue; `total_count` is the real size |
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
`
|
|
372
|
-
|
|
373
|
-
|
|
381
|
+
| `get_walmart_stores` | Stores near a US ZIP or Canadian postal code, nearest first, with `store_id`, address, distance and hours |
|
|
382
|
+
|
|
383
|
+
Walmart is priced by the request body, not at a flat rate: `com` (US, default)
|
|
384
|
+
and `ca` cost 1 credit, `com.mx` costs 2. Only `search_walmart` and
|
|
385
|
+
`get_walmart_category` accept every `domain`.
|
|
386
|
+
|
|
387
|
+
Store targeting: pass `delivery_zip` and `store_id` together on `search_walmart`
|
|
388
|
+
or `get_walmart_product` to get one store's assortment and availability. Take the
|
|
389
|
+
`store_id` from `get_walmart_stores` on the same domain (walmart.com or
|
|
390
|
+
walmart.ca). A store-targeted call costs 2 credits, takes 10-60 seconds, and
|
|
391
|
+
echoes the store it used in `data.location`. `get_walmart_product` accepts
|
|
392
|
+
`domain: "ca"` only together with a store pair.
|
|
374
393
|
|
|
375
394
|
Two shapes to plan for. `get_walmart_offers` returns the buy-box winner only —
|
|
376
395
|
Walmart server-renders just that one offer, so expect a single row even when
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export async function fetchClientMetadata(clientIdUrl) {
|
|
2
|
+
try {
|
|
3
|
+
const res = await fetch(clientIdUrl, {
|
|
4
|
+
headers: { Accept: "application/json" },
|
|
5
|
+
signal: AbortSignal.timeout(5000),
|
|
6
|
+
});
|
|
7
|
+
if (!res.ok)
|
|
8
|
+
return null;
|
|
9
|
+
const meta = await res.json();
|
|
10
|
+
if (!meta.client_id || !Array.isArray(meta.redirect_uris))
|
|
11
|
+
return null;
|
|
12
|
+
if (meta.client_id !== clientIdUrl)
|
|
13
|
+
return null;
|
|
14
|
+
return meta;
|
|
15
|
+
}
|
|
16
|
+
catch {
|
|
17
|
+
return null;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=cimd.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cimd.js","sourceRoot":"","sources":["../../src/auth/cimd.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,KAAK,UAAU,mBAAmB,CACvC,WAAmB;IAEnB,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,WAAW,EAAE;YACnC,OAAO,EAAE,EAAE,MAAM,EAAE,kBAAkB,EAAE;YACvC,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,IAAI,CAAC;SAClC,CAAC,CAAC;QACH,IAAI,CAAC,GAAG,CAAC,EAAE;YAAE,OAAO,IAAI,CAAC;QACzB,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC;QAC9B,IAAI,CAAC,IAAI,CAAC,SAAS,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,aAAa,CAAC;YAAE,OAAO,IAAI,CAAC;QACvE,IAAI,IAAI,CAAC,SAAS,KAAK,WAAW;YAAE,OAAO,IAAI,CAAC;QAChD,OAAO,IAAkC,CAAC;IAC5C,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { AuthCodeStore, PendingSessionStore, ClientStore } from "./stores.js";
|
|
2
|
+
type SignedPayload = {
|
|
3
|
+
key: string;
|
|
4
|
+
sid: string;
|
|
5
|
+
exp: number;
|
|
6
|
+
};
|
|
7
|
+
export declare function verifySignedToken(token: string): SignedPayload | null;
|
|
8
|
+
export declare function verifyApiKey(apiKey: string): Promise<boolean>;
|
|
9
|
+
export declare const authCodeStore: AuthCodeStore;
|
|
10
|
+
export declare const pendingSessionStore: PendingSessionStore;
|
|
11
|
+
export declare const clientStore: ClientStore;
|
|
12
|
+
export {};
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { createHmac, timingSafeEqual } from "node:crypto";
|
|
2
|
+
import { env } from "../lib/env.js";
|
|
3
|
+
import { ScavioClient } from "../lib/client.js";
|
|
4
|
+
import { AuthCodeStore, PendingSessionStore, ClientStore } from "./stores.js";
|
|
5
|
+
export function verifySignedToken(token) {
|
|
6
|
+
const secret = env.MCP_AUTH_SECRET;
|
|
7
|
+
if (!secret)
|
|
8
|
+
return null;
|
|
9
|
+
const dotIndex = token.indexOf(".");
|
|
10
|
+
if (dotIndex < 0)
|
|
11
|
+
return null;
|
|
12
|
+
const payloadB64 = token.slice(0, dotIndex);
|
|
13
|
+
const sigB64 = token.slice(dotIndex + 1);
|
|
14
|
+
const expectedSig = createHmac("sha256", secret)
|
|
15
|
+
.update(payloadB64)
|
|
16
|
+
.digest();
|
|
17
|
+
const actualSig = Buffer.from(sigB64, "base64url");
|
|
18
|
+
if (expectedSig.length !== actualSig.length || !timingSafeEqual(expectedSig, actualSig))
|
|
19
|
+
return null;
|
|
20
|
+
try {
|
|
21
|
+
const payload = JSON.parse(Buffer.from(payloadB64, "base64url").toString());
|
|
22
|
+
if (payload.exp < Date.now())
|
|
23
|
+
return null;
|
|
24
|
+
return payload;
|
|
25
|
+
}
|
|
26
|
+
catch {
|
|
27
|
+
return null;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
export async function verifyApiKey(apiKey) {
|
|
31
|
+
try {
|
|
32
|
+
const client = new ScavioClient(apiKey);
|
|
33
|
+
await client.get("/api/v1/usage");
|
|
34
|
+
return true;
|
|
35
|
+
}
|
|
36
|
+
catch {
|
|
37
|
+
return false;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
export const authCodeStore = new AuthCodeStore();
|
|
41
|
+
export const pendingSessionStore = new PendingSessionStore();
|
|
42
|
+
export const clientStore = new ClientStore();
|
|
43
|
+
//# sourceMappingURL=provider.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"provider.js","sourceRoot":"","sources":["../../src/auth/provider.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAC1D,OAAO,EAAE,GAAG,EAAE,MAAM,eAAe,CAAC;AACpC,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAChD,OAAO,EAAE,aAAa,EAAE,mBAAmB,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAQ9E,MAAM,UAAU,iBAAiB,CAAC,KAAa;IAC7C,MAAM,MAAM,GAAG,GAAG,CAAC,eAAe,CAAC;IACnC,IAAI,CAAC,MAAM;QAAE,OAAO,IAAI,CAAC;IAEzB,MAAM,QAAQ,GAAG,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IACpC,IAAI,QAAQ,GAAG,CAAC;QAAE,OAAO,IAAI,CAAC;IAE9B,MAAM,UAAU,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC;IAC5C,MAAM,MAAM,GAAG,KAAK,CAAC,KAAK,CAAC,QAAQ,GAAG,CAAC,CAAC,CAAC;IAEzC,MAAM,WAAW,GAAG,UAAU,CAAC,QAAQ,EAAE,MAAM,CAAC;SAC7C,MAAM,CAAC,UAAU,CAAC;SAClB,MAAM,EAAE,CAAC;IACZ,MAAM,SAAS,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;IAEnD,IAAI,WAAW,CAAC,MAAM,KAAK,SAAS,CAAC,MAAM,IAAI,CAAC,eAAe,CAAC,WAAW,EAAE,SAAS,CAAC;QAAE,OAAO,IAAI,CAAC;IAErG,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CACxB,MAAM,CAAC,IAAI,CAAC,UAAU,EAAE,WAAW,CAAC,CAAC,QAAQ,EAAE,CAC/B,CAAC;QACnB,IAAI,OAAO,CAAC,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE;YAAE,OAAO,IAAI,CAAC;QAC1C,OAAO,OAAO,CAAC;IACjB,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,MAAc;IAC/C,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,IAAI,YAAY,CAAC,MAAM,CAAC,CAAC;QACxC,MAAM,MAAM,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC;QAClC,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED,MAAM,CAAC,MAAM,aAAa,GAAG,IAAI,aAAa,EAAE,CAAC;AACjD,MAAM,CAAC,MAAM,mBAAmB,GAAG,IAAI,mBAAmB,EAAE,CAAC;AAC7D,MAAM,CAAC,MAAM,WAAW,GAAG,IAAI,WAAW,EAAE,CAAC"}
|
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
import { Hono } from "hono";
|
|
2
|
+
import { cors } from "hono/cors";
|
|
3
|
+
import { createHash } from "node:crypto";
|
|
4
|
+
import { env } from "../lib/env.js";
|
|
5
|
+
import { authCodeStore, pendingSessionStore, clientStore, verifySignedToken, } from "./provider.js";
|
|
6
|
+
export const authApp = new Hono();
|
|
7
|
+
// --- OAuth Metadata ---
|
|
8
|
+
const buildOAuthMetadata = () => ({
|
|
9
|
+
issuer: env.ISSUER_URL,
|
|
10
|
+
authorization_endpoint: `${env.ISSUER_URL}/authorize`,
|
|
11
|
+
token_endpoint: `${env.ISSUER_URL}/token`,
|
|
12
|
+
registration_endpoint: `${env.ISSUER_URL}/register`,
|
|
13
|
+
response_types_supported: ["code"],
|
|
14
|
+
grant_types_supported: ["authorization_code"],
|
|
15
|
+
code_challenge_methods_supported: ["S256"],
|
|
16
|
+
token_endpoint_auth_methods_supported: ["none"],
|
|
17
|
+
client_id_metadata_document_supported: true,
|
|
18
|
+
});
|
|
19
|
+
const buildResourceMetadata = () => ({
|
|
20
|
+
resource: `${env.ISSUER_URL}/mcp`,
|
|
21
|
+
authorization_servers: [env.ISSUER_URL],
|
|
22
|
+
resource_name: "Scavio MCP Server",
|
|
23
|
+
resource_documentation: "https://scavio.dev/docs/mcp",
|
|
24
|
+
});
|
|
25
|
+
authApp.get("/.well-known/oauth-authorization-server", cors({ origin: "*" }), (c) => c.json(buildOAuthMetadata()));
|
|
26
|
+
authApp.get("/.well-known/oauth-protected-resource/mcp", cors({ origin: "*" }), (c) => c.json(buildResourceMetadata()));
|
|
27
|
+
// --- Dynamic Client Registration (RFC 7591) ---
|
|
28
|
+
authApp.post("/register", cors({ origin: "*" }), async (c) => {
|
|
29
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
30
|
+
let body;
|
|
31
|
+
try {
|
|
32
|
+
body = await c.req.json();
|
|
33
|
+
}
|
|
34
|
+
catch {
|
|
35
|
+
return c.json({ error: "invalid_client_metadata", error_description: "Invalid JSON" }, 400);
|
|
36
|
+
}
|
|
37
|
+
if (!body.redirect_uris || !Array.isArray(body.redirect_uris)) {
|
|
38
|
+
return c.json({ error: "invalid_client_metadata", error_description: "redirect_uris required" }, 400);
|
|
39
|
+
}
|
|
40
|
+
const invalidScheme = body.redirect_uris.some((uri) => {
|
|
41
|
+
try {
|
|
42
|
+
const u = new URL(uri);
|
|
43
|
+
if (u.protocol === "https:")
|
|
44
|
+
return false;
|
|
45
|
+
if (u.protocol === "http:" && (u.hostname === "localhost" || u.hostname === "127.0.0.1"))
|
|
46
|
+
return false;
|
|
47
|
+
return true;
|
|
48
|
+
}
|
|
49
|
+
catch {
|
|
50
|
+
return true;
|
|
51
|
+
}
|
|
52
|
+
});
|
|
53
|
+
if (invalidScheme) {
|
|
54
|
+
return c.json({ error: "invalid_client_metadata", error_description: "redirect_uris must use https (or http for localhost)" }, 400);
|
|
55
|
+
}
|
|
56
|
+
const client = await clientStore.registerClient(body);
|
|
57
|
+
return c.json(client, 201);
|
|
58
|
+
});
|
|
59
|
+
// --- Authorization Endpoint ---
|
|
60
|
+
authApp.all("/authorize", async (c) => {
|
|
61
|
+
if (!env.MCP_AUTH_SECRET) {
|
|
62
|
+
return c.json({ error: "server_error", error_description: "OAuth not configured" }, 500);
|
|
63
|
+
}
|
|
64
|
+
const params = c.req.method === "GET" ? c.req.query() : await c.req.parseBody();
|
|
65
|
+
const clientId = params.client_id;
|
|
66
|
+
const redirectUri = params.redirect_uri;
|
|
67
|
+
const responseType = params.response_type;
|
|
68
|
+
const codeChallenge = params.code_challenge;
|
|
69
|
+
const codeChallengeMethod = params.code_challenge_method;
|
|
70
|
+
const state = params.state;
|
|
71
|
+
const scope = params.scope;
|
|
72
|
+
// Validate client
|
|
73
|
+
if (!clientId) {
|
|
74
|
+
return c.json({ error: "invalid_request", error_description: "client_id required" }, 400);
|
|
75
|
+
}
|
|
76
|
+
const client = await clientStore.getClient(clientId);
|
|
77
|
+
if (!client) {
|
|
78
|
+
return c.json({ error: "invalid_client", error_description: "Unknown client_id" }, 400);
|
|
79
|
+
}
|
|
80
|
+
// Resolve redirect_uri
|
|
81
|
+
let resolvedRedirect = redirectUri;
|
|
82
|
+
if (!resolvedRedirect) {
|
|
83
|
+
if (client.redirect_uris.length === 1) {
|
|
84
|
+
resolvedRedirect = client.redirect_uris[0].toString();
|
|
85
|
+
}
|
|
86
|
+
else {
|
|
87
|
+
return c.json({ error: "invalid_request", error_description: "redirect_uri required" }, 400);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
// Validate redirect_uri against registered URIs
|
|
91
|
+
if (!client.redirect_uris.some(u => u.toString() === resolvedRedirect)) {
|
|
92
|
+
return c.json({ error: "invalid_request", error_description: "Unregistered redirect_uri" }, 400);
|
|
93
|
+
}
|
|
94
|
+
// Validate remaining params (errors redirect to client)
|
|
95
|
+
const errorRedirect = (error, desc) => {
|
|
96
|
+
const url = new URL(resolvedRedirect);
|
|
97
|
+
url.searchParams.set("error", error);
|
|
98
|
+
url.searchParams.set("error_description", desc);
|
|
99
|
+
if (state)
|
|
100
|
+
url.searchParams.set("state", state);
|
|
101
|
+
return c.redirect(url.toString(), 302);
|
|
102
|
+
};
|
|
103
|
+
if (responseType !== "code")
|
|
104
|
+
return errorRedirect("unsupported_response_type", "Only 'code' supported");
|
|
105
|
+
if (!codeChallenge)
|
|
106
|
+
return errorRedirect("invalid_request", "code_challenge required");
|
|
107
|
+
if (codeChallengeMethod !== "S256")
|
|
108
|
+
return errorRedirect("invalid_request", "Only S256 supported");
|
|
109
|
+
// Store pending session, redirect to dashboard consent page
|
|
110
|
+
const sessionId = pendingSessionStore.create({
|
|
111
|
+
clientId,
|
|
112
|
+
redirectUri: resolvedRedirect,
|
|
113
|
+
state,
|
|
114
|
+
codeChallenge,
|
|
115
|
+
scopes: scope ? scope.split(" ") : [],
|
|
116
|
+
});
|
|
117
|
+
const callbackUrl = `${env.ISSUER_URL}/oauth/callback`;
|
|
118
|
+
const dashboardUrl = new URL(`${env.DASHBOARD_URL}/mcp/authorize`);
|
|
119
|
+
dashboardUrl.searchParams.set("session", sessionId);
|
|
120
|
+
dashboardUrl.searchParams.set("callback", callbackUrl);
|
|
121
|
+
return c.redirect(dashboardUrl.toString(), 302);
|
|
122
|
+
});
|
|
123
|
+
// --- OAuth Callback (from dashboard consent page) ---
|
|
124
|
+
authApp.get("/oauth/callback", async (c) => {
|
|
125
|
+
const token = c.req.query("token");
|
|
126
|
+
const sessionId = c.req.query("session");
|
|
127
|
+
const error = c.req.query("error");
|
|
128
|
+
if (!sessionId) {
|
|
129
|
+
return c.json({ error: "invalid_request", error_description: "Missing session" }, 400);
|
|
130
|
+
}
|
|
131
|
+
const session = pendingSessionStore.consume(sessionId);
|
|
132
|
+
if (!session) {
|
|
133
|
+
return c.json({ error: "invalid_request", error_description: "Invalid or expired session" }, 400);
|
|
134
|
+
}
|
|
135
|
+
const errorRedirect = (errCode, desc) => {
|
|
136
|
+
const url = new URL(session.redirectUri);
|
|
137
|
+
url.searchParams.set("error", errCode);
|
|
138
|
+
url.searchParams.set("error_description", desc);
|
|
139
|
+
if (session.state)
|
|
140
|
+
url.searchParams.set("state", session.state);
|
|
141
|
+
return c.redirect(url.toString(), 302);
|
|
142
|
+
};
|
|
143
|
+
// User denied
|
|
144
|
+
if (error === "access_denied") {
|
|
145
|
+
return errorRedirect("access_denied", "User denied authorization");
|
|
146
|
+
}
|
|
147
|
+
if (!token) {
|
|
148
|
+
return errorRedirect("server_error", "Missing token");
|
|
149
|
+
}
|
|
150
|
+
// Verify the signed token from the backend
|
|
151
|
+
const payload = verifySignedToken(token);
|
|
152
|
+
if (!payload) {
|
|
153
|
+
return errorRedirect("server_error", "Invalid or expired token");
|
|
154
|
+
}
|
|
155
|
+
if (payload.sid !== sessionId) {
|
|
156
|
+
return errorRedirect("server_error", "Session mismatch");
|
|
157
|
+
}
|
|
158
|
+
// Generate auth code
|
|
159
|
+
const code = authCodeStore.generate({
|
|
160
|
+
apiKey: payload.key,
|
|
161
|
+
codeChallenge: session.codeChallenge,
|
|
162
|
+
redirectUri: session.redirectUri,
|
|
163
|
+
clientId: session.clientId,
|
|
164
|
+
});
|
|
165
|
+
const redirectUrl = new URL(session.redirectUri);
|
|
166
|
+
redirectUrl.searchParams.set("code", code);
|
|
167
|
+
if (session.state)
|
|
168
|
+
redirectUrl.searchParams.set("state", session.state);
|
|
169
|
+
return c.redirect(redirectUrl.toString(), 302);
|
|
170
|
+
});
|
|
171
|
+
// --- Token Endpoint ---
|
|
172
|
+
authApp.post("/token", cors({ origin: "*" }), async (c) => {
|
|
173
|
+
const body = await c.req.parseBody();
|
|
174
|
+
const grantType = body.grant_type;
|
|
175
|
+
const code = body.code;
|
|
176
|
+
const codeVerifier = body.code_verifier;
|
|
177
|
+
const clientId = body.client_id;
|
|
178
|
+
const redirectUri = body.redirect_uri;
|
|
179
|
+
if (grantType !== "authorization_code") {
|
|
180
|
+
return c.json({ error: "unsupported_grant_type" }, 400);
|
|
181
|
+
}
|
|
182
|
+
if (!code || !codeVerifier || !clientId) {
|
|
183
|
+
return c.json({ error: "invalid_request", error_description: "code, code_verifier, client_id required" }, 400);
|
|
184
|
+
}
|
|
185
|
+
// Validate client
|
|
186
|
+
const client = await clientStore.getClient(clientId);
|
|
187
|
+
if (!client) {
|
|
188
|
+
return c.json({ error: "invalid_client" }, 401);
|
|
189
|
+
}
|
|
190
|
+
// Consume the auth code
|
|
191
|
+
const codeData = authCodeStore.consume(code);
|
|
192
|
+
if (!codeData) {
|
|
193
|
+
return c.json({ error: "invalid_grant", error_description: "Invalid or expired code" }, 400);
|
|
194
|
+
}
|
|
195
|
+
if (codeData.clientId !== clientId) {
|
|
196
|
+
return c.json({ error: "invalid_grant", error_description: "Client mismatch" }, 400);
|
|
197
|
+
}
|
|
198
|
+
if (redirectUri && codeData.redirectUri !== redirectUri) {
|
|
199
|
+
return c.json({ error: "invalid_grant", error_description: "redirect_uri mismatch" }, 400);
|
|
200
|
+
}
|
|
201
|
+
// PKCE: verify S256
|
|
202
|
+
const expectedChallenge = createHash("sha256")
|
|
203
|
+
.update(codeVerifier)
|
|
204
|
+
.digest("base64url");
|
|
205
|
+
if (expectedChallenge !== codeData.codeChallenge) {
|
|
206
|
+
return c.json({ error: "invalid_grant", error_description: "PKCE verification failed" }, 400);
|
|
207
|
+
}
|
|
208
|
+
// Issue the access token (the user's actual API key)
|
|
209
|
+
return c.json({
|
|
210
|
+
access_token: codeData.apiKey,
|
|
211
|
+
token_type: "Bearer",
|
|
212
|
+
});
|
|
213
|
+
});
|
|
214
|
+
//# sourceMappingURL=routes.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"routes.js","sourceRoot":"","sources":["../../src/auth/routes.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import type { OAuthClientInformationFull } from "@modelcontextprotocol/sdk/shared/auth.js";
|
|
2
|
+
import type { OAuthRegisteredClientsStore } from "@modelcontextprotocol/sdk/server/auth/clients.js";
|
|
3
|
+
type AuthCodeData = {
|
|
4
|
+
apiKey: string;
|
|
5
|
+
codeChallenge: string;
|
|
6
|
+
redirectUri: string;
|
|
7
|
+
clientId: string;
|
|
8
|
+
expiresAt: number;
|
|
9
|
+
};
|
|
10
|
+
type PendingSession = {
|
|
11
|
+
clientId: string;
|
|
12
|
+
redirectUri: string;
|
|
13
|
+
state?: string;
|
|
14
|
+
codeChallenge: string;
|
|
15
|
+
scopes: string[];
|
|
16
|
+
expiresAt: number;
|
|
17
|
+
};
|
|
18
|
+
export declare class AuthCodeStore {
|
|
19
|
+
private codes;
|
|
20
|
+
generate(data: Omit<AuthCodeData, "expiresAt">): string;
|
|
21
|
+
consume(code: string): AuthCodeData | null;
|
|
22
|
+
}
|
|
23
|
+
export declare class PendingSessionStore {
|
|
24
|
+
private sessions;
|
|
25
|
+
create(data: Omit<PendingSession, "expiresAt">): string;
|
|
26
|
+
consume(id: string): PendingSession | null;
|
|
27
|
+
}
|
|
28
|
+
export declare class ClientStore implements OAuthRegisteredClientsStore {
|
|
29
|
+
private clients;
|
|
30
|
+
getClient(clientId: string): Promise<OAuthClientInformationFull | undefined>;
|
|
31
|
+
registerClient(client: Omit<OAuthClientInformationFull, "client_id" | "client_id_issued_at">): Promise<OAuthClientInformationFull>;
|
|
32
|
+
}
|
|
33
|
+
export {};
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { randomBytes } from "node:crypto";
|
|
2
|
+
import { fetchClientMetadata } from "./cimd.js";
|
|
3
|
+
const AUTH_CODE_TTL = 5 * 60 * 1000; // 5 min
|
|
4
|
+
const SESSION_TTL = 10 * 60 * 1000; // 10 min
|
|
5
|
+
const CLIENT_CACHE_TTL = 60 * 60 * 1000; // 1 hour
|
|
6
|
+
export class AuthCodeStore {
|
|
7
|
+
codes = new Map();
|
|
8
|
+
generate(data) {
|
|
9
|
+
const code = randomBytes(32).toString("hex");
|
|
10
|
+
this.codes.set(code, { ...data, expiresAt: Date.now() + AUTH_CODE_TTL });
|
|
11
|
+
return code;
|
|
12
|
+
}
|
|
13
|
+
consume(code) {
|
|
14
|
+
const data = this.codes.get(code);
|
|
15
|
+
if (!data)
|
|
16
|
+
return null;
|
|
17
|
+
this.codes.delete(code);
|
|
18
|
+
if (data.expiresAt < Date.now())
|
|
19
|
+
return null;
|
|
20
|
+
return data;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
export class PendingSessionStore {
|
|
24
|
+
sessions = new Map();
|
|
25
|
+
create(data) {
|
|
26
|
+
const id = randomBytes(24).toString("hex");
|
|
27
|
+
this.sessions.set(id, { ...data, expiresAt: Date.now() + SESSION_TTL });
|
|
28
|
+
return id;
|
|
29
|
+
}
|
|
30
|
+
consume(id) {
|
|
31
|
+
const data = this.sessions.get(id);
|
|
32
|
+
if (!data)
|
|
33
|
+
return null;
|
|
34
|
+
this.sessions.delete(id);
|
|
35
|
+
if (data.expiresAt < Date.now())
|
|
36
|
+
return null;
|
|
37
|
+
return data;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
export class ClientStore {
|
|
41
|
+
clients = new Map();
|
|
42
|
+
async getClient(clientId) {
|
|
43
|
+
// Check cache first
|
|
44
|
+
const cached = this.clients.get(clientId);
|
|
45
|
+
if (cached && cached.cachedAt + CLIENT_CACHE_TTL > Date.now()) {
|
|
46
|
+
return cached.client;
|
|
47
|
+
}
|
|
48
|
+
// CIMD: if client_id is a URL, fetch metadata from it
|
|
49
|
+
if (clientId.startsWith("https://")) {
|
|
50
|
+
const meta = await fetchClientMetadata(clientId);
|
|
51
|
+
if (meta) {
|
|
52
|
+
this.clients.set(clientId, { client: meta, cachedAt: Date.now() });
|
|
53
|
+
return meta;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
return cached?.client;
|
|
57
|
+
}
|
|
58
|
+
async registerClient(client) {
|
|
59
|
+
const clientId = `scavio_${randomBytes(16).toString("hex")}`;
|
|
60
|
+
const full = {
|
|
61
|
+
...client,
|
|
62
|
+
client_id: clientId,
|
|
63
|
+
client_id_issued_at: Math.floor(Date.now() / 1000),
|
|
64
|
+
};
|
|
65
|
+
this.clients.set(clientId, { client: full, cachedAt: Date.now() });
|
|
66
|
+
return full;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
//# sourceMappingURL=stores.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stores.js","sourceRoot":"","sources":["../../src/auth/stores.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -39,7 +39,9 @@ async function startHttp() {
|
|
|
39
39
|
const { Hono } = await import("hono");
|
|
40
40
|
const { serve } = await import("@hono/node-server");
|
|
41
41
|
const { WebStandardStreamableHTTPServerTransport } = await import("@modelcontextprotocol/sdk/server/webStandardStreamableHttp.js");
|
|
42
|
+
const { authApp } = await import("./auth/routes.js");
|
|
42
43
|
const app = new Hono();
|
|
44
|
+
// Health / info endpoints
|
|
43
45
|
app.get("/", (c) => c.json({
|
|
44
46
|
status: "ok",
|
|
45
47
|
server: SERVER_NAME,
|
|
@@ -48,12 +50,23 @@ async function startHttp() {
|
|
|
48
50
|
default_platforms: DEFAULT_PLATFORMS,
|
|
49
51
|
}));
|
|
50
52
|
app.get("/health", (c) => c.json({ status: "ok" }));
|
|
53
|
+
// Glama directory ownership claim; must stay in place to keep the listing verified.
|
|
54
|
+
app.get("/.well-known/glama.json", (c) => c.json({
|
|
55
|
+
$schema: "https://glama.ai/mcp/schemas/connector.json",
|
|
56
|
+
claim: "glama_claim_fNJqMMssWxtODfRrgf2jT_07_SnFry23",
|
|
57
|
+
}));
|
|
58
|
+
// Mount OAuth routes (well-known, authorize, token, register, callback)
|
|
59
|
+
app.route("/", authApp);
|
|
60
|
+
// MCP endpoint with dual auth: OAuth bearer or legacy API key
|
|
51
61
|
app.post("/mcp", async (c) => {
|
|
52
62
|
const apiKey = c.req.header("x-api-key") ??
|
|
53
63
|
c.req.header("authorization")?.replace("Bearer ", "") ??
|
|
54
64
|
c.req.query("api_key");
|
|
55
65
|
if (!apiKey) {
|
|
56
|
-
|
|
66
|
+
// Return 401 with OAuth discovery for OAuth-capable clients
|
|
67
|
+
const resourceMetadataUrl = `${env.ISSUER_URL}/.well-known/oauth-protected-resource/mcp`;
|
|
68
|
+
c.header("WWW-Authenticate", `Bearer resource_metadata="${resourceMetadataUrl}"`);
|
|
69
|
+
return c.json({ error: "Unauthorized" }, 401);
|
|
57
70
|
}
|
|
58
71
|
// A hosted remote has no per-user env var, so the allowlist is selectable
|
|
59
72
|
// per connection. Falls back to SCAVIO_PLATFORMS, then to the default set.
|
|
@@ -67,6 +80,12 @@ async function startHttp() {
|
|
|
67
80
|
});
|
|
68
81
|
serve({ fetch: app.fetch, port: env.PORT }, (info) => {
|
|
69
82
|
console.error(`${SERVER_NAME} v${SERVER_VERSION} started (http) on port ${info.port}`);
|
|
83
|
+
if (env.MCP_AUTH_SECRET) {
|
|
84
|
+
console.error(`OAuth enabled (issuer: ${env.ISSUER_URL})`);
|
|
85
|
+
}
|
|
86
|
+
else {
|
|
87
|
+
console.error("OAuth disabled (MCP_AUTH_SECRET not set)");
|
|
88
|
+
}
|
|
70
89
|
});
|
|
71
90
|
}
|
|
72
91
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACpE,OAAO,EAAE,GAAG,EAAE,MAAM,cAAc,CAAC;AACnC,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAC/C,OAAO,EAAE,gBAAgB,EAAE,aAAa,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAEtF,MAAM,WAAW,GAAG,YAAY,CAAC;AAEjC;;;;;GAKG;AACH,MAAM,cAAc,GAClB,IAAI,CAAC,KAAK,CACR,YAAY,CAAC,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,cAAc,CAAC,EAAE,MAAM,CAAC,CAE5F,CAAC,OAAO,CAAC;AAEV,IAAI,GAAG,CAAC,SAAS,KAAK,OAAO,EAAE,CAAC;IAC9B,MAAM,UAAU,EAAE,CAAC;AACrB,CAAC;KAAM,CAAC;IACN,MAAM,SAAS,EAAE,CAAC;AACpB,CAAC;AAED,KAAK,UAAU,UAAU;IACvB,MAAM,EAAE,oBAAoB,EAAE,GAAG,MAAM,MAAM,CAC3C,2CAA2C,CAC5C,CAAC;IAEF,MAAM,MAAM,GAAG,GAAG,CAAC,cAAc,CAAC;IAClC,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,OAAO,CAAC,KAAK,CAAC,gDAAgD,CAAC,CAAC;QAChE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,MAAM,MAAM,GAAG,IAAI,SAAS,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,OAAO,EAAE,cAAc,EAAE,CAAC,CAAC;IAC7E,MAAM,MAAM,GAAG,IAAI,YAAY,CAAC,MAAM,CAAC,CAAC;IACxC,MAAM,SAAS,GAAG,gBAAgB,CAAC,MAAM,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,CAAC;IAEzD,MAAM,SAAS,GAAG,IAAI,oBAAoB,EAAE,CAAC;IAC7C,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IAChC,OAAO,CAAC,KAAK,CACX,GAAG,WAAW,KAAK,cAAc,iCAAiC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,MAAM,EAAE;QAChG,GAAG,GAAG,CAAC,gBAAgB,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,6DAA6D,EAAE,CACjG,CAAC;AACJ,CAAC;AAED,KAAK,UAAU,SAAS;IACtB,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC,CAAC;IACtC,MAAM,EAAE,KAAK,EAAE,GAAG,MAAM,MAAM,CAAC,mBAAmB,CAAC,CAAC;IACpD,MAAM,EAAE,wCAAwC,EAAE,GAAG,MAAM,MAAM,CAC/D,+DAA+D,CAChE,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/lib/client.js
CHANGED
|
@@ -19,14 +19,17 @@ export class ScavioClient {
|
|
|
19
19
|
if (!response.ok) {
|
|
20
20
|
const text = await response.text();
|
|
21
21
|
let message;
|
|
22
|
+
let billingUrl;
|
|
22
23
|
try {
|
|
23
24
|
const json = JSON.parse(text);
|
|
24
25
|
message = json.error ?? json.message ?? text;
|
|
26
|
+
if (typeof json.billing_url === "string")
|
|
27
|
+
billingUrl = json.billing_url;
|
|
25
28
|
}
|
|
26
29
|
catch {
|
|
27
30
|
message = text;
|
|
28
31
|
}
|
|
29
|
-
throw new ApiError(response.status, message);
|
|
32
|
+
throw new ApiError(response.status, message, undefined, billingUrl);
|
|
30
33
|
}
|
|
31
34
|
return response.json();
|
|
32
35
|
}
|
package/dist/lib/client.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/lib/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,UAAU,CAAC;AAC/B,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAEvC,MAAM,OAAO,YAAY;IACf,OAAO,CAAS;IAChB,MAAM,CAAS;IAEvB,YAAY,MAAc;QACxB,IAAI,CAAC,OAAO,GAAG,GAAG,CAAC,mBAAmB,CAAC;QACvC,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;IACvB,CAAC;IAEO,KAAK,CAAC,OAAO,CAAI,MAAc,EAAE,IAAY,EAAE,IAAc;QACnE,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,IAAI,CAAC,OAAO,GAAG,IAAI,EAAE,EAAE;YACrD,MAAM;YACN,OAAO,EAAE;gBACP,cAAc,EAAE,kBAAkB;gBAClC,eAAe,EAAE,UAAU,IAAI,CAAC,MAAM,EAAE;aACzC;YACD,GAAG,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SAC9D,CAAC,CAAC;QAEH,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;YACjB,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;YACnC,IAAI,OAAe,CAAC;YACpB,IAAI,CAAC;gBACH,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;gBAC9B,OAAO,GAAG,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/lib/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,UAAU,CAAC;AAC/B,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAEvC,MAAM,OAAO,YAAY;IACf,OAAO,CAAS;IAChB,MAAM,CAAS;IAEvB,YAAY,MAAc;QACxB,IAAI,CAAC,OAAO,GAAG,GAAG,CAAC,mBAAmB,CAAC;QACvC,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;IACvB,CAAC;IAEO,KAAK,CAAC,OAAO,CAAI,MAAc,EAAE,IAAY,EAAE,IAAc;QACnE,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,IAAI,CAAC,OAAO,GAAG,IAAI,EAAE,EAAE;YACrD,MAAM;YACN,OAAO,EAAE;gBACP,cAAc,EAAE,kBAAkB;gBAClC,eAAe,EAAE,UAAU,IAAI,CAAC,MAAM,EAAE;aACzC;YACD,GAAG,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SAC9D,CAAC,CAAC;QAEH,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;YACjB,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;YACnC,IAAI,OAAe,CAAC;YACpB,IAAI,UAA8B,CAAC;YACnC,IAAI,CAAC;gBACH,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;gBAC9B,OAAO,GAAG,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC;gBAC7C,IAAI,OAAO,IAAI,CAAC,WAAW,KAAK,QAAQ;oBAAE,UAAU,GAAG,IAAI,CAAC,WAAW,CAAC;YAC1E,CAAC;YAAC,MAAM,CAAC;gBACP,OAAO,GAAG,IAAI,CAAC;YACjB,CAAC;YACD,MAAM,IAAI,QAAQ,CAAC,QAAQ,CAAC,MAAM,EAAE,OAAO,EAAE,SAAS,EAAE,UAAU,CAAC,CAAC;QACtE,CAAC;QAED,OAAO,QAAQ,CAAC,IAAI,EAAgB,CAAC;IACvC,CAAC;IAED,KAAK,CAAC,GAAG,CAAI,IAAY;QACvB,OAAO,IAAI,CAAC,OAAO,CAAI,KAAK,EAAE,IAAI,CAAC,CAAC;IACtC,CAAC;IAED,KAAK,CAAC,IAAI,CAAI,IAAY,EAAE,IAAc;QACxC,OAAO,IAAI,CAAC,OAAO,CAAI,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;IAC7C,CAAC;CACF"}
|
package/dist/lib/env.d.ts
CHANGED
|
@@ -2,6 +2,9 @@ export declare const env: {
|
|
|
2
2
|
SCAVIO_API_BASE_URL: string;
|
|
3
3
|
PORT: number;
|
|
4
4
|
TRANSPORT: "http" | "stdio";
|
|
5
|
+
ISSUER_URL: string;
|
|
6
|
+
DASHBOARD_URL: string;
|
|
5
7
|
SCAVIO_API_KEY?: string | undefined;
|
|
6
8
|
SCAVIO_PLATFORMS?: string | undefined;
|
|
9
|
+
MCP_AUTH_SECRET?: string | undefined;
|
|
7
10
|
};
|
package/dist/lib/env.js
CHANGED
|
@@ -11,6 +11,10 @@ const envSchema = z.object({
|
|
|
11
11
|
.default(3000),
|
|
12
12
|
TRANSPORT: z.enum(["http", "stdio"])
|
|
13
13
|
.default("stdio"),
|
|
14
|
+
// OAuth
|
|
15
|
+
MCP_AUTH_SECRET: z.string().min(32).optional(),
|
|
16
|
+
ISSUER_URL: z.string().url().default("https://mcp.scavio.dev"),
|
|
17
|
+
DASHBOARD_URL: z.string().url().default("https://dashboard.scavio.dev"),
|
|
14
18
|
});
|
|
15
19
|
export const env = envSchema.parse(process.env);
|
|
16
20
|
//# sourceMappingURL=env.js.map
|
package/dist/lib/env.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"env.js","sourceRoot":"","sources":["../../src/lib/env.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,MAAM,SAAS,GAAG,CAAC,CAAC,MAAM,CAAC;IACzB,mBAAmB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE;SAClC,OAAO,CAAC,wBAAwB,CAAC;IACpC,cAAc,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IACrC,mFAAmF;IACnF,+EAA+E;IAC/E,8EAA8E;IAC9E,gBAAgB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IACvC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC;SAC5C,OAAO,CAAC,IAAI,CAAC;IAChB,SAAS,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;SACjC,OAAO,CAAC,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"env.js","sourceRoot":"","sources":["../../src/lib/env.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,MAAM,SAAS,GAAG,CAAC,CAAC,MAAM,CAAC;IACzB,mBAAmB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE;SAClC,OAAO,CAAC,wBAAwB,CAAC;IACpC,cAAc,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IACrC,mFAAmF;IACnF,+EAA+E;IAC/E,8EAA8E;IAC9E,gBAAgB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IACvC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC;SAC5C,OAAO,CAAC,IAAI,CAAC;IAChB,SAAS,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;SACjC,OAAO,CAAC,OAAO,CAAC;IACnB,QAAQ;IACR,eAAe,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,QAAQ,EAAE;IAC9C,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,wBAAwB,CAAC;IAC9D,aAAa,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,8BAA8B,CAAC;CACxE,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,GAAG,GAAG,SAAS,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC"}
|
package/dist/lib/errors.d.ts
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
export declare class ApiError extends Error {
|
|
2
2
|
readonly status: number;
|
|
3
3
|
readonly code?: string | undefined;
|
|
4
|
-
|
|
4
|
+
/** Where to top up, when the API sent one (402 responses do). */
|
|
5
|
+
readonly billingUrl?: string | undefined;
|
|
6
|
+
constructor(status: number, message: string, code?: string | undefined,
|
|
7
|
+
/** Where to top up, when the API sent one (402 responses do). */
|
|
8
|
+
billingUrl?: string | undefined);
|
|
5
9
|
}
|
package/dist/lib/errors.js
CHANGED
|
@@ -1,10 +1,14 @@
|
|
|
1
1
|
export class ApiError extends Error {
|
|
2
2
|
status;
|
|
3
3
|
code;
|
|
4
|
-
|
|
4
|
+
billingUrl;
|
|
5
|
+
constructor(status, message, code,
|
|
6
|
+
/** Where to top up, when the API sent one (402 responses do). */
|
|
7
|
+
billingUrl) {
|
|
5
8
|
super(message);
|
|
6
9
|
this.status = status;
|
|
7
10
|
this.code = code;
|
|
11
|
+
this.billingUrl = billingUrl;
|
|
8
12
|
this.name = "ApiError";
|
|
9
13
|
}
|
|
10
14
|
}
|
package/dist/lib/errors.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/lib/errors.ts"],"names":[],"mappings":"AAAA,MAAM,OAAO,QAAS,SAAQ,KAAK;IAEf;IAEA;
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/lib/errors.ts"],"names":[],"mappings":"AAAA,MAAM,OAAO,QAAS,SAAQ,KAAK;IAEf;IAEA;IAEA;IALlB,YACkB,MAAc,EAC9B,OAAe,EACC,IAAa;IAC7B,iEAAiE;IACjD,UAAmB;QAEnC,KAAK,CAAC,OAAO,CAAC,CAAC;QANC,WAAM,GAAN,MAAM,CAAQ;QAEd,SAAI,GAAJ,IAAI,CAAS;QAEb,eAAU,GAAV,UAAU,CAAS;QAGnC,IAAI,CAAC,IAAI,GAAG,UAAU,CAAC;IACzB,CAAC;CACF"}
|
package/dist/lib/tool-error.js
CHANGED
|
@@ -19,6 +19,16 @@ export function handleApiError(err) {
|
|
|
19
19
|
if (err instanceof ApiError) {
|
|
20
20
|
if (err.status === 429)
|
|
21
21
|
return { isError: true, content: [{ type: "text", text: "Rate limited. Wait and retry." }] };
|
|
22
|
+
// The API's 402 body carries billing_url; the bare "Insufficient credits"
|
|
23
|
+
// string used to be all the model saw, so it could not tell the user where
|
|
24
|
+
// to go. Surface the link, and say that nothing needs reconfiguring.
|
|
25
|
+
if (err.status === 402) {
|
|
26
|
+
const url = err.billingUrl ?? "https://dashboard.scavio.dev/billing";
|
|
27
|
+
return {
|
|
28
|
+
isError: true,
|
|
29
|
+
content: [{ type: "text", text: `Out of Scavio credits (402). Top up or upgrade at ${url}; the same key keeps working afterwards, no config change needed.` }],
|
|
30
|
+
};
|
|
31
|
+
}
|
|
22
32
|
if (err.status === 401)
|
|
23
33
|
throw new McpError(ErrorCode.InternalError, "Invalid SCAVIO_API_KEY. Check your configuration.");
|
|
24
34
|
return { isError: true, content: [{ type: "text", text: `Scavio API error (${err.status}): ${err.message}` }] };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tool-error.js","sourceRoot":"","sources":["../../src/lib/tool-error.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,oCAAoC,CAAC;AACzE,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAEvC;;;;;;;;;;;;;;GAcG;AACH,MAAM,UAAU,cAAc,CAAC,GAAY;IACzC,IAAI,GAAG,YAAY,QAAQ,EAAE,CAAC;QAC5B,IAAI,GAAG,CAAC,MAAM,KAAK,GAAG;YAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,+BAA+B,EAAE,CAAC,EAAE,CAAC;QACrH,IAAI,GAAG,CAAC,MAAM,KAAK,GAAG;YAAE,MAAM,IAAI,QAAQ,CAAC,SAAS,CAAC,aAAa,EAAE,mDAAmD,CAAC,CAAC;QACzH,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,qBAAqB,GAAG,CAAC,MAAM,MAAM,GAAG,CAAC,OAAO,EAAE,EAAE,CAAC,EAAE,CAAC;IAClH,CAAC;IACD,MAAM,IAAI,QAAQ,CAAC,SAAS,CAAC,aAAa,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;AAC3D,CAAC"}
|
|
1
|
+
{"version":3,"file":"tool-error.js","sourceRoot":"","sources":["../../src/lib/tool-error.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,oCAAoC,CAAC;AACzE,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAEvC;;;;;;;;;;;;;;GAcG;AACH,MAAM,UAAU,cAAc,CAAC,GAAY;IACzC,IAAI,GAAG,YAAY,QAAQ,EAAE,CAAC;QAC5B,IAAI,GAAG,CAAC,MAAM,KAAK,GAAG;YAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,+BAA+B,EAAE,CAAC,EAAE,CAAC;QACrH,0EAA0E;QAC1E,2EAA2E;QAC3E,qEAAqE;QACrE,IAAI,GAAG,CAAC,MAAM,KAAK,GAAG,EAAE,CAAC;YACvB,MAAM,GAAG,GAAG,GAAG,CAAC,UAAU,IAAI,sCAAsC,CAAC;YACrE,OAAO;gBACL,OAAO,EAAE,IAAI;gBACb,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,qDAAqD,GAAG,mEAAmE,EAAE,CAAC;aAC/J,CAAC;QACJ,CAAC;QACD,IAAI,GAAG,CAAC,MAAM,KAAK,GAAG;YAAE,MAAM,IAAI,QAAQ,CAAC,SAAS,CAAC,aAAa,EAAE,mDAAmD,CAAC,CAAC;QACzH,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,qBAAqB,GAAG,CAAC,MAAM,MAAM,GAAG,CAAC,OAAO,EAAE,EAAE,CAAC,EAAE,CAAC;IAClH,CAAC;IACD,MAAM,IAAI,QAAQ,CAAC,SAAS,CAAC,aAAa,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;AAC3D,CAAC"}
|
package/dist/tools/index.d.ts
CHANGED
|
@@ -4,11 +4,12 @@ export declare const PLATFORM_KEYS: string[];
|
|
|
4
4
|
/**
|
|
5
5
|
* What registers when SCAVIO_PLATFORMS is unset.
|
|
6
6
|
*
|
|
7
|
-
* Registering everything is not an option any more. The full surface is
|
|
8
|
-
* tools, which serialises to
|
|
9
|
-
*
|
|
10
|
-
* has typed anything, and past the
|
|
11
|
-
* enforce. The
|
|
7
|
+
* Registering everything is not an option any more. The full surface is 192
|
|
8
|
+
* tools, which serialises to 138KB of tools/list (measured with
|
|
9
|
+
* `npm run toolslist`, not estimated) — roughly 35k tokens pushed into the
|
|
10
|
+
* context of EVERY session before the user has typed anything, and past the
|
|
11
|
+
* hard tool-count ceiling some clients enforce. The default set below is 107
|
|
12
|
+
* tools, 65KB.
|
|
12
13
|
*
|
|
13
14
|
* The default is therefore exactly what 0.12.x registered, plus extract:
|
|
14
15
|
* upgrading must never silently remove a tool someone already depends on. A
|
|
@@ -25,7 +26,7 @@ export declare const DEFAULT_PLATFORMS: string[];
|
|
|
25
26
|
* Turn a SCAVIO_PLATFORMS value into the canonical platform keys to register.
|
|
26
27
|
*
|
|
27
28
|
* Accepts a comma-separated list of platform keys, plus three keywords:
|
|
28
|
-
* all — every platform (
|
|
29
|
+
* all — every platform (192 tools)
|
|
29
30
|
* default — expands to DEFAULT_PLATFORMS, so `default,sec,g2` is additive
|
|
30
31
|
* none — no platform tools at all, leaving only get_usage
|
|
31
32
|
*
|
package/dist/tools/index.js
CHANGED
|
@@ -94,11 +94,12 @@ export const PLATFORM_KEYS = Object.keys(PLATFORMS);
|
|
|
94
94
|
/**
|
|
95
95
|
* What registers when SCAVIO_PLATFORMS is unset.
|
|
96
96
|
*
|
|
97
|
-
* Registering everything is not an option any more. The full surface is
|
|
98
|
-
* tools, which serialises to
|
|
99
|
-
*
|
|
100
|
-
* has typed anything, and past the
|
|
101
|
-
* enforce. The
|
|
97
|
+
* Registering everything is not an option any more. The full surface is 192
|
|
98
|
+
* tools, which serialises to 138KB of tools/list (measured with
|
|
99
|
+
* `npm run toolslist`, not estimated) — roughly 35k tokens pushed into the
|
|
100
|
+
* context of EVERY session before the user has typed anything, and past the
|
|
101
|
+
* hard tool-count ceiling some clients enforce. The default set below is 107
|
|
102
|
+
* tools, 65KB.
|
|
102
103
|
*
|
|
103
104
|
* The default is therefore exactly what 0.12.x registered, plus extract:
|
|
104
105
|
* upgrading must never silently remove a tool someone already depends on. A
|
|
@@ -150,7 +151,7 @@ function warnOnce(message) {
|
|
|
150
151
|
* Turn a SCAVIO_PLATFORMS value into the canonical platform keys to register.
|
|
151
152
|
*
|
|
152
153
|
* Accepts a comma-separated list of platform keys, plus three keywords:
|
|
153
|
-
* all — every platform (
|
|
154
|
+
* all — every platform (192 tools)
|
|
154
155
|
* default — expands to DEFAULT_PLATFORMS, so `default,sec,g2` is additive
|
|
155
156
|
* none — no platform tools at all, leaving only get_usage
|
|
156
157
|
*
|
package/dist/tools/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":"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"}
|
package/dist/tools/walmart.js
CHANGED
|
@@ -2,9 +2,9 @@ import { z } from "zod";
|
|
|
2
2
|
import { handleApiError } from "../lib/tool-error.js";
|
|
3
3
|
import { trimResponse } from "../lib/trim-response.js";
|
|
4
4
|
/**
|
|
5
|
-
* Walmart marketplace.
|
|
6
|
-
*
|
|
7
|
-
*
|
|
5
|
+
* Walmart marketplace. A price-bearing parameter: com and ca bill 1 credit,
|
|
6
|
+
* com.mx bills 2. Search and category accept all three; product accepts ca
|
|
7
|
+
* only together with a store target (see storeFields).
|
|
8
8
|
*
|
|
9
9
|
* Never given a zod default: the MCP SDK applies defaults BEFORE the handler
|
|
10
10
|
* runs, so a default is posted on every call whether the caller meant it or not.
|
|
@@ -19,10 +19,20 @@ const domainField = z.enum(["com", "ca", "com.mx"]).optional()
|
|
|
19
19
|
*/
|
|
20
20
|
const fulfillmentSpeedField = z.enum(["today", "tomorrow"]).optional()
|
|
21
21
|
.describe("'today' or 'tomorrow'. Omit for all items.");
|
|
22
|
+
/**
|
|
23
|
+
* Store targeting (search + product). Both or neither: the API 400s one alone.
|
|
24
|
+
* store_id comes from get_walmart_stores on the same domain. walmart.com and
|
|
25
|
+
* walmart.ca only. A store-targeted call bills 2 credits regardless of domain.
|
|
26
|
+
* No defaults, for the same reason as domainField.
|
|
27
|
+
*/
|
|
28
|
+
const deliveryZipField = z.string().min(5).max(7).optional()
|
|
29
|
+
.describe("Shopper postal code: 5-digit US ZIP, or Canadian postal code (e.g. 'M5V 2T6') with domain 'ca'. Must be passed with store_id.");
|
|
30
|
+
const storeIdField = z.string().min(1).optional()
|
|
31
|
+
.describe("Walmart store id from get_walmart_stores (same domain). Must be passed with delivery_zip. The store used is echoed in data.location.");
|
|
22
32
|
const sortByField = z.enum(["best_match", "price_low", "price_high", "best_seller", "rating_high", "new"]).optional()
|
|
23
33
|
.describe("Sort order. Default 'best_match'.");
|
|
24
34
|
export function registerWalmartTools(server, getClient) {
|
|
25
|
-
server.tool("search_walmart", `Search Walmart products. Paginate with page while has_more_pages. 1 credit (US/CA), 2 credits (Mexico).`, {
|
|
35
|
+
server.tool("search_walmart", `Search Walmart products. Paginate with page while has_more_pages. 1 credit (US/CA), 2 credits (Mexico). Optional store targeting: pass delivery_zip + store_id together (store_id from get_walmart_stores, same domain) for one store's assortment and availability - walmart.com and walmart.ca only, 2 credits, takes 10-60s, store echoed in data.location.`, {
|
|
26
36
|
query: z.string().min(1).max(500)
|
|
27
37
|
.describe("Product search query."),
|
|
28
38
|
page: z.number().int().min(1).optional()
|
|
@@ -36,6 +46,8 @@ export function registerWalmartTools(server, getClient) {
|
|
|
36
46
|
fulfillment_type: z.enum(["in_store"]).optional()
|
|
37
47
|
.describe("'in_store' for pickup only. Omit for all."),
|
|
38
48
|
domain: domainField,
|
|
49
|
+
delivery_zip: deliveryZipField,
|
|
50
|
+
store_id: storeIdField,
|
|
39
51
|
}, async (params) => {
|
|
40
52
|
try {
|
|
41
53
|
const data = await getClient().post("/api/v1/walmart/search", params);
|
|
@@ -45,9 +57,13 @@ export function registerWalmartTools(server, getClient) {
|
|
|
45
57
|
return handleApiError(err);
|
|
46
58
|
}
|
|
47
59
|
});
|
|
48
|
-
server.tool("get_walmart_product", `Get full Walmart product detail. No reviews (use get_walmart_reviews) or offers (use get_walmart_offers).
|
|
60
|
+
server.tool("get_walmart_product", `Get full Walmart product detail. No reviews (use get_walmart_reviews) or offers (use get_walmart_offers). seller_catalog_id is the NUMERIC id for seller endpoints. 1 credit. Optional store targeting: delivery_zip + store_id together (store_id from get_walmart_stores) - 2 credits, takes 10-60s, store echoed in data.location; 404 if that store does not carry the item. domain 'ca' only with a store pair.`, {
|
|
49
61
|
product_id: z.string().min(1)
|
|
50
62
|
.describe("Walmart usItemId, e.g. '13544111159'."),
|
|
63
|
+
domain: z.enum(["com", "ca"]).optional()
|
|
64
|
+
.describe("'com' (default) or 'ca'. 'ca' requires delivery_zip + store_id."),
|
|
65
|
+
delivery_zip: deliveryZipField,
|
|
66
|
+
store_id: storeIdField,
|
|
51
67
|
}, async (params) => {
|
|
52
68
|
try {
|
|
53
69
|
const data = await getClient().post("/api/v1/walmart/product", params);
|
|
@@ -57,6 +73,20 @@ export function registerWalmartTools(server, getClient) {
|
|
|
57
73
|
return handleApiError(err);
|
|
58
74
|
}
|
|
59
75
|
});
|
|
76
|
+
server.tool("get_walmart_stores", `Find Walmart stores near a US ZIP (walmart.com) or Canadian postal code (domain 'ca'), nearest first: store_id, name, distance_miles, address, coordinates, hours. Use a store_id with delivery_zip on search_walmart or get_walmart_product (same domain) to target that store. 1 credit.`, {
|
|
77
|
+
zipcode: z.string().min(5).max(7)
|
|
78
|
+
.describe("5-digit US ZIP, e.g. '50036', or Canadian postal code with domain 'ca', e.g. 'M5V 2T6'."),
|
|
79
|
+
domain: z.enum(["com", "ca"]).optional()
|
|
80
|
+
.describe("'com' (walmart.com, default) or 'ca' (walmart.ca)."),
|
|
81
|
+
}, async (params) => {
|
|
82
|
+
try {
|
|
83
|
+
const data = await getClient().post("/api/v1/walmart/stores", params);
|
|
84
|
+
return trimResponse(data);
|
|
85
|
+
}
|
|
86
|
+
catch (err) {
|
|
87
|
+
return handleApiError(err);
|
|
88
|
+
}
|
|
89
|
+
});
|
|
60
90
|
server.tool("get_walmart_reviews", `Get Walmart product reviews. 10/page, paginate with page param. Includes rating_breakdown and top positive/negative. 1 credit/page.`, {
|
|
61
91
|
product_id: z.string().min(1)
|
|
62
92
|
.describe("Walmart usItemId."),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"walmart.js","sourceRoot":"","sources":["../../src/tools/walmart.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAEvD;;;;;;;GAOG;AACH,MAAM,WAAW,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,IAAI,EAAE,QAAQ,CAAC,CAAC,CAAC,QAAQ,EAAE;KAC3D,QAAQ,CAAC,0EAA0E,CAAC,CAAC;AAExF;;;;;GAKG;AACH,MAAM,qBAAqB,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,UAAU,CAAC,CAAC,CAAC,QAAQ,EAAE;KACnE,QAAQ,CAAC,4CAA4C,CAAC,CAAC;AAE1D,MAAM,WAAW,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,YAAY,EAAE,WAAW,EAAE,YAAY,EAAE,aAAa,EAAE,aAAa,EAAE,KAAK,CAAC,CAAC,CAAC,QAAQ,EAAE;KAClH,QAAQ,CAAC,mCAAmC,CAAC,CAAC;AAEjD,MAAM,UAAU,oBAAoB,CAAC,MAAiB,EAAE,SAA6B;IACnF,MAAM,CAAC,IAAI,CACT,gBAAgB,EAChB,
|
|
1
|
+
{"version":3,"file":"walmart.js","sourceRoot":"","sources":["../../src/tools/walmart.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@scavio/mcp-server",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.15.0",
|
|
4
4
|
"mcpName": "io.github.scavio-ai/scavio-mcp",
|
|
5
5
|
"description": "MCP server connecting AI agents to Scavio: web search, page extraction, and structured e-commerce, social, travel, jobs, real-estate, app-store, ad-library and company-filing data. 191 tools across 31 platforms plus Extract, one API key.",
|
|
6
6
|
"type": "module",
|