@ggui-ai/mcp-server 0.1.0-rc.1
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/LICENSE +201 -0
- package/README.md +48 -0
- package/dist/admin-blueprints-transport.d.ts +114 -0
- package/dist/admin-blueprints-transport.d.ts.map +1 -0
- package/dist/admin-blueprints-transport.js +118 -0
- package/dist/admin-oauth-providers-transport.d.ts +40 -0
- package/dist/admin-oauth-providers-transport.d.ts.map +1 -0
- package/dist/admin-oauth-providers-transport.js +263 -0
- package/dist/auth.d.ts +39 -0
- package/dist/auth.d.ts.map +1 -0
- package/dist/auth.js +75 -0
- package/dist/build-mcp.d.ts +128 -0
- package/dist/build-mcp.d.ts.map +1 -0
- package/dist/build-mcp.js +113 -0
- package/dist/code-store-fs.d.ts +19 -0
- package/dist/code-store-fs.d.ts.map +1 -0
- package/dist/code-store-fs.js +98 -0
- package/dist/console-auth.d.ts +139 -0
- package/dist/console-auth.d.ts.map +1 -0
- package/dist/console-auth.js +102 -0
- package/dist/console-cache.d.ts +78 -0
- package/dist/console-cache.d.ts.map +1 -0
- package/dist/console-cache.js +105 -0
- package/dist/console-headers.d.ts +124 -0
- package/dist/console-headers.d.ts.map +1 -0
- package/dist/console-headers.js +49 -0
- package/dist/console-llm-trace.d.ts +66 -0
- package/dist/console-llm-trace.d.ts.map +1 -0
- package/dist/console-llm-trace.js +105 -0
- package/dist/console-payloads.d.ts +67 -0
- package/dist/console-payloads.d.ts.map +1 -0
- package/dist/console-payloads.js +105 -0
- package/dist/console-theme-routes.d.ts +111 -0
- package/dist/console-theme-routes.d.ts.map +1 -0
- package/dist/console-theme-routes.js +202 -0
- package/dist/console-timeline.d.ts +45 -0
- package/dist/console-timeline.d.ts.map +1 -0
- package/dist/console-timeline.js +169 -0
- package/dist/console-validator.d.ts +67 -0
- package/dist/console-validator.d.ts.map +1 -0
- package/dist/console-validator.js +105 -0
- package/dist/console-welcome.d.ts +7 -0
- package/dist/console-welcome.d.ts.map +1 -0
- package/dist/console-welcome.js +221 -0
- package/dist/csrf-middleware.d.ts +55 -0
- package/dist/csrf-middleware.d.ts.map +1 -0
- package/dist/csrf-middleware.js +138 -0
- package/dist/email-login.d.ts +174 -0
- package/dist/email-login.d.ts.map +1 -0
- package/dist/email-login.js +254 -0
- package/dist/email-resend.d.ts +29 -0
- package/dist/email-resend.d.ts.map +1 -0
- package/dist/email-resend.js +71 -0
- package/dist/email-sender-from-env.d.ts +34 -0
- package/dist/email-sender-from-env.d.ts.map +1 -0
- package/dist/email-sender-from-env.js +112 -0
- package/dist/email-smtp.d.ts +42 -0
- package/dist/email-smtp.d.ts.map +1 -0
- package/dist/email-smtp.js +81 -0
- package/dist/index.d.ts +102 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +122 -0
- package/dist/instructions-presets.d.ts +112 -0
- package/dist/instructions-presets.d.ts.map +1 -0
- package/dist/instructions-presets.js +195 -0
- package/dist/llm-backed-negotiator.d.ts +178 -0
- package/dist/llm-backed-negotiator.d.ts.map +1 -0
- package/dist/llm-backed-negotiator.js +579 -0
- package/dist/logger.d.ts +23 -0
- package/dist/logger.d.ts.map +1 -0
- package/dist/logger.js +41 -0
- package/dist/mcp-apps-inbound.d.ts +86 -0
- package/dist/mcp-apps-inbound.d.ts.map +1 -0
- package/dist/mcp-apps-inbound.js +278 -0
- package/dist/mcp-apps-outbound.d.ts +448 -0
- package/dist/mcp-apps-outbound.d.ts.map +1 -0
- package/dist/mcp-apps-outbound.js +1163 -0
- package/dist/mcp-mounts.d.ts +239 -0
- package/dist/mcp-mounts.d.ts.map +1 -0
- package/dist/mcp-mounts.js +222 -0
- package/dist/oauth-login-types.d.ts +160 -0
- package/dist/oauth-login-types.d.ts.map +1 -0
- package/dist/oauth-login-types.js +9 -0
- package/dist/oauth-login.d.ts +77 -0
- package/dist/oauth-login.d.ts.map +1 -0
- package/dist/oauth-login.js +455 -0
- package/dist/oauth-providers/github.d.ts +17 -0
- package/dist/oauth-providers/github.d.ts.map +1 -0
- package/dist/oauth-providers/github.js +89 -0
- package/dist/oauth-providers/google.d.ts +18 -0
- package/dist/oauth-providers/google.d.ts.map +1 -0
- package/dist/oauth-providers/google.js +59 -0
- package/dist/oauth-providers-store.d.ts +32 -0
- package/dist/oauth-providers-store.d.ts.map +1 -0
- package/dist/oauth-providers-store.js +291 -0
- package/dist/oauth.d.ts +347 -0
- package/dist/oauth.d.ts.map +1 -0
- package/dist/oauth.js +686 -0
- package/dist/pairing-transport.d.ts +99 -0
- package/dist/pairing-transport.d.ts.map +1 -0
- package/dist/pairing-transport.js +223 -0
- package/dist/rate-limit-middleware.d.ts +36 -0
- package/dist/rate-limit-middleware.d.ts.map +1 -0
- package/dist/rate-limit-middleware.js +57 -0
- package/dist/render-gate.d.ts +87 -0
- package/dist/render-gate.d.ts.map +1 -0
- package/dist/render-gate.js +77 -0
- package/dist/render-rate-limit.d.ts +59 -0
- package/dist/render-rate-limit.d.ts.map +1 -0
- package/dist/render-rate-limit.js +73 -0
- package/dist/render-signing.d.ts +98 -0
- package/dist/render-signing.d.ts.map +1 -0
- package/dist/render-signing.js +113 -0
- package/dist/request-context.d.ts +113 -0
- package/dist/request-context.d.ts.map +1 -0
- package/dist/request-context.js +154 -0
- package/dist/reserved-validators.d.ts +22 -0
- package/dist/reserved-validators.d.ts.map +1 -0
- package/dist/reserved-validators.js +101 -0
- package/dist/schema-compat.d.ts +167 -0
- package/dist/schema-compat.d.ts.map +1 -0
- package/dist/schema-compat.js +187 -0
- package/dist/security-headers-middleware.d.ts +38 -0
- package/dist/security-headers-middleware.d.ts.map +1 -0
- package/dist/security-headers-middleware.js +30 -0
- package/dist/server.d.ts +2060 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +6338 -0
- package/dist/session-channel.d.ts +651 -0
- package/dist/session-channel.d.ts.map +1 -0
- package/dist/session-channel.js +1756 -0
- package/dist/storage.d.ts +89 -0
- package/dist/storage.d.ts.map +1 -0
- package/dist/storage.js +171 -0
- package/dist/thread-transport.d.ts +118 -0
- package/dist/thread-transport.d.ts.map +1 -0
- package/dist/thread-transport.js +478 -0
- package/dist/user-session-auth.d.ts +167 -0
- package/dist/user-session-auth.d.ts.map +1 -0
- package/dist/user-session-auth.js +148 -0
- package/package.json +76 -0
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cookie name. Distinct from `ggui_console_session` so cross-kind
|
|
3
|
+
* confusion is impossible — a cookie value never gets misinterpreted
|
|
4
|
+
* as a different auth artifact. Change carries a compat concern (the
|
|
5
|
+
* `/login` mint endpoint, `cookieAuthMiddleware`, and `/logout` clear
|
|
6
|
+
* read this exact name); keep this export as the single source of
|
|
7
|
+
* truth.
|
|
8
|
+
*/
|
|
9
|
+
export const USER_SESSION_COOKIE_NAME = 'ggui_user_session';
|
|
10
|
+
/**
|
|
11
|
+
* Default cookie TTL (seconds). 8 hours mirrors the console session
|
|
12
|
+
* cookie default — operators leaving a tab open for a workday don't
|
|
13
|
+
* get re-prompted, but a stale cookie on a forgotten device expires
|
|
14
|
+
* before it ages further. Operators wanting longer sessions pass
|
|
15
|
+
* `ttlSec` at mount time.
|
|
16
|
+
*/
|
|
17
|
+
export const DEFAULT_USER_SESSION_TTL_SEC = 8 * 60 * 60;
|
|
18
|
+
/**
|
|
19
|
+
* Format the `Set-Cookie` header value. Caller does
|
|
20
|
+
* `res.setHeader('Set-Cookie', formatUserSessionCookieHeader(...))`.
|
|
21
|
+
*
|
|
22
|
+
* The bearer is URL-encoded so values containing `;` / `,` / `=`
|
|
23
|
+
* survive the cookie wire format. `extractUserSessionCookie` decodes
|
|
24
|
+
* symmetrically.
|
|
25
|
+
*/
|
|
26
|
+
export function formatUserSessionCookieHeader(input) {
|
|
27
|
+
const ttlSec = input.ttlSec ?? DEFAULT_USER_SESSION_TTL_SEC;
|
|
28
|
+
const attrs = [
|
|
29
|
+
`${USER_SESSION_COOKIE_NAME}=${encodeURIComponent(input.bearer)}`,
|
|
30
|
+
`Path=${input.path ?? '/'}`,
|
|
31
|
+
`Max-Age=${ttlSec}`,
|
|
32
|
+
`SameSite=${input.sameSite ?? 'Lax'}`,
|
|
33
|
+
`HttpOnly`,
|
|
34
|
+
];
|
|
35
|
+
if (input.secure)
|
|
36
|
+
attrs.push('Secure');
|
|
37
|
+
return attrs.join('; ');
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Format a `Set-Cookie` header that immediately invalidates the
|
|
41
|
+
* user-session cookie. Used by `/logout` and `/revoke-bearer` so the
|
|
42
|
+
* browser drops it without waiting for `Max-Age`.
|
|
43
|
+
*
|
|
44
|
+
* `Max-Age=0` is the canonical clear pattern; matching attrs (Path,
|
|
45
|
+
* Secure) are required so the browser pairs this with the original
|
|
46
|
+
* mint and replaces it.
|
|
47
|
+
*/
|
|
48
|
+
export function formatClearUserSessionCookieHeader(input) {
|
|
49
|
+
const attrs = [
|
|
50
|
+
`${USER_SESSION_COOKIE_NAME}=`,
|
|
51
|
+
`Path=${input.path ?? '/'}`,
|
|
52
|
+
`Max-Age=0`,
|
|
53
|
+
`SameSite=${input.sameSite ?? 'Lax'}`,
|
|
54
|
+
`HttpOnly`,
|
|
55
|
+
];
|
|
56
|
+
if (input.secure)
|
|
57
|
+
attrs.push('Secure');
|
|
58
|
+
return attrs.join('; ');
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Read the user-session cookie value from a `Cookie` header string.
|
|
62
|
+
* Returns the URL-decoded bearer, or `null` when the cookie is absent
|
|
63
|
+
* / malformed.
|
|
64
|
+
*
|
|
65
|
+
* Manual parser — same shape as `extractDevtoolCookie`. Tolerant of
|
|
66
|
+
* multi-cookie headers (`a=1; ggui_user_session=xyz; b=2`); rejects
|
|
67
|
+
* empty values rather than treating them as an authenticated bearer.
|
|
68
|
+
*/
|
|
69
|
+
export function extractUserSessionCookie(cookieHeader) {
|
|
70
|
+
if (!cookieHeader)
|
|
71
|
+
return null;
|
|
72
|
+
const pairs = cookieHeader.split(';');
|
|
73
|
+
for (const raw of pairs) {
|
|
74
|
+
const trimmed = raw.trim();
|
|
75
|
+
if (!trimmed)
|
|
76
|
+
continue;
|
|
77
|
+
const eq = trimmed.indexOf('=');
|
|
78
|
+
if (eq <= 0)
|
|
79
|
+
continue;
|
|
80
|
+
const name = trimmed.slice(0, eq);
|
|
81
|
+
if (name !== USER_SESSION_COOKIE_NAME)
|
|
82
|
+
continue;
|
|
83
|
+
const value = trimmed.slice(eq + 1);
|
|
84
|
+
if (!value)
|
|
85
|
+
return null;
|
|
86
|
+
try {
|
|
87
|
+
return decodeURIComponent(value);
|
|
88
|
+
}
|
|
89
|
+
catch {
|
|
90
|
+
// Malformed URL-encoding — treat as no cookie. The browser
|
|
91
|
+
// shouldn't produce this, but defensive.
|
|
92
|
+
return null;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
return null;
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Read the cookie off Node `IncomingHttpHeaders` directly. Thin
|
|
99
|
+
* wrapper for callers operating below Express (raw `IncomingMessage`,
|
|
100
|
+
* WebSocket upgrade).
|
|
101
|
+
*/
|
|
102
|
+
export function readUserSessionCookieFromHeaders(headers) {
|
|
103
|
+
const raw = headers['cookie'];
|
|
104
|
+
if (typeof raw === 'string')
|
|
105
|
+
return extractUserSessionCookie(raw);
|
|
106
|
+
return null;
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Express middleware that bridges the cookie → header path.
|
|
110
|
+
*
|
|
111
|
+
* When a request arrives WITHOUT an `Authorization` header but WITH a
|
|
112
|
+
* valid user-session cookie, the middleware synthesizes
|
|
113
|
+
* `Authorization: Bearer <cookie>` so every existing
|
|
114
|
+
* `resolveIdentity(auth, req)` call works transparently. No new auth
|
|
115
|
+
* codepath, no new gate logic.
|
|
116
|
+
*
|
|
117
|
+
* When the request already has an `Authorization` header, the cookie
|
|
118
|
+
* is ignored — the explicit header wins. This preserves the existing
|
|
119
|
+
* `/mcp` ingress posture (claude.ai's connector sends Authorization;
|
|
120
|
+
* the cookie does not interfere with it).
|
|
121
|
+
*
|
|
122
|
+
* Composition-time: mount BEFORE any gate that reads
|
|
123
|
+
* `req.headers['authorization']` (the `/ggui/console/llm-keys` gate,
|
|
124
|
+
* the `/mcp` ingress, etc.). Order matters — middleware runs
|
|
125
|
+
* top-to-bottom in the Express chain.
|
|
126
|
+
*/
|
|
127
|
+
export function cookieAuthMiddleware() {
|
|
128
|
+
return (req, _res, next) => {
|
|
129
|
+
if (req.headers['authorization']) {
|
|
130
|
+
next();
|
|
131
|
+
return;
|
|
132
|
+
}
|
|
133
|
+
const cookieValue = readUserSessionCookieFromHeaders(req.headers);
|
|
134
|
+
if (cookieValue) {
|
|
135
|
+
req.headers['authorization'] = `Bearer ${cookieValue}`;
|
|
136
|
+
}
|
|
137
|
+
next();
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* Read the user-session cookie off an Express request. Used by
|
|
142
|
+
* `/logout` to know whether there's anything to clear, by
|
|
143
|
+
* `/revoke-bearer` to identify the pairing to revoke, and by tests
|
|
144
|
+
* that need to inspect the cookie without going through middleware.
|
|
145
|
+
*/
|
|
146
|
+
export function readUserSessionCookie(req) {
|
|
147
|
+
return readUserSessionCookieFromHeaders(req.headers);
|
|
148
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@ggui-ai/mcp-server",
|
|
3
|
+
"version": "0.1.0-rc.1",
|
|
4
|
+
"description": "Self-hosted MCP server for the ggui protocol. An HTTP/MCP binding layer over @ggui-ai/mcp-server-handlers and the reference adapters from @ggui-ai/mcp-server-core — run it via `ggui serve`.",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"ggui",
|
|
7
|
+
"mcp",
|
|
8
|
+
"mcp-server",
|
|
9
|
+
"generative-ui",
|
|
10
|
+
"agent",
|
|
11
|
+
"self-hosted"
|
|
12
|
+
],
|
|
13
|
+
"license": "Apache-2.0",
|
|
14
|
+
"files": [
|
|
15
|
+
"dist",
|
|
16
|
+
"README.md"
|
|
17
|
+
],
|
|
18
|
+
"type": "module",
|
|
19
|
+
"main": "dist/index.js",
|
|
20
|
+
"types": "dist/index.d.ts",
|
|
21
|
+
"exports": {
|
|
22
|
+
".": {
|
|
23
|
+
"types": "./dist/index.d.ts",
|
|
24
|
+
"import": "./dist/index.js"
|
|
25
|
+
}
|
|
26
|
+
},
|
|
27
|
+
"dependencies": {
|
|
28
|
+
"@modelcontextprotocol/sdk": "^1.27.0",
|
|
29
|
+
"express": "^4.21.0",
|
|
30
|
+
"nodemailer": "^8.0.7",
|
|
31
|
+
"resend": "^6.12.2",
|
|
32
|
+
"ws": "^8.20.1",
|
|
33
|
+
"zod": "^4.3.6",
|
|
34
|
+
"@ggui-ai/console": "0.1.0-rc.1",
|
|
35
|
+
"@ggui-ai/mcp-server-core": "0.1.0-rc.1",
|
|
36
|
+
"@ggui-ai/mcp-server-handlers": "0.1.0-rc.1",
|
|
37
|
+
"@ggui-ai/negotiator": "0.1.0-rc.1",
|
|
38
|
+
"@ggui-ai/iframe-runtime": "0.1.0-rc.1",
|
|
39
|
+
"@ggui-ai/preview-a2ui": "0.1.0-rc.1",
|
|
40
|
+
"@ggui-ai/project-config": "0.1.0-rc.1",
|
|
41
|
+
"@ggui-ai/ui-registry": "0.1.0-rc.1",
|
|
42
|
+
"@ggui-ai/protocol": "0.1.0-rc.1",
|
|
43
|
+
"@ggui-ai/ui-gen": "0.1.0-rc.1"
|
|
44
|
+
},
|
|
45
|
+
"devDependencies": {
|
|
46
|
+
"@types/express": "^4.17.21",
|
|
47
|
+
"@types/node": "^22.0.0",
|
|
48
|
+
"@types/nodemailer": "^8.0.0",
|
|
49
|
+
"@types/ws": "^8.5.10",
|
|
50
|
+
"typescript": "^5.0.0",
|
|
51
|
+
"vitest": "^3.0.0"
|
|
52
|
+
},
|
|
53
|
+
"repository": {
|
|
54
|
+
"type": "git",
|
|
55
|
+
"url": "https://github.com/ggui-ai/ggui.git",
|
|
56
|
+
"directory": "packages/mcp-server"
|
|
57
|
+
},
|
|
58
|
+
"homepage": "https://github.com/ggui-ai/ggui/tree/main/packages/mcp-server",
|
|
59
|
+
"bugs": {
|
|
60
|
+
"url": "https://github.com/ggui-ai/ggui/issues"
|
|
61
|
+
},
|
|
62
|
+
"publishConfig": {
|
|
63
|
+
"access": "public"
|
|
64
|
+
},
|
|
65
|
+
"engines": {
|
|
66
|
+
"node": ">=20.0.0"
|
|
67
|
+
},
|
|
68
|
+
"author": "ggui contributors <hello@ggui.ai>",
|
|
69
|
+
"scripts": {
|
|
70
|
+
"build": "tsc -p tsconfig.build.json && node ../scripts/fix-esm-imports.mjs dist",
|
|
71
|
+
"dev": "tsc --watch",
|
|
72
|
+
"typecheck": "tsc --noEmit",
|
|
73
|
+
"test": "vitest run",
|
|
74
|
+
"test:watch": "vitest"
|
|
75
|
+
}
|
|
76
|
+
}
|