@kajidog/connpass-mcp-server 0.1.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 (68) hide show
  1. package/LICENCE +21 -0
  2. package/README.md +190 -0
  3. package/dist/apps-sdk.d.ts +8 -0
  4. package/dist/apps-sdk.d.ts.map +1 -0
  5. package/dist/apps-sdk.js +77 -0
  6. package/dist/apps-sdk.js.map +1 -0
  7. package/dist/auth/jwt.d.ts +23 -0
  8. package/dist/auth/jwt.d.ts.map +1 -0
  9. package/dist/auth/jwt.js +143 -0
  10. package/dist/auth/jwt.js.map +1 -0
  11. package/dist/config.d.ts +5 -0
  12. package/dist/config.d.ts.map +1 -0
  13. package/dist/config.js +60 -0
  14. package/dist/config.js.map +1 -0
  15. package/dist/index.d.ts +3 -0
  16. package/dist/index.d.ts.map +1 -0
  17. package/dist/index.js +178 -0
  18. package/dist/index.js.map +1 -0
  19. package/dist/session.d.ts +9 -0
  20. package/dist/session.d.ts.map +1 -0
  21. package/dist/session.js +58 -0
  22. package/dist/session.js.map +1 -0
  23. package/dist/tools/events.d.ts +82 -0
  24. package/dist/tools/events.d.ts.map +1 -0
  25. package/dist/tools/events.js +390 -0
  26. package/dist/tools/events.js.map +1 -0
  27. package/dist/tools/formatting.d.ts +74 -0
  28. package/dist/tools/formatting.d.ts.map +1 -0
  29. package/dist/tools/formatting.js +211 -0
  30. package/dist/tools/formatting.js.map +1 -0
  31. package/dist/tools/groups.d.ts +48 -0
  32. package/dist/tools/groups.d.ts.map +1 -0
  33. package/dist/tools/groups.js +115 -0
  34. package/dist/tools/groups.js.map +1 -0
  35. package/dist/tools/index.d.ts +58 -0
  36. package/dist/tools/index.d.ts.map +1 -0
  37. package/dist/tools/index.js +21 -0
  38. package/dist/tools/index.js.map +1 -0
  39. package/dist/tools/shared.d.ts +24 -0
  40. package/dist/tools/shared.d.ts.map +1 -0
  41. package/dist/tools/shared.js +136 -0
  42. package/dist/tools/shared.js.map +1 -0
  43. package/dist/tools/users.d.ts +51 -0
  44. package/dist/tools/users.d.ts.map +1 -0
  45. package/dist/tools/users.js +252 -0
  46. package/dist/tools/users.js.map +1 -0
  47. package/dist/transports/http.d.ts +17 -0
  48. package/dist/transports/http.d.ts.map +1 -0
  49. package/dist/transports/http.js +166 -0
  50. package/dist/transports/http.js.map +1 -0
  51. package/dist/transports/sse.d.ts +21 -0
  52. package/dist/transports/sse.d.ts.map +1 -0
  53. package/dist/transports/sse.js +153 -0
  54. package/dist/transports/sse.js.map +1 -0
  55. package/dist/transports/stdio.d.ts +38 -0
  56. package/dist/transports/stdio.d.ts.map +1 -0
  57. package/dist/transports/stdio.js +29 -0
  58. package/dist/transports/stdio.js.map +1 -0
  59. package/dist/widgets/connpass-events.d.ts +29 -0
  60. package/dist/widgets/connpass-events.d.ts.map +1 -0
  61. package/dist/widgets/connpass-events.html +2269 -0
  62. package/dist/widgets/connpass-events.js +58 -0
  63. package/dist/widgets/connpass-events.js.map +1 -0
  64. package/dist/widgets/index.d.ts +6 -0
  65. package/dist/widgets/index.d.ts.map +1 -0
  66. package/dist/widgets/index.js +31 -0
  67. package/dist/widgets/index.js.map +1 -0
  68. package/package.json +58 -0
package/LICENCE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 kajidog
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,190 @@
1
+ # Connpass MCP Server
2
+
3
+ Connpass MCP Server は、MCP (Model Context Protocol) 経由で Connpass API を扱うためのツール群です。AI やエージェントが理解しやすいパラメータ設計になっており、自然言語に近い入力でイベント・グループ・ユーザー情報を取得できます。
4
+
5
+ ## セットアップ
6
+
7
+ 1. 依存関係をインストールします。
8
+
9
+ ```bash
10
+ pnpm install
11
+ ```
12
+
13
+ 2. ビルドして利用可能な状態にします。
14
+
15
+ ```bash
16
+ pnpm --filter @kajidog/connpass-mcp-server build
17
+ ```
18
+
19
+ 3. Connpass API キーを環境変数で指定してサーバーを起動します。
20
+
21
+ ```bash
22
+ CONNPASS_API_KEY=あなたのAPIキー pnpm --filter @kajidog/connpass-mcp-server start
23
+ ```
24
+
25
+ > ローカル開発時などで API キーが未設定の場合、`dummy-key` が自動で使用されます。
26
+
27
+ 必要に応じて、デフォルトで参照するユーザー ID を `CONNPASS_DEFAULT_USER_ID` に設定できます。`get_my_upcoming_events` ツールで `userId` を省略した場合に利用されます。
28
+
29
+ ## トランスポート方式
30
+
31
+ Connpass MCP Server は2つのトランスポート方式に対応しています。
32
+
33
+ ### HTTP (Streamable HTTP) - デフォルト
34
+
35
+ デフォルトのトランスポート方式です。HTTPリクエスト/レスポンスベースで通信します。
36
+
37
+ ```bash
38
+ # デフォルトで HTTP トランスポートを使用 (ポート 3000)
39
+ connpass-mcp-server
40
+
41
+ # ポートを指定
42
+ connpass-mcp-server --port 8080
43
+ connpass-mcp-server -p 8080
44
+
45
+ # 明示的に HTTP トランスポートを指定
46
+ connpass-mcp-server --transport http
47
+ connpass-mcp-server -t http
48
+ ```
49
+
50
+ ### SSE (Server-Sent Events)
51
+
52
+ Server-Sent Events を使用した双方向通信です。
53
+
54
+ ```bash
55
+ # SSE トランスポートを使用
56
+ connpass-mcp-server --transport sse
57
+
58
+ # ポートを指定
59
+ connpass-mcp-server --transport sse --port 8080
60
+ connpass-mcp-server -t sse -p 8080
61
+ ```
62
+
63
+ ### コマンドラインオプション
64
+
65
+ ```
66
+ Usage: connpass-mcp-server [options]
67
+
68
+ Options:
69
+ -t, --transport <type> Transport type: http or sse (default: http)
70
+ -p, --port <number> Port number for http/sse transports (default: 3000)
71
+ -h, --help Show this help message
72
+
73
+ Examples:
74
+ connpass-mcp-server # Start with HTTP transport on port 3000
75
+ connpass-mcp-server --transport sse --port 8080 # Start with SSE transport on port 8080
76
+ connpass-mcp-server -t http -p 5000 # Start with HTTP transport on port 5000
77
+ ```
78
+
79
+ > **注意:** `PORT` および `MCP_TRANSPORT` 環境変数を設定することでも、ポートやトランスポート方式を変更できます。コマンドライン引数よりも環境変数が優先されます。
80
+
81
+ ### 環境変数一覧
82
+
83
+ | 変数名 | 説明 | 既定値 |
84
+ | --- | --- | --- |
85
+ | `CONNPASS_API_KEY` | Connpass API Key。未設定の場合は `dummy-key` が使われます(本番利用不可)。 | `dummy-key` |
86
+ | `CONNPASS_DEFAULT_USER_ID` | `get_my_upcoming_events` で `userId` を省略したときに使うユーザー ID。 | 未設定 |
87
+ | `CONNPASS_INCLUDE_PRESENTATIONS_DEFAULT` | `get_my_upcoming_events` の `includePresentations` の既定値。`true/false` や `1/0` などで指定。 | 未設定(false と同等) |
88
+ | `CONNPASS_PRESENTATION_CACHE_ENABLED` | プレゼンテーション取得結果をディスクキャッシュするかどうか。 | `true` |
89
+ | `CONNPASS_PRESENTATION_CACHE_TTL_MS` | キャッシュ保持期間(ミリ秒)。 | `3600000` |
90
+ | `CONNPASS_PRESENTATION_CACHE_PATH` | キャッシュファイルの保存先パス。 | `./data/presentation-cache.json` |
91
+ | `CONNPASS_ENABLE_APPS_SDK_OUTPUT` | Apps SDK 互換の `structuredContent` をツール応答に含めるかどうか。`true/false` や `1/0` などで指定。 | `false` |
92
+ | `MCP_BASE_PATH` | MCP エンドポイントのベースパス。リバースプロキシで `/mcp` を `/` に転送する場合などに `/` を指定。(SSE トランスポートのみ) | `/mcp` |
93
+ | `MCP_TRANSPORT` | トランスポート方式 (`http`, `sse`)。コマンドライン引数より優先されます。 | 未設定 |
94
+ | `PORT` | サーバーのポート番号 (http, sse トランスポートのみ)。コマンドライン引数より優先されます。 | `3000` |
95
+
96
+ ## ツール一覧
97
+
98
+ | ツール名 | 説明 | 主な入力フィールド |
99
+ | --- | --- | --- |
100
+ | `search_events` | 自然言語の日付やキーワードでイベントを検索 | `query`, `anyQuery`, `on`, `from`, `to`, `participantNickname`, `hostNickname`, `groupIds`, `prefectures`, `page`, `pageSize`, `sort` |
101
+ | `get_event_presentations` | 指定イベントの発表情報を取得 | `eventId` |
102
+ | `search_groups` | グループをキーワードや所在地で検索 | `query`, `groupIds`, `country`, `prefecture`, `page`, `pageSize`, `sort` |
103
+ | `search_users` | ニックネームなどでユーザーを検索 | `nickname`, `userIds`, `page`, `pageSize`, `sort` |
104
+ | `get_user_groups` | 指定ユーザーが所属するグループ一覧 | `userId`, `limit`, `page` |
105
+ | `get_user_attended_events` | 指定ユーザーが参加したイベント一覧 | `userId`, `limit`, `page`, `sort` |
106
+ | `get_user_presenter_events` | 指定ユーザーが登壇したイベント一覧 | `userId`, `limit`, `page`, `sort` |
107
+ | `get_my_upcoming_events` | 今日と指定期間内のイベントを取得(自分の ID を自動使用可能) | `userId`, `nickname`, `daysAhead`, `maxEvents`, `includePresentations` |
108
+
109
+ ## シンプルな使い方
110
+
111
+ ### イベント検索(例)
112
+
113
+ ```json
114
+ {
115
+ "name": "search_events",
116
+ "arguments": {
117
+ "query": "React 勉強会",
118
+ "from": "next Monday",
119
+ "to": "next Friday",
120
+ "prefectures": "東京都",
121
+ "sort": "start-date-asc"
122
+ }
123
+ }
124
+ ```
125
+
126
+ - 日付は `"2024-05-01"` のような ISO 形式に加えて、`today` / `tomorrow` / `next Monday` などの自然言語も指定できます。
127
+ - `prefectures` や `on` は単一文字列でも配列でも指定可能です。
128
+
129
+ ### グループ検索(例)
130
+
131
+ ```json
132
+ {
133
+ "name": "search_groups",
134
+ "arguments": {
135
+ "query": "AI",
136
+ "country": "JP",
137
+ "sort": "most-members"
138
+ }
139
+ }
140
+ ```
141
+
142
+ ### ユーザーの登壇イベント取得(例)
143
+
144
+ ```json
145
+ {
146
+ "name": "get_user_presenter_events",
147
+ "arguments": {
148
+ "userId": 123456,
149
+ "limit": 30,
150
+ "sort": "newly-added"
151
+ }
152
+ }
153
+ ```
154
+
155
+ ### 自分の今日・直近イベント取得(例)
156
+
157
+ ```json
158
+ {
159
+ "name": "get_my_upcoming_events",
160
+ "arguments": {
161
+ "nickname": "kajidog",
162
+ "daysAhead": 10,
163
+ "includePresentations": true
164
+ }
165
+ }
166
+ ```
167
+
168
+ - `userId` を省略すると、`CONNPASS_DEFAULT_USER_ID` 環境変数が使われます。
169
+ - `nickname` を指定すると、そのニックネームでユーザーを検索してイベントを取得します。`userId` と `nickname` の両方が指定された場合は `nickname` が優先されます。
170
+ - `includePresentations` を有効にすると、各イベントの発表詳細を個別に取得します( Connpass API は 1 秒あたり 1 リクエストのレートリミットなので、イベント数が多いと時間がかかります)。省略時は `CONNPASS_INCLUDE_PRESENTATIONS_DEFAULT` の設定が利用されます。
171
+
172
+ ## 返り値
173
+
174
+
175
+ `CONNPASS_ENABLE_APPS_SDK_OUTPUT` を `true` にすると、MCP の `call_tool` 応答へ OpenAI Apps SDK が扱いやすい `structuredContent` を追加します。Apps SDK 側では `toolOutput` として同じペイロードが受け取れるため、カスタム UI でデータをレンダリングしやすくなります。既存のテキスト出力は変わりません。
176
+
177
+ ### Apps SDK 向けウィジェット
178
+
179
+ - `search_events` または `get_my_upcoming_events` の実行結果には、Inline 表示のカルーセルとフルスクリーン詳細を切り替えられるウィジェットを付与できます。
180
+ - `CONNPASS_ENABLE_APPS_SDK_OUTPUT=true` を指定すると、`openai/outputTemplate` メタデータが `ui://connpass/widgets/events-carousel` を指し、Apps SDK 側で iframe がレンダリングされます。
181
+ - ウィジェットの HTML は `packages/mcp-server/src/widgets/connpass-events.html` に置いており、`pnpm --filter @kajidog/connpass-mcp-server build` 実行時に `dist/widgets/` へコピーされます。
182
+ - カルーセルでは参加者数バッジや Connpass への外部リンクを表示。`詳細を見る` ボタンを押すと `requestDisplayMode` API で全画面表示に切り替わり、イベント概要・発表セッション・外部リンクを閲覧できます。
183
+ - サーバーをサブパスで公開する場合は `MCP_BASE_PATH` を設定してください(例: リバースプロキシで `/mcp` を `/` にリライトする場合は `MCP_BASE_PATH=/`)。`GET ${MCP_BASE_PATH}` が SSE ストリーム、`${MCP_BASE_PATH}/messages` が POST エンドポイントになります。
184
+
185
+ ## 開発補助
186
+
187
+ - 型チェック: `pnpm --filter @kajidog/connpass-mcp-server typecheck`
188
+ - ウォッチビルド: `pnpm --filter @kajidog/connpass-mcp-server dev`
189
+
190
+ ツールの追加や更新を行った際は、`pnpm build` 実行後に README も更新して最新の引数仕様を反映するようにしてください。
@@ -0,0 +1,8 @@
1
+ import type { CallToolResult } from "@modelcontextprotocol/sdk/types.js";
2
+ export interface BuildCallToolResultOptions {
3
+ toolName: string;
4
+ result: unknown;
5
+ includeAppsSdkPayload: boolean;
6
+ }
7
+ export declare function buildCallToolResult(options: BuildCallToolResultOptions): CallToolResult;
8
+ //# sourceMappingURL=apps-sdk.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"apps-sdk.d.ts","sourceRoot":"","sources":["../src/apps-sdk.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oCAAoC,CAAC;AAezE,MAAM,WAAW,0BAA0B;IACzC,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,OAAO,CAAC;IAChB,qBAAqB,EAAE,OAAO,CAAC;CAChC;AAgCD,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,0BAA0B,GAAG,cAAc,CA2CvF"}
@@ -0,0 +1,77 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.buildCallToolResult = buildCallToolResult;
4
+ const index_js_1 = require("./widgets/index.js");
5
+ const TOOL_KIND_MAP = new Map([
6
+ ["search_events", "events"],
7
+ ["get_event_presentations", "event_presentations"],
8
+ ["get_my_upcoming_events", "events"],
9
+ ["search_groups", "groups"],
10
+ ["search_users", "users"],
11
+ ["get_user_groups", "groups"],
12
+ ["get_user_attended_events", "events"],
13
+ ["get_user_presenter_events", "events"],
14
+ ]);
15
+ function toDisplayText(result) {
16
+ if (typeof result === "string") {
17
+ return result;
18
+ }
19
+ if (result === undefined) {
20
+ return "Tool returned no data.";
21
+ }
22
+ try {
23
+ return JSON.stringify(result, null, 2);
24
+ }
25
+ catch (error) {
26
+ return `Failed to serialize tool output: ${error instanceof Error ? error.message : String(error)}`;
27
+ }
28
+ }
29
+ function inferResultKind(toolName) {
30
+ return TOOL_KIND_MAP.get(toolName) ?? "generic";
31
+ }
32
+ function buildStructuredContent(toolName, result) {
33
+ return {
34
+ app: "connpass",
35
+ tool: toolName,
36
+ kind: inferResultKind(toolName),
37
+ generatedAt: new Date().toISOString(),
38
+ data: result ?? null,
39
+ };
40
+ }
41
+ function buildCallToolResult(options) {
42
+ const { toolName, result, includeAppsSdkPayload } = options;
43
+ const templateUri = includeAppsSdkPayload ? (0, index_js_1.getWidgetTemplateForTool)(toolName) : undefined;
44
+ const contentItem = {
45
+ type: "text",
46
+ text: toDisplayText(result),
47
+ };
48
+ const base = { content: [contentItem] };
49
+ if (includeAppsSdkPayload) {
50
+ console.log(`[apps-sdk] tool=${toolName} includeAppsSdkPayload=true template=${templateUri ?? "<missing>"}`);
51
+ base.structuredContent = buildStructuredContent(toolName, result);
52
+ if (templateUri) {
53
+ // ★ 重要:content アイテム側にも _meta を付ける
54
+ contentItem._meta = {
55
+ ...(contentItem._meta ?? {}),
56
+ "openai/outputTemplate": templateUri,
57
+ "openai/resultCanProduceWidget": true,
58
+ "openai/widgetAccessible": true,
59
+ "openai/widgetCategory": "carousel",
60
+ };
61
+ // 互換性のため、従来通り top-level にも残しておく(不要なら削除OK)
62
+ base._meta = {
63
+ ...(base._meta ?? {}),
64
+ "openai/outputTemplate": templateUri,
65
+ "openai/resultCanProduceWidget": true,
66
+ "openai/widgetAccessible": true,
67
+ "openai/widgetCategory": "carousel",
68
+ };
69
+ console.log("[apps-sdk] widget meta", contentItem._meta);
70
+ }
71
+ else {
72
+ console.warn(`[apps-sdk] tool=${toolName} has no widget template mapping; UI will not render.`);
73
+ }
74
+ }
75
+ return base;
76
+ }
77
+ //# sourceMappingURL=apps-sdk.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"apps-sdk.js","sourceRoot":"","sources":["../src/apps-sdk.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,23 @@
1
+ export declare class JwtError extends Error {
2
+ constructor(message: string);
3
+ }
4
+ export interface JwtHeader extends Record<string, unknown> {
5
+ alg: string;
6
+ typ?: string;
7
+ }
8
+ export type JwtPayload = Record<string, unknown>;
9
+ export interface VerifyJwtOptions {
10
+ secret?: string;
11
+ issuer?: string;
12
+ audience?: string | string[];
13
+ clockToleranceSeconds?: number;
14
+ requireExpiration?: boolean;
15
+ }
16
+ export interface JwtVerificationResult {
17
+ header: JwtHeader;
18
+ payload: JwtPayload;
19
+ signatureValid: boolean;
20
+ }
21
+ export declare function verifyJwt(token: string, options: VerifyJwtOptions): JwtVerificationResult;
22
+ export declare function extractBearerToken(authorizationHeader: string | undefined): string | undefined;
23
+ //# sourceMappingURL=jwt.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"jwt.d.ts","sourceRoot":"","sources":["../../src/auth/jwt.ts"],"names":[],"mappings":"AAEA,qBAAa,QAAS,SAAQ,KAAK;gBACrB,OAAO,EAAE,MAAM;CAI5B;AAED,MAAM,WAAW,SAAU,SAAQ,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IACxD,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED,MAAM,MAAM,UAAU,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAEjD,MAAM,WAAW,gBAAgB;IAC/B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IAC7B,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B,iBAAiB,CAAC,EAAE,OAAO,CAAC;CAC7B;AAED,MAAM,WAAW,qBAAqB;IACpC,MAAM,EAAE,SAAS,CAAC;IAClB,OAAO,EAAE,UAAU,CAAC;IACpB,cAAc,EAAE,OAAO,CAAC;CACzB;AAyBD,wBAAgB,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,gBAAgB,GAAG,qBAAqB,CAoDzF;AA8DD,wBAAgB,kBAAkB,CAAC,mBAAmB,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,CAY9F"}
@@ -0,0 +1,143 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.JwtError = void 0;
4
+ exports.verifyJwt = verifyJwt;
5
+ exports.extractBearerToken = extractBearerToken;
6
+ const node_crypto_1 = require("node:crypto");
7
+ class JwtError extends Error {
8
+ constructor(message) {
9
+ super(message);
10
+ this.name = "JwtError";
11
+ }
12
+ }
13
+ exports.JwtError = JwtError;
14
+ function decodeBase64Url(input) {
15
+ const normalized = input.replace(/-/g, "+").replace(/_/g, "/");
16
+ const padLength = (4 - (normalized.length % 4)) % 4;
17
+ const padded = normalized + "=".repeat(padLength);
18
+ return Buffer.from(padded, "base64");
19
+ }
20
+ function parseJson(buffer, context) {
21
+ try {
22
+ const text = buffer.toString("utf8");
23
+ return JSON.parse(text);
24
+ }
25
+ catch (error) {
26
+ throw new JwtError(`Failed to parse JWT ${context}: ${error instanceof Error ? error.message : String(error)}`);
27
+ }
28
+ }
29
+ function ensureString(value, name) {
30
+ if (typeof value !== "string" || value.length === 0) {
31
+ throw new JwtError(`JWT ${name} must be a non-empty string`);
32
+ }
33
+ return value;
34
+ }
35
+ function verifyJwt(token, options) {
36
+ const parts = token.split(".");
37
+ if (parts.length !== 3) {
38
+ throw new JwtError("JWT must have three parts");
39
+ }
40
+ const [encodedHeader, encodedPayload, encodedSignature] = parts;
41
+ const signingInput = `${encodedHeader}.${encodedPayload}`;
42
+ const header = parseJson(decodeBase64Url(encodedHeader), "header");
43
+ if (!header || typeof header !== "object") {
44
+ throw new JwtError("JWT header is not an object");
45
+ }
46
+ const payload = parseJson(decodeBase64Url(encodedPayload), "payload");
47
+ if (!payload || typeof payload !== "object") {
48
+ throw new JwtError("JWT payload is not an object");
49
+ }
50
+ const algorithm = ensureString(header.alg, "algorithm");
51
+ const secret = options.secret?.trim();
52
+ let signatureValid = false;
53
+ if (secret) {
54
+ if (algorithm !== "HS256") {
55
+ throw new JwtError(`Unsupported JWT algorithm: ${algorithm}`);
56
+ }
57
+ const expectedSignature = (0, node_crypto_1.createHmac)("sha256", secret).update(signingInput).digest();
58
+ const receivedSignature = decodeBase64Url(encodedSignature);
59
+ if (expectedSignature.length !== receivedSignature.length) {
60
+ signatureValid = false;
61
+ }
62
+ else {
63
+ signatureValid = (0, node_crypto_1.timingSafeEqual)(expectedSignature, receivedSignature);
64
+ }
65
+ if (!signatureValid) {
66
+ throw new JwtError("JWT signature verification failed");
67
+ }
68
+ }
69
+ else {
70
+ console.warn("[auth] CONNPASS_JWT_SECRET is not set; skipping signature verification");
71
+ }
72
+ validateRegisteredClaims(payload, options);
73
+ return {
74
+ header,
75
+ payload,
76
+ signatureValid,
77
+ };
78
+ }
79
+ function toArray(value) {
80
+ if (Array.isArray(value)) {
81
+ return value;
82
+ }
83
+ if (typeof value === "string") {
84
+ return [value];
85
+ }
86
+ return undefined;
87
+ }
88
+ function validateRegisteredClaims(payload, options) {
89
+ const tolerance = options.clockToleranceSeconds ?? 30;
90
+ const now = Math.floor(Date.now() / 1000);
91
+ const exp = payload.exp;
92
+ if (exp !== undefined) {
93
+ const expiry = Number(exp);
94
+ if (!Number.isFinite(expiry)) {
95
+ throw new JwtError("JWT exp claim is not a number");
96
+ }
97
+ if (now - tolerance > expiry) {
98
+ throw new JwtError("JWT has expired");
99
+ }
100
+ }
101
+ else if (options.requireExpiration) {
102
+ throw new JwtError("JWT exp claim is required");
103
+ }
104
+ const nbf = payload.nbf;
105
+ if (nbf !== undefined) {
106
+ const notBefore = Number(nbf);
107
+ if (!Number.isFinite(notBefore)) {
108
+ throw new JwtError("JWT nbf claim is not a number");
109
+ }
110
+ if (now + tolerance < notBefore) {
111
+ throw new JwtError("JWT is not yet valid (nbf)");
112
+ }
113
+ }
114
+ const issuer = options.issuer;
115
+ if (issuer) {
116
+ const iss = ensureString(payload.iss, "iss claim");
117
+ if (iss !== issuer) {
118
+ throw new JwtError(`Invalid JWT issuer: expected '${issuer}'`);
119
+ }
120
+ }
121
+ const audience = toArray(options.audience);
122
+ if (audience && audience.length > 0) {
123
+ const rawAud = payload.aud;
124
+ const audValues = Array.isArray(rawAud) ? rawAud : [rawAud];
125
+ const normalized = audValues.filter((value) => typeof value === "string");
126
+ const hasMatch = normalized.some((value) => audience.includes(value));
127
+ if (!hasMatch) {
128
+ throw new JwtError("JWT audience mismatch");
129
+ }
130
+ }
131
+ }
132
+ function extractBearerToken(authorizationHeader) {
133
+ if (!authorizationHeader) {
134
+ return undefined;
135
+ }
136
+ const match = authorizationHeader.match(/^Bearer\s+(.+)$/i);
137
+ if (!match) {
138
+ return undefined;
139
+ }
140
+ const token = match[1]?.trim();
141
+ return token || undefined;
142
+ }
143
+ //# sourceMappingURL=jwt.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"jwt.js","sourceRoot":"","sources":["../../src/auth/jwt.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ export declare function getDefaultUserId(): number | undefined;
2
+ export declare function getDefaultIncludePresentations(): boolean | undefined;
3
+ export declare function isAppsSdkOutputEnabled(): boolean;
4
+ export declare function getMcpBasePath(): string;
5
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAuDA,wBAAgB,gBAAgB,IAAI,MAAM,GAAG,SAAS,CAErD;AAED,wBAAgB,8BAA8B,IAAI,OAAO,GAAG,SAAS,CAEpE;AAED,wBAAgB,sBAAsB,IAAI,OAAO,CAEhD;AAED,wBAAgB,cAAc,IAAI,MAAM,CAYvC"}
package/dist/config.js ADDED
@@ -0,0 +1,60 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getDefaultUserId = getDefaultUserId;
4
+ exports.getDefaultIncludePresentations = getDefaultIncludePresentations;
5
+ exports.isAppsSdkOutputEnabled = isAppsSdkOutputEnabled;
6
+ exports.getMcpBasePath = getMcpBasePath;
7
+ const BOOLEAN_TRUE_VALUES = new Set(["1", "true", "yes", "y", "on"]);
8
+ const BOOLEAN_FALSE_VALUES = new Set(["0", "false", "no", "n", "off"]);
9
+ function parseOptionalBooleanEnv(raw, envName) {
10
+ if (!raw) {
11
+ return undefined;
12
+ }
13
+ const normalized = raw.trim().toLowerCase();
14
+ if (BOOLEAN_TRUE_VALUES.has(normalized)) {
15
+ return true;
16
+ }
17
+ if (BOOLEAN_FALSE_VALUES.has(normalized)) {
18
+ return false;
19
+ }
20
+ console.warn(`[mcp-server] ${envName} is set but not a recognizable boolean. It will be ignored.`);
21
+ return undefined;
22
+ }
23
+ const RAW_DEFAULT_USER_ID = process.env.CONNPASS_DEFAULT_USER_ID;
24
+ const RAW_INCLUDE_PRESENTATIONS_DEFAULT = process.env.CONNPASS_INCLUDE_PRESENTATIONS_DEFAULT;
25
+ const RAW_ENABLE_APPS_SDK_OUTPUT = process.env.CONNPASS_ENABLE_APPS_SDK_OUTPUT;
26
+ const RAW_MCP_BASE_PATH = process.env.MCP_BASE_PATH;
27
+ const parsedDefaultUserId = (() => {
28
+ if (!RAW_DEFAULT_USER_ID) {
29
+ return undefined;
30
+ }
31
+ const numeric = Number(RAW_DEFAULT_USER_ID);
32
+ if (!Number.isFinite(numeric) || numeric <= 0) {
33
+ console.warn("[mcp-server] CONNPASS_DEFAULT_USER_ID is set but not a positive number. It will be ignored.");
34
+ return undefined;
35
+ }
36
+ return Math.trunc(numeric);
37
+ })();
38
+ const parsedIncludePresentationsDefault = parseOptionalBooleanEnv(RAW_INCLUDE_PRESENTATIONS_DEFAULT, "CONNPASS_INCLUDE_PRESENTATIONS_DEFAULT");
39
+ const parsedEnableAppsSdkOutput = parseOptionalBooleanEnv(RAW_ENABLE_APPS_SDK_OUTPUT, "CONNPASS_ENABLE_APPS_SDK_OUTPUT");
40
+ function getDefaultUserId() {
41
+ return parsedDefaultUserId;
42
+ }
43
+ function getDefaultIncludePresentations() {
44
+ return parsedIncludePresentationsDefault;
45
+ }
46
+ function isAppsSdkOutputEnabled() {
47
+ return parsedEnableAppsSdkOutput ?? false;
48
+ }
49
+ function getMcpBasePath() {
50
+ const raw = RAW_MCP_BASE_PATH?.trim();
51
+ if (!raw) {
52
+ return "/mcp";
53
+ }
54
+ if (raw === "/") {
55
+ return raw;
56
+ }
57
+ const ensureLeadingSlash = raw.startsWith("/") ? raw : `/${raw}`;
58
+ return ensureLeadingSlash.replace(/\/+$/, "");
59
+ }
60
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":";;AAuDA,4CAEC;AAED,wEAEC;AAED,wDAEC;AAED,wCAYC;AA/ED,MAAM,mBAAmB,GAAG,IAAI,GAAG,CAAC,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,EAAE,IAAI,CAAC,CAAC,CAAC;AACrE,MAAM,oBAAoB,GAAG,IAAI,GAAG,CAAC,CAAC,GAAG,EAAE,OAAO,EAAE,IAAI,EAAE,GAAG,EAAE,KAAK,CAAC,CAAC,CAAC;AAEvE,SAAS,uBAAuB,CAAC,GAAuB,EAAE,OAAe;IACvE,IAAI,CAAC,GAAG,EAAE,CAAC;QACT,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,MAAM,UAAU,GAAG,GAAG,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IAE5C,IAAI,mBAAmB,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE,CAAC;QACxC,OAAO,IAAI,CAAC;IACd,CAAC;IAED,IAAI,oBAAoB,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE,CAAC;QACzC,OAAO,KAAK,CAAC;IACf,CAAC;IAED,OAAO,CAAC,IAAI,CACV,gBAAgB,OAAO,6DAA6D,CACrF,CAAC;IACF,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,MAAM,mBAAmB,GAAG,OAAO,CAAC,GAAG,CAAC,wBAAwB,CAAC;AACjE,MAAM,iCAAiC,GAAG,OAAO,CAAC,GAAG,CAAC,sCAAsC,CAAC;AAC7F,MAAM,0BAA0B,GAAG,OAAO,CAAC,GAAG,CAAC,+BAA+B,CAAC;AAC/E,MAAM,iBAAiB,GAAG,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC;AAEpD,MAAM,mBAAmB,GAAG,CAAC,GAAG,EAAE;IAChC,IAAI,CAAC,mBAAmB,EAAE,CAAC;QACzB,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,MAAM,OAAO,GAAG,MAAM,CAAC,mBAAmB,CAAC,CAAC;IAC5C,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,OAAO,IAAI,CAAC,EAAE,CAAC;QAC9C,OAAO,CAAC,IAAI,CACV,6FAA6F,CAC9F,CAAC;QACF,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,OAAO,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;AAC7B,CAAC,CAAC,EAAE,CAAC;AAEL,MAAM,iCAAiC,GAAG,uBAAuB,CAC/D,iCAAiC,EACjC,wCAAwC,CACzC,CAAC;AAEF,MAAM,yBAAyB,GAAG,uBAAuB,CACvD,0BAA0B,EAC1B,iCAAiC,CAClC,CAAC;AAEF,SAAgB,gBAAgB;IAC9B,OAAO,mBAAmB,CAAC;AAC7B,CAAC;AAED,SAAgB,8BAA8B;IAC5C,OAAO,iCAAiC,CAAC;AAC3C,CAAC;AAED,SAAgB,sBAAsB;IACpC,OAAO,yBAAyB,IAAI,KAAK,CAAC;AAC5C,CAAC;AAED,SAAgB,cAAc;IAC5B,MAAM,GAAG,GAAG,iBAAiB,EAAE,IAAI,EAAE,CAAC;IACtC,IAAI,CAAC,GAAG,EAAE,CAAC;QACT,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,IAAI,GAAG,KAAK,GAAG,EAAE,CAAC;QAChB,OAAO,GAAG,CAAC;IACb,CAAC;IAED,MAAM,kBAAkB,GAAG,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,GAAG,EAAE,CAAC;IACjE,OAAO,kBAAkB,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;AAChD,CAAC"}
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}