@lobstack-ai/mcp 0.1.0 → 0.1.2

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 CHANGED
@@ -1,8 +1,9 @@
1
1
  # @lobstack-ai/mcp
2
2
 
3
- An MCP server for the [Lobstack](https://www.lobstack.ai) Gateway. One API key
4
- reaches every major model, and every call comes back with a receipt: which model
5
- served it, how many tokens, what it cost.
3
+ An MCP server for the [Lobstack API](https://www.lobstack.ai/api-platform). One
4
+ API key reaches [26 models across 9 providers](https://www.lobstack.ai/models), and
5
+ every call comes back with a receipt: which model served it, how many tokens,
6
+ what it cost.
6
7
 
7
8
  Works in Claude Desktop, Claude Code, Cursor, Zed, or anything else that speaks
8
9
  the Model Context Protocol over stdio.
@@ -118,8 +119,17 @@ against.
118
119
  The catalogue: model key, label, tier, provider, context window, and USD per
119
120
  million input and output tokens. Optional `tier` and `provider` filters.
120
121
 
121
- A model the registry cannot price comes back with `null` prices and renders as
122
- `—`. It is not free.
122
+ **The first entry is `auto` — Nex 1, the router.** It carries `tier: "router"`
123
+ and a null price on purpose: its cost is whichever model it picks, which is not
124
+ knowable until the request is scored. That is the one null in this list that is
125
+ not a gap.
126
+
127
+ Every other null price is. A model the registry cannot price comes back with
128
+ `null` and renders as `—`, and it is not free — a zero there would be a claim
129
+ that a real charge did not happen.
130
+
131
+ The full catalogue with rates is also public, no key required, at
132
+ <https://www.lobstack.ai/models>.
123
133
 
124
134
  ### `lobstack_chat`
125
135
 
@@ -129,7 +139,7 @@ Sends a prompt or a conversation and returns the reply plus the receipt.
129
139
  | --- | --- | --- |
130
140
  | `prompt` | string | A single user message. Use this **or** `messages`. |
131
141
  | `messages` | array | `{ role, content }`, OpenAI-shaped. Use this **or** `prompt`. |
132
- | `model` | string | Defaults to `auto` — the router picks the cheapest capable model. |
142
+ | `model` | string | Defaults to `auto` — **Nex 1**, the router, picks the cheapest capable model. |
133
143
  | `system` | string | Prepended to the conversation. |
134
144
  | `max_tokens` | integer | Cap on the reply. |
135
145
  | `temperature` | number | Some models do not accept it; the receipt says when it was dropped. |
@@ -171,14 +181,14 @@ It also reports `unpriced_requests` and sets `is_floor`. The endpoint sums an
171
181
  unpriced row as zero — the only arithmetic available — so a total that includes
172
182
  one is a lower bound, not a total, and this tool says which.
173
183
 
174
- It does **not** report a savings total. `/api/v1/usage` does not compute one,
175
- and adding up savings client-side would mean pricing the org's tokens against a
176
- copy of the rate card. Savings are reported per call, by `lobstack_chat`, where
177
- the gateway sends them with the reason attached.
184
+ It does **not** report a savings total. Savings are reported per call, by
185
+ `lobstack_chat`, where the API sends them with the reason attached. Adding them
186
+ up client-side would mean pricing the org's tokens against a copy of the rate
187
+ card, and a copy drifts.
178
188
 
179
189
  ## Two rules about the numbers
180
190
 
181
- **A null cost is not zero.** `cost_usd: null` means the gateway could not price
191
+ **A null cost is not zero.** `cost_usd: null` means the API could not price
182
192
  the call. It renders as `unpriced`, never as `$0.00`. Rendering it as `$0.00`
183
193
  writes off a real charge, and that exact substitution ran for three months in
184
194
  production.
@@ -198,11 +208,11 @@ production.
198
208
  | variable | default | notes |
199
209
  | --- | --- | --- |
200
210
  | `LOBSTACK_API_KEY` | none | Read once at startup. Never logged, never in a tool result. |
201
- | `LOBSTACK_BASE_URL` | `https://www.lobstack.ai/api/gateway/v1` | For staging and self-hosted deployments. |
211
+ | `LOBSTACK_BASE_URL` | `https://www.lobstack.ai/api/gateway/v1` | The Lobstack API base URL. Change it only to point at a staging deployment. |
202
212
 
203
213
  **Use `www`, not the bare apex.** `lobstack.ai` redirects to `www.lobstack.ai`,
204
214
  and [RFC 9110 §15.4](https://www.rfc-editor.org/rfc/rfc9110#section-15.4)
205
- requires a client to drop `Authorization` across a host change — so the gateway
215
+ requires a client to drop `Authorization` across a host change — so the API
206
216
  answers a perfectly good key with "missing credentials". This server rewrites
207
217
  the apex and tells you it did, and refuses to follow any other 3xx rather than
208
218
  send a request whose credential has been stripped.
package/dist/server.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * The MCP server: four tools over the Lobstack Gateway.
2
+ * The MCP server: four tools over the Lobstack API.
3
3
  *
4
4
  * Exported as a factory rather than wired straight to stdio so the tests can
5
5
  * drive it over an in-memory transport with a real MCP client on the other end,
package/dist/server.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * The MCP server: four tools over the Lobstack Gateway.
2
+ * The MCP server: four tools over the Lobstack API.
3
3
  *
4
4
  * Exported as a factory rather than wired straight to stdio so the tests can
5
5
  * drive it over an in-memory transport with a real MCP client on the other end,
@@ -48,7 +48,7 @@ export const SERVER_VERSION = (() => {
48
48
  return "0.0.0";
49
49
  }
50
50
  })();
51
- const INSTRUCTIONS = `Lobstack is a metered LLM gateway: one key reaches every major model, and every call
51
+ const INSTRUCTIONS = `The Lobstack API is a metered LLM gateway: one key reaches every major model, and every call
52
52
  comes back with a receipt saying which model served it and what it cost.
53
53
 
54
54
  - lobstack_route_preview needs NO API key. It scores a prompt against the same
@@ -56,7 +56,7 @@ comes back with a receipt saying which model served it and what it cost.
56
56
  estimated cost. Use it to choose a model, or to show what routing does.
57
57
  - lobstack_chat runs the completion. Send model "auto" to let the router pick
58
58
  the cheapest model that can handle the prompt.
59
- - Costs are reported as the gateway priced them. A null cost means the gateway
59
+ - Costs are reported as the API priced them. A null cost means the API
60
60
  could not price the call — it does not mean the call was free.
61
61
  - A saving labelled "saved" is like-for-like: the caller named a model and got
62
62
  something cheaper. A saving labelled "vs ceiling" is measured against the most
@@ -69,23 +69,23 @@ export function createServer(options = {}) {
69
69
  title: "Preview routing and cost",
70
70
  description: "Score a prompt and report which model the Lobstack router would serve it with, and what that would cost. " +
71
71
  "Runs no inference, spends nothing, and NEEDS NO API KEY — use it to pick a model before calling lobstack_chat, " +
72
- "or to show what the gateway does on a machine with no key configured. Token counts are estimates; the billed " +
72
+ "or to show what the Lobstack API does on a machine with no key configured. Token counts are estimates; the billed " +
73
73
  "figure comes from the provider's usage block on the real call.",
74
74
  inputSchema: routePreviewInput,
75
75
  outputSchema: routePreviewOutput,
76
76
  annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: true },
77
77
  }, async (args) => runRoutePreview(cfg, args));
78
78
  server.registerTool("lobstack_models", {
79
- title: "List gateway models",
80
- description: "The models the Lobstack Gateway serves, with capability tier, provider, context window and USD price per " +
79
+ title: "List Lobstack API models",
80
+ description: "The models the Lobstack API serves, with capability tier, provider, context window and USD price per " +
81
81
  "million input and output tokens. A model the registry cannot price shows a null price, not zero.",
82
82
  inputSchema: modelsInput,
83
83
  outputSchema: modelsOutput,
84
84
  annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: true },
85
85
  }, async (args) => runModels(cfg, args));
86
86
  server.registerTool("lobstack_chat", {
87
- title: "Chat through the gateway",
88
- description: "Send a prompt or conversation through the Lobstack Gateway and get the reply plus a receipt: the model that " +
87
+ title: "Chat through the Lobstack API",
88
+ description: "Send a prompt or conversation through the Lobstack API and get the reply plus a receipt: the model that " +
89
89
  'actually served it, token counts, USD cost, and any saving with the reason it may be claimed. Model "auto" ' +
90
90
  "(the default) lets the router pick the cheapest model that can handle the prompt. This call spends money " +
91
91
  "against the configured key's allowance.",
@@ -95,7 +95,7 @@ export function createServer(options = {}) {
95
95
  }, async (args) => runChat(cfg, args));
96
96
  server.registerTool("lobstack_spend", {
97
97
  title: "Read spend and usage",
98
- description: "What this organization has spent through the gateway over a range, broken down by day, model, key or agent, " +
98
+ description: "What this organization has spent through the Lobstack API over a range, broken down by day, model, key or agent, " +
99
99
  "with request counts, tokens, error counts and latency percentiles. Requires an API key with the usage:read " +
100
100
  "scope. Reports how many requests could not be priced, because a total that includes them is a floor.",
101
101
  inputSchema: spendInput,
@@ -17,15 +17,18 @@
17
17
  * `truncated` — the endpoint pages to a cap. When it binds, the sums are a
18
18
  * floor for a second, independent reason.
19
19
  *
20
- * WHAT THIS TOOL DOES NOT REPORT
20
+ * WHAT THIS TOOL DOES NOT REPORT (YET)
21
21
  *
22
- * A savings total. `/api/v1/usage` does not compute one — its summary carries
23
- * requests, tokens, cost, error rate and latency percentiles, and nothing else.
24
- * Adding up per-call savings client-side would require the baselines, which are
25
- * not in this response, and printing a number derived from a rate card we hold
26
- * a copy of is the failure mode this whole product argues against. Savings are
27
- * reported per call, by lobstack_chat, where the Gateway sends them with the
28
- * reason attached.
22
+ * A savings total. `/api/v1/usage` now computes one, server-side from the
23
+ * priced ledger, as a top-level `savings` object split in two and never
24
+ * summed: `named` (a measured saving against a model the caller asked for) and
25
+ * `plan_ceiling` (a counterfactual against the priciest model the plan allows,
26
+ * when the caller sent `auto`). `savings` is null when the ledger could not be
27
+ * read. This tool does not read it yet; if it ever does, the two blocks must
28
+ * stay separate and `plan_ceiling` must be labelled as a counterfactual. What
29
+ * it must never do is add up per-call savings client-side from a rate card we
30
+ * hold a copy of. Per-call savings are reported by lobstack_chat, where the
31
+ * API sends them with the reason attached.
29
32
  */
30
33
  import { z } from "zod";
31
34
  import type { Config } from "../config.js";
@@ -17,15 +17,18 @@
17
17
  * `truncated` — the endpoint pages to a cap. When it binds, the sums are a
18
18
  * floor for a second, independent reason.
19
19
  *
20
- * WHAT THIS TOOL DOES NOT REPORT
20
+ * WHAT THIS TOOL DOES NOT REPORT (YET)
21
21
  *
22
- * A savings total. `/api/v1/usage` does not compute one — its summary carries
23
- * requests, tokens, cost, error rate and latency percentiles, and nothing else.
24
- * Adding up per-call savings client-side would require the baselines, which are
25
- * not in this response, and printing a number derived from a rate card we hold
26
- * a copy of is the failure mode this whole product argues against. Savings are
27
- * reported per call, by lobstack_chat, where the Gateway sends them with the
28
- * reason attached.
22
+ * A savings total. `/api/v1/usage` now computes one, server-side from the
23
+ * priced ledger, as a top-level `savings` object split in two and never
24
+ * summed: `named` (a measured saving against a model the caller asked for) and
25
+ * `plan_ceiling` (a counterfactual against the priciest model the plan allows,
26
+ * when the caller sent `auto`). `savings` is null when the ledger could not be
27
+ * read. This tool does not read it yet; if it ever does, the two blocks must
28
+ * stay separate and `plan_ceiling` must be labelled as a counterfactual. What
29
+ * it must never do is add up per-call savings client-side from a rate card we
30
+ * hold a copy of. Per-call savings are reported by lobstack_chat, where the
31
+ * API sends them with the reason attached.
29
32
  */
30
33
  import { z } from "zod";
31
34
  import { apiUrl } from "../config.js";
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@lobstack-ai/mcp",
3
- "version": "0.1.0",
4
- "description": "The Lobstack Gateway as an MCP server: thirty models behind one key, and what each call cost.",
3
+ "version": "0.1.2",
4
+ "description": "The Lobstack API as an MCP server: one key across many model providers, and what each call cost.",
5
5
  "type": "module",
6
6
  "bin": {
7
7
  "lobstack-mcp": "./dist/index.js"
@@ -38,7 +38,8 @@
38
38
  "anthropic",
39
39
  "claude",
40
40
  "cursor",
41
- "lobstack"
41
+ "lobstack",
42
+ "lobstack-api"
42
43
  ],
43
44
  "license": "MIT",
44
45
  "author": "Lobstack",
@@ -49,7 +50,7 @@
49
50
  "bugs": {
50
51
  "url": "https://github.com/Lobstack-ai/lobstack-mcp/issues"
51
52
  },
52
- "homepage": "https://github.com/Lobstack-ai/lobstack-mcp#readme",
53
+ "homepage": "https://www.lobstack.ai/docs/mcp",
53
54
  "dependencies": {
54
55
  "@modelcontextprotocol/sdk": "^1.30.0",
55
56
  "zod": "^3.25.76"