@lynq/lynq 0.2.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.
Files changed (40) hide show
  1. package/README.md +79 -139
  2. package/dist/adapters/express.d.ts +1 -1
  3. package/dist/adapters/hono.d.ts +1 -1
  4. package/dist/chunk-2KEVF6YL.mjs +1 -0
  5. package/dist/chunk-L7SD7KKW.mjs +1 -0
  6. package/dist/chunk-STWVQGX5.mjs +1 -0
  7. package/dist/chunk-VAAZWX4U.mjs +1 -0
  8. package/dist/index.d.ts +2 -2
  9. package/dist/index.mjs +1 -1
  10. package/dist/middleware/auth.d.ts +6 -8
  11. package/dist/middleware/auth.mjs +1 -1
  12. package/dist/middleware/bearer.d.ts +19 -0
  13. package/dist/middleware/bearer.mjs +1 -0
  14. package/dist/middleware/combine.d.ts +12 -0
  15. package/dist/middleware/combine.mjs +1 -0
  16. package/dist/middleware/credentials.d.ts +19 -0
  17. package/dist/middleware/credentials.mjs +1 -0
  18. package/dist/middleware/github-oauth.d.ts +42 -0
  19. package/dist/middleware/github-oauth.mjs +2 -0
  20. package/dist/middleware/google-oauth.d.ts +43 -0
  21. package/dist/middleware/google-oauth.mjs +2 -0
  22. package/dist/middleware/guard.d.ts +15 -0
  23. package/dist/middleware/guard.mjs +1 -0
  24. package/dist/middleware/jwt.d.ts +27 -0
  25. package/dist/middleware/jwt.mjs +1 -0
  26. package/dist/middleware/logger.d.ts +11 -0
  27. package/dist/middleware/logger.mjs +1 -0
  28. package/dist/middleware/oauth.d.ts +22 -0
  29. package/dist/middleware/oauth.mjs +1 -0
  30. package/dist/middleware/payment.d.ts +22 -0
  31. package/dist/middleware/payment.mjs +1 -0
  32. package/dist/middleware/rate-limit.d.ts +15 -0
  33. package/dist/middleware/rate-limit.mjs +1 -0
  34. package/dist/middleware/truncate.d.ts +13 -0
  35. package/dist/middleware/truncate.mjs +1 -0
  36. package/dist/middleware/url-action.d.ts +24 -0
  37. package/dist/middleware/url-action.mjs +1 -0
  38. package/dist/test.d.ts +1 -1
  39. package/dist/{types-BqH9Me9B.d.ts → types-CqT2idkd.d.ts} +48 -24
  40. package/package.json +61 -3
package/README.md CHANGED
@@ -1,181 +1,121 @@
1
1
  # lynq
2
2
 
3
3
  [![CI](https://github.com/hogekai/lynq/actions/workflows/ci.yml/badge.svg)](https://github.com/hogekai/lynq/actions/workflows/ci.yml)
4
- [![npm](https://img.shields.io/npm/v/lynq)](https://www.npmjs.com/package/lynq)
4
+ [![npm](https://img.shields.io/npm/v/@lynq/lynq)](https://www.npmjs.com/package/@lynq/lynq)
5
5
 
6
- Lightweight MCP server framework. Tool visibility control through middleware.
6
+ MCP servers are stateless by default. lynq makes them session-aware.
7
7
 
8
- ```ts
9
- import { createMCPServer } from "lynq";
10
- import { auth } from "lynq/auth";
11
- import { z } from "zod";
8
+ ## The Problem
12
9
 
13
- const server = createMCPServer({ name: "my-server", version: "1.0.0" });
10
+ With the official SDK, adding session-aware tool visibility requires manual plumbing:
14
11
 
15
- // Login tool — always visible
16
- server.tool("login", {
17
- input: z.object({ username: z.string(), password: z.string() }),
18
- }, async (args, ctx) => {
19
- const user = await authenticate(args.username, args.password);
20
- ctx.session.set("user", user);
21
- ctx.session.authorize("auth");
22
- return { content: [{ type: "text", text: `Welcome, ${user.name}` }] };
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 };
23
21
  });
24
22
 
25
- // Weather tool hidden until authenticated
26
- server.tool("weather", auth(), {
27
- description: "Get weather for a city",
28
- input: z.object({ city: z.string() }),
29
- }, async (args) => {
30
- const data = await fetchWeather(args.city);
31
- return { content: [{ type: "text", text: JSON.stringify(data) }] };
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
+ // ...
32
29
  });
30
+ ```
33
31
 
34
- await server.stdio();
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.
35
38
  ```
36
39
 
37
40
  ## Install
38
41
 
39
42
  ```sh
40
- npm install lynq @modelcontextprotocol/sdk zod
43
+ npm install @lynq/lynq
41
44
  ```
42
45
 
43
- ## Why lynq
44
-
45
- When you build an MCP server, you often need to show different tools depending on session state — hide admin tools from unauthenticated users, reveal features after onboarding, etc. The MCP protocol supports this via bidirectional tool list notifications, but wiring it by hand means managing visibility sets, diffing tool lists, and calling `sendToolListChanged` at the right time. lynq lets you declare visibility as middleware and handles the rest.
46
-
47
- ## API
48
-
49
- ### `createMCPServer(info)`
50
-
51
- Creates a server instance.
46
+ ## Quick Start
52
47
 
53
48
  ```ts
54
- const server = createMCPServer({ name: "my-server", version: "1.0.0" });
55
- ```
56
-
57
- ### `server.tool(name, ...middlewares?, config, handler)`
58
-
59
- Register a tool. Middlewares are optional, config holds `description` and `input` schema.
49
+ import { createMCPServer } from "@lynq/lynq";
50
+ import { guard } from "@lynq/lynq/guard";
51
+ import { z } from "zod";
60
52
 
61
- ```ts
62
- server.tool("greet", {
63
- description: "Greet someone",
64
- input: z.object({ name: z.string() }),
65
- }, async (args) => ({
66
- content: [{ type: "text", text: `Hello ${args.name}` }],
67
- }));
68
-
69
- server.tool("secret", auth(), {
70
- input: z.object({ query: z.string() }),
71
- }, async (args) => ({
72
- content: [{ type: "text", text: args.query }],
73
- }));
74
- ```
53
+ const server = createMCPServer({ name: "my-server", version: "1.0.0" });
75
54
 
76
- ### `server.resource(uri, ...middlewares?, config, handler)`
55
+ server.tool("login", {
56
+ input: z.object({ username: z.string(), password: z.string() }),
57
+ }, async (args, c) => {
58
+ const user = await authenticate(args.username, args.password);
59
+ c.session.set("user", user);
60
+ c.session.authorize("guard");
61
+ return c.text(`Welcome, ${user.name}`);
62
+ });
77
63
 
78
- Register a resource. Same middleware pattern as `tool()`. Global middleware (`server.use()`) does not apply to resources.
64
+ server.tool("weather", guard(), {
65
+ description: "Get weather for a city",
66
+ input: z.object({ city: z.string() }),
67
+ }, async (args, c) => {
68
+ return c.text(JSON.stringify(await fetchWeather(args.city)));
69
+ });
79
70
 
80
- ```ts
81
- server.resource("config://settings", {
82
- name: "App Settings",
83
- mimeType: "application/json",
84
- }, async (uri) => ({
85
- text: JSON.stringify(config),
86
- }));
87
-
88
- server.resource("data://users", auth(), {
89
- name: "User Database",
90
- mimeType: "application/json",
91
- }, async (uri, ctx) => ({
92
- text: JSON.stringify(await db.getUsers()),
93
- }));
71
+ await server.stdio();
94
72
  ```
95
73
 
96
- ### `server.use(middleware)`
97
-
98
- Apply middleware to all subsequently registered tools.
99
-
100
- ```ts
101
- server.use(auth());
74
+ ```sh
75
+ npx tsx server.ts
102
76
  ```
103
77
 
104
- ### Session
78
+ ## Features
105
79
 
106
- Available in handlers and middleware via `ctx.session`:
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.
107
88
 
108
- ```ts
109
- ctx.session.set("key", value);
110
- ctx.session.get("key");
111
- ctx.session.authorize("auth"); // Enable tools guarded by "auth" middleware
112
- ```
113
-
114
- ### `auth(options?)`
115
-
116
- Middleware that hides tools until authenticated.
89
+ ## Middleware Composition
117
90
 
118
91
  ```ts
119
- import { auth } from "lynq/auth";
92
+ import { guard } from "@lynq/lynq/guard";
93
+ import { rateLimit } from "@lynq/lynq/rate-limit";
94
+ import { logger } from "@lynq/lynq/logger";
120
95
 
121
- auth(); // checks ctx.session.get("user")
122
- auth({ sessionKey: "token" }); // checks ctx.session.get("token")
123
- auth({ message: "Login first" }); // custom error message
96
+ server.use(logger()); // global
97
+ server.tool("search", guard(), rateLimit({ max: 10 }), config, handler); // per-tool stack
124
98
  ```
125
99
 
126
- ## Testing
100
+ ## Comparison
127
101
 
128
- lynq ships a test helper that eliminates MCP boilerplate. No manual `Client`/`InMemoryTransport` setup.
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 |
129
110
 
130
- ```ts
131
- import { createTestClient } from "lynq/test";
132
- import { createMCPServer } from "lynq";
133
- import { auth } from "lynq/auth";
134
- import { z } from "zod";
111
+ ## Documentation
135
112
 
136
- const server = createMCPServer({ name: "my-server", version: "1.0.0" });
137
- server.tool("weather", auth(), {
138
- input: z.object({ city: z.string() }),
139
- }, async (args) => ({
140
- content: [{ type: "text", text: `Sunny in ${args.city}` }],
141
- }));
142
-
143
- const t = await createTestClient(server);
144
-
145
- // Tool visibility
146
- const tools = await t.listTools(); // string[]
147
- expect(tools).not.toContain("weather");
148
-
149
- // Authorize and call
150
- t.authorize("auth");
151
- const text = await t.callToolText("weather", { city: "Tokyo" });
152
- expect(text).toContain("Sunny");
153
-
154
- // Full result access
155
- const result = await t.callTool("weather", { city: "Tokyo" });
156
-
157
- // Resources
158
- const uris = await t.listResources();
159
- const content = await t.readResource("config://settings");
160
-
161
- // Session access
162
- t.session.set("user", { name: "alice" });
113
+ [https://hogekai.github.io/lynq/](https://hogekai.github.io/lynq/)
163
114
 
164
- await t.close();
165
- ```
166
-
167
- ### Custom matchers
168
-
169
- Optional vitest/jest matchers for more expressive assertions:
170
-
171
- ```ts
172
- import { matchers } from "lynq/test";
173
- expect.extend(matchers);
174
-
175
- const result = await t.callTool("weather", { city: "Tokyo" });
176
- expect(result).toHaveTextContent("Sunny");
177
- expect(result).not.toBeError();
178
- ```
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/)
179
119
 
180
120
  ## License
181
121
 
@@ -1,5 +1,5 @@
1
1
  import { Express } from 'express';
2
- import { M as MCPServer } from '../types-BqH9Me9B.js';
2
+ import { M as MCPServer } from '../types-CqT2idkd.js';
3
3
  import '@modelcontextprotocol/sdk/types.js';
4
4
  import 'zod';
5
5
 
@@ -1,5 +1,5 @@
1
1
  import { Hono } from 'hono';
2
- import { M as MCPServer } from '../types-BqH9Me9B.js';
2
+ import { M as MCPServer } from '../types-CqT2idkd.js';
3
3
  import '@modelcontextprotocol/sdk/types.js';
4
4
  import 'zod';
5
5
 
@@ -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};
@@ -0,0 +1 @@
1
+ function t(e,n){return {content:e,...n?{isError:true}:{},text(o){return t([...e,{type:"text",text:o}],n)},json(o){return t([...e,{type:"text",text:JSON.stringify(o,null,2)}],n)},error(o){return t([...e,{type:"text",text:o}],true)},image(o,r){return t([...e,{type:"image",data:o,mimeType:r}],n)}}}function s(e){return t([{type:"text",text:e}])}function l(e){return t([{type:"text",text:JSON.stringify(e,null,2)}])}function p(e){return t([{type:"text",text:e}],true)}function i(e,n){return t([{type:"image",data:e,mimeType:n}])}export{s as a,l as b,p as c,i as d};
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { M as MCPServer } from './types-BqH9Me9B.js';
2
- export { E as Elicit, a as ElicitFormParams, b as ElicitFormResult, c as ElicitUrlParams, d as ElicitUrlResult, H as HttpAdapterOptions, R as ResourceConfig, e as ResourceContent, f as ResourceContext, g as ResourceHandler, h as RootInfo, S as Sample, i as SampleOptions, j as SampleRawParams, k as SampleRawResult, l as ServerInfo, m as Session, T as TaskConfig, n as TaskContext, o as TaskControl, p as TaskHandler, q as ToolConfig, r as ToolContext, s as ToolHandler, t as ToolInfo, u as ToolMiddleware } from './types-BqH9Me9B.js';
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 {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 ne(a){return {async form({message:l,schema:c}){let i=await a.elicitInput({message:l,requestedSchema:{type:"object",properties:c}});return {action:i.action,content:i.content??{}}},async url({message:l,url:c}){return {action:(await a.elicitInput({mode:"url",message:l,url:c,elicitationId:crypto.randomUUID()})).action}}}}function A(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 se(a){async function l(i,u){let p={messages:[{role:"user",content:{type:"text",text:i}}],maxTokens:u?.maxTokens??1024};u?.model!==void 0&&(p.modelPreferences={hints:[{name:u.model}]}),u?.system!==void 0&&(p.systemPrompt=u.system),u?.temperature!==void 0&&(p.temperature=u.temperature),u?.stopSequences!==void 0&&(p.stopSequences=u.stopSequences);let f=(await a.createMessage(p)).content;return f.type==="text"?f.text:""}async function c(i){return a.createMessage(i)}return Object.assign(l,{raw:c})}function q(a,l,c,i,u){return {toolName:i,session:c,signal:u,sessionId:l,elicit:ne(a),roots:A(a),sample:se(a)}}function B(a){if(a==null)return {type:"object"};let l=normalizeObjectSchema(a);return l?toJsonSchemaCompat(l):a}function H(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 u=l.slice(0,-2);for(let p of u)if(!p||typeof p!="object"||typeof p.name!="string")throw new TypeError(`${a}: each middleware must have a "name" property`);return {middlewares:u,config:i,handler:c}}function j(a,l){let c=[];for(let i of l)i.onRegister?.(a)===false&&c.push(i.name);return c}function L(a){let c=a.split(/\{[^}]+\}/).map(i=>i.replace(/[.*+?^$|()[\]\\]/g,"\\$&"));return new RegExp(`^${c.join("(.+)")}$`)}function E(a,l,c,i){let u=c.get(l);if(u==="disabled")return false;if(u==="enabled")return true;for(let p of a)if(!i.has(p))return false;return true}function z(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 $(a,l,c){let i=a.filter(f=>f.onCall),u=a.filter(f=>f.onResult).reverse(),p=0,y=async()=>{if(p>=i.length){let b=await c();for(let C of u)b=await C.onResult(b,l);return b}return i[p++].onCall(l,y)};return y}function pe(a){let l=[],c=new Map,i=new Map,u=new Map,p=new Map,y=new Map,f=new Set,b=new InMemoryTaskStore,C=new Proxy(b,{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)}}),h=new Server(a,{capabilities:{tools:{listChanged:true},resources:{listChanged:true},tasks:{list:{},cancel:{},requests:{tools:{call:{}}}}},taskStore:C});function S(e){let n=p.get(e);return n||(n={data:new Map,grants:new Set,toolOverrides:new Map,resourceOverrides:new Map},p.set(e,n)),n}function O(e,n){let t=S(n);return E(e.hiddenByMiddlewares,e.name,t.toolOverrides,t.grants)}function k(e,n){let t=S(n);return E(e.hiddenByMiddlewares,e.uri,t.resourceOverrides,t.grants)}function _(e,n){let t=S(n);return E(e.hiddenByMiddlewares,e.name,t.toolOverrides,t.grants)}function M(e){(e&&y.get(e)||h).sendToolListChanged().catch(()=>{});}function x(e){(e&&y.get(e)||h).sendResourceListChanged().catch(()=>{});}function I(e){let n=S(e);return {get(t){return n.data.get(t)},set(t,s){n.data.set(t,s);},authorize(t){n.grants.add(t),M(e),x(e);},revoke(t){n.grants.delete(t),M(e),x(e);},enableTools(...t){for(let s of t)n.toolOverrides.set(s,"enabled");M(e);},disableTools(...t){for(let s of t)n.toolOverrides.set(s,"disabled");M(e);},enableResources(...t){for(let s of t)n.resourceOverrides.set(s,"enabled");x(e);},disableResources(...t){for(let s of t)n.resourceOverrides.set(s,"disabled");x(e);}}}function V(e){e.setRequestHandler(ListToolsRequestSchema,(n,t)=>{let s=t.sessionId??"default",r=[];for(let o of c.values())O(o,s)&&r.push({name:o.name,description:o.description,inputSchema:B(o.input)});for(let o of u.values())_(o,s)&&r.push({name:o.name,description:o.description,inputSchema:B(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=d=>({content:[{type:"text",text:d}],isError:true}),g=c.get(s);if(g){if(!O(g,o))return w(`Tool not available: ${s}`);let d=q(e,o,I(o),s,t.signal),v=()=>Promise.resolve(g.handler(r??{},d));return $(g.middlewares,d,v)()}let T=u.get(s);if(T){if(!_(T,o))return w(`Tool not available: ${s}`);let d=t.taskStore;if(!d)return w("Task store not available");let v=await d.createTask({pollInterval:1e3}),m=v.taskId,Y={progress(R,P){if(f.has(m))return;let te=P?`${R}% ${P}`:`${R}%`;d.updateTaskStatus(m,"working",te).catch(()=>{});},get cancelled(){return f.has(m)}},J={...q(e,o,I(o),s,t.signal),task:Y},ee=async()=>((async()=>{try{let R=await T.handler(r??{},J);f.has(m)||await d.storeTaskResult(m,"completed",R);}catch(R){if(!f.has(m)){let P=R instanceof Error?R.message:String(R);await d.storeTaskResult(m,"failed",{content:[{type:"text",text:P}],isError:true}).catch(()=>{});}}})(),{task:v});return $(T.middlewares,J,ee)()}return w(`Unknown tool: ${s}`)}),e.setRequestHandler(ListResourcesRequestSchema,(n,t)=>{let s=t.sessionId??"default",r=[];for(let o of i.values())!o.isTemplate&&k(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 i.values())o.isTemplate&&k(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=z(i,s);if(!r)throw new Error(`Unknown resource: ${s}`);let o=t.sessionId??"default";if(!k(r,o))throw new Error(`Resource not available: ${s}`);let w=I(o),g={uri:s,session:w,sessionId:o,roots:A(e)},T=q(e,o,w,r.uri,t.signal),d=async()=>{let m=await r.handler(s,g);return {contents:[{uri:s,mimeType:m.mimeType??r.mimeType,...m.text!=null?{text:m.text}:{},...m.blob!=null?{blob:m.blob}:{}}]}};return $(r.middlewares,T,d)()});}V(h);function F(e){l.push(e);}function G(...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.set(n,{name:n,description:s.description,input:s.input,handler:t.handler,middlewares:r,hiddenByMiddlewares:j(o,r)});}function D(...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("{");i.set(n,{uri:n,isTemplate:o,uriPattern:o?L(n):null,name:s.name,description:s.description,mimeType:s.mimeType,handler:t.handler,middlewares:t.middlewares,hiddenByMiddlewares:j(r,t.middlewares)});}function W(...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:j(o,r)});}async function Z(){let{StdioServerTransport:e}=await import('@modelcontextprotocol/sdk/server/stdio.js'),n=new e;await h.connect(n);}async function K(e){await h.connect(e);}let Q={tools:{listChanged:true},resources:{listChanged:true},tasks:{list:{},cancel:{},requests:{tools:{call:{}}}}};function U(){let e=new Server(a,{capabilities:Q,taskStore:C});return V(e),e}function X(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=U(),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 d=s.get(w);return d?d.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=U(),T=new o({sessionIdGenerator:e?.sessionIdGenerator??(()=>crypto.randomUUID()),enableJsonResponse:e?.enableJsonResponse,onsessioninitialized:d=>{s.set(d,{server:g,transport:T}),y.set(d,g);},onsessionclosed:d=>{s.delete(d),y.delete(d);}});return await g.connect(T),T.handleRequest(r)}}return {use:F,tool:G,resource:D,task:W,stdio:Z,http:X,connect:K,_server:h,_getSession:S,_isToolVisible(e,n){let t=c.get(e);return t?O(t,n):false},_isResourceVisible(e,n){let t=i.get(e);return t?k(t,n):false},_isTaskVisible(e,n){let t=u.get(e);return t?_(t,n):false},_createSessionAPI:I}}export{pe 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 { u as ToolMiddleware } from '../types-BqH9Me9B.js';
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
- interface AuthOptions {
6
- /** Session key to check for authentication. Default: "user" */
7
- sessionKey?: string;
8
- /** Error message when not authenticated. */
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 };
@@ -1 +1 @@
1
- function i(e){let t=e?.sessionKey??"user",s=e?.message??"Authentication required. Please login first.";return {name:"auth",onRegister(){return false},async onCall(n,r){return n.session.get(t)?r():{content:[{type:"text",text:s}],isError:true}}}}export{i as auth};
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
@@ -1,5 +1,5 @@
1
1
  import { CallToolResult } from '@modelcontextprotocol/sdk/types.js';
2
- import { m as Session, M as MCPServer } from './types-BqH9Me9B.js';
2
+ import { l as Session, M as MCPServer } from './types-CqT2idkd.js';
3
3
  import 'zod';
4
4
 
5
5
  interface TestClient {
@@ -1,6 +1,21 @@
1
- import { CreateMessageRequestParamsBase, CreateMessageResult, CallToolResult } from '@modelcontextprotocol/sdk/types.js';
1
+ import { CallToolResult, CreateMessageRequestParamsBase, CreateMessageResult } from '@modelcontextprotocol/sdk/types.js';
2
2
  import { z } from 'zod';
3
3
 
4
+ interface ToolResponse extends CallToolResult {
5
+ text(value: string): ToolResponse;
6
+ json(value: unknown): ToolResponse;
7
+ error(message: string): ToolResponse;
8
+ image(data: string, mimeType: string): ToolResponse;
9
+ }
10
+ /** Create a text response. Chainable. */
11
+ declare function text(value: string): ToolResponse;
12
+ /** Create a JSON response (serialized to text). Chainable. */
13
+ declare function json(value: unknown): ToolResponse;
14
+ /** Create an error response. Chainable. */
15
+ declare function error(message: string): ToolResponse;
16
+ /** Create an image response. Chainable. */
17
+ declare function image(data: string, mimeType: string): ToolResponse;
18
+
4
19
  interface ServerInfo {
5
20
  name: string;
6
21
  version: string;
@@ -23,31 +38,26 @@ interface Session {
23
38
  /** Disable specific resources by URI. */
24
39
  disableResources(...uris: string[]): void;
25
40
  }
26
- interface ElicitFormParams {
27
- message: string;
28
- schema: Record<string, {
29
- type: "string" | "number" | "boolean";
30
- description?: string;
31
- enum?: string[];
32
- default?: unknown;
33
- }>;
34
- }
35
- interface ElicitFormResult {
41
+ interface ElicitFormResult<T = Record<string, string | number | boolean | string[]>> {
36
42
  action: "accept" | "decline" | "cancel";
37
- content: Record<string, string | number | boolean | string[]>;
38
- }
39
- interface ElicitUrlParams {
40
- message: string;
41
- url: string;
43
+ content: T;
42
44
  }
43
45
  interface ElicitUrlResult {
44
46
  action: "accept" | "decline" | "cancel";
45
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
+ }
46
56
  interface Elicit {
47
57
  /** Request structured data from the user via a form. */
48
- form(params: ElicitFormParams): Promise<ElicitFormResult>;
58
+ form<T extends z.ZodObject<z.ZodRawShape>>(message: string, schema: T): Promise<ElicitFormResult<z.infer<T>>>;
49
59
  /** Direct the user to an external URL. */
50
- url(params: ElicitUrlParams): Promise<ElicitUrlResult>;
60
+ url(message: string, url: string, options?: ElicitUrlOptions): Promise<ElicitUrlResult>;
51
61
  }
52
62
  interface SampleOptions {
53
63
  maxTokens?: number;
@@ -86,6 +96,14 @@ interface ToolContext {
86
96
  roots: () => Promise<RootInfo[]>;
87
97
  /** Request LLM inference from the client. */
88
98
  sample: Sample;
99
+ /** Create a text response. Chainable. */
100
+ text(value: string): ToolResponse;
101
+ /** Create a JSON response. Chainable. */
102
+ json(value: unknown): ToolResponse;
103
+ /** Create an error response. Chainable. */
104
+ error(message: string): ToolResponse;
105
+ /** Create an image response. Chainable. */
106
+ image(data: string, mimeType: string): ToolResponse;
89
107
  }
90
108
  interface ToolInfo {
91
109
  name: string;
@@ -98,16 +116,16 @@ interface ToolMiddleware {
98
116
  /** Called when a tool is registered. Return false to hide the tool initially. */
99
117
  onRegister?(tool: ToolInfo): boolean | undefined;
100
118
  /** Called when a tool is invoked. Must call next() to continue the chain. */
101
- onCall?(ctx: ToolContext, next: () => Promise<CallToolResult>): Promise<CallToolResult>;
119
+ onCall?(c: ToolContext, next: () => Promise<CallToolResult>): Promise<CallToolResult>;
102
120
  /** Called after the handler returns. Runs in reverse middleware order. */
103
- onResult?(result: CallToolResult, ctx: ToolContext): CallToolResult | Promise<CallToolResult>;
121
+ onResult?(result: CallToolResult, c: ToolContext): CallToolResult | Promise<CallToolResult>;
104
122
  }
105
123
  type InferInput<T> = T extends z.ZodTypeAny ? z.output<T> : Record<string, unknown>;
106
124
  interface ToolConfig<TInput = unknown> {
107
125
  description?: string;
108
126
  input?: TInput;
109
127
  }
110
- type ToolHandler<TInput = unknown> = (args: InferInput<TInput>, ctx: ToolContext) => CallToolResult | Promise<CallToolResult>;
128
+ type ToolHandler<TInput = unknown> = (args: InferInput<TInput>, c: ToolContext) => CallToolResult | Promise<CallToolResult>;
111
129
  /** @experimental */
112
130
  interface TaskConfig<TInput = unknown> {
113
131
  description?: string;
@@ -125,7 +143,7 @@ interface TaskContext extends ToolContext {
125
143
  task: TaskControl;
126
144
  }
127
145
  /** @experimental */
128
- type TaskHandler<TInput = unknown> = (args: InferInput<TInput>, ctx: TaskContext) => CallToolResult | Promise<CallToolResult>;
146
+ type TaskHandler<TInput = unknown> = (args: InferInput<TInput>, c: TaskContext) => CallToolResult | Promise<CallToolResult>;
129
147
  interface ResourceConfig {
130
148
  name: string;
131
149
  description?: string;
@@ -143,7 +161,7 @@ interface ResourceContext {
143
161
  /** Query client-provided filesystem roots. */
144
162
  roots: () => Promise<RootInfo[]>;
145
163
  }
146
- type ResourceHandler = (uri: string, ctx: ResourceContext) => ResourceContent | Promise<ResourceContent>;
164
+ type ResourceHandler = (uri: string, c: ResourceContext) => ResourceContent | Promise<ResourceContent>;
147
165
  interface HttpAdapterOptions {
148
166
  /** Disable session management. Default: false. */
149
167
  sessionless?: boolean;
@@ -151,6 +169,8 @@ interface HttpAdapterOptions {
151
169
  sessionIdGenerator?: () => string;
152
170
  /** Return JSON instead of SSE streams. Default: false. */
153
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>;
154
174
  }
155
175
  interface MCPServer {
156
176
  /** Register a global middleware applied to all subsequently registered tools. */
@@ -171,6 +191,10 @@ interface MCPServer {
171
191
  stdio(): Promise<void>;
172
192
  /** Start HTTP transport. Returns a Web Standard request handler. */
173
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;
174
198
  }
175
199
 
176
- export type { Elicit as E, HttpAdapterOptions as H, MCPServer as M, ResourceConfig as R, Sample as S, TaskConfig as T, ElicitFormParams as a, ElicitFormResult as b, ElicitUrlParams as c, ElicitUrlResult as d, ResourceContent as e, ResourceContext as f, ResourceHandler as g, RootInfo as h, SampleOptions as i, SampleRawParams as j, SampleRawResult as k, ServerInfo as l, Session as m, TaskContext as n, TaskControl as o, TaskHandler as p, ToolConfig as q, ToolContext as r, ToolHandler as s, ToolInfo as t, ToolMiddleware as u };
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.2.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": {