@chaindaddy/mcp 0.6.9 → 0.6.11

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@chaindaddy/mcp",
3
- "version": "0.6.9",
3
+ "version": "0.6.11",
4
4
  "description": "MCP server for Chain Daddy: search tickers, launch a token or verify ownership of one, and run its creator store",
5
5
  "mcpName": "io.chaindaddy/mcp",
6
6
  "homepage": "https://docs.chaindaddy.io/developer/store-and-rewards#tools-for-agents",
@@ -27,7 +27,7 @@ Use discovery: `https://api.chaindaddy.io/.well-known/openid-configuration`
27
27
 
28
28
  Any site can sign people in without registering anything.
29
29
 
30
- Replace `YOUR_SITE` with the site's https origin. Nothing is registered with Chain Daddy. The origin must be public, even while you build (a tunnel such as `cloudflared tunnel --url http://localhost:3000`, which needs no account, or a preview deployment): Chain Daddy's server fetches `client.json`, so `localhost` cannot be a client id.
30
+ Replace `YOUR_SITE` with the site's host, such as `example.com`. Nothing is registered with Chain Daddy. The site must be public, on https: Chain Daddy's server fetches `client.json`, so `localhost` cannot be your own client id. To build on `http://localhost` first with nothing hosted, use the built-in development client: skip `client.json`, set the button's `client-id` to `chaindaddy-dev` and its `redirect-uri` to `http://localhost:3000/callback.html`, and set the server's `audience` to `'chaindaddy-dev'`. It asks every time, its `sub` matches no real site's, and it answers nothing about holdings or crowns, so put your own values back before you ship. To try your real `client.json` or a coin gate before the site is live, use a tunnel such as `cloudflared tunnel --url http://localhost:3000`, which needs no account, or a preview deployment.
31
31
 
32
32
  1. Host this at `https://YOUR_SITE/client.json` (served 200, no redirect; `client_id` must equal its own URL):
33
33
 
@@ -111,9 +111,15 @@ async function verifyChainDaddy(idToken) {
111
111
  return payload; // sub: the person's id at this site; wallets[0]: the wallet they signed in with
112
112
  }
113
113
 
114
- // Your own sessions, by the id in the cookie. A real deployment keeps these in its session store or Redis.
114
+ // Your own sessions, by the id in the cookie, for a day. A real deployment keeps these in its session store or Redis.
115
115
  const sessions = new Map();
116
- const sessionOf = (req) => sessions.get(/(?:^|; )session=([^;]+)/.exec(req.headers.cookie ?? '')?.[1] ?? '');
116
+ const DAY = 24 * 60 * 60 * 1000;
117
+ const sessionId = (req) => /(?:^|; )session=([^;]+)/.exec(req.headers.cookie ?? '')?.[1] ?? '';
118
+ const sessionOf = (req) => {
119
+ const user = sessions.get(sessionId(req));
120
+ if (user && user.expires > Date.now()) return user;
121
+ sessions.delete(sessionId(req));
122
+ };
117
123
 
118
124
  const app = express();
119
125
  app.use(express.json());
@@ -127,8 +133,8 @@ app.post('/session', async (req, res) => {
127
133
  return res.status(401).json({ error: 'sign_in_failed', message: 'That sign-in could not be checked. Sign in again.' });
128
134
  }
129
135
  const id = randomUUID();
130
- sessions.set(id, { sub: payload.sub, wallet: payload.wallets?.[0] });
131
- res.cookie('session', id, { httpOnly: true, secure: true, sameSite: 'lax' });
136
+ sessions.set(id, { sub: payload.sub, wallet: payload.wallets?.[0], expires: Date.now() + DAY });
137
+ res.cookie('session', id, { httpOnly: true, secure: req.hostname !== 'localhost', sameSite: 'lax', maxAge: DAY });
132
138
  res.json({ ok: true });
133
139
  });
134
140
 
@@ -158,7 +164,7 @@ export function holdsCoin(payload) {
158
164
  }
159
165
  ```
160
166
 
161
- In `POST /session`, keep the answer in the session: `sessions.set(id, { sub: payload.sub, wallet: payload.wallets?.[0], holder: holdsCoin(payload) });`. Then add the holders' route:
167
+ In `POST /session`, keep the answer in the session: `sessions.set(id, { sub: payload.sub, wallet: payload.wallets?.[0], holder: holdsCoin(payload), expires: Date.now() + DAY });`. Then add the holders' route:
162
168
 
163
169
  ```js
164
170
  // Only a holder gets this. Everyone else stays signed in and is told why not.