@softure-ai/mcp-access 0.1.12 → 0.1.13
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/CHANGELOG.md +23 -0
- package/README.md +126 -4
- package/dist/cli/bin.d.ts +3 -0
- package/dist/cli/bin.d.ts.map +1 -0
- package/dist/cli/bin.js +5 -0
- package/dist/cli/bin.js.map +1 -0
- package/dist/cli/command.d.ts +9 -0
- package/dist/cli/command.d.ts.map +1 -0
- package/dist/cli/command.js +30 -0
- package/dist/cli/command.js.map +1 -0
- package/dist/cli/index.d.ts +3 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +4 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/run.d.ts +24 -0
- package/dist/cli/run.d.ts.map +1 -0
- package/dist/cli/run.js +58 -0
- package/dist/cli/run.js.map +1 -0
- package/dist/contract.d.ts +4 -2
- package/dist/contract.d.ts.map +1 -1
- package/dist/index.d.ts +20 -7
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +6 -11
- package/dist/index.js.map +1 -1
- package/dist/messages/en.d.ts +2 -0
- package/dist/messages/en.d.ts.map +1 -1
- package/dist/messages/en.js +2 -0
- package/dist/messages/en.js.map +1 -1
- package/dist/messages/index.d.ts +4 -0
- package/dist/messages/index.d.ts.map +1 -1
- package/dist/messages/pl.d.ts.map +1 -1
- package/dist/messages/pl.js +2 -0
- package/dist/messages/pl.js.map +1 -1
- package/dist/next/actions.d.ts +2 -2
- package/dist/next/actions.d.ts.map +1 -1
- package/dist/next/actions.js +8 -47
- package/dist/next/actions.js.map +1 -1
- package/dist/next/format.d.ts +1 -1
- package/dist/next/format.d.ts.map +1 -1
- package/dist/next/format.js +3 -1
- package/dist/next/format.js.map +1 -1
- package/dist/next/index.d.ts +2 -1
- package/dist/next/index.d.ts.map +1 -1
- package/dist/next/index.js +1 -0
- package/dist/next/index.js.map +1 -1
- package/dist/next/issue-token.d.ts +15 -0
- package/dist/next/issue-token.d.ts.map +1 -0
- package/dist/next/issue-token.js +77 -0
- package/dist/next/issue-token.js.map +1 -0
- package/dist/next/pages.d.ts +9 -1
- package/dist/next/pages.d.ts.map +1 -1
- package/dist/next/pages.js +2 -2
- package/dist/next/pages.js.map +1 -1
- package/dist/options.d.ts +16 -0
- package/dist/options.d.ts.map +1 -1
- package/dist/options.js +4 -0
- package/dist/options.js.map +1 -1
- package/dist/routes.d.ts +15 -0
- package/dist/routes.d.ts.map +1 -0
- package/dist/routes.js +17 -0
- package/dist/routes.js.map +1 -0
- package/dist/server/action-tool.d.ts +21 -0
- package/dist/server/action-tool.d.ts.map +1 -0
- package/dist/server/action-tool.js +51 -0
- package/dist/server/action-tool.js.map +1 -0
- package/dist/server/index.d.ts +3 -0
- package/dist/server/index.d.ts.map +1 -1
- package/dist/server/index.js +3 -0
- package/dist/server/index.js.map +1 -1
- package/dist/server/prune.d.ts +8 -0
- package/dist/server/prune.d.ts.map +1 -0
- package/dist/server/prune.js +10 -0
- package/dist/server/prune.js.map +1 -0
- package/dist/server/tools.d.ts +25 -0
- package/dist/server/tools.d.ts.map +1 -0
- package/dist/server/tools.js +61 -0
- package/dist/server/tools.js.map +1 -0
- package/dist/stdio/index.d.ts +2 -0
- package/dist/stdio/index.d.ts.map +1 -0
- package/dist/stdio/index.js +4 -0
- package/dist/stdio/index.js.map +1 -0
- package/dist/stdio/register.d.ts +2 -0
- package/dist/stdio/register.d.ts.map +1 -0
- package/dist/stdio/register.js +10 -0
- package/dist/stdio/register.js.map +1 -0
- package/dist/stdio/serve.d.ts +45 -0
- package/dist/stdio/serve.d.ts.map +1 -0
- package/dist/stdio/serve.js +89 -0
- package/dist/stdio/serve.js.map +1 -0
- package/dist/testing/catalog.d.ts +15 -0
- package/dist/testing/catalog.d.ts.map +1 -0
- package/dist/testing/catalog.js +51 -0
- package/dist/testing/catalog.js.map +1 -0
- package/dist/testing/index.d.ts +2 -0
- package/dist/testing/index.d.ts.map +1 -0
- package/dist/testing/index.js +3 -0
- package/dist/testing/index.js.map +1 -0
- package/module.json +1 -1
- package/package.json +31 -5
- package/src/cli/bin.ts +5 -0
- package/src/cli/command.ts +38 -0
- package/src/cli/index.ts +3 -0
- package/src/cli/run.ts +79 -0
- package/src/contract.ts +5 -2
- package/src/index.ts +9 -12
- package/src/messages/en.ts +2 -0
- package/src/messages/pl.ts +2 -0
- package/src/next/actions.ts +8 -45
- package/src/next/format.ts +2 -2
- package/src/next/index.ts +2 -1
- package/src/next/issue-token.ts +90 -0
- package/src/next/pages.tsx +11 -3
- package/src/options.ts +4 -0
- package/src/routes.ts +17 -0
- package/src/server/action-tool.ts +64 -0
- package/src/server/index.ts +3 -0
- package/src/server/prune.ts +14 -0
- package/src/server/tools.ts +72 -0
- package/src/stdio/index.ts +12 -0
- package/src/stdio/register.ts +11 -0
- package/src/stdio/serve.ts +133 -0
- package/src/testing/catalog.ts +74 -0
- package/src/testing/index.ts +2 -0
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,27 @@ Newest first. Each version lists what changed for an app that uses `@softure-ai/
|
|
|
4
4
|
production, the version gets a line `verified in: <app>@<commit>` ([docs/05](../../docs/05-adoption-playbook.md),
|
|
5
5
|
"Definition of done"). Versions before the first one below are described in their GitHub Releases (`mcp-access@x.y.z`).
|
|
6
6
|
|
|
7
|
+
## 0.1.13
|
|
8
|
+
|
|
9
|
+
- Token and grant dates use core's `formatCalendarDay` on the day in the app's zone; same output. Requires
|
|
10
|
+
`@softure-ai/core` `^0.1.9` (#312).
|
|
11
|
+
- What an adopting app wrote around the endpoint ships with the package (#315):
|
|
12
|
+
- `toolResult`, `toolError` and `withToolErrors(work, { hints, label })` (`/server`): a thrown error reaches the
|
|
13
|
+
assistant only as a `PublicError` message or a hint, and the log only by kind, never with its SQL.
|
|
14
|
+
- `actionTool(handler, { message, hints })` (`/server`): a server action as a write tool, its arguments sent as
|
|
15
|
+
the form the action reads.
|
|
16
|
+
- `@softure-ai/mcp-access/stdio`: `serveMcpStdio({ config, createServer, userIdEnv, allowWrites })` serves the
|
|
17
|
+
factory over stdio for the account in `MCP_USER_ID`, or the only account; `/stdio/register` resolves
|
|
18
|
+
`server-only` to an empty module for `node`/`tsx --import`.
|
|
19
|
+
- `@softure-ai/mcp-access/testing`: `expectToolCatalogMatchesServer(config, createServer)` and
|
|
20
|
+
`getToolCatalogDifferences`. Catalog tools take optional localized `title` and `example`.
|
|
21
|
+
- `DEFAULT_MCP_ACCESS_ROUTES` from the root entry; the manifest uses it.
|
|
22
|
+
- `issueToken(previous, form, { beforeIssue })` (`/next`) for a gate before a token is issued, with the codes
|
|
23
|
+
`mcp-access.issue_refused` and `mcp-access.write_refused` (copy in en and pl); `McpAccessPage` takes an
|
|
24
|
+
optional `issueAction`. `issueTokenAction` is unchanged.
|
|
25
|
+
- `pruneMcpAccess(ctx)` (`/server`) and the `softure-mcp prune` command (bin, `/cli`) for a daily job such as a
|
|
26
|
+
deploy `maintain` hook.
|
|
27
|
+
|
|
7
28
|
## 0.1.12
|
|
8
29
|
|
|
9
30
|
- Without a `resolveAppOrigin` option, the app origin comes from core's `resolveAppOrigin` (#311): a listed origin
|
|
@@ -12,6 +33,8 @@ production, the version gets a line `verified in: <app>@<commit>` ([docs/05](../
|
|
|
12
33
|
answers `null` for a host that is no host). The consent decision still reads `Host` only. Discovery documents vary
|
|
13
34
|
on `x-forwarded-host` too.
|
|
14
35
|
- `getRequestOrigins(config, path)` is exported from `@softure-ai/mcp-access/next`. Needs `@softure-ai/core` 0.1.8.
|
|
36
|
+
- `MCP_RATE_LIMIT_BUCKETS` declares `key: "ip"` on `mcp` and `mcp-oauth` (security 0.1.8 bucket kinds).
|
|
37
|
+
- Requires `@softure-ai/security` `^0.1.8`: earlier versions refuse the `key` field.
|
|
15
38
|
|
|
16
39
|
## 0.1.11
|
|
17
40
|
|
package/README.md
CHANGED
|
@@ -38,6 +38,9 @@ limit check made race-free.
|
|
|
38
38
|
count against `maxTokensPerUser` and are not listed with the hand-issued ones.
|
|
39
39
|
- Tokens an app issued before adopting the module keep working through `legacyTokenPattern`.
|
|
40
40
|
- Server functions for scripts and other hosts, and a health check for `GET /api/health`.
|
|
41
|
+
- For the app's own server: tool result helpers with a safe error boundary and server actions as write tools
|
|
42
|
+
(`/server`), a stdio entry for local assistants (`/stdio`), a catalog parity check (`/testing`), a gate before a
|
|
43
|
+
token is issued (`issueToken`, `/next`) and the `softure-mcp prune` command for a daily cleanup (§4, §5).
|
|
41
44
|
|
|
42
45
|
## 2. Installation
|
|
43
46
|
|
|
@@ -74,7 +77,7 @@ mcpAccess({
|
|
|
74
77
|
| Option | Type | Default | Meaning |
|
|
75
78
|
| --- | --- | --- | --- |
|
|
76
79
|
| `serverName` | `string` | required | The name clients list the server under (lowercase, digits, inner dashes; no quotes needed in a shell). |
|
|
77
|
-
| `tools` | `{ name, access: "read" \| "write", description: { en, pl? } }[]` | `[]` | The catalog the token page shows. Keep it next to the factory;
|
|
80
|
+
| `tools` | `{ name, access: "read" \| "write", description: { en, pl? }, title?: { en, pl? }, example?: { en, pl? } }[]` | `[]` | The catalog the token page shows. `title` (a display name) and `example` (a request a person could make) are for agent docs that read the catalog. Keep it next to the factory; `expectToolCatalogMatchesServer` (`/testing`) checks that both list the same tools. |
|
|
78
81
|
| `allowWrites` | `boolean` | `false` | Lets write tokens be issued and used. Off, the page offers no write tokens and every token reads only. |
|
|
79
82
|
| `tokenLifetimeDays` | `integer` 1–365 | `90` | How long a hand-issued token works. There is no renewal: the user issues a new one. |
|
|
80
83
|
| `maxTokensPerUser` | `integer` 1–100 | `20` | Unexpired tokens one account may hold. Counted under a per-user lock, so parallel requests cannot overshoot. |
|
|
@@ -88,7 +91,7 @@ mcpAccess({
|
|
|
88
91
|
| `oauth.metadata` | `{ authorizationServer?, protectedResource? }`, each an object or `(origins) => object` | — | Extra keys of the discovery documents (`jwks_uri`, `service_documentation`, `resource_documentation`, `agent_auth`…). Generated keys win; a static object that sets one is refused at startup. The protected resource document takes the app's `resource_name` (default: `serverName`). |
|
|
89
92
|
| `resolveAppOrigin` | `(request) => string \| null` | — | The app origin of one request, ahead of the config's `origins` block (prefer that block: every module reads it). `readRequestOrigin` reads it from `Host`. Null falls back to the block's rule; anything but a bare http(s) origin throws. |
|
|
90
93
|
| `resourceOrigins` | `string[]` (≤ 16 http(s) origins) | `[]` | Other public hosts of the app, e.g. the apex next to `app.`: the root protected resource metadata asked on one of them names it as `resource`, and the OAuth endpoints accept it as `resource`. |
|
|
91
|
-
| `routes` | `{ page?, endpoint?, oauthConsent?, oauthDecision?, oauthToken?, oauthRegister? }` | `/account/mcp`, `/api/mcp`, `/oauth/authorize`, `/api/oauth/authorize`, `/api/oauth/token`, `/api/oauth/register` | Move the page, the endpoint or the OAuth paths; URLs in the setup and the metadata are the app origin (`appOrigin`, or `resolveAppOrigin`'s) + the path. |
|
|
94
|
+
| `routes` | `{ page?, endpoint?, oauthConsent?, oauthDecision?, oauthToken?, oauthRegister? }` | `DEFAULT_MCP_ACCESS_ROUTES` (root entry): `/account/mcp`, `/api/mcp`, `/oauth/authorize`, `/api/oauth/authorize`, `/api/oauth/token`, `/api/oauth/register` | Move the page, the endpoint or the OAuth paths; URLs in the setup and the metadata are the app origin (`appOrigin`, or `resolveAppOrigin`'s) + the path. |
|
|
92
95
|
| `messages` | partial `en` / `pl` | — | Copy overrides. |
|
|
93
96
|
|
|
94
97
|
`allowWrites` is a deploy decision, so read it from the environment rather than hard-coding it:
|
|
@@ -138,6 +141,112 @@ Answers to 2025-era clients come as one SSE `message` event, to 2026-07-28 clien
|
|
|
138
141
|
mid-call notifications (progress, logging) are dropped. Keep `/api/mcp` out of a proxy guard that
|
|
139
142
|
redirects to the login page: the endpoint authenticates by token, not by cookie.
|
|
140
143
|
|
|
144
|
+
### Writing tools
|
|
145
|
+
|
|
146
|
+
`/server` answers tools safely, so a failure never hands the assistant a query or an error's text:
|
|
147
|
+
|
|
148
|
+
```ts
|
|
149
|
+
import { actionTool, toolResult, withToolErrors } from "@softure-ai/mcp-access/server";
|
|
150
|
+
|
|
151
|
+
server.registerTool("list_orders", { description: "Lists your orders." }, () =>
|
|
152
|
+
withToolErrors(() => findOrders(db, userId), { label: "list_orders", hints: { "orders.locked": "The shop is closed for stock-taking." } }),
|
|
153
|
+
);
|
|
154
|
+
if (canWrite) {
|
|
155
|
+
server.registerTool("place_order", { inputSchema: z.object({ sku: z.string(), quantity: z.number() }) }, actionTool(
|
|
156
|
+
(form) => placeOrderAction({ status: "idle" }, form),
|
|
157
|
+
{ message: "Order placed.", hints: { "orders.out_of_stock": "That item is out of stock." } },
|
|
158
|
+
));
|
|
159
|
+
}
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
- `toolResult(value)`: a string as text, anything else as JSON. `toolError(message)`: the same with `isError`.
|
|
163
|
+
- `withToolErrors(work, { hints?, label? })`: a `CallToolResult` passes; a result value is unwrapped (`ok` → its
|
|
164
|
+
value, else the hint for its error code, else the code); any other value becomes `toolResult`. A thrown
|
|
165
|
+
`PublicError` (core) gives its message. Anything else is logged by kind only (`errorLogLabel`, never the SQL or
|
|
166
|
+
its parameters) and answered with the hint for its `safeError` code (`core.database_failed`, `core.unexpected`),
|
|
167
|
+
else a fixed English text.
|
|
168
|
+
- `actionTool(handler, { message?, hints?, label? })`: the server action behind a form as a write tool, so both
|
|
169
|
+
share one validation path. The arguments become `FormData` (numbers as text, `true` as `"on"`, `false` and `null`
|
|
170
|
+
left out, arrays one entry per item, dates as ISO, objects as JSON). A `{ ok: false, error }` or
|
|
171
|
+
`{ status: "error", error }` state is a tool error through the hints; otherwise the answer is `message` (text or
|
|
172
|
+
`(state) => text`), else the state as JSON.
|
|
173
|
+
|
|
174
|
+
### Stdio
|
|
175
|
+
|
|
176
|
+
A local assistant on the machine that holds the database can run the same factory over stdio, without a token:
|
|
177
|
+
|
|
178
|
+
```ts
|
|
179
|
+
// scripts/mcp-stdio.ts
|
|
180
|
+
import { serveMcpStdio } from "@softure-ai/mcp-access/stdio";
|
|
181
|
+
import config from "../softure.config";
|
|
182
|
+
import { createServer } from "../lib/mcp-server";
|
|
183
|
+
|
|
184
|
+
const started = await serveMcpStdio({ config, createServer, allowWrites: process.env.MCP_ALLOW_WRITES === "1" });
|
|
185
|
+
if (!started.ok) {
|
|
186
|
+
console.error(started.error.message);
|
|
187
|
+
process.exitCode = 1;
|
|
188
|
+
}
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
```bash
|
|
192
|
+
claude mcp add acme -e MCP_USER_ID=<account id> -- npx tsx --import @softure-ai/mcp-access/stdio/register scripts/mcp-stdio.ts
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
- The account: `MCP_USER_ID` (or `userIdEnv`) when set, which must name an account; else the only account in the
|
|
196
|
+
database. With several accounts and no id the entry refuses (`mcp-access.stdio_account_ambiguous`): it never
|
|
197
|
+
picks one.
|
|
198
|
+
- `canWrite` needs `allowWrites: true` here and the app's `allowWrites`. The token id is `"stdio"`.
|
|
199
|
+
- The database opens like a package command's (`database.handle`, else `database.url`) and closes with the
|
|
200
|
+
connection. Messages go to stderr; stdout is the protocol.
|
|
201
|
+
- `@softure-ai/mcp-access/stdio/register` (`--import`) resolves `server-only` to an empty module, so a factory
|
|
202
|
+
written for Next runs in plain Node. It needs Node 22.15 or later (`module.registerHooks`).
|
|
203
|
+
|
|
204
|
+
### Catalog parity
|
|
205
|
+
|
|
206
|
+
```ts
|
|
207
|
+
// lib/mcp-server.test.ts
|
|
208
|
+
import { expectToolCatalogMatchesServer } from "@softure-ai/mcp-access/testing";
|
|
209
|
+
|
|
210
|
+
it("lists the same tools as the server", () => expectToolCatalogMatchesServer(config, createServer));
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
It lists the server's tools for a read-only and a write identity and throws naming every configured tool the
|
|
214
|
+
server lacks, every registered tool the catalog lacks, and every write tool a read-only token gets.
|
|
215
|
+
`getToolCatalogDifferences` returns the same as lists.
|
|
216
|
+
|
|
217
|
+
### Gating token issue
|
|
218
|
+
|
|
219
|
+
An app that checks something before a token is issued (a plan that includes write access) calls `issueToken` from
|
|
220
|
+
its own server action instead of copying `issueTokenAction`:
|
|
221
|
+
|
|
222
|
+
```ts
|
|
223
|
+
// app/account/mcp/actions.ts
|
|
224
|
+
"use server";
|
|
225
|
+
import { err, ok } from "@softure-ai/core";
|
|
226
|
+
import { issueToken } from "@softure-ai/mcp-access/next";
|
|
227
|
+
import type { IssueTokenFormState } from "@softure-ai/mcp-access";
|
|
228
|
+
|
|
229
|
+
export async function issueGatedToken(previous: IssueTokenFormState, form: FormData) {
|
|
230
|
+
return issueToken(previous, form, {
|
|
231
|
+
beforeIssue: async ({ userId, canWrite }) => (canWrite && !(await hasWritePlan(userId)) ? err("mcp-access.write_refused") : ok()),
|
|
232
|
+
});
|
|
233
|
+
}
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
```tsx
|
|
237
|
+
// app/account/mcp/page.tsx
|
|
238
|
+
import { McpAccessPage } from "@softure-ai/mcp-access/next";
|
|
239
|
+
import { issueGatedToken } from "./actions";
|
|
240
|
+
|
|
241
|
+
export default function Page() {
|
|
242
|
+
return <McpAccessPage issueAction={issueGatedToken} />;
|
|
243
|
+
}
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
The gate runs after the session check and before anything is issued. `mcp-access.write_refused` and
|
|
247
|
+
`mcp-access.issue_refused` have copy in `messages.errors["mcp-access"]` (override it per app); a gate that throws
|
|
248
|
+
becomes a `safeError` code. The gate stays in the app's code, out of `softure.config.ts`.
|
|
249
|
+
|
|
141
250
|
`TokenManager` (`@softure-ai/mcp-access/ui`) takes the actions `issueTokenAction` and
|
|
142
251
|
`revokeTokenAction` (`/next`) as props for an app that composes its own page, and `grants` with
|
|
143
252
|
`revokeGrantAction` for the connected apps list.
|
|
@@ -226,7 +335,7 @@ whose last argument they are; `OAuthClientRow` is exported from the package root
|
|
|
226
335
|
| `last_used_at` | Written on verification at most once a minute; informational only. |
|
|
227
336
|
|
|
228
337
|
Issuing deletes the issuer's expired tokens; `pruneAccessTokens(ctx)` (`/server`) deletes every
|
|
229
|
-
expired token, for a scheduled job. Rollback: in the migration header.
|
|
338
|
+
expired token, for a scheduled job (see "Scheduled pruning" below). Rollback: in the migration header.
|
|
230
339
|
|
|
231
340
|
`migrations/0002_create_oauth_grants.sql` creates `mcp.oauth_clients` (client id, name, redirect
|
|
232
341
|
URIs, auth method, sha256 of a confidential client's secret), `mcp.oauth_authorization_codes`
|
|
@@ -236,6 +345,18 @@ expiry, last use), and adds `access_tokens.grant_id` (null for hand-issued token
|
|
|
236
345
|
with the account. `pruneOAuthRecords(ctx)` deletes expired codes, grants whose refresh token has
|
|
237
346
|
expired (with their access tokens) and clients registered over a day ago that hold no grant.
|
|
238
347
|
|
|
348
|
+
### Scheduled pruning
|
|
349
|
+
|
|
350
|
+
`pruneMcpAccess(ctx)` (`/server`) runs both prunes and counts what each removed. The `softure-mcp prune` command
|
|
351
|
+
runs it with the app's config (loaded like `softure migrate`, or from an app script through `runMcpAccessCli` from
|
|
352
|
+
`/cli`) and prints one line. Run it daily, e.g. as a `maintain` hook of `@softure-ai/deploy`:
|
|
353
|
+
|
|
354
|
+
```json
|
|
355
|
+
{ "hooks": { "maintain": [{ "name": "mcp-prune", "compose": ["exec", "-T", "app", "npx", "softure-mcp", "prune"] }] } }
|
|
356
|
+
```
|
|
357
|
+
|
|
358
|
+
An app that pruned inline on every token exchange can drop that code.
|
|
359
|
+
|
|
239
360
|
### Adopting an app's own tables
|
|
240
361
|
|
|
241
362
|
An app that ran its own `public.access_tokens` (with `grant_id`) and `oauth_clients`,
|
|
@@ -280,7 +401,8 @@ the `tools` option, per locale.
|
|
|
280
401
|
|
|
281
402
|
## 10. Hooks
|
|
282
403
|
|
|
283
|
-
The MCP server factory passed to `createMcpRoute`
|
|
404
|
+
The MCP server factory passed to `createMcpRoute` (and to `serveMcpStdio`) and the `beforeIssue` gate of
|
|
405
|
+
`issueToken` are the module's hooks. `/server` also exports
|
|
284
406
|
`createMcpEndpoint({ createServer })`, a `(ctx, request) => Response` for hosts other than Next, and
|
|
285
407
|
`issueAccessToken`, `listAccessTokens`, `revokeAccessToken`, `verifyAccessToken` and
|
|
286
408
|
`pruneAccessTokens` for scripts. For OAuth: `listOAuthGrants`, `revokeOAuthGrant`,
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bin.d.ts","sourceRoot":"","sources":["../../src/cli/bin.ts"],"names":[],"mappings":""}
|
package/dist/cli/bin.js
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// The `softure-mcp` executable. All logic lives in command.ts and run.ts, which the tests call directly.
|
|
3
|
+
import { runMcpAccessCommand } from "./command.js";
|
|
4
|
+
process.exitCode = await runMcpAccessCommand({ argv: process.argv.slice(2), cwd: process.cwd() });
|
|
5
|
+
//# sourceMappingURL=bin.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bin.js","sourceRoot":"","sources":["../../src/cli/bin.ts"],"names":[],"mappings":";AACA,yGAAyG;AACzG,OAAO,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AAEnD,OAAO,CAAC,QAAQ,GAAG,MAAM,mBAAmB,CAAC,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,OAAO,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { type CliOutput } from "./run.js";
|
|
2
|
+
export interface RunMcpAccessCommandOptions {
|
|
3
|
+
readonly argv: readonly string[];
|
|
4
|
+
readonly cwd: string;
|
|
5
|
+
readonly output?: CliOutput;
|
|
6
|
+
}
|
|
7
|
+
/** Loads the config (unless only help is asked for) and runs `runMcpAccessCli`. */
|
|
8
|
+
export declare function runMcpAccessCommand(options: RunMcpAccessCommandOptions): Promise<number>;
|
|
9
|
+
//# sourceMappingURL=command.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"command.d.ts","sourceRoot":"","sources":["../../src/cli/command.ts"],"names":[],"mappings":"AAIA,OAAO,EAA8D,KAAK,SAAS,EAAE,MAAM,UAAU,CAAC;AAEtG,MAAM,WAAW,0BAA0B;IACzC,QAAQ,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,CAAC;IACjC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,MAAM,CAAC,EAAE,SAAS,CAAC;CAC7B;AASD,mFAAmF;AACnF,wBAAsB,mBAAmB,CAAC,OAAO,EAAE,0BAA0B,GAAG,OAAO,CAAC,MAAM,CAAC,CAiB9F"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
// The `softure-mcp` bin. It loads the app's config through `@softure-ai/core/cli`, like `softure-mail`
|
|
2
|
+
// (@softure-ai/mailing): the file must be loadable by Node itself (`.js`/`.mjs`, or `.ts` where Node
|
|
3
|
+
// strips types). Anything else uses an app script with `runMcpAccessCli` instead (see run.ts).
|
|
4
|
+
import { loadAppConfig, takeConfigOption } from "@softure-ai/core/cli";
|
|
5
|
+
import { EXIT_FAILED, EXIT_USAGE, MCP_ACCESS_USAGE, runMcpAccessCli } from "./run.js";
|
|
6
|
+
const APP_SCRIPT = { runner: "runMcpAccessCli", packageName: "@softure-ai/mcp-access" };
|
|
7
|
+
const consoleOutput = {
|
|
8
|
+
log: (line) => console.log(line),
|
|
9
|
+
error: (line) => console.error(line),
|
|
10
|
+
};
|
|
11
|
+
/** Loads the config (unless only help is asked for) and runs `runMcpAccessCli`. */
|
|
12
|
+
export async function runMcpAccessCommand(options) {
|
|
13
|
+
const output = options.output ?? consoleOutput;
|
|
14
|
+
const taken = takeConfigOption(options.argv);
|
|
15
|
+
if (!taken.ok) {
|
|
16
|
+
output.error(`softure-mcp: ${taken.problem}`);
|
|
17
|
+
output.error(MCP_ACCESS_USAGE);
|
|
18
|
+
return EXIT_USAGE;
|
|
19
|
+
}
|
|
20
|
+
const { configPath, argv } = taken;
|
|
21
|
+
if (argv[0] !== "prune")
|
|
22
|
+
return runMcpAccessCli({ argv, output });
|
|
23
|
+
const loaded = await loadAppConfig({ cwd: options.cwd, configPath, appScript: APP_SCRIPT });
|
|
24
|
+
if (!loaded.ok) {
|
|
25
|
+
output.error(`softure-mcp: ${loaded.problem}`);
|
|
26
|
+
return EXIT_FAILED;
|
|
27
|
+
}
|
|
28
|
+
return runMcpAccessCli({ config: loaded.config, argv, output });
|
|
29
|
+
}
|
|
30
|
+
//# sourceMappingURL=command.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"command.js","sourceRoot":"","sources":["../../src/cli/command.ts"],"names":[],"mappings":"AAAA,uGAAuG;AACvG,qGAAqG;AACrG,+FAA+F;AAC/F,OAAO,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AACvE,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,gBAAgB,EAAE,eAAe,EAAkB,MAAM,UAAU,CAAC;AAQtG,MAAM,UAAU,GAAG,EAAE,MAAM,EAAE,iBAAiB,EAAE,WAAW,EAAE,wBAAwB,EAAE,CAAC;AAExF,MAAM,aAAa,GAAc;IAC/B,GAAG,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC;IAChC,KAAK,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC;CACrC,CAAC;AAEF,mFAAmF;AACnF,MAAM,CAAC,KAAK,UAAU,mBAAmB,CAAC,OAAmC;IAC3E,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,IAAI,aAAa,CAAC;IAC/C,MAAM,KAAK,GAAG,gBAAgB,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IAC7C,IAAI,CAAC,KAAK,CAAC,EAAE,EAAE,CAAC;QACd,MAAM,CAAC,KAAK,CAAC,gBAAgB,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;QAC9C,MAAM,CAAC,KAAK,CAAC,gBAAgB,CAAC,CAAC;QAC/B,OAAO,UAAU,CAAC;IACpB,CAAC;IACD,MAAM,EAAE,UAAU,EAAE,IAAI,EAAE,GAAG,KAAK,CAAC;IACnC,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,OAAO;QAAE,OAAO,eAAe,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC;IAElE,MAAM,MAAM,GAAG,MAAM,aAAa,CAAC,EAAE,GAAG,EAAE,OAAO,CAAC,GAAG,EAAE,UAAU,EAAE,SAAS,EAAE,UAAU,EAAE,CAAC,CAAC;IAC5F,IAAI,CAAC,MAAM,CAAC,EAAE,EAAE,CAAC;QACf,MAAM,CAAC,KAAK,CAAC,gBAAgB,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC;QAC/C,OAAO,WAAW,CAAC;IACrB,CAAC;IACD,OAAO,eAAe,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC;AAClE,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,mBAAmB,EAAE,KAAK,0BAA0B,EAAE,MAAM,cAAc,CAAC;AACpF,OAAO,EAAE,WAAW,EAAE,OAAO,EAAE,UAAU,EAAE,gBAAgB,EAAE,eAAe,EAAE,KAAK,SAAS,EAAE,KAAK,sBAAsB,EAAE,MAAM,UAAU,CAAC"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
// `@softure-ai/mcp-access/cli`: the `softure-mcp` command for app scripts and container bundles.
|
|
2
|
+
export { runMcpAccessCommand } from "./command.js";
|
|
3
|
+
export { EXIT_FAILED, EXIT_OK, EXIT_USAGE, MCP_ACCESS_USAGE, runMcpAccessCli } from "./run.js";
|
|
4
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":"AAAA,iGAAiG;AACjG,OAAO,EAAE,mBAAmB,EAAmC,MAAM,cAAc,CAAC;AACpF,OAAO,EAAE,WAAW,EAAE,OAAO,EAAE,UAAU,EAAE,gBAAgB,EAAE,eAAe,EAA+C,MAAM,UAAU,CAAC"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { type Clock, type SoftureConfig, type SoftureDatabaseConfig } from "@softure-ai/core";
|
|
2
|
+
import { type CommandDatabase } from "@softure-ai/db";
|
|
3
|
+
export interface CliOutput {
|
|
4
|
+
readonly log: (line: string) => void;
|
|
5
|
+
readonly error: (line: string) => void;
|
|
6
|
+
}
|
|
7
|
+
export interface RunMcpAccessCliOptions {
|
|
8
|
+
/** The app's config; only help needs none. */
|
|
9
|
+
readonly config?: SoftureConfig;
|
|
10
|
+
/** The arguments after the executable, e.g. `["prune"]`. */
|
|
11
|
+
readonly argv: readonly string[];
|
|
12
|
+
readonly output?: CliOutput;
|
|
13
|
+
/** Default: the wall clock. */
|
|
14
|
+
readonly clock?: Clock;
|
|
15
|
+
/** Default: the config's `database.handle`, else a connection on `database.url`. */
|
|
16
|
+
readonly openDatabase?: (database: SoftureDatabaseConfig) => Promise<CommandDatabase>;
|
|
17
|
+
}
|
|
18
|
+
export declare const EXIT_OK = 0;
|
|
19
|
+
export declare const EXIT_FAILED = 1;
|
|
20
|
+
export declare const EXIT_USAGE = 2;
|
|
21
|
+
export declare const MCP_ACCESS_USAGE = "Usage:\n softure-mcp prune deletes expired access tokens, authorization codes, grants and abandoned clients";
|
|
22
|
+
/** Runs one command and answers its exit code. */
|
|
23
|
+
export declare function runMcpAccessCli(options: RunMcpAccessCliOptions): Promise<number>;
|
|
24
|
+
//# sourceMappingURL=run.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"run.d.ts","sourceRoot":"","sources":["../../src/cli/run.ts"],"names":[],"mappings":"AAQA,OAAO,EAA8B,KAAK,KAAK,EAAE,KAAK,aAAa,EAAE,KAAK,qBAAqB,EAAE,MAAM,kBAAkB,CAAC;AAC1H,OAAO,EAAuB,KAAK,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAG3E,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,GAAG,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IACrC,QAAQ,CAAC,KAAK,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;CACxC;AAED,MAAM,WAAW,sBAAsB;IACrC,8CAA8C;IAC9C,QAAQ,CAAC,MAAM,CAAC,EAAE,aAAa,CAAC;IAChC,4DAA4D;IAC5D,QAAQ,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,CAAC;IACjC,QAAQ,CAAC,MAAM,CAAC,EAAE,SAAS,CAAC;IAC5B,+BAA+B;IAC/B,QAAQ,CAAC,KAAK,CAAC,EAAE,KAAK,CAAC;IACvB,oFAAoF;IACpF,QAAQ,CAAC,YAAY,CAAC,EAAE,CAAC,QAAQ,EAAE,qBAAqB,KAAK,OAAO,CAAC,eAAe,CAAC,CAAC;CACvF;AAED,eAAO,MAAM,OAAO,IAAI,CAAC;AACzB,eAAO,MAAM,WAAW,IAAI,CAAC;AAC7B,eAAO,MAAM,UAAU,IAAI,CAAC;AAE5B,eAAO,MAAM,gBAAgB,oHAC2E,CAAC;AAOzG,kDAAkD;AAClD,wBAAsB,eAAe,CAAC,OAAO,EAAE,sBAAsB,GAAG,OAAO,CAAC,MAAM,CAAC,CAatF"}
|
package/dist/cli/run.js
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
// `softure-mcp`: the module's maintenance command. `prune` deletes expired access tokens and dead OAuth
|
|
2
|
+
// records (`pruneMcpAccess`), for a daily job such as a deploy `maintain` hook. The app passes its
|
|
3
|
+
// validated config, so the same function serves the bin and an app script a bundler packs:
|
|
4
|
+
//
|
|
5
|
+
// // scripts/mcp.ts
|
|
6
|
+
// import { runMcpAccessCli } from "@softure-ai/mcp-access/cli";
|
|
7
|
+
// import config from "../softure.config";
|
|
8
|
+
// process.exitCode = await runMcpAccessCli({ config, argv: process.argv.slice(2) });
|
|
9
|
+
import { errorLogLabel, systemClock } from "@softure-ai/core";
|
|
10
|
+
import { openCommandDatabase } from "@softure-ai/db";
|
|
11
|
+
import { pruneMcpAccess } from "../server/prune.js";
|
|
12
|
+
export const EXIT_OK = 0;
|
|
13
|
+
export const EXIT_FAILED = 1;
|
|
14
|
+
export const EXIT_USAGE = 2;
|
|
15
|
+
export const MCP_ACCESS_USAGE = `Usage:
|
|
16
|
+
softure-mcp prune deletes expired access tokens, authorization codes, grants and abandoned clients`;
|
|
17
|
+
const consoleOutput = {
|
|
18
|
+
log: (line) => console.log(line),
|
|
19
|
+
error: (line) => console.error(line),
|
|
20
|
+
};
|
|
21
|
+
/** Runs one command and answers its exit code. */
|
|
22
|
+
export async function runMcpAccessCli(options) {
|
|
23
|
+
const output = options.output ?? consoleOutput;
|
|
24
|
+
const [command, ...rest] = options.argv;
|
|
25
|
+
if (command === undefined || command === "--help" || command === "help") {
|
|
26
|
+
output.log(MCP_ACCESS_USAGE);
|
|
27
|
+
return EXIT_OK;
|
|
28
|
+
}
|
|
29
|
+
if (command !== "prune" || rest.length > 0) {
|
|
30
|
+
output.error(command === "prune" ? `softure-mcp prune: unexpected argument "${rest[0] ?? ""}"` : `softure-mcp: unknown command "${command}"`);
|
|
31
|
+
output.error(MCP_ACCESS_USAGE);
|
|
32
|
+
return EXIT_USAGE;
|
|
33
|
+
}
|
|
34
|
+
return prune(options, output);
|
|
35
|
+
}
|
|
36
|
+
async function prune(options, output) {
|
|
37
|
+
const database = options.config?.database ?? null;
|
|
38
|
+
if (options.config === undefined || database === null) {
|
|
39
|
+
output.error("softure-mcp prune: the config has no database; set database.url in softure.config");
|
|
40
|
+
return EXIT_FAILED;
|
|
41
|
+
}
|
|
42
|
+
let opened;
|
|
43
|
+
try {
|
|
44
|
+
opened = await (options.openDatabase ?? ((settings) => openCommandDatabase(settings, { max: 1 })))(database);
|
|
45
|
+
const removed = await pruneMcpAccess({ db: opened.handle.db, clock: options.clock ?? systemClock, config: options.config });
|
|
46
|
+
output.log(`softure-mcp prune: removed ${String(removed.accessTokens)} access tokens, ${String(removed.codes)} authorization codes, ${String(removed.grants)} grants, ${String(removed.clients)} clients`);
|
|
47
|
+
return EXIT_OK;
|
|
48
|
+
}
|
|
49
|
+
catch (error) {
|
|
50
|
+
// The kind only: a driver message can carry the database address or credentials.
|
|
51
|
+
output.error(`softure-mcp prune: failed: ${errorLogLabel(error)}`);
|
|
52
|
+
return EXIT_FAILED;
|
|
53
|
+
}
|
|
54
|
+
finally {
|
|
55
|
+
await opened?.close();
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
//# sourceMappingURL=run.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"run.js","sourceRoot":"","sources":["../../src/cli/run.ts"],"names":[],"mappings":"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"}
|
package/dist/contract.d.ts
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import type { CoreErrorCode } from "@softure-ai/core";
|
|
2
2
|
export type McpAccessErrorCode = "mcp-access.name_required" | "mcp-access.name_too_long" | "mcp-access.token_limit_reached" | "mcp-access.token_not_found" | "mcp-access.grant_not_found";
|
|
3
|
-
/**
|
|
4
|
-
export type
|
|
3
|
+
/** What an app's `beforeIssue` gate may answer instead of letting a token be issued. */
|
|
4
|
+
export type McpIssueRefusalCode = "mcp-access.issue_refused" | "mcp-access.write_refused";
|
|
5
|
+
/** Every code the token page can show: its own, a gate's refusal, a missing session and the generic ones. */
|
|
6
|
+
export type TokenFormErrorCode = McpAccessErrorCode | McpIssueRefusalCode | "auth.unauthenticated" | CoreErrorCode;
|
|
5
7
|
/** What the app's MCP server factory receives for one request. */
|
|
6
8
|
export interface McpServerIdentity {
|
|
7
9
|
/** The auth user id of the token's owner: every query of the server is scoped to it. */
|
package/dist/contract.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"contract.d.ts","sourceRoot":"","sources":["../src/contract.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAEtD,MAAM,MAAM,kBAAkB,GAC1B,0BAA0B,GAC1B,0BAA0B,GAC1B,gCAAgC,GAChC,4BAA4B,GAC5B,4BAA4B,CAAC;AAEjC,
|
|
1
|
+
{"version":3,"file":"contract.d.ts","sourceRoot":"","sources":["../src/contract.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -8,6 +8,7 @@ export declare const MCP_RATE_LIMIT_BUCKETS: {
|
|
|
8
8
|
readonly mcp: {
|
|
9
9
|
readonly limit: 200;
|
|
10
10
|
readonly windowMinutes: 15;
|
|
11
|
+
readonly key: "ip";
|
|
11
12
|
};
|
|
12
13
|
/**
|
|
13
14
|
* OAuth registration (per address) and token requests (per address and client id), when
|
|
@@ -17,6 +18,7 @@ export declare const MCP_RATE_LIMIT_BUCKETS: {
|
|
|
17
18
|
readonly "mcp-oauth": {
|
|
18
19
|
readonly limit: 60;
|
|
19
20
|
readonly windowMinutes: 15;
|
|
21
|
+
readonly key: "ip";
|
|
20
22
|
};
|
|
21
23
|
};
|
|
22
24
|
/**
|
|
@@ -24,12 +26,12 @@ export declare const MCP_RATE_LIMIT_BUCKETS: {
|
|
|
24
26
|
* `mcpAccess({ serverName: "acme", tools: [{ name: "list_orders", access: "read", description: { en: "Lists your orders." } }] })`.
|
|
25
27
|
*/
|
|
26
28
|
export declare const mcpAccess: import("@softure-ai/core").ModuleFactory<{
|
|
27
|
-
page:
|
|
28
|
-
endpoint:
|
|
29
|
-
oauthConsent:
|
|
30
|
-
oauthDecision:
|
|
31
|
-
oauthToken:
|
|
32
|
-
oauthRegister:
|
|
29
|
+
page: "/account/mcp";
|
|
30
|
+
endpoint: "/api/mcp";
|
|
31
|
+
oauthConsent: "/oauth/authorize";
|
|
32
|
+
oauthDecision: "/api/oauth/authorize";
|
|
33
|
+
oauthToken: "/api/oauth/token";
|
|
34
|
+
oauthRegister: "/api/oauth/register";
|
|
33
35
|
}, {
|
|
34
36
|
page: {
|
|
35
37
|
title: string;
|
|
@@ -124,6 +126,8 @@ export declare const mcpAccess: import("@softure-ai/core").ModuleFactory<{
|
|
|
124
126
|
token_limit_reached: string;
|
|
125
127
|
token_not_found: string;
|
|
126
128
|
grant_not_found: string;
|
|
129
|
+
issue_refused: string;
|
|
130
|
+
write_refused: string;
|
|
127
131
|
};
|
|
128
132
|
auth: {
|
|
129
133
|
unauthenticated: string;
|
|
@@ -145,6 +149,14 @@ export declare const mcpAccess: import("@softure-ai/core").ModuleFactory<{
|
|
|
145
149
|
en: "en";
|
|
146
150
|
pl: "pl";
|
|
147
151
|
}> & import("zod/v4/core").$partial, import("zod").ZodString>;
|
|
152
|
+
title: import("zod").ZodOptional<import("zod").ZodRecord<import("zod").ZodEnum<{
|
|
153
|
+
en: "en";
|
|
154
|
+
pl: "pl";
|
|
155
|
+
}> & import("zod/v4/core").$partial, import("zod").ZodString>>;
|
|
156
|
+
example: import("zod").ZodOptional<import("zod").ZodRecord<import("zod").ZodEnum<{
|
|
157
|
+
en: "en";
|
|
158
|
+
pl: "pl";
|
|
159
|
+
}> & import("zod/v4/core").$partial, import("zod").ZodString>>;
|
|
148
160
|
}, import("zod/v4/core").$strict>>>;
|
|
149
161
|
allowWrites: import("zod").ZodDefault<import("zod").ZodBoolean>;
|
|
150
162
|
tokenLifetimeDays: import("zod").ZodDefault<import("zod").ZodInt>;
|
|
@@ -166,9 +178,10 @@ export declare const mcpAccess: import("@softure-ai/core").ModuleFactory<{
|
|
|
166
178
|
}, import("zod/v4/core").$strict>>;
|
|
167
179
|
}, import("zod/v4/core").$strict>>;
|
|
168
180
|
export { getAuthorizationHeader, getClaudeCodeCommand, getClaudeCodeLink, getDesktopConfig, getJsonConfig, getMcpClientSetup, type McpClientSetupInput, } from "./client-setup.js";
|
|
169
|
-
export type { AccessTokenStatus, AccessTokenView, IssuedToken, IssueTokenFormState, McpAccessErrorCode, McpClientSetup, McpServerIdentity, OAuthGrantView, RevokeGrantFormState, RevokeTokenFormState, TokenFormErrorCode, } from "./contract.js";
|
|
181
|
+
export type { AccessTokenStatus, AccessTokenView, IssuedToken, IssueTokenFormState, McpAccessErrorCode, McpIssueRefusalCode, McpClientSetup, McpServerIdentity, OAuthGrantView, RevokeGrantFormState, RevokeTokenFormState, TokenFormErrorCode, } from "./contract.js";
|
|
170
182
|
export { getTokenErrorMessage, mcpAccessMessages, type McpAccessMessages } from "./messages/index.js";
|
|
171
183
|
export { MAX_PRESENTED_TOKEN_LENGTH, MAX_TOKEN_NAME_LENGTH, SERVER_NAME_PATTERN, TOOL_NAME_PATTERN, GENERATED_AUTHORIZATION_SERVER_KEYS, GENERATED_PROTECTED_RESOURCE_KEYS, type McpAccessOptions, type McpAccessOptionsInput, type McpAppOriginResolver, type McpMetadataExtension, type McpOAuthOptions, type McpToolAccess, type McpToolDefinition, type McpToolDefinitionInput, } from "./options.js";
|
|
184
|
+
export { DEFAULT_MCP_ACCESS_ROUTES } from "./routes.js";
|
|
172
185
|
export { readRequestOrigin, type McpOriginRequest, type McpOrigins } from "./origins.js";
|
|
173
186
|
export { accessTokens, oauthAuthorizationCodes, oauthClients, oauthGrants, type OAuthClientRow, type OAuthTokenEndpointAuthMethod } from "./schema.js";
|
|
174
187
|
export { getAccessTokenStatus, type AccessTokenStatusOptions } from "./token-status.js";
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAYA,eAAO,MAAM,SAAS,eAAe,CAAC;AAEtC;;;;GAIG;AACH,eAAO,MAAM,sBAAsB;;;;;;IAEjC;;;;OAIG;;;;;;CAE8D,CAAC;AAEpE;;;GAGG;AACH,eAAO,MAAM,SAAS;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kCA4BpB,CAAC;AAEH,OAAO,EACL,sBAAsB,EACtB,oBAAoB,EACpB,iBAAiB,EACjB,gBAAgB,EAChB,aAAa,EACb,iBAAiB,EACjB,KAAK,mBAAmB,GACzB,MAAM,mBAAmB,CAAC;AAC3B,YAAY,EACV,iBAAiB,EACjB,eAAe,EACf,WAAW,EACX,mBAAmB,EACnB,kBAAkB,EAClB,mBAAmB,EACnB,cAAc,EACd,iBAAiB,EACjB,cAAc,EACd,oBAAoB,EACpB,oBAAoB,EACpB,kBAAkB,GACnB,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,oBAAoB,EAAE,iBAAiB,EAAE,KAAK,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AACtG,OAAO,EACL,0BAA0B,EAC1B,qBAAqB,EACrB,mBAAmB,EACnB,iBAAiB,EACjB,mCAAmC,EACnC,iCAAiC,EACjC,KAAK,gBAAgB,EACrB,KAAK,qBAAqB,EAC1B,KAAK,oBAAoB,EACzB,KAAK,oBAAoB,EACzB,KAAK,eAAe,EACpB,KAAK,aAAa,EAClB,KAAK,iBAAiB,EACtB,KAAK,sBAAsB,GAC5B,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,yBAAyB,EAAE,MAAM,aAAa,CAAC;AACxD,OAAO,EAAE,iBAAiB,EAAE,KAAK,gBAAgB,EAAE,KAAK,UAAU,EAAE,MAAM,cAAc,CAAC;AACzF,OAAO,EAAE,YAAY,EAAE,uBAAuB,EAAE,YAAY,EAAE,WAAW,EAAE,KAAK,cAAc,EAAE,KAAK,4BAA4B,EAAE,MAAM,aAAa,CAAC;AACvJ,OAAO,EAAE,oBAAoB,EAAE,KAAK,wBAAwB,EAAE,MAAM,mBAAmB,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
import { defineModule, resolveMigrationsDir } from "@softure-ai/core";
|
|
6
6
|
import { mcpAccessMessages } from "./messages/index.js";
|
|
7
7
|
import { mcpAccessOptionsSchema } from "./options.js";
|
|
8
|
+
import { DEFAULT_MCP_ACCESS_ROUTES } from "./routes.js";
|
|
8
9
|
import { checkAccessTokensTable } from "./server/health.js";
|
|
9
10
|
import { mcpAccessPrivacyContributor } from "./server/privacy.js";
|
|
10
11
|
export const MODULE_ID = "mcp-access";
|
|
@@ -14,13 +15,13 @@ export const MODULE_ID = "mcp-access";
|
|
|
14
15
|
* the traffic behind one address (several assistants share it), not for one token.
|
|
15
16
|
*/
|
|
16
17
|
export const MCP_RATE_LIMIT_BUCKETS = {
|
|
17
|
-
mcp: { limit: 200, windowMinutes: 15 },
|
|
18
|
+
mcp: { limit: 200, windowMinutes: 15, key: "ip" },
|
|
18
19
|
/**
|
|
19
20
|
* OAuth registration (per address) and token requests (per address and client id), when
|
|
20
21
|
* `oauth.enabled`. Enough for an assistant platform refreshing many users' tokens per client,
|
|
21
22
|
* too little for a script filling the clients table.
|
|
22
23
|
*/
|
|
23
|
-
"mcp-oauth": { limit: 60, windowMinutes: 15 },
|
|
24
|
+
"mcp-oauth": { limit: 60, windowMinutes: 15, key: "ip" },
|
|
24
25
|
};
|
|
25
26
|
/**
|
|
26
27
|
* Enables MCP access in `softure.config.ts` (after `security` and `auth`):
|
|
@@ -29,20 +30,13 @@ export const MCP_RATE_LIMIT_BUCKETS = {
|
|
|
29
30
|
export const mcpAccess = defineModule({
|
|
30
31
|
manifest: {
|
|
31
32
|
id: MODULE_ID,
|
|
32
|
-
version: "0.1.
|
|
33
|
+
version: "0.1.13",
|
|
33
34
|
dependsOn: { security: "^0.1.0", auth: "^0.1.0" },
|
|
34
35
|
dbSchema: "mcp",
|
|
35
36
|
tables: ["access_tokens", "oauth_clients", "oauth_authorization_codes", "oauth_grants"],
|
|
36
37
|
env: [],
|
|
37
38
|
switches: [],
|
|
38
|
-
routes: {
|
|
39
|
-
page: "/account/mcp",
|
|
40
|
-
endpoint: "/api/mcp",
|
|
41
|
-
oauthConsent: "/oauth/authorize",
|
|
42
|
-
oauthDecision: "/api/oauth/authorize",
|
|
43
|
-
oauthToken: "/api/oauth/token",
|
|
44
|
-
oauthRegister: "/api/oauth/register",
|
|
45
|
-
},
|
|
39
|
+
routes: { ...DEFAULT_MCP_ACCESS_ROUTES },
|
|
46
40
|
mount: [
|
|
47
41
|
{ kind: "page", path: "app/account/mcp/page.tsx", export: "McpAccessPage" },
|
|
48
42
|
{ kind: "route-handler", path: "app/api/mcp/route.ts", export: "createMcpRoute" },
|
|
@@ -65,6 +59,7 @@ export const mcpAccess = defineModule({
|
|
|
65
59
|
export { getAuthorizationHeader, getClaudeCodeCommand, getClaudeCodeLink, getDesktopConfig, getJsonConfig, getMcpClientSetup, } from "./client-setup.js";
|
|
66
60
|
export { getTokenErrorMessage, mcpAccessMessages } from "./messages/index.js";
|
|
67
61
|
export { MAX_PRESENTED_TOKEN_LENGTH, MAX_TOKEN_NAME_LENGTH, SERVER_NAME_PATTERN, TOOL_NAME_PATTERN, GENERATED_AUTHORIZATION_SERVER_KEYS, GENERATED_PROTECTED_RESOURCE_KEYS, } from "./options.js";
|
|
62
|
+
export { DEFAULT_MCP_ACCESS_ROUTES } from "./routes.js";
|
|
68
63
|
export { readRequestOrigin } from "./origins.js";
|
|
69
64
|
export { accessTokens, oauthAuthorizationCodes, oauthClients, oauthGrants } from "./schema.js";
|
|
70
65
|
export { getAccessTokenStatus } from "./token-status.js";
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,iGAAiG;AACjG,kGAAkG;AAClG,kGAAkG;AAClG,mDAAmD;AACnD,OAAO,EAAE,YAAY,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/messages/en.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"en.d.ts","sourceRoot":"","sources":["../../src/messages/en.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,EAAE
|
|
1
|
+
{"version":3,"file":"en.d.ts","sourceRoot":"","sources":["../../src/messages/en.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAyGd,CAAC"}
|
package/dist/messages/en.js
CHANGED
|
@@ -92,6 +92,8 @@ export const en = {
|
|
|
92
92
|
token_limit_reached: "You already hold the most active tokens allowed. Revoke one before creating another.",
|
|
93
93
|
token_not_found: "This token no longer exists. It may have been revoked already.",
|
|
94
94
|
grant_not_found: "This app is no longer connected.",
|
|
95
|
+
issue_refused: "Your account cannot create tokens right now.",
|
|
96
|
+
write_refused: "Your account cannot create tokens with write access. Create a read-only token instead.",
|
|
95
97
|
},
|
|
96
98
|
auth: {
|
|
97
99
|
unauthenticated: "Your session has ended. Log in again.",
|
package/dist/messages/en.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"en.js","sourceRoot":"","sources":["../../src/messages/en.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,EAAE,GAAG;IAChB,IAAI,EAAE;QACJ,KAAK,EAAE,qBAAqB;QAC5B,IAAI,EAAE,uIAAuI;KAC9I;IACD,KAAK,EAAE;QACL,KAAK,EAAE,0BAA0B;QACjC,KAAK,EAAE,6BAA6B;QACpC,IAAI,EAAE,OAAO;QACb,KAAK,EAAE,cAAc;QACrB,gBAAgB,EAAE,uCAAuC;KAC1D;IACD,KAAK,EAAE;QACL,KAAK,EAAE,WAAW;QAClB,IAAI,EAAE,MAAM;QACZ,QAAQ,EAAE,uDAAuD;QACjE,QAAQ,EAAE,eAAe;QACzB,YAAY,EAAE,0CAA0C;QACxD,MAAM,EAAE,cAAc;QACtB,OAAO,EAAE,WAAW;QACpB,KAAK,EAAE,yCAAyC;KACjD;IACD,MAAM,EAAE;QACN,KAAK,EAAE,uBAAuB;QAC9B,IAAI,EAAE,uFAAuF;QAC7F,OAAO,EAAE,qBAAqB;QAC9B,QAAQ,EAAE,2BAA2B;QACrC,SAAS,EAAE,sCAAsC;QACjD,WAAW,EAAE,oCAAoC;QACjD,UAAU,EAAE,iGAAiG;QAC7G,cAAc,EAAE,qBAAqB;QACrC,YAAY,EAAE,gCAAgC;QAC9C,SAAS,EAAE,gDAAgD;QAC3D,YAAY,EAAE,6CAA6C;QAC3D,WAAW,EAAE,wDAAwD;QACrE,IAAI,EAAE,MAAM;QACZ,MAAM,EAAE,QAAQ;QAChB,IAAI,EAAE,sBAAsB;KAC7B;IACD,KAAK,EAAE;QACL,eAAe,EAAE,6IAA6I;KAC/J;IACD,IAAI,EAAE;QACJ,KAAK,EAAE,aAAa;QACpB,KAAK,EAAE,yBAAyB;QAChC,QAAQ,EAAE,WAAW;QACrB,SAAS,EAAE,iBAAiB;QAC5B,MAAM,EAAE,QAAQ;QAChB,OAAO,EAAE,SAAS;QAClB,YAAY,EAAE,eAAe;QAC7B,eAAe,EAAE,kBAAkB;QACnC,aAAa,EAAE,wBAAwB;QACvC,SAAS,EAAE,oBAAoB;QAC/B,SAAS,EAAE,mBAAmB;QAC9B,SAAS,EAAE,gBAAgB;QAC3B,QAAQ,EAAE,kBAAkB;QAC5B,SAAS,EAAE,cAAc;QACzB,MAAM,EAAE,QAAQ;QAChB,QAAQ,EAAE,WAAW;KACtB;IACD,MAAM,EAAE;QACN,KAAK,EAAE,gBAAgB;QACvB,IAAI,EAAE,mHAAmH;QACzH,KAAK,EAAE,sBAAsB;QAC7B,WAAW,EAAE,kBAAkB;QAC/B,UAAU,EAAE,YAAY;QACxB,aAAa,EAAE,gBAAgB;KAChC;IACD,OAAO,EAAE;QACP,KAAK,EAAE,uCAAuC;QAC9C,IAAI,EAAE,mIAAmI;QACzI,GAAG,EAAE,KAAK;QACV,SAAS,EAAE,qBAAqB;QAChC,OAAO,EAAE,SAAS;QAClB,MAAM,EAAE,QAAQ;QAChB,UAAU,EAAE,gBAAgB;QAC5B,UAAU,EAAE,oBAAoB;QAChC,cAAc,EAAE,0CAA0C;QAC1D,KAAK,EAAE,OAAO;QACd,IAAI,EAAE,MAAM;QACZ,UAAU,EAAE,mCAAmC;QAC/C,aAAa,EAAE,oFAAoF;QACnG,gBAAgB,EAAE,oGAAoG;QACtH,cAAc,EAAE,2DAA2D;QAC3E,cAAc,EAAE,wBAAwB;QACxC,SAAS,EAAE,4BAA4B;KACxC;IACD,MAAM,EAAE;QACN,YAAY,EAAE;YACZ,aAAa,EAAE,4DAA4D;YAC3E,aAAa,EAAE,uBAAuB;YACtC,mBAAmB,EAAE,sFAAsF;YAC3G,eAAe,EAAE,gEAAgE;YACjF,eAAe,EAAE,kCAAkC;
|
|
1
|
+
{"version":3,"file":"en.js","sourceRoot":"","sources":["../../src/messages/en.ts"],"names":[],"mappings":"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"}
|