@lynq/lynq 0.3.0 → 0.4.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 +88 -12
- package/dist/adapters/express.d.ts +1 -1
- package/dist/adapters/hono.d.ts +1 -1
- package/dist/chunk-2KEVF6YL.mjs +1 -0
- package/dist/chunk-L7SD7KKW.mjs +1 -0
- package/dist/chunk-STWVQGX5.mjs +1 -0
- package/dist/index.d.ts +2 -2
- package/dist/index.mjs +1 -1
- package/dist/middleware/auth.d.ts +6 -8
- package/dist/middleware/auth.mjs +1 -1
- package/dist/middleware/bearer.d.ts +19 -0
- package/dist/middleware/bearer.mjs +1 -0
- package/dist/middleware/combine.d.ts +12 -0
- package/dist/middleware/combine.mjs +1 -0
- package/dist/middleware/credentials.d.ts +19 -0
- package/dist/middleware/credentials.mjs +1 -0
- package/dist/middleware/github-oauth.d.ts +42 -0
- package/dist/middleware/github-oauth.mjs +2 -0
- package/dist/middleware/google-oauth.d.ts +43 -0
- package/dist/middleware/google-oauth.mjs +2 -0
- package/dist/middleware/guard.d.ts +15 -0
- package/dist/middleware/guard.mjs +1 -0
- package/dist/middleware/jwt.d.ts +27 -0
- package/dist/middleware/jwt.mjs +1 -0
- package/dist/middleware/logger.d.ts +11 -0
- package/dist/middleware/logger.mjs +1 -0
- package/dist/middleware/oauth.d.ts +22 -0
- package/dist/middleware/oauth.mjs +1 -0
- package/dist/middleware/payment.d.ts +22 -0
- package/dist/middleware/payment.mjs +1 -0
- package/dist/middleware/rate-limit.d.ts +15 -0
- package/dist/middleware/rate-limit.mjs +1 -0
- package/dist/middleware/truncate.d.ts +13 -0
- package/dist/middleware/truncate.mjs +1 -0
- package/dist/middleware/url-action.d.ts +24 -0
- package/dist/middleware/url-action.mjs +1 -0
- package/dist/test.d.ts +1 -1
- package/dist/{types-D504PjnN.d.ts → types-CqT2idkd.d.ts} +21 -7
- package/package.json +61 -3
package/README.md
CHANGED
|
@@ -3,44 +3,120 @@
|
|
|
3
3
|
[](https://github.com/hogekai/lynq/actions/workflows/ci.yml)
|
|
4
4
|
[](https://www.npmjs.com/package/@lynq/lynq)
|
|
5
5
|
|
|
6
|
-
|
|
6
|
+
MCP servers are stateless by default. lynq makes them session-aware.
|
|
7
|
+
|
|
8
|
+
## The Problem
|
|
9
|
+
|
|
10
|
+
With the official SDK, adding session-aware tool visibility requires manual plumbing:
|
|
11
|
+
|
|
12
|
+
```ts
|
|
13
|
+
// Without lynq — manual session tracking, manual notifications
|
|
14
|
+
const sessions = new Map();
|
|
15
|
+
|
|
16
|
+
server.setRequestHandler(ListToolsRequestSchema, (req, extra) => {
|
|
17
|
+
const session = sessions.get(extra.sessionId);
|
|
18
|
+
const tools = [loginTool];
|
|
19
|
+
if (session?.authorized) tools.push(weatherTool); // manual filtering
|
|
20
|
+
return { tools };
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
server.setRequestHandler(CallToolRequestSchema, async (req, extra) => {
|
|
24
|
+
if (req.params.name === "login") {
|
|
25
|
+
sessions.set(extra.sessionId, { authorized: true });
|
|
26
|
+
server.sendToolListChanged(); // manual notification
|
|
27
|
+
}
|
|
28
|
+
// ...
|
|
29
|
+
});
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## The Solution
|
|
33
|
+
|
|
34
|
+
```ts
|
|
35
|
+
// With lynq — one line
|
|
36
|
+
server.tool("weather", guard(), config, handler);
|
|
37
|
+
// Client gets notified automatically. No manual wiring.
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
## Install
|
|
41
|
+
|
|
42
|
+
```sh
|
|
43
|
+
npm install @lynq/lynq
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
## Quick Start
|
|
7
47
|
|
|
8
48
|
```ts
|
|
9
49
|
import { createMCPServer } from "@lynq/lynq";
|
|
10
|
-
import {
|
|
50
|
+
import { guard } from "@lynq/lynq/guard";
|
|
11
51
|
import { z } from "zod";
|
|
12
52
|
|
|
13
53
|
const server = createMCPServer({ name: "my-server", version: "1.0.0" });
|
|
14
54
|
|
|
15
55
|
server.tool("login", {
|
|
16
56
|
input: z.object({ username: z.string(), password: z.string() }),
|
|
17
|
-
}, async (args,
|
|
57
|
+
}, async (args, c) => {
|
|
18
58
|
const user = await authenticate(args.username, args.password);
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
return
|
|
59
|
+
c.session.set("user", user);
|
|
60
|
+
c.session.authorize("guard");
|
|
61
|
+
return c.text(`Welcome, ${user.name}`);
|
|
22
62
|
});
|
|
23
63
|
|
|
24
|
-
server.tool("weather",
|
|
64
|
+
server.tool("weather", guard(), {
|
|
25
65
|
description: "Get weather for a city",
|
|
26
66
|
input: z.object({ city: z.string() }),
|
|
27
|
-
}, async (args,
|
|
28
|
-
return
|
|
67
|
+
}, async (args, c) => {
|
|
68
|
+
return c.text(JSON.stringify(await fetchWeather(args.city)));
|
|
29
69
|
});
|
|
30
70
|
|
|
31
71
|
await server.stdio();
|
|
32
72
|
```
|
|
33
73
|
|
|
34
|
-
## Install
|
|
35
|
-
|
|
36
74
|
```sh
|
|
37
|
-
|
|
75
|
+
npx tsx server.ts
|
|
38
76
|
```
|
|
39
77
|
|
|
78
|
+
## Features
|
|
79
|
+
|
|
80
|
+
- **Session-Scoped Visibility** — `authorize()` shows tools, `revoke()` hides them. Client notification is automatic.
|
|
81
|
+
- **Hono-Style Middleware** — Global via `server.use()`, per-tool inline. Three hooks: `onRegister`, `onCall`, `onResult`.
|
|
82
|
+
- **Built-in Middleware** — `guard()` `rateLimit()` `logger()` `truncate()` `credentials()` `some()` `every()` `except()`
|
|
83
|
+
- **Response Helpers** — `c.text()` `c.json()` `c.error()` `c.image()` — chainable: `c.text("done").json({ id: 1 })`
|
|
84
|
+
- **Elicitation** — `c.elicit.form(message, zodSchema)` for structured user input. `c.elicit.url()` for external flows.
|
|
85
|
+
- **Framework Adapters** — `server.http()` returns `(Request) => Response`. Mount in Hono, Express, Deno, Workers.
|
|
86
|
+
- **Test Helpers** — `createTestClient()` for in-memory testing. No transport setup.
|
|
87
|
+
- **Tiny Core** — One dependency. ESM only. No config files, no magic.
|
|
88
|
+
|
|
89
|
+
## Middleware Composition
|
|
90
|
+
|
|
91
|
+
```ts
|
|
92
|
+
import { guard } from "@lynq/lynq/guard";
|
|
93
|
+
import { rateLimit } from "@lynq/lynq/rate-limit";
|
|
94
|
+
import { logger } from "@lynq/lynq/logger";
|
|
95
|
+
|
|
96
|
+
server.use(logger()); // global
|
|
97
|
+
server.tool("search", guard(), rateLimit({ max: 10 }), config, handler); // per-tool stack
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
## Comparison
|
|
101
|
+
|
|
102
|
+
| | lynq | FastMCP | Official SDK |
|
|
103
|
+
|---|---|---|---|
|
|
104
|
+
| Per-tool middleware | Yes | No | No |
|
|
105
|
+
| Session-scoped visibility | Auto-notify | Manual | Manual |
|
|
106
|
+
| onResult hook | Yes | No | No |
|
|
107
|
+
| Response helpers | Chainable | Basic | No |
|
|
108
|
+
| Test helpers | Yes | No | No |
|
|
109
|
+
| HTTP server built-in | No (you choose) | Yes (opinionated) | No |
|
|
110
|
+
|
|
40
111
|
## Documentation
|
|
41
112
|
|
|
42
113
|
[https://hogekai.github.io/lynq/](https://hogekai.github.io/lynq/)
|
|
43
114
|
|
|
115
|
+
- [Quick Start](https://hogekai.github.io/lynq/getting-started/quick-start)
|
|
116
|
+
- [Middleware Concepts](https://hogekai.github.io/lynq/concepts/middleware)
|
|
117
|
+
- [Why lynq](https://hogekai.github.io/lynq/why-lynq)
|
|
118
|
+
- [API Reference](https://hogekai.github.io/lynq/api-reference/)
|
|
119
|
+
|
|
44
120
|
## License
|
|
45
121
|
|
|
46
122
|
MIT
|
package/dist/adapters/hono.d.ts
CHANGED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import {a}from'./chunk-STWVQGX5.mjs';function n(e){let t={name:e.name??"oauth",sessionKey:e.sessionKey??"user",message:e.message??"Please sign in to continue.",buildUrl:e.buildUrl,declineMessage:"Authentication cancelled."};return e.timeout!==void 0&&(t.timeout=e.timeout),a(t)}export{n as a};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import {c}from'./chunk-VAAZWX4U.mjs';function g(e){let s=e?.name??"guard",n=e?.sessionKey??"user",t=e?.message??"Authorization required.";return {name:s,onRegister(){return false},async onCall(o,a){return o.session.get(n)?a():c(t)}}}export{g as a};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import {c}from'./chunk-VAAZWX4U.mjs';function m(e){let n=e.name??"url-action",i=e.sessionKey??"user",l=e.timeout??3e5,a=e.declineMessage??"Action cancelled.";return {name:n,onRegister(){return false},async onCall(s,r){if(s.session.get(i))return r();let o=crypto.randomUUID(),c$1=e.buildUrl({sessionId:s.sessionId,elicitationId:o});return (await s.elicit.url(e.message,c$1,{elicitationId:o,waitForCompletion:true,timeout:l})).action!=="accept"?c(a):s.session.get(i)?(s.session.authorize(n),r()):c("Action was not completed.")}}}export{m as a};
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { M as MCPServer } from './types-
|
|
2
|
-
export { E as Elicit, a as ElicitFormResult, b as ElicitUrlResult, H as HttpAdapterOptions, R as ResourceConfig,
|
|
1
|
+
import { M as MCPServer } from './types-CqT2idkd.js';
|
|
2
|
+
export { E as Elicit, a as ElicitFormResult, b as ElicitUrlOptions, c as ElicitUrlResult, H as HttpAdapterOptions, R as ResourceConfig, d as ResourceContent, e as ResourceContext, f as ResourceHandler, g as RootInfo, S as Sample, h as SampleOptions, i as SampleRawParams, j as SampleRawResult, k as ServerInfo, l as Session, T as TaskConfig, m as TaskContext, n as TaskControl, o as TaskHandler, p as ToolConfig, q as ToolContext, r as ToolHandler, s as ToolInfo, t as ToolMiddleware, u as ToolResponse, v as error, w as image, x as json, y as text } from './types-CqT2idkd.js';
|
|
3
3
|
import '@modelcontextprotocol/sdk/types.js';
|
|
4
4
|
import 'zod';
|
|
5
5
|
|
package/dist/index.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import {c,d,b,a}from'./chunk-VAAZWX4U.mjs';export{c as error,d as image,b as json,a as text}from'./chunk-VAAZWX4U.mjs';import {InMemoryTaskStore}from'@modelcontextprotocol/sdk/experimental/tasks';import {Server}from'@modelcontextprotocol/sdk/server/index.js';import {ListToolsRequestSchema,CallToolRequestSchema,ListResourcesRequestSchema,ListResourceTemplatesRequestSchema,ReadResourceRequestSchema}from'@modelcontextprotocol/sdk/types.js';import {normalizeObjectSchema}from'@modelcontextprotocol/sdk/server/zod-compat.js';import {toJsonSchemaCompat}from'@modelcontextprotocol/sdk/server/zod-json-schema-compat.js';function k(i){if(i==null)return {type:"object"};let l=normalizeObjectSchema(i);return l?toJsonSchemaCompat(l):i}function H(i,l){let c=l[l.length-1];if(typeof c!="function")throw new TypeError(`${i}: last argument must be a handler function`);let a=l[l.length-2];if(a==null||typeof a!="object"||Array.isArray(a))throw new TypeError(`${i}: second-to-last argument must be a config object`);let u=l.slice(0,-2);for(let d of u)if(!d||typeof d!="object"||typeof d.name!="string")throw new TypeError(`${i}: each middleware must have a "name" property`);return {middlewares:u,config:a,handler:c}}function $(i,l){let c=[];for(let a of l)a.onRegister?.(i)===false&&c.push(a.name);return c}function G(i){let c=i.split(/\{[^}]+\}/).map(a=>a.replace(/[.*+?^$|()[\]\\]/g,"\\$&"));return new RegExp(`^${c.join("(.+)")}$`)}function O(i,l,c,a){let u=c.get(l);if(u==="disabled")return false;if(u==="enabled")return true;for(let d of i)if(!a.has(d))return false;return true}function D(i,l){let c=i.get(l);if(c)return c;for(let a of i.values())if(a.isTemplate&&a.uriPattern?.test(l))return a}function E(i,l,c){let a=i.filter(f=>f.onCall),u=i.filter(f=>f.onResult).reverse(),d=0,y=async()=>{if(d>=a.length){let v=await c();for(let M of u)v=await M.onResult(v,l);return v}return a[d++].onCall(l,y)};return y}function ie(i){return {async form(l,c){let a=k(c),u=await i.elicitInput({message:l,requestedSchema:a});return {action:u.action,content:u.content??{}}},async url(l,c){return {action:(await i.elicitInput({mode:"url",message:l,url:c,elicitationId:crypto.randomUUID()})).action}}}}function L(i){return async()=>{try{return (await i.listRoots()).roots.map(c=>{let a={uri:c.uri};return c.name!==void 0&&(a.name=c.name),a})}catch{return []}}}function le(i){async function l(a,u){let d={messages:[{role:"user",content:{type:"text",text:a}}],maxTokens:u?.maxTokens??1024};u?.model!==void 0&&(d.modelPreferences={hints:[{name:u.model}]}),u?.system!==void 0&&(d.systemPrompt=u.system),u?.temperature!==void 0&&(d.temperature=u.temperature),u?.stopSequences!==void 0&&(d.stopSequences=u.stopSequences);let f=(await i.createMessage(d)).content;return f.type==="text"?f.text:""}async function c(a){return i.createMessage(a)}return Object.assign(l,{raw:c})}function _(i,l,c$1,a$1,u){return {toolName:a$1,session:c$1,signal:u,sessionId:l,elicit:ie(i),roots:L(i),sample:le(i),text:a,json:b,error:c,image:d}}function ge(i){let l=[],c$1=new Map,a=new Map,u=new Map,d=new Map,y=new Map,f=new Set,v=new InMemoryTaskStore,M=new Proxy(v,{get(e,n,t){return n==="updateTaskStatus"?async(s,r,...o)=>(r==="cancelled"&&f.add(s),e.updateTaskStatus.call(e,s,r,...o)):Reflect.get(e,n,t)}}),b=new Server(i,{capabilities:{tools:{listChanged:true},resources:{listChanged:true},tasks:{list:{},cancel:{},requests:{tools:{call:{}}}}},taskStore:M});function C(e){let n=d.get(e);return n||(n={data:new Map,grants:new Set,toolOverrides:new Map,resourceOverrides:new Map},d.set(e,n)),n}function A(e,n){let t=C(n);return O(e.hiddenByMiddlewares,e.name,t.toolOverrides,t.grants)}function x(e,n){let t=C(n);return O(e.hiddenByMiddlewares,e.uri,t.resourceOverrides,t.grants)}function B(e,n){let t=C(n);return O(e.hiddenByMiddlewares,e.name,t.toolOverrides,t.grants)}function I(e){(e&&y.get(e)||b).sendToolListChanged().catch(()=>{});}function P(e){(e&&y.get(e)||b).sendResourceListChanged().catch(()=>{});}function q(e){let n=C(e);return {get(t){return n.data.get(t)},set(t,s){n.data.set(t,s);},authorize(t){n.grants.add(t),I(e),P(e);},revoke(t){n.grants.delete(t),I(e),P(e);},enableTools(...t){for(let s of t)n.toolOverrides.set(s,"enabled");I(e);},disableTools(...t){for(let s of t)n.toolOverrides.set(s,"disabled");I(e);},enableResources(...t){for(let s of t)n.resourceOverrides.set(s,"enabled");P(e);},disableResources(...t){for(let s of t)n.resourceOverrides.set(s,"disabled");P(e);}}}function z(e){e.setRequestHandler(ListToolsRequestSchema,(n,t)=>{let s=t.sessionId??"default",r=[];for(let o of c$1.values())A(o,s)&&r.push({name:o.name,description:o.description,inputSchema:k(o.input)});for(let o of u.values())B(o,s)&&r.push({name:o.name,description:o.description,inputSchema:k(o.input),execution:{taskSupport:"required"}});return {tools:r}}),e.setRequestHandler(CallToolRequestSchema,async(n,t)=>{let{name:s,arguments:r}=n.params,o=t.sessionId??"default",w=c$1.get(s);if(w){if(!A(w,o))return c(`Tool not available: ${s}`);let m=_(e,o,q(o),s,t.signal),p=()=>Promise.resolve(w.handler(r??{},m));return E(w.middlewares,m,p)()}let g=u.get(s);if(g){if(!B(g,o))return c(`Tool not available: ${s}`);let m=t.taskStore;if(!m)return c("Task store not available");let p=await m.createTask({pollInterval:1e3}),T=p.taskId,S={progress(h,j){if(f.has(T))return;let oe=j?`${h}% ${j}`:`${h}%`;m.updateTaskStatus(T,"working",oe).catch(()=>{});},get cancelled(){return f.has(T)}},F={..._(e,o,q(o),s,t.signal),task:S},se=async()=>((async()=>{try{let h=await g.handler(r??{},F);f.has(T)||await m.storeTaskResult(T,"completed",h);}catch(h){if(!f.has(T)){let j=h instanceof Error?h.message:String(h);await m.storeTaskResult(T,"failed",c(j)).catch(()=>{});}}})(),{task:p});return E(g.middlewares,F,se)()}return c(`Unknown tool: ${s}`)}),e.setRequestHandler(ListResourcesRequestSchema,(n,t)=>{let s=t.sessionId??"default",r=[];for(let o of a.values())!o.isTemplate&&x(o,s)&&r.push({uri:o.uri,name:o.name,description:o.description,mimeType:o.mimeType});return {resources:r}}),e.setRequestHandler(ListResourceTemplatesRequestSchema,(n,t)=>{let s=t.sessionId??"default",r=[];for(let o of a.values())o.isTemplate&&x(o,s)&&r.push({uriTemplate:o.uri,name:o.name,description:o.description,mimeType:o.mimeType});return {resourceTemplates:r}}),e.setRequestHandler(ReadResourceRequestSchema,async(n,t)=>{let{uri:s}=n.params,r=D(a,s);if(!r)throw new Error(`Unknown resource: ${s}`);let o=t.sessionId??"default";if(!x(r,o))throw new Error(`Resource not available: ${s}`);let w=q(o),g={uri:s,session:w,sessionId:o,roots:L(e)},m=_(e,o,w,r.uri,t.signal),p=async()=>{let S=await r.handler(s,g);return {contents:[{uri:s,mimeType:S.mimeType??r.mimeType,...S.text!=null?{text:S.text}:{},...S.blob!=null?{blob:S.blob}:{}}]}};return E(r.middlewares,m,p)()});}z(b);function Z(e){l.push(e);}function K(...e){let n=e[0],t=H(`tool("${n}")`,e.slice(1));if(typeof t.config.name=="string")throw new TypeError(`tool("${n}"): second-to-last argument must be a config object`);let s=t.config,r=[...l,...t.middlewares],o={name:n,description:s.description,middlewares:r};c$1.set(n,{name:n,description:s.description,input:s.input,handler:t.handler,middlewares:r,hiddenByMiddlewares:$(o,r)});}function Q(...e){let n=e[0],t=H(`resource("${n}")`,e.slice(1));if(typeof t.config.name!="string")throw new TypeError(`resource("${n}"): second-to-last argument must be a config object with a "name" property`);let s=t.config,r={name:s.name,description:s.description,middlewares:t.middlewares},o=n.includes("{");a.set(n,{uri:n,isTemplate:o,uriPattern:o?G(n):null,name:s.name,description:s.description,mimeType:s.mimeType,handler:t.handler,middlewares:t.middlewares,hiddenByMiddlewares:$(r,t.middlewares)});}function X(...e){let n=e[0],t=H(`task("${n}")`,e.slice(1));if(typeof t.config.name=="string")throw new TypeError(`task("${n}"): second-to-last argument must be a config object`);let s=t.config,r=[...l,...t.middlewares],o={name:n,description:s.description,middlewares:r};u.set(n,{name:n,description:s.description,input:s.input,handler:t.handler,middlewares:r,hiddenByMiddlewares:$(o,r)});}async function Y(){let{StdioServerTransport:e}=await import('@modelcontextprotocol/sdk/server/stdio.js'),n=new e;await b.connect(n);}async function ee(e){await b.connect(e);}let te={tools:{listChanged:true},resources:{listChanged:true},tasks:{list:{},cancel:{},requests:{tools:{call:{}}}}};function N(){let e=new Server(i,{capabilities:te,taskStore:M});return z(e),e}function ne(e){let n=null;async function t(){return n||(n=(await import('@modelcontextprotocol/sdk/server/webStandardStreamableHttp.js')).WebStandardStreamableHTTPServerTransport),n}if(e?.sessionless)return async r=>{let o=await t(),w=N(),g=new o({sessionIdGenerator:void 0,enableJsonResponse:e?.enableJsonResponse});return await w.connect(g),g.handleRequest(r)};let s=new Map;return async r=>{let o=await t(),w=r.headers.get("mcp-session-id");if(w){let p=s.get(w);return p?p.transport.handleRequest(r):new Response(JSON.stringify({jsonrpc:"2.0",error:{code:-32e3,message:"Session not found"}}),{status:404,headers:{"Content-Type":"application/json"}})}let g=N(),m=new o({sessionIdGenerator:e?.sessionIdGenerator??(()=>crypto.randomUUID()),enableJsonResponse:e?.enableJsonResponse,onsessioninitialized:p=>{s.set(p,{server:g,transport:m}),y.set(p,g);},onsessionclosed:p=>{s.delete(p),y.delete(p);}});return await g.connect(m),m.handleRequest(r)}}return {use:Z,tool:K,resource:Q,task:X,stdio:Y,http:ne,connect:ee,_server:b,_getSession:C,_isToolVisible(e,n){let t=c$1.get(e);return t?A(t,n):false},_isResourceVisible(e,n){let t=a.get(e);return t?x(t,n):false},_isTaskVisible(e,n){let t=u.get(e);return t?B(t,n):false},_createSessionAPI:q}}export{ge as createMCPServer};
|
|
1
|
+
import {c,d,b,a}from'./chunk-VAAZWX4U.mjs';export{c as error,d as image,b as json,a as text}from'./chunk-VAAZWX4U.mjs';import {InMemoryTaskStore}from'@modelcontextprotocol/sdk/experimental/tasks';import {Server}from'@modelcontextprotocol/sdk/server/index.js';import {ListToolsRequestSchema,CallToolRequestSchema,ListResourcesRequestSchema,ListResourceTemplatesRequestSchema,ReadResourceRequestSchema}from'@modelcontextprotocol/sdk/types.js';import {normalizeObjectSchema}from'@modelcontextprotocol/sdk/server/zod-compat.js';import {toJsonSchemaCompat}from'@modelcontextprotocol/sdk/server/zod-json-schema-compat.js';function j(a){if(a==null)return {type:"object"};let l=normalizeObjectSchema(a);return l?toJsonSchemaCompat(l):a}function $(a,l){let c=l[l.length-1];if(typeof c!="function")throw new TypeError(`${a}: last argument must be a handler function`);let i=l[l.length-2];if(i==null||typeof i!="object"||Array.isArray(i))throw new TypeError(`${a}: second-to-last argument must be a config object`);let d=l.slice(0,-2);for(let u of d)if(!u||typeof u!="object"||typeof u.name!="string")throw new TypeError(`${a}: each middleware must have a "name" property`);return {middlewares:d,config:i,handler:c}}function A(a,l){let c=[];for(let i of l)i.onRegister?.(a)===false&&c.push(i.name);return c}function Q(a){let c=a.split(/\{[^}]+\}/).map(i=>i.replace(/[.*+?^$|()[\]\\]/g,"\\$&"));return new RegExp(`^${c.join("(.+)")}$`)}function B(a,l,c,i){let d=c.get(l);if(d==="disabled")return false;if(d==="enabled")return true;for(let u of a)if(!i.has(u))return false;return true}function X(a,l){let c=a.get(l);if(c)return c;for(let i of a.values())if(i.isTemplate&&i.uriPattern?.test(l))return i}function U(a,l,c){let i=a.filter(m=>m.onCall),d=a.filter(m=>m.onResult).reverse(),u=0,p=async()=>{if(u>=i.length){let S=await c();for(let C of d)S=await C.onResult(S,l);return S}return i[u++].onCall(l,p)};return p}function pe(a,l,c){return {async form(i,d){let u=j(d),p=await a.elicitInput({message:i,requestedSchema:u});return {action:p.action,content:p.content??{}}},async url(i,d,u){let p=u?.elicitationId??crypto.randomUUID(),m;u?.waitForCompletion&&l&&(m=l(p,a));let S=await a.elicitInput({mode:"url",message:i,url:d,elicitationId:p});if(S.action==="accept"&&m){let C=u?.timeout??3e5,x=new Promise((G,I)=>{setTimeout(()=>I(new Error("Elicitation timed out")),C);});await Promise.race([m,x]);}else m&&c&&c(p);return {action:S.action}}}}function F(a){return async()=>{try{return (await a.listRoots()).roots.map(c=>{let i={uri:c.uri};return c.name!==void 0&&(i.name=c.name),i})}catch{return []}}}function fe(a){async function l(i,d){let u={messages:[{role:"user",content:{type:"text",text:i}}],maxTokens:d?.maxTokens??1024};d?.model!==void 0&&(u.modelPreferences={hints:[{name:d.model}]}),d?.system!==void 0&&(u.systemPrompt=d.system),d?.temperature!==void 0&&(u.temperature=d.temperature),d?.stopSequences!==void 0&&(u.stopSequences=d.stopSequences);let m=(await a.createMessage(u)).content;return m.type==="text"?m.text:""}async function c(i){return a.createMessage(i)}return Object.assign(l,{raw:c})}function N(a$1,l,c$1,i,d$1,u,p){return {toolName:i,session:c$1,signal:d$1,sessionId:l,elicit:pe(a$1,u,p),roots:F(a$1),sample:fe(a$1),text:a,json:b,error:c,image:d}}function ve(a){let l=[],c$1=new Map,i=new Map,d=new Map,u=new Map,p=new Map,m=new Map,S=36e5;function C(){let e=Date.now();for(let[t,n]of m)e-n.createdAt>S&&m.delete(t);}function x(e,t,n){return C(),new Promise(o=>{let r;try{r=n.createElicitationCompletionNotifier(e);}catch{}m.set(e,{resolver:o,completionNotifier:r,createdAt:Date.now()});})}function G(e){C();let t=m.get(e);t&&(m.delete(e),t.completionNotifier&&t.completionNotifier().catch(()=>{}),t.resolver());}function I(e){let t=m.get(e);t&&(m.delete(e),t.resolver());}let q=new Set,ee=new InMemoryTaskStore,W=new Proxy(ee,{get(e,t,n){return t==="updateTaskStatus"?async(o,r,...s)=>(r==="cancelled"&&q.add(o),e.updateTaskStatus.call(e,o,r,...s)):Reflect.get(e,t,n)}}),k=new Server(a,{capabilities:{tools:{listChanged:true},resources:{listChanged:true},tasks:{list:{},cancel:{},requests:{tools:{call:{}}}}},taskStore:W});function E(e){let t=u.get(e);return t||(t={data:new Map,grants:new Set,toolOverrides:new Map,resourceOverrides:new Map},u.set(e,t)),t}function V(e,t){let n=E(t);return B(e.hiddenByMiddlewares,e.name,n.toolOverrides,n.grants)}function H(e,t){let n=E(t);return B(e.hiddenByMiddlewares,e.uri,n.resourceOverrides,n.grants)}function J(e,t){let n=E(t);return B(e.hiddenByMiddlewares,e.name,n.toolOverrides,n.grants)}function O(e){(e&&p.get(e)||k).sendToolListChanged().catch(()=>{});}function _(e){(e&&p.get(e)||k).sendResourceListChanged().catch(()=>{});}function b(e){let t=E(e);return {get(n){return t.data.get(n)},set(n,o){t.data.set(n,o);},authorize(n){t.grants.add(n),O(e),_(e);},revoke(n){t.grants.delete(n),O(e),_(e);},enableTools(...n){for(let o of n)t.toolOverrides.set(o,"enabled");O(e);},disableTools(...n){for(let o of n)t.toolOverrides.set(o,"disabled");O(e);},enableResources(...n){for(let o of n)t.resourceOverrides.set(o,"enabled");_(e);},disableResources(...n){for(let o of n)t.resourceOverrides.set(o,"disabled");_(e);}}}function Z(e){e.setRequestHandler(ListToolsRequestSchema,(t,n)=>{let o=n.sessionId??"default",r=[];for(let s of c$1.values())V(s,o)&&r.push({name:s.name,description:s.description,inputSchema:j(s.input)});for(let s of d.values())J(s,o)&&r.push({name:s.name,description:s.description,inputSchema:j(s.input),execution:{taskSupport:"required"}});return {tools:r}}),e.setRequestHandler(CallToolRequestSchema,async(t,n)=>{let{name:o,arguments:r}=t.params,s=n.sessionId??"default",g=c$1.get(o);if(g){if(!V(g,s))return c(`Tool not available: ${o}`);let w=N(e,s,b(s),o,n.signal,(R,M)=>x(R,s,M),I),f=()=>Promise.resolve(g.handler(r??{},w));return U(g.middlewares,w,f)()}let T=d.get(o);if(T){if(!J(T,s))return c(`Tool not available: ${o}`);let w=n.taskStore;if(!w)return c("Task store not available");let f=await w.createTask({pollInterval:1e3}),h=f.taskId,R={progress(y,P){if(q.has(h))return;let de=P?`${y}% ${P}`:`${y}%`;w.updateTaskStatus(h,"working",de).catch(()=>{});},get cancelled(){return q.has(h)}},M={...N(e,s,b(s),o,n.signal,(y,P)=>x(y,s,P),I),task:R},ce=async()=>((async()=>{try{let y=await T.handler(r??{},M);q.has(h)||await w.storeTaskResult(h,"completed",y);}catch(y){if(!q.has(h)){let P=y instanceof Error?y.message:String(y);await w.storeTaskResult(h,"failed",c(P)).catch(()=>{});}}})(),{task:f});return U(T.middlewares,M,ce)()}return c(`Unknown tool: ${o}`)}),e.setRequestHandler(ListResourcesRequestSchema,(t,n)=>{let o=n.sessionId??"default",r=[];for(let s of i.values())!s.isTemplate&&H(s,o)&&r.push({uri:s.uri,name:s.name,description:s.description,mimeType:s.mimeType});return {resources:r}}),e.setRequestHandler(ListResourceTemplatesRequestSchema,(t,n)=>{let o=n.sessionId??"default",r=[];for(let s of i.values())s.isTemplate&&H(s,o)&&r.push({uriTemplate:s.uri,name:s.name,description:s.description,mimeType:s.mimeType});return {resourceTemplates:r}}),e.setRequestHandler(ReadResourceRequestSchema,async(t,n)=>{let{uri:o}=t.params,r=X(i,o);if(!r)throw new Error(`Unknown resource: ${o}`);let s=n.sessionId??"default";if(!H(r,s))throw new Error(`Resource not available: ${o}`);let g=b(s),T={uri:o,session:g,sessionId:s,roots:F(e)},w=N(e,s,g,r.uri,n.signal,(R,M)=>x(R,s,M),I),f=async()=>{let R=await r.handler(o,T);return {contents:[{uri:o,mimeType:R.mimeType??r.mimeType,...R.text!=null?{text:R.text}:{},...R.blob!=null?{blob:R.blob}:{}}]}};return U(r.middlewares,w,f)()});}Z(k);function te(e){l.push(e);}function ne(...e){let t=e[0],n=$(`tool("${t}")`,e.slice(1));if(typeof n.config.name=="string")throw new TypeError(`tool("${t}"): second-to-last argument must be a config object`);let o=n.config,r=[...l,...n.middlewares],s={name:t,description:o.description,middlewares:r};c$1.set(t,{name:t,description:o.description,input:o.input,handler:n.handler,middlewares:r,hiddenByMiddlewares:A(s,r)});}function oe(...e){let t=e[0],n=$(`resource("${t}")`,e.slice(1));if(typeof n.config.name!="string")throw new TypeError(`resource("${t}"): second-to-last argument must be a config object with a "name" property`);let o=n.config,r={name:o.name,description:o.description,middlewares:n.middlewares},s=t.includes("{");i.set(t,{uri:t,isTemplate:s,uriPattern:s?Q(t):null,name:o.name,description:o.description,mimeType:o.mimeType,handler:n.handler,middlewares:n.middlewares,hiddenByMiddlewares:A(r,n.middlewares)});}function se(...e){let t=e[0],n=$(`task("${t}")`,e.slice(1));if(typeof n.config.name=="string")throw new TypeError(`task("${t}"): second-to-last argument must be a config object`);let o=n.config,r=[...l,...n.middlewares],s={name:t,description:o.description,middlewares:r};d.set(t,{name:t,description:o.description,input:o.input,handler:n.handler,middlewares:r,hiddenByMiddlewares:A(s,r)});}async function re(){let{StdioServerTransport:e}=await import('@modelcontextprotocol/sdk/server/stdio.js'),t=new e;await k.connect(t);}async function ie(e){await k.connect(e);}let ae={tools:{listChanged:true},resources:{listChanged:true},tasks:{list:{},cancel:{},requests:{tools:{call:{}}}}};function K(){let e=new Server(a,{capabilities:ae,taskStore:W});return Z(e),e}function le(e){let t=null;async function n(){return t||(t=(await import('@modelcontextprotocol/sdk/server/webStandardStreamableHttp.js')).WebStandardStreamableHTTPServerTransport),t}if(e?.sessionless)return async r=>{let s=await n(),g=K(),T=new s({sessionIdGenerator:void 0,enableJsonResponse:e?.enableJsonResponse});return await g.connect(T),T.handleRequest(r)};let o=new Map;return async r=>{let s=await n(),g=r.headers.get("mcp-session-id");if(g){let f=o.get(g);return f?(e?.onRequest&&await e.onRequest(r,g,b(g)),f.transport.handleRequest(r)):new Response(JSON.stringify({jsonrpc:"2.0",error:{code:-32e3,message:"Session not found"}}),{status:404,headers:{"Content-Type":"application/json"}})}let T=K(),w=new s({sessionIdGenerator:e?.sessionIdGenerator??(()=>crypto.randomUUID()),enableJsonResponse:e?.enableJsonResponse,onsessioninitialized:f=>{o.set(f,{server:T,transport:w}),p.set(f,T),e?.onRequest&&e.onRequest(r,f,b(f));},onsessionclosed:f=>{o.delete(f),p.delete(f);}});return await T.connect(w),w.handleRequest(r)}}return {use:te,tool:ne,resource:oe,task:se,stdio:re,http:le,session:b,completeElicitation:G,connect:ie,_server:k,_getSession:E,_isToolVisible(e,t){let n=c$1.get(e);return n?V(n,t):false},_isResourceVisible(e,t){let n=i.get(e);return n?H(n,t):false},_isTaskVisible(e,t){let n=d.get(e);return n?J(n,t):false},_createSessionAPI:b}}export{ve as createMCPServer};
|
|
@@ -1,13 +1,11 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { t as ToolMiddleware } from '../types-CqT2idkd.js';
|
|
2
|
+
import { GuardOptions } from './guard.js';
|
|
2
3
|
import '@modelcontextprotocol/sdk/types.js';
|
|
3
4
|
import 'zod';
|
|
4
5
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
message?: string;
|
|
10
|
-
}
|
|
11
|
-
declare function auth(options?: AuthOptions): ToolMiddleware;
|
|
6
|
+
/** @deprecated Use `GuardOptions` from `@lynq/lynq/guard` instead. */
|
|
7
|
+
type AuthOptions = GuardOptions;
|
|
8
|
+
/** @deprecated Use `guard()` from `@lynq/lynq/guard` instead. */
|
|
9
|
+
declare function auth(options?: GuardOptions): ToolMiddleware;
|
|
12
10
|
|
|
13
11
|
export { type AuthOptions, auth };
|
package/dist/middleware/auth.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {a}from'../chunk-L7SD7KKW.mjs';import'../chunk-VAAZWX4U.mjs';function e(o){return a({name:"auth",...o})}export{e as auth};
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { t as ToolMiddleware } from '../types-CqT2idkd.js';
|
|
2
|
+
import '@modelcontextprotocol/sdk/types.js';
|
|
3
|
+
import 'zod';
|
|
4
|
+
|
|
5
|
+
interface BearerOptions {
|
|
6
|
+
/** Middleware name. Default: "bearer" */
|
|
7
|
+
name?: string;
|
|
8
|
+
/** Session key where the raw token is stored. Default: "token" */
|
|
9
|
+
tokenKey?: string;
|
|
10
|
+
/** Session key to store verified user. Default: "user" */
|
|
11
|
+
sessionKey?: string;
|
|
12
|
+
/** Verify the token. Return user data or null/throw on failure. */
|
|
13
|
+
verify: (token: string) => Promise<unknown | null>;
|
|
14
|
+
/** Error message. Default: "Invalid or missing token." */
|
|
15
|
+
message?: string;
|
|
16
|
+
}
|
|
17
|
+
declare function bearer(options: BearerOptions): ToolMiddleware;
|
|
18
|
+
|
|
19
|
+
export { type BearerOptions, bearer };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import {c}from'../chunk-VAAZWX4U.mjs';function y(e){let n=e.name??"bearer",m=e.tokenKey??"token",t=e.sessionKey??"user",o=e.message??"Invalid or missing token.";return {name:n,onRegister(){return false},async onCall(s,i){if(s.session.get(t))return i();let a=s.session.get(m);if(!a)return c(o);let g=await e.verify(a);return g?(s.session.set(t,g),s.session.authorize(n),i()):c(o)}}}export{y as bearer};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { t as ToolMiddleware, q as ToolContext } from '../types-CqT2idkd.js';
|
|
2
|
+
import '@modelcontextprotocol/sdk/types.js';
|
|
3
|
+
import 'zod';
|
|
4
|
+
|
|
5
|
+
/** Run the first middleware that doesn't short-circuit. */
|
|
6
|
+
declare function some(...middlewares: ToolMiddleware[]): ToolMiddleware;
|
|
7
|
+
/** Run all middlewares. Stop if any short-circuits. */
|
|
8
|
+
declare function every(...middlewares: ToolMiddleware[]): ToolMiddleware;
|
|
9
|
+
/** Run middleware only when the condition is false. */
|
|
10
|
+
declare function except(condition: (c: ToolContext) => boolean, middleware: ToolMiddleware): ToolMiddleware;
|
|
11
|
+
|
|
12
|
+
export { every, except, some };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
function f(...n){return {name:`some(${n.map(e=>e.name).join(",")})`,onRegister(e){for(let o of n)if(o.onRegister?.(e)===false)return false},async onCall(e,o){let t,r;for(let s of n){if(!s.onCall){t=s;break}let u=false,a=async()=>(u=true,o()),i=await s.onCall(e,a);if(u)return t=s,i;r=i;}return t?o():r},onResult(e){return e}}}function c(...n){let l=n.map(o=>o.name),e=n.filter(o=>o.onResult).reverse();return {name:`every(${l.join(",")})`,onRegister(o){for(let t of n)if(t.onRegister?.(o)===false)return false},async onCall(o,t){let r=n.filter(a=>a.onCall),s=0,u=async()=>s>=r.length?t():r[s++].onCall(o,u);return u()},onResult(o,t){let r=o;for(let s of e){let u=s.onResult(r,t);u instanceof Promise||(r=u);}return r}}}function T(n,l){return {name:`except(${l.name})`,onRegister(e){return l.onRegister?.(e)},async onCall(e,o){return n(e)?o():l.onCall?l.onCall(e,o):o()},onResult(e,o){return l.onResult?l.onResult(e,o):e}}}export{c as every,T as except,f as some};
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { t as ToolMiddleware } from '../types-CqT2idkd.js';
|
|
3
|
+
import '@modelcontextprotocol/sdk/types.js';
|
|
4
|
+
|
|
5
|
+
interface CredentialsOptions<T extends z.ZodObject<z.ZodRawShape>> {
|
|
6
|
+
/** Middleware name. Default: "credentials" */
|
|
7
|
+
name?: string;
|
|
8
|
+
/** Message shown to the user. */
|
|
9
|
+
message: string;
|
|
10
|
+
/** Zod schema for the form fields. */
|
|
11
|
+
schema: T;
|
|
12
|
+
/** Verify the submitted credentials. Return user data or null. */
|
|
13
|
+
verify: (fields: z.infer<T>) => Promise<unknown | null>;
|
|
14
|
+
/** Session key to store verified user. Default: "user" */
|
|
15
|
+
sessionKey?: string;
|
|
16
|
+
}
|
|
17
|
+
declare function credentials<T extends z.ZodObject<z.ZodRawShape>>(options: CredentialsOptions<T>): ToolMiddleware;
|
|
18
|
+
|
|
19
|
+
export { type CredentialsOptions, credentials };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import {c as c$1}from'../chunk-VAAZWX4U.mjs';function c(e){let r=e.name??"credentials",t=e.sessionKey??"user";return {name:r,onRegister(){return false},async onCall(s,i){if(s.session.get(t))return i();let a=await s.elicit.form(e.message,e.schema);if(a.action!=="accept")return c$1("Authentication cancelled.");let o=await e.verify(a.content);return o?(s.session.set(t,o),s.session.authorize(r),i()):c$1("Invalid credentials.")}}}export{c as credentials};
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { t as ToolMiddleware, M as MCPServer } from '../types-CqT2idkd.js';
|
|
2
|
+
import '@modelcontextprotocol/sdk/types.js';
|
|
3
|
+
import 'zod';
|
|
4
|
+
|
|
5
|
+
interface GitHubOAuthOptions {
|
|
6
|
+
/** Middleware name. Default: "github-oauth" */
|
|
7
|
+
name?: string;
|
|
8
|
+
/** GitHub OAuth App client ID. */
|
|
9
|
+
clientId: string;
|
|
10
|
+
/** GitHub OAuth App client secret. */
|
|
11
|
+
clientSecret: string;
|
|
12
|
+
/** OAuth callback URL (your server's callback endpoint). */
|
|
13
|
+
redirectUri: string;
|
|
14
|
+
/** GitHub OAuth scopes. Default: [] */
|
|
15
|
+
scopes?: string[];
|
|
16
|
+
/** Session key for user data. Default: "user" */
|
|
17
|
+
sessionKey?: string;
|
|
18
|
+
/** Message shown to the user. Default: "Please sign in with GitHub to continue." */
|
|
19
|
+
message?: string;
|
|
20
|
+
/** Timeout in ms. Default: 300000 */
|
|
21
|
+
timeout?: number;
|
|
22
|
+
}
|
|
23
|
+
declare function githubOAuth(options: GitHubOAuthOptions): ToolMiddleware;
|
|
24
|
+
interface HandleGitHubCallbackOptions {
|
|
25
|
+
clientId: string;
|
|
26
|
+
clientSecret: string;
|
|
27
|
+
/** Session key for user data. Default: "user" */
|
|
28
|
+
sessionKey?: string;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Handle GitHub OAuth callback. Call from your HTTP callback route.
|
|
32
|
+
* Exchanges code for token, fetches user info, stores in session, and completes elicitation.
|
|
33
|
+
*/
|
|
34
|
+
declare function handleGitHubCallback(server: MCPServer, params: {
|
|
35
|
+
code: string;
|
|
36
|
+
state: string;
|
|
37
|
+
}, options: HandleGitHubCallbackOptions): Promise<{
|
|
38
|
+
success: boolean;
|
|
39
|
+
error?: string;
|
|
40
|
+
}>;
|
|
41
|
+
|
|
42
|
+
export { type GitHubOAuthOptions, type HandleGitHubCallbackOptions, githubOAuth, handleGitHubCallback };
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import {a}from'../chunk-2KEVF6YL.mjs';import'../chunk-STWVQGX5.mjs';import'../chunk-VAAZWX4U.mjs';function h(e){let s=e.scopes??[],t={name:e.name??"github-oauth",sessionKey:e.sessionKey??"user",message:e.message??"Please sign in with GitHub to continue.",buildUrl({sessionId:c,elicitationId:n}){let r=new URLSearchParams({client_id:e.clientId,redirect_uri:e.redirectUri,state:`${c}:${n}`});return s.length>0&&r.set("scope",s.join(" ")),`https://github.com/login/oauth/authorize?${r}`}};return e.timeout!==void 0&&(t.timeout=e.timeout),a(t)}async function m(e,s,t){let c=t.sessionKey??"user",[n,r]=s.state.split(":");if(!n||!r)return {success:false,error:"Invalid state parameter"};try{let i=await(await fetch("https://github.com/login/oauth/access_token",{method:"POST",headers:{"Content-Type":"application/json",Accept:"application/json"},body:JSON.stringify({client_id:t.clientId,client_secret:t.clientSecret,code:s.code})})).json();if(!i.access_token)return {success:!1,error:i.error_description??i.error??"Token exchange failed"};let l=await(await fetch("https://api.github.com/user",{headers:{Authorization:`Bearer ${i.access_token}`}})).json(),a=e.session(n);return a.set(c,l),a.set("accessToken",i.access_token),e.completeElicitation(r),{success:!0}}catch(o){return {success:false,error:o instanceof Error?o.message:String(o)}}}
|
|
2
|
+
export{h as githubOAuth,m as handleGitHubCallback};
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { t as ToolMiddleware, M as MCPServer } from '../types-CqT2idkd.js';
|
|
2
|
+
import '@modelcontextprotocol/sdk/types.js';
|
|
3
|
+
import 'zod';
|
|
4
|
+
|
|
5
|
+
interface GoogleOAuthOptions {
|
|
6
|
+
/** Middleware name. Default: "google-oauth" */
|
|
7
|
+
name?: string;
|
|
8
|
+
/** Google OAuth client ID. */
|
|
9
|
+
clientId: string;
|
|
10
|
+
/** Google OAuth client secret. */
|
|
11
|
+
clientSecret: string;
|
|
12
|
+
/** OAuth callback URL (your server's callback endpoint). */
|
|
13
|
+
redirectUri: string;
|
|
14
|
+
/** OAuth scopes. Default: ["openid", "profile", "email"] */
|
|
15
|
+
scopes?: string[];
|
|
16
|
+
/** Session key for user data. Default: "user" */
|
|
17
|
+
sessionKey?: string;
|
|
18
|
+
/** Message shown to the user. Default: "Please sign in with Google to continue." */
|
|
19
|
+
message?: string;
|
|
20
|
+
/** Timeout in ms. Default: 300000 */
|
|
21
|
+
timeout?: number;
|
|
22
|
+
}
|
|
23
|
+
declare function googleOAuth(options: GoogleOAuthOptions): ToolMiddleware;
|
|
24
|
+
interface HandleGoogleCallbackOptions {
|
|
25
|
+
clientId: string;
|
|
26
|
+
clientSecret: string;
|
|
27
|
+
redirectUri: string;
|
|
28
|
+
/** Session key for user data. Default: "user" */
|
|
29
|
+
sessionKey?: string;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Handle Google OAuth callback. Call from your HTTP callback route.
|
|
33
|
+
* Exchanges code for tokens, fetches user info, stores in session, and completes elicitation.
|
|
34
|
+
*/
|
|
35
|
+
declare function handleGoogleCallback(server: MCPServer, params: {
|
|
36
|
+
code: string;
|
|
37
|
+
state: string;
|
|
38
|
+
}, options: HandleGoogleCallbackOptions): Promise<{
|
|
39
|
+
success: boolean;
|
|
40
|
+
error?: string;
|
|
41
|
+
}>;
|
|
42
|
+
|
|
43
|
+
export { type GoogleOAuthOptions, type HandleGoogleCallbackOptions, googleOAuth, handleGoogleCallback };
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import {a}from'../chunk-2KEVF6YL.mjs';import'../chunk-STWVQGX5.mjs';import'../chunk-VAAZWX4U.mjs';function m(e){let r=e.scopes??["openid","profile","email"],t={name:e.name??"google-oauth",sessionKey:e.sessionKey??"user",message:e.message??"Please sign in with Google to continue.",buildUrl({sessionId:i,elicitationId:o}){return `https://accounts.google.com/o/oauth2/v2/auth?${new URLSearchParams({client_id:e.clientId,redirect_uri:e.redirectUri,response_type:"code",scope:r.join(" "),state:`${i}:${o}`,access_type:"offline"})}`}};return e.timeout!==void 0&&(t.timeout=e.timeout),a(t)}async function p(e,r,t){let i=t.sessionKey??"user",[o,c]=r.state.split(":");if(!o||!c)return {success:false,error:"Invalid state parameter"};try{let s=await(await fetch("https://oauth2.googleapis.com/token",{method:"POST",headers:{"Content-Type":"application/x-www-form-urlencoded"},body:new URLSearchParams({code:r.code,client_id:t.clientId,client_secret:t.clientSecret,redirect_uri:t.redirectUri,grant_type:"authorization_code"})})).json();if(!s.access_token)return {success:!1,error:s.error_description??s.error??"Token exchange failed"};let d=await(await fetch("https://www.googleapis.com/oauth2/v2/userinfo",{headers:{Authorization:`Bearer ${s.access_token}`}})).json(),a=e.session(o);return a.set(i,d),a.set("accessToken",s.access_token),s.id_token&&a.set("idToken",s.id_token),e.completeElicitation(c),{success:!0}}catch(n){return {success:false,error:n instanceof Error?n.message:String(n)}}}
|
|
2
|
+
export{m as googleOAuth,p as handleGoogleCallback};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { t as ToolMiddleware } from '../types-CqT2idkd.js';
|
|
2
|
+
import '@modelcontextprotocol/sdk/types.js';
|
|
3
|
+
import 'zod';
|
|
4
|
+
|
|
5
|
+
interface GuardOptions {
|
|
6
|
+
/** Middleware name. Used for authorize()/revoke(). Default: "guard" */
|
|
7
|
+
name?: string;
|
|
8
|
+
/** Session key to check. Default: "user" */
|
|
9
|
+
sessionKey?: string;
|
|
10
|
+
/** Error message when not authorized. */
|
|
11
|
+
message?: string;
|
|
12
|
+
}
|
|
13
|
+
declare function guard(options?: GuardOptions): ToolMiddleware;
|
|
14
|
+
|
|
15
|
+
export { type GuardOptions, guard };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export{a as guard}from'../chunk-L7SD7KKW.mjs';import'../chunk-VAAZWX4U.mjs';
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { t as ToolMiddleware } from '../types-CqT2idkd.js';
|
|
2
|
+
import '@modelcontextprotocol/sdk/types.js';
|
|
3
|
+
import 'zod';
|
|
4
|
+
|
|
5
|
+
interface JwtOptions {
|
|
6
|
+
/** Middleware name. Default: "jwt" */
|
|
7
|
+
name?: string;
|
|
8
|
+
/** Session key where the raw token is stored. Default: "token" */
|
|
9
|
+
tokenKey?: string;
|
|
10
|
+
/** Session key to store decoded payload. Default: "user" */
|
|
11
|
+
sessionKey?: string;
|
|
12
|
+
/** Symmetric secret for HMAC verification. */
|
|
13
|
+
secret?: string;
|
|
14
|
+
/** JWKS URI for remote key fetching. */
|
|
15
|
+
jwksUri?: string;
|
|
16
|
+
/** Expected issuer claim. */
|
|
17
|
+
issuer?: string;
|
|
18
|
+
/** Expected audience claim. */
|
|
19
|
+
audience?: string;
|
|
20
|
+
/** Additional validation on the decoded payload. Return user data or null. */
|
|
21
|
+
validate?: (payload: Record<string, unknown>) => unknown | null | Promise<unknown | null>;
|
|
22
|
+
/** Error message. Default: "Invalid or expired JWT." */
|
|
23
|
+
message?: string;
|
|
24
|
+
}
|
|
25
|
+
declare function jwt(options: JwtOptions): ToolMiddleware;
|
|
26
|
+
|
|
27
|
+
export { type JwtOptions, jwt };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import {c}from'../chunk-VAAZWX4U.mjs';function j(e){let u=e.name??"jwt",y=e.tokenKey??"token",l=e.sessionKey??"user",d=e.message??"Invalid or expired JWT.",s=null;function m(){return s||(s=import('jose').catch(()=>(s=null,null))),s}return {name:u,onRegister(){return false},async onCall(n,c$1){if(n.session.get(l))return c$1();let a=n.session.get(y);if(!a)return c("JWT required.");let t=await m();if(!t)return c("jose library is required for JWT middleware. Install it: pnpm add jose");try{let i;if(e.jwksUri){let o=t.createRemoteJWKSet(new URL(e.jwksUri));i=(await t.jwtVerify(a,o,{issuer:e.issuer,audience:e.audience})).payload;}else if(e.secret){let o=new TextEncoder().encode(e.secret);i=(await t.jwtVerify(a,o,{issuer:e.issuer,audience:e.audience})).payload;}else return c("JWT middleware misconfigured: provide secret or jwksUri.");let w=e.validate?await e.validate(i):i;return w?(n.session.set(l,w),n.session.authorize(u),c$1()):c(d)}catch{return c(d)}}}}export{j as jwt};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { t as ToolMiddleware } from '../types-CqT2idkd.js';
|
|
2
|
+
import '@modelcontextprotocol/sdk/types.js';
|
|
3
|
+
import 'zod';
|
|
4
|
+
|
|
5
|
+
interface LoggerOptions {
|
|
6
|
+
/** Custom log function. Default: console.log */
|
|
7
|
+
log?: (message: string) => void;
|
|
8
|
+
}
|
|
9
|
+
declare function logger(options?: LoggerOptions): ToolMiddleware;
|
|
10
|
+
|
|
11
|
+
export { type LoggerOptions, logger };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
function a(s){let e=s?.log??console.log;return {name:"logger",async onCall(o,t){let n=performance.now();e(`[${o.toolName}] called (session: ${o.sessionId})`);let r=await t(),l=(performance.now()-n).toFixed(1);return e(`[${o.toolName}] ${l}ms${r.isError?" ERROR":""}`),r}}}export{a as logger};
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { t as ToolMiddleware } from '../types-CqT2idkd.js';
|
|
2
|
+
import '@modelcontextprotocol/sdk/types.js';
|
|
3
|
+
import 'zod';
|
|
4
|
+
|
|
5
|
+
interface OAuthOptions {
|
|
6
|
+
/** Middleware name. Default: "oauth" */
|
|
7
|
+
name?: string;
|
|
8
|
+
/** Session key for storing tokens. Default: "user" */
|
|
9
|
+
sessionKey?: string;
|
|
10
|
+
/** Message shown to the user. Default: "Please sign in to continue." */
|
|
11
|
+
message?: string;
|
|
12
|
+
/** Build the OAuth authorization URL. */
|
|
13
|
+
buildUrl: (params: {
|
|
14
|
+
sessionId: string;
|
|
15
|
+
elicitationId: string;
|
|
16
|
+
}) => string;
|
|
17
|
+
/** Timeout in ms. Default: 300000 */
|
|
18
|
+
timeout?: number;
|
|
19
|
+
}
|
|
20
|
+
declare function oauth(options: OAuthOptions): ToolMiddleware;
|
|
21
|
+
|
|
22
|
+
export { type OAuthOptions, oauth };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export{a as oauth}from'../chunk-2KEVF6YL.mjs';import'../chunk-STWVQGX5.mjs';import'../chunk-VAAZWX4U.mjs';
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { t as ToolMiddleware } from '../types-CqT2idkd.js';
|
|
2
|
+
import '@modelcontextprotocol/sdk/types.js';
|
|
3
|
+
import 'zod';
|
|
4
|
+
|
|
5
|
+
interface PaymentOptions {
|
|
6
|
+
/** Middleware name. Default: "payment" */
|
|
7
|
+
name?: string;
|
|
8
|
+
/** Session key for storing payment confirmation. Default: "payment" */
|
|
9
|
+
sessionKey?: string;
|
|
10
|
+
/** Message shown to the user. Default: "Please complete payment to continue." */
|
|
11
|
+
message?: string;
|
|
12
|
+
/** Build the payment page URL. */
|
|
13
|
+
buildUrl: (params: {
|
|
14
|
+
sessionId: string;
|
|
15
|
+
elicitationId: string;
|
|
16
|
+
}) => string;
|
|
17
|
+
/** Timeout in ms. Default: 300000 */
|
|
18
|
+
timeout?: number;
|
|
19
|
+
}
|
|
20
|
+
declare function payment(options: PaymentOptions): ToolMiddleware;
|
|
21
|
+
|
|
22
|
+
export { type PaymentOptions, payment };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import {a}from'../chunk-STWVQGX5.mjs';import'../chunk-VAAZWX4U.mjs';function i(e){let t={name:e.name??"payment",sessionKey:e.sessionKey??"payment",message:e.message??"Please complete payment to continue.",buildUrl:e.buildUrl,declineMessage:"Payment cancelled."};return e.timeout!==void 0&&(t.timeout=e.timeout),a(t)}export{i as payment};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { t as ToolMiddleware } from '../types-CqT2idkd.js';
|
|
2
|
+
import '@modelcontextprotocol/sdk/types.js';
|
|
3
|
+
import 'zod';
|
|
4
|
+
|
|
5
|
+
interface RateLimitOptions {
|
|
6
|
+
/** Maximum calls per window. */
|
|
7
|
+
max: number;
|
|
8
|
+
/** Window duration in milliseconds. Default: 60000 (1 minute) */
|
|
9
|
+
windowMs?: number;
|
|
10
|
+
/** Error message. */
|
|
11
|
+
message?: string;
|
|
12
|
+
}
|
|
13
|
+
declare function rateLimit(options: RateLimitOptions): ToolMiddleware;
|
|
14
|
+
|
|
15
|
+
export { type RateLimitOptions, rateLimit };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import {c}from'../chunk-VAAZWX4U.mjs';function l(n){let{max:o,windowMs:r=6e4}=n,u=n.message??`Rate limit exceeded. Max ${o} calls per ${r/1e3}s.`;return {name:"rateLimit",async onCall(t,i){let s=`rateLimit:${t.toolName}`,e=t.session.get(s),a=Date.now();return !e||a>=e.resetAt?(t.session.set(s,{count:1,resetAt:a+r}),i()):e.count>=o?c(u):(t.session.set(s,{...e,count:e.count+1}),i())}}}export{l as rateLimit};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { t as ToolMiddleware } from '../types-CqT2idkd.js';
|
|
2
|
+
import '@modelcontextprotocol/sdk/types.js';
|
|
3
|
+
import 'zod';
|
|
4
|
+
|
|
5
|
+
interface TruncateOptions {
|
|
6
|
+
/** Maximum characters per text content block. */
|
|
7
|
+
maxChars: number;
|
|
8
|
+
/** Suffix appended when truncated. Default: "..." */
|
|
9
|
+
suffix?: string;
|
|
10
|
+
}
|
|
11
|
+
declare function truncate(options: TruncateOptions): ToolMiddleware;
|
|
12
|
+
|
|
13
|
+
export { type TruncateOptions, truncate };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
function a(e){let{maxChars:r}=e,n=e.suffix??"...";return {name:"truncate",onResult(s){return {...s,content:s.content.map(t=>t.type==="text"&&t.text&&t.text.length>r?{...t,text:t.text.slice(0,r-n.length)+n}:t)}}}}export{a as truncate};
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { t as ToolMiddleware } from '../types-CqT2idkd.js';
|
|
2
|
+
import '@modelcontextprotocol/sdk/types.js';
|
|
3
|
+
import 'zod';
|
|
4
|
+
|
|
5
|
+
interface UrlActionOptions {
|
|
6
|
+
/** Middleware name. Default: "url-action" */
|
|
7
|
+
name?: string;
|
|
8
|
+
/** Session key to check/store result. Default: "user" */
|
|
9
|
+
sessionKey?: string;
|
|
10
|
+
/** Message shown to the user in the elicitation. */
|
|
11
|
+
message: string;
|
|
12
|
+
/** Build the URL. Receives sessionId and elicitationId for callback routing. */
|
|
13
|
+
buildUrl: (params: {
|
|
14
|
+
sessionId: string;
|
|
15
|
+
elicitationId: string;
|
|
16
|
+
}) => string;
|
|
17
|
+
/** Timeout in ms for waiting for external callback. Default: 300000 (5 min). */
|
|
18
|
+
timeout?: number;
|
|
19
|
+
/** Error message when user declines. Default: "Action cancelled." */
|
|
20
|
+
declineMessage?: string;
|
|
21
|
+
}
|
|
22
|
+
declare function urlAction(options: UrlActionOptions): ToolMiddleware;
|
|
23
|
+
|
|
24
|
+
export { type UrlActionOptions, urlAction };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export{a as urlAction}from'../chunk-STWVQGX5.mjs';import'../chunk-VAAZWX4U.mjs';
|
package/dist/test.d.ts
CHANGED
|
@@ -45,11 +45,19 @@ interface ElicitFormResult<T = Record<string, string | number | boolean | string
|
|
|
45
45
|
interface ElicitUrlResult {
|
|
46
46
|
action: "accept" | "decline" | "cancel";
|
|
47
47
|
}
|
|
48
|
+
interface ElicitUrlOptions {
|
|
49
|
+
/** Pre-generated elicitation ID. If omitted, a random UUID is used. */
|
|
50
|
+
elicitationId?: string;
|
|
51
|
+
/** If true, wait for completeElicitation() before resolving. Default: false. */
|
|
52
|
+
waitForCompletion?: boolean;
|
|
53
|
+
/** Timeout in ms for waiting. Default: 300000 (5 minutes). */
|
|
54
|
+
timeout?: number;
|
|
55
|
+
}
|
|
48
56
|
interface Elicit {
|
|
49
57
|
/** Request structured data from the user via a form. */
|
|
50
58
|
form<T extends z.ZodObject<z.ZodRawShape>>(message: string, schema: T): Promise<ElicitFormResult<z.infer<T>>>;
|
|
51
59
|
/** Direct the user to an external URL. */
|
|
52
|
-
url(message: string, url: string): Promise<ElicitUrlResult>;
|
|
60
|
+
url(message: string, url: string, options?: ElicitUrlOptions): Promise<ElicitUrlResult>;
|
|
53
61
|
}
|
|
54
62
|
interface SampleOptions {
|
|
55
63
|
maxTokens?: number;
|
|
@@ -108,16 +116,16 @@ interface ToolMiddleware {
|
|
|
108
116
|
/** Called when a tool is registered. Return false to hide the tool initially. */
|
|
109
117
|
onRegister?(tool: ToolInfo): boolean | undefined;
|
|
110
118
|
/** Called when a tool is invoked. Must call next() to continue the chain. */
|
|
111
|
-
onCall?(
|
|
119
|
+
onCall?(c: ToolContext, next: () => Promise<CallToolResult>): Promise<CallToolResult>;
|
|
112
120
|
/** Called after the handler returns. Runs in reverse middleware order. */
|
|
113
|
-
onResult?(result: CallToolResult,
|
|
121
|
+
onResult?(result: CallToolResult, c: ToolContext): CallToolResult | Promise<CallToolResult>;
|
|
114
122
|
}
|
|
115
123
|
type InferInput<T> = T extends z.ZodTypeAny ? z.output<T> : Record<string, unknown>;
|
|
116
124
|
interface ToolConfig<TInput = unknown> {
|
|
117
125
|
description?: string;
|
|
118
126
|
input?: TInput;
|
|
119
127
|
}
|
|
120
|
-
type ToolHandler<TInput = unknown> = (args: InferInput<TInput>,
|
|
128
|
+
type ToolHandler<TInput = unknown> = (args: InferInput<TInput>, c: ToolContext) => CallToolResult | Promise<CallToolResult>;
|
|
121
129
|
/** @experimental */
|
|
122
130
|
interface TaskConfig<TInput = unknown> {
|
|
123
131
|
description?: string;
|
|
@@ -135,7 +143,7 @@ interface TaskContext extends ToolContext {
|
|
|
135
143
|
task: TaskControl;
|
|
136
144
|
}
|
|
137
145
|
/** @experimental */
|
|
138
|
-
type TaskHandler<TInput = unknown> = (args: InferInput<TInput>,
|
|
146
|
+
type TaskHandler<TInput = unknown> = (args: InferInput<TInput>, c: TaskContext) => CallToolResult | Promise<CallToolResult>;
|
|
139
147
|
interface ResourceConfig {
|
|
140
148
|
name: string;
|
|
141
149
|
description?: string;
|
|
@@ -153,7 +161,7 @@ interface ResourceContext {
|
|
|
153
161
|
/** Query client-provided filesystem roots. */
|
|
154
162
|
roots: () => Promise<RootInfo[]>;
|
|
155
163
|
}
|
|
156
|
-
type ResourceHandler = (uri: string,
|
|
164
|
+
type ResourceHandler = (uri: string, c: ResourceContext) => ResourceContent | Promise<ResourceContent>;
|
|
157
165
|
interface HttpAdapterOptions {
|
|
158
166
|
/** Disable session management. Default: false. */
|
|
159
167
|
sessionless?: boolean;
|
|
@@ -161,6 +169,8 @@ interface HttpAdapterOptions {
|
|
|
161
169
|
sessionIdGenerator?: () => string;
|
|
162
170
|
/** Return JSON instead of SSE streams. Default: false. */
|
|
163
171
|
enableJsonResponse?: boolean;
|
|
172
|
+
/** Called on each HTTP request after session is resolved. Use to inject auth headers into sessions. */
|
|
173
|
+
onRequest?: (req: Request, sessionId: string, session: Session) => void | Promise<void>;
|
|
164
174
|
}
|
|
165
175
|
interface MCPServer {
|
|
166
176
|
/** Register a global middleware applied to all subsequently registered tools. */
|
|
@@ -181,6 +191,10 @@ interface MCPServer {
|
|
|
181
191
|
stdio(): Promise<void>;
|
|
182
192
|
/** Start HTTP transport. Returns a Web Standard request handler. */
|
|
183
193
|
http(options?: HttpAdapterOptions): (req: Request) => Promise<Response>;
|
|
194
|
+
/** Access a session by ID (for external HTTP callback routes). Stateful mode only. */
|
|
195
|
+
session(sessionId: string): Session;
|
|
196
|
+
/** Complete a pending URL elicitation (called from external HTTP callback). */
|
|
197
|
+
completeElicitation(elicitationId: string): void;
|
|
184
198
|
}
|
|
185
199
|
|
|
186
|
-
export { type Elicit as E, type HttpAdapterOptions as H, type MCPServer as M, type ResourceConfig as R, type Sample as S, type TaskConfig as T, type ElicitFormResult as a, type
|
|
200
|
+
export { type Elicit as E, type HttpAdapterOptions as H, type MCPServer as M, type ResourceConfig as R, type Sample as S, type TaskConfig as T, type ElicitFormResult as a, type ElicitUrlOptions as b, type ElicitUrlResult as c, type ResourceContent as d, type ResourceContext as e, type ResourceHandler as f, type RootInfo as g, type SampleOptions as h, type SampleRawParams as i, type SampleRawResult as j, type ServerInfo as k, type Session as l, type TaskContext as m, type TaskControl as n, type TaskHandler as o, type ToolConfig as p, type ToolContext as q, type ToolHandler as r, type ToolInfo as s, type ToolMiddleware as t, type ToolResponse as u, error as v, image as w, json as x, text as y };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lynq/lynq",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"description": "Lightweight MCP server framework. Tool visibility control through middleware.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"exports": {
|
|
@@ -27,6 +27,58 @@
|
|
|
27
27
|
"./test": {
|
|
28
28
|
"types": "./dist/test.d.ts",
|
|
29
29
|
"import": "./dist/test.mjs"
|
|
30
|
+
},
|
|
31
|
+
"./guard": {
|
|
32
|
+
"types": "./dist/middleware/guard.d.ts",
|
|
33
|
+
"import": "./dist/middleware/guard.mjs"
|
|
34
|
+
},
|
|
35
|
+
"./logger": {
|
|
36
|
+
"types": "./dist/middleware/logger.d.ts",
|
|
37
|
+
"import": "./dist/middleware/logger.mjs"
|
|
38
|
+
},
|
|
39
|
+
"./rate-limit": {
|
|
40
|
+
"types": "./dist/middleware/rate-limit.d.ts",
|
|
41
|
+
"import": "./dist/middleware/rate-limit.mjs"
|
|
42
|
+
},
|
|
43
|
+
"./truncate": {
|
|
44
|
+
"types": "./dist/middleware/truncate.d.ts",
|
|
45
|
+
"import": "./dist/middleware/truncate.mjs"
|
|
46
|
+
},
|
|
47
|
+
"./combine": {
|
|
48
|
+
"types": "./dist/middleware/combine.d.ts",
|
|
49
|
+
"import": "./dist/middleware/combine.mjs"
|
|
50
|
+
},
|
|
51
|
+
"./credentials": {
|
|
52
|
+
"types": "./dist/middleware/credentials.d.ts",
|
|
53
|
+
"import": "./dist/middleware/credentials.mjs"
|
|
54
|
+
},
|
|
55
|
+
"./url-action": {
|
|
56
|
+
"types": "./dist/middleware/url-action.d.ts",
|
|
57
|
+
"import": "./dist/middleware/url-action.mjs"
|
|
58
|
+
},
|
|
59
|
+
"./oauth": {
|
|
60
|
+
"types": "./dist/middleware/oauth.d.ts",
|
|
61
|
+
"import": "./dist/middleware/oauth.mjs"
|
|
62
|
+
},
|
|
63
|
+
"./payment": {
|
|
64
|
+
"types": "./dist/middleware/payment.d.ts",
|
|
65
|
+
"import": "./dist/middleware/payment.mjs"
|
|
66
|
+
},
|
|
67
|
+
"./bearer": {
|
|
68
|
+
"types": "./dist/middleware/bearer.d.ts",
|
|
69
|
+
"import": "./dist/middleware/bearer.mjs"
|
|
70
|
+
},
|
|
71
|
+
"./jwt": {
|
|
72
|
+
"types": "./dist/middleware/jwt.d.ts",
|
|
73
|
+
"import": "./dist/middleware/jwt.mjs"
|
|
74
|
+
},
|
|
75
|
+
"./github-oauth": {
|
|
76
|
+
"types": "./dist/middleware/github-oauth.d.ts",
|
|
77
|
+
"import": "./dist/middleware/github-oauth.mjs"
|
|
78
|
+
},
|
|
79
|
+
"./google-oauth": {
|
|
80
|
+
"types": "./dist/middleware/google-oauth.d.ts",
|
|
81
|
+
"import": "./dist/middleware/google-oauth.mjs"
|
|
30
82
|
}
|
|
31
83
|
},
|
|
32
84
|
"files": [
|
|
@@ -46,12 +98,15 @@
|
|
|
46
98
|
"docs:preview": "vitepress preview docs",
|
|
47
99
|
"prepublishOnly": "pnpm build"
|
|
48
100
|
},
|
|
101
|
+
"dependencies": {
|
|
102
|
+
"@modelcontextprotocol/sdk": "^1.27.0"
|
|
103
|
+
},
|
|
49
104
|
"devDependencies": {
|
|
50
105
|
"@biomejs/biome": "^1.9.0",
|
|
51
|
-
"@modelcontextprotocol/sdk": "^1.27.0",
|
|
52
106
|
"@types/express": "^5.0.6",
|
|
53
107
|
"express": "^5.2.1",
|
|
54
108
|
"hono": "^4.12.5",
|
|
109
|
+
"jose": "^6.2.1",
|
|
55
110
|
"tsup": "^8.0.0",
|
|
56
111
|
"typedoc": "^0.28.17",
|
|
57
112
|
"typedoc-plugin-markdown": "^4.10.0",
|
|
@@ -61,9 +116,9 @@
|
|
|
61
116
|
"zod": "^3.24.0"
|
|
62
117
|
},
|
|
63
118
|
"peerDependencies": {
|
|
64
|
-
"@modelcontextprotocol/sdk": "^1.27.0",
|
|
65
119
|
"express": "^5.0.0",
|
|
66
120
|
"hono": "^4.0.0",
|
|
121
|
+
"jose": "^6.0.0",
|
|
67
122
|
"zod": "^3.0.0"
|
|
68
123
|
},
|
|
69
124
|
"peerDependenciesMeta": {
|
|
@@ -75,6 +130,9 @@
|
|
|
75
130
|
},
|
|
76
131
|
"express": {
|
|
77
132
|
"optional": true
|
|
133
|
+
},
|
|
134
|
+
"jose": {
|
|
135
|
+
"optional": true
|
|
78
136
|
}
|
|
79
137
|
},
|
|
80
138
|
"publishConfig": {
|