@ampless/mcp-server 1.0.0-alpha.17 → 1.0.0-alpha.18
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.ja.md +45 -123
- package/README.md +45 -123
- package/dist/index.d.ts +127 -1
- package/dist/index.js +1283 -32299
- package/package.json +17 -29
- package/LICENSE +0 -21
- package/dist/bowser-WRHMEFK3.js +0 -2822
- package/dist/chunk-6HZB2ZCT.js +0 -4715
- package/dist/chunk-7JQMGUAU.js +0 -134
- package/dist/chunk-ERHOBKHD.js +0 -891
- package/dist/chunk-ETWWJEHN.js +0 -574
- package/dist/chunk-FLMNALC3.js +0 -47
- package/dist/chunk-FM7TW5TD.js +0 -3558
- package/dist/chunk-IKXKDSVH.js +0 -1414
- package/dist/chunk-LD7M476A.js +0 -502
- package/dist/chunk-LMMQX4CK.js +0 -49
- package/dist/chunk-OBZN5IWW.js +0 -1375
- package/dist/chunk-Q4OVSLY4.js +0 -14
- package/dist/chunk-SPCUAJQT.js +0 -435
- package/dist/chunk-USNYVOYF.js +0 -1422
- package/dist/chunk-WAP4WAMQ.js +0 -867
- package/dist/chunk-YR5GD2D7.js +0 -165
- package/dist/dist-es-2B6UPU6D.js +0 -485
- package/dist/dist-es-4QBVIVDD.js +0 -23
- package/dist/dist-es-DAQMEDLM.js +0 -165
- package/dist/dist-es-DWVRWSTC.js +0 -70
- package/dist/dist-es-H7Y5BZEG.js +0 -315
- package/dist/dist-es-QZOTLLWC.js +0 -377
- package/dist/dist-es-S3US4EVE.js +0 -88
- package/dist/event-streams-IEZDQ3X3.js +0 -44
- package/dist/event-streams-R54SMYED.js +0 -891
- package/dist/loadSso-B4NUZPX5.js +0 -552
- package/dist/signin-BEDHRSJ2.js +0 -647
- package/dist/sso-oidc-UXLRODTA.js +0 -787
- package/dist/sts-3BBU2O3O.js +0 -1366
- package/dist/tools/index.d.ts +0 -127
- package/dist/tools/index.js +0 -16
package/README.ja.md
CHANGED
|
@@ -3,151 +3,73 @@
|
|
|
3
3
|
|
|
4
4
|
# @ampless/mcp-server
|
|
5
5
|
|
|
6
|
-
[ampless](https://github.com/heavymoons/ampless) 向け MCP
|
|
6
|
+
[ampless](https://github.com/heavymoons/ampless) 向け MCP ツールレジストリ。
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
**直接インストールする必要はありません。** `@ampless/backend` の `mcp-handler` Lambda が `./tools` サブパスエクスポート経由で使い、`@ampless/admin` / `@ampless/backend` を入れると推移的に付いてきます。
|
|
9
9
|
|
|
10
|
-
##
|
|
11
|
-
|
|
12
|
-
| ツール | 機能 |
|
|
13
|
-
|---|---|
|
|
14
|
-
| `list_posts` | オプションの `status` フィルターとページネーション付きで投稿一覧を取得 |
|
|
15
|
-
| `get_post` | `slug` または `postId` で単一の投稿を取得 |
|
|
16
|
-
| `create_post` | 新しい投稿を作成(下書きまたは公開済み) |
|
|
17
|
-
| `update_post` | 既存の投稿のフィールドをパッチ更新 |
|
|
18
|
-
| `delete_post` | 投稿を削除しタグインデックスをクリーンアップ |
|
|
19
|
-
| `upload_media` | Base64 エンコードされたバイト列を S3 にアップロードし `Media` レコードを作成 |
|
|
20
|
-
| `get_schema` | CMS コンテンツスキーマ(Post / Page / Media のフィールド形状)を返す |
|
|
21
|
-
|
|
22
|
-
サーバーは指定した認証情報(環境変数)で Cognito ユーザープールにサインインするため、各ツールはそのユーザーのロール(`ampless-admin` または `ampless-editor`)で動作します。下書きや編集内容は認証済みユーザーにのみ表示されます。リゾルバー側の `status === 'published'` フィルターにより、未公開コンテンツはパブリック読み取りからは見えません。
|
|
23
|
-
|
|
24
|
-
## インストール
|
|
25
|
-
|
|
26
|
-
サーバーは Node CLI として公開されています。グローバルインストールは通常不要です — MCP クライアントから `npx -y @ampless/mcp-server@alpha` を指定してください。
|
|
27
|
-
|
|
28
|
-
## 設定
|
|
29
|
-
|
|
30
|
-
以下が必要です:
|
|
31
|
-
|
|
32
|
-
1. **`amplify_outputs.json`** — `npx ampx sandbox` または `npx ampx pipeline-deploy` で生成されます。パスは `--outputs` で渡します。
|
|
33
|
-
2. **Cognito ユーザーアカウント** — ユーザープールのメールアドレスとパスワード。管理 UI から最初に作成したユーザーは自動的に `ampless-admin` に登録されます。
|
|
34
|
-
3. **AWS 認証情報** — `upload_media` を使用する場合にのみ必要です。デフォルトの認証情報チェーン(`AWS_PROFILE`、環境変数、インスタンスロール)が使用されます。読み取り専用ツールは AWS 認証情報なしで動作します。
|
|
35
|
-
|
|
36
|
-
### Claude Desktop
|
|
37
|
-
|
|
38
|
-
`~/Library/Application Support/Claude/claude_desktop_config.json`(macOS)またはプラットフォームに応じた同等のパスを編集します:
|
|
10
|
+
## 全体の構成
|
|
39
11
|
|
|
40
|
-
```
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
"-y",
|
|
47
|
-
"@ampless/mcp-server",
|
|
48
|
-
"--outputs",
|
|
49
|
-
"/absolute/path/to/your-site/amplify_outputs.json"
|
|
50
|
-
],
|
|
51
|
-
"env": {
|
|
52
|
-
"AMPLESS_MCP_EMAIL": "you@example.com",
|
|
53
|
-
"AMPLESS_MCP_PASSWORD": "your-password"
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
}
|
|
12
|
+
```
|
|
13
|
+
MCP クライアント (.mcp.json)
|
|
14
|
+
└── HTTP Bearer トークン (amk_...)
|
|
15
|
+
└── mcp-handler Lambda (packages/backend/src/functions/mcp-handler.ts)
|
|
16
|
+
└── @ampless/mcp-server/tools ← このパッケージ
|
|
17
|
+
└── ToolDefinition[], dispatchToolCall
|
|
58
18
|
```
|
|
59
19
|
|
|
60
|
-
|
|
20
|
+
`mcp-handler` Lambda は Bearer トークンを `McpToken` AppSync モデル(admin 専用)に照合し、`ToolContext`(GraphQL クライアント + S3 クライアント + サイトコンテキスト)を構築して、各ツール呼び出しをこのパッケージの `dispatchToolCall` に委譲します。
|
|
61
21
|
|
|
62
|
-
|
|
22
|
+
エンドユーザーは管理画面経由で MCP を設定します:
|
|
63
23
|
|
|
64
|
-
|
|
24
|
+
1. `/admin/mcp-tokens` にアクセスし、Bearer トークン(`amk_...`)を発行する。
|
|
25
|
+
2. Amplify コンソールまたは `amplify_outputs.json` で `mcp-handler` Lambda の Function URL を確認する。
|
|
26
|
+
3. MCP クライアントの設定ファイル(`.mcp.json`、`claude_desktop_config.json` など)にエントリを追加する:
|
|
65
27
|
|
|
66
28
|
```json
|
|
67
29
|
{
|
|
68
30
|
"mcpServers": {
|
|
69
31
|
"ampless": {
|
|
70
|
-
"
|
|
71
|
-
"
|
|
72
|
-
"
|
|
73
|
-
"
|
|
74
|
-
"AMPLESS_MCP_PASSWORD": "your-password"
|
|
32
|
+
"url": "https://<function-url-id>.lambda-url.<region>.on.aws/",
|
|
33
|
+
"transport": "http",
|
|
34
|
+
"headers": {
|
|
35
|
+
"Authorization": "Bearer amk_..."
|
|
75
36
|
}
|
|
76
37
|
}
|
|
77
38
|
}
|
|
78
39
|
}
|
|
79
40
|
```
|
|
80
41
|
|
|
81
|
-
|
|
42
|
+
HTTP MCP のアーキテクチャ全体については `docs/architecture/04-access-layer-mcp.md` を参照してください。
|
|
82
43
|
|
|
83
|
-
|
|
44
|
+
## エクスポート
|
|
84
45
|
|
|
85
|
-
|
|
86
|
-
claude mcp add ampless \
|
|
87
|
-
--env AMPLESS_MCP_EMAIL=you@example.com \
|
|
88
|
-
--env AMPLESS_MCP_PASSWORD=your-password \
|
|
89
|
-
-- npx -y @ampless/mcp-server --outputs /path/to/amplify_outputs.json
|
|
90
|
-
```
|
|
91
|
-
|
|
92
|
-
## 使用例
|
|
93
|
-
|
|
94
|
-
登録後、AI エージェントに次のように指示できます:
|
|
95
|
-
|
|
96
|
-
- 「最新の投稿を 5 件表示して。」
|
|
97
|
-
- 「スラッグ `welcome` の投稿を見せて。」
|
|
98
|
-
- 「タイトル '2 記事目' の下書きを markdown 形式で、本文 'Hello world.' で作成して。」
|
|
99
|
-
- 「投稿 `post-1234` を公開して。」
|
|
100
|
-
- 「スラッグ `bad-draft` の投稿を削除して。」
|
|
101
|
-
|
|
102
|
-
エージェントが自動的に適切なツールを選択します。
|
|
103
|
-
|
|
104
|
-
### `format` ごとの `body` の形式
|
|
105
|
-
|
|
106
|
-
- `format: 'markdown'` → body は markdown ソース文字列
|
|
107
|
-
- `format: 'html'` → body は生の HTML 文字列(そのままレンダリングされます — 下記のエディタートラストモデルを参照)
|
|
108
|
-
- `format: 'tiptap'` → body は tiptap ドキュメント JSON、例:
|
|
109
|
-
|
|
110
|
-
```json
|
|
111
|
-
{
|
|
112
|
-
"type": "doc",
|
|
113
|
-
"content": [
|
|
114
|
-
{ "type": "paragraph", "content": [{ "type": "text", "text": "Hello" }] }
|
|
115
|
-
]
|
|
116
|
-
}
|
|
117
|
-
```
|
|
118
|
-
|
|
119
|
-
AI に投稿本文を生成させる場合は、markdown を指定するのが最も簡単です。
|
|
120
|
-
|
|
121
|
-
## セキュリティに関する注意
|
|
122
|
-
|
|
123
|
-
- **エディタートラストモデル。** ampless は `editor` と `admin` を同一のトラストクラスとして扱います — どちらも投稿本文に任意の HTML / JS を格納できます(`docs/architecture/04-access-layer-mcp.md` 参照)。MCP サーバーが書き込める内容は、そのユーザーアカウントが管理 UI から書き込める内容と同じです。
|
|
124
|
-
- **設定ファイル内の認証情報。** `AMPLESS_MCP_PASSWORD` は Claude Desktop / Cursor の設定ファイル内にプレーンテキストで保存されます。SSH 秘密鍵と同様に扱ってください。OS キーチェーン連携はロードマップで対応予定です。
|
|
125
|
-
- **AWS 認証情報。** `upload_media` のみ必要です。サイトの S3 バケットへの書き込み権限のみを持つ専用の IAM ユーザー / ロールを使用してください。
|
|
126
|
-
|
|
127
|
-
## CLI フラグ
|
|
46
|
+
### `./tools`
|
|
128
47
|
|
|
48
|
+
```typescript
|
|
49
|
+
import { getTools, dispatchToolCall } from '@ampless/mcp-server/tools'
|
|
50
|
+
import type { ToolDefinition, ToolContext, ResolvedSite } from '@ampless/mcp-server/tools'
|
|
129
51
|
```
|
|
130
|
-
ampless-mcp [options]
|
|
131
|
-
|
|
132
|
-
--outputs <path> amplify_outputs.json へのパス(AMPLESS_MCP_OUTPUTS でも指定可)
|
|
133
|
-
--site-name <name> コンテキスト用のサイト表示名(AMPLESS_MCP_SITE_NAME でも指定可、例: "mysite.net")
|
|
134
|
-
--site-url <url> ツール結果に含めるサイト URL(AMPLESS_MCP_SITE_URL でも指定可、省略可)
|
|
135
|
-
--environment <env> デプロイ環境: prod | stg | dev(AMPLESS_MCP_ENVIRONMENT でも指定可、デフォルト "dev")
|
|
136
|
-
--site-id <id> クエリのデフォルト siteId(AMPLESS_MCP_SITE_ID でも指定可、デフォルト "default")
|
|
137
|
-
```
|
|
138
|
-
|
|
139
|
-
`--site-name` を設定すると、MCP クライアントに表示されるサーバー名にサイトと環境が含まれ(例: `@ampless/mcp-server [mysite.net/prod]`)、ツールの description に `[mysite.net / prod]` が前置され、結果が `{ site, result }` でラップされます。`--environment prod` 設定時、破壊的ツール(`delete_post`、`delete_static_file`、`upload_static_bundle`)の呼び出しにはサイト名と一致する `confirmSite` 引数が必要です。
|
|
140
52
|
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
53
|
+
| エクスポート | 説明 |
|
|
54
|
+
|---|---|
|
|
55
|
+
| `getTools()` | `ToolDefinition` オブジェクトのリスト(name、description、inputSchema)を返す |
|
|
56
|
+
| `dispatchToolCall(name, args, ctx)` | 名前でツール呼び出しをディスパッチする。不明なツール名の場合は例外をスロー |
|
|
57
|
+
| `ToolDefinition` | 単一ツールのインターフェース(name、description、inputSchema、handler) |
|
|
58
|
+
| `ToolContext` | ランタイムコンテキストのインターフェース(graphql、storage、site) |
|
|
59
|
+
| `ResolvedSite` | 解決済みサイトコンテキストのインターフェース(name、url、environment、siteId) |
|
|
147
60
|
|
|
148
|
-
##
|
|
61
|
+
## ツール一覧
|
|
149
62
|
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
63
|
+
| ツール | role | 説明 |
|
|
64
|
+
|---|---|---|
|
|
65
|
+
| `list_posts` | reader | オプションの status フィルターとページネーション付きで投稿一覧を取得 |
|
|
66
|
+
| `get_post` | reader | slug または postId で単一の投稿を取得 |
|
|
67
|
+
| `create_post` | editor | 新しい投稿を作成(下書きまたは公開済み) |
|
|
68
|
+
| `update_post` | editor | 既存の投稿のフィールドをパッチ更新 |
|
|
69
|
+
| `delete_post` | editor | 投稿を削除しタグインデックスをクリーンアップ |
|
|
70
|
+
| `upload_media` | editor | Base64 エンコードされたバイト列を S3 にアップロードし Media レコードを作成 |
|
|
71
|
+
| `get_schema` | reader | CMS コンテンツスキーマを返す |
|
|
72
|
+
| `upload_static_bundle` | editor | ビルド済み静的バンドルを S3 にアップロード |
|
|
73
|
+
| `list_static_files` | reader | 静的バンドルファイルを一覧表示 |
|
|
74
|
+
| `delete_static_file` | editor | 静的ファイルを S3 から削除 |
|
|
75
|
+
| `get_site_context` | reader | 現在のサイトコンテキスト(name、url、environment)を返す |
|
package/README.md
CHANGED
|
@@ -3,151 +3,73 @@
|
|
|
3
3
|
|
|
4
4
|
# @ampless/mcp-server
|
|
5
5
|
|
|
6
|
-
MCP
|
|
6
|
+
MCP tool registry for [ampless](https://github.com/heavymoons/ampless).
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
**No direct install needed.** This package is consumed by `@ampless/backend`'s `mcp-handler` Lambda via the `./tools` subpath export, and arrives transitively when you install `@ampless/admin` or `@ampless/backend`.
|
|
9
9
|
|
|
10
|
-
##
|
|
11
|
-
|
|
12
|
-
| Tool | What it does |
|
|
13
|
-
|---|---|
|
|
14
|
-
| `list_posts` | List posts with optional `status` filter and pagination |
|
|
15
|
-
| `get_post` | Fetch a single post by `slug` or `postId` |
|
|
16
|
-
| `create_post` | Create a new post (draft or published) |
|
|
17
|
-
| `update_post` | Patch fields on an existing post |
|
|
18
|
-
| `delete_post` | Delete a post and clean up its tag index |
|
|
19
|
-
| `upload_media` | Upload base64-encoded bytes to S3 and create a `Media` record |
|
|
20
|
-
| `get_schema` | Return the CMS content schema (Post / Page / Media field shapes) |
|
|
21
|
-
|
|
22
|
-
The server signs in to your Cognito User Pool with the credentials you provide (env vars), so each tool runs with the role of that user (`ampless-admin` or `ampless-editor`). Drafts and editing surface only to authenticated users; the resolver-side `status === 'published'` filter still keeps unpublished content invisible to public reads.
|
|
23
|
-
|
|
24
|
-
## Install
|
|
25
|
-
|
|
26
|
-
The server is published as a Node CLI; you typically don't install it globally — point your MCP client at `npx -y @ampless/mcp-server@alpha` instead.
|
|
27
|
-
|
|
28
|
-
## Configure
|
|
29
|
-
|
|
30
|
-
You need:
|
|
31
|
-
|
|
32
|
-
1. **`amplify_outputs.json`** — generated by `npx ampx sandbox` or `npx ampx pipeline-deploy`. The path is passed via `--outputs`.
|
|
33
|
-
2. **A Cognito user account** — email + password from your User Pool. The first user created via the admin UI is automatically in `ampless-admin`.
|
|
34
|
-
3. **AWS credentials** — only required if you intend to use `upload_media`. The default credential chain (`AWS_PROFILE`, env vars, instance role) is used. Read-only tools work without AWS credentials.
|
|
35
|
-
|
|
36
|
-
### Claude Desktop
|
|
37
|
-
|
|
38
|
-
Edit `~/Library/Application Support/Claude/claude_desktop_config.json` (macOS) or the equivalent path on your platform:
|
|
10
|
+
## How it fits together
|
|
39
11
|
|
|
40
|
-
```
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
"-y",
|
|
47
|
-
"@ampless/mcp-server",
|
|
48
|
-
"--outputs",
|
|
49
|
-
"/absolute/path/to/your-site/amplify_outputs.json"
|
|
50
|
-
],
|
|
51
|
-
"env": {
|
|
52
|
-
"AMPLESS_MCP_EMAIL": "you@example.com",
|
|
53
|
-
"AMPLESS_MCP_PASSWORD": "your-password"
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
}
|
|
12
|
+
```
|
|
13
|
+
MCP client (.mcp.json)
|
|
14
|
+
└── HTTP Bearer token (amk_...)
|
|
15
|
+
└── mcp-handler Lambda (packages/backend/src/functions/mcp-handler.ts)
|
|
16
|
+
└── @ampless/mcp-server/tools ← this package
|
|
17
|
+
└── ToolDefinition[], dispatchToolCall
|
|
58
18
|
```
|
|
59
19
|
|
|
60
|
-
|
|
20
|
+
The `mcp-handler` Lambda resolves the Bearer token against the `McpToken` AppSync model (admin-only), builds a `ToolContext` (GraphQL client + S3 client + site context), and delegates each incoming tool call to `dispatchToolCall` from this package.
|
|
61
21
|
|
|
62
|
-
|
|
22
|
+
End users configure MCP via the admin UI:
|
|
63
23
|
|
|
64
|
-
|
|
24
|
+
1. Go to `/admin/mcp-tokens` and issue a Bearer token (`amk_...`).
|
|
25
|
+
2. Find the `mcp-handler` Lambda Function URL in the Amplify console or `amplify_outputs.json`.
|
|
26
|
+
3. Add an entry to your MCP client's config (`.mcp.json`, `claude_desktop_config.json`, etc.):
|
|
65
27
|
|
|
66
28
|
```json
|
|
67
29
|
{
|
|
68
30
|
"mcpServers": {
|
|
69
31
|
"ampless": {
|
|
70
|
-
"
|
|
71
|
-
"
|
|
72
|
-
"
|
|
73
|
-
"
|
|
74
|
-
"AMPLESS_MCP_PASSWORD": "your-password"
|
|
32
|
+
"url": "https://<function-url-id>.lambda-url.<region>.on.aws/",
|
|
33
|
+
"transport": "http",
|
|
34
|
+
"headers": {
|
|
35
|
+
"Authorization": "Bearer amk_..."
|
|
75
36
|
}
|
|
76
37
|
}
|
|
77
38
|
}
|
|
78
39
|
}
|
|
79
40
|
```
|
|
80
41
|
|
|
81
|
-
|
|
42
|
+
See `docs/architecture/04-access-layer-mcp.md` for the full HTTP MCP architecture.
|
|
82
43
|
|
|
83
|
-
|
|
44
|
+
## Exports
|
|
84
45
|
|
|
85
|
-
|
|
86
|
-
claude mcp add ampless \
|
|
87
|
-
--env AMPLESS_MCP_EMAIL=you@example.com \
|
|
88
|
-
--env AMPLESS_MCP_PASSWORD=your-password \
|
|
89
|
-
-- npx -y @ampless/mcp-server --outputs /path/to/amplify_outputs.json
|
|
90
|
-
```
|
|
91
|
-
|
|
92
|
-
## Usage examples
|
|
93
|
-
|
|
94
|
-
Once registered, prompt your AI agent:
|
|
95
|
-
|
|
96
|
-
- "List the latest 5 posts."
|
|
97
|
-
- "Show me the post with slug `welcome`."
|
|
98
|
-
- "Create a draft titled 'My second post' with format markdown and body 'Hello world.'"
|
|
99
|
-
- "Publish post `post-1234`."
|
|
100
|
-
- "Delete the post with slug `bad-draft`."
|
|
101
|
-
|
|
102
|
-
The agent will pick the right tool automatically.
|
|
103
|
-
|
|
104
|
-
### `body` shape per `format`
|
|
105
|
-
|
|
106
|
-
- `format: 'markdown'` → body is a markdown source string
|
|
107
|
-
- `format: 'html'` → body is a raw HTML string (rendered verbatim — see editor trust model below)
|
|
108
|
-
- `format: 'tiptap'` → body is the tiptap document JSON, e.g.
|
|
109
|
-
|
|
110
|
-
```json
|
|
111
|
-
{
|
|
112
|
-
"type": "doc",
|
|
113
|
-
"content": [
|
|
114
|
-
{ "type": "paragraph", "content": [{ "type": "text", "text": "Hello" }] }
|
|
115
|
-
]
|
|
116
|
-
}
|
|
117
|
-
```
|
|
118
|
-
|
|
119
|
-
If you're letting the AI generate post bodies, asking for markdown is usually easiest.
|
|
120
|
-
|
|
121
|
-
## Security notes
|
|
122
|
-
|
|
123
|
-
- **Editor trust model.** ampless treats `editor` and `admin` as a single trust class — both can store arbitrary HTML/JS in post bodies (see `docs/architecture/04-access-layer-mcp.md`). Whatever the MCP server can write, that user account could already write through the admin UI.
|
|
124
|
-
- **Credentials in the config file.** `AMPLESS_MCP_PASSWORD` lives in plaintext inside Claude Desktop / Cursor's config file. Treat that file like an SSH private key. OS keychain integration is on the roadmap.
|
|
125
|
-
- **AWS credentials.** Only `upload_media` requires them. Use a dedicated IAM user / role with write access only to your site's S3 bucket.
|
|
126
|
-
|
|
127
|
-
## CLI flags
|
|
46
|
+
### `./tools`
|
|
128
47
|
|
|
48
|
+
```typescript
|
|
49
|
+
import { getTools, dispatchToolCall } from '@ampless/mcp-server/tools'
|
|
50
|
+
import type { ToolDefinition, ToolContext, ResolvedSite } from '@ampless/mcp-server/tools'
|
|
129
51
|
```
|
|
130
|
-
ampless-mcp [options]
|
|
131
|
-
|
|
132
|
-
--outputs <path> Path to amplify_outputs.json (also AMPLESS_MCP_OUTPUTS)
|
|
133
|
-
--site-name <name> Site display name for context (also AMPLESS_MCP_SITE_NAME; e.g. "mysite.net")
|
|
134
|
-
--site-url <url> Site URL included in tool results (also AMPLESS_MCP_SITE_URL; optional)
|
|
135
|
-
--environment <env> Deployment environment: prod | stg | dev (also AMPLESS_MCP_ENVIRONMENT; default "dev")
|
|
136
|
-
--site-id <id> Default siteId for queries (also AMPLESS_MCP_SITE_ID; default "default")
|
|
137
|
-
```
|
|
138
|
-
|
|
139
|
-
When `--site-name` is set, the server name shown in MCP clients includes the site and environment (e.g. `@ampless/mcp-server [mysite.net/prod]`), tool descriptions are prefixed with `[mysite.net / prod]`, and results are wrapped in `{ site, result }`. Destructive tools (`delete_post`, `delete_static_file`, `upload_static_bundle`) require a `confirmSite` argument equal to the site name when `--environment prod` is set.
|
|
140
52
|
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
53
|
+
| Export | Description |
|
|
54
|
+
|---|---|
|
|
55
|
+
| `getTools()` | Returns the list of `ToolDefinition` objects (name, description, inputSchema) |
|
|
56
|
+
| `dispatchToolCall(name, args, ctx)` | Dispatches a tool call by name; throws if unknown |
|
|
57
|
+
| `ToolDefinition` | Interface for a single tool (name, description, inputSchema, handler) |
|
|
58
|
+
| `ToolContext` | Interface for the runtime context (graphql, storage, site) |
|
|
59
|
+
| `ResolvedSite` | Interface for the resolved site context (name, url, environment, siteId) |
|
|
147
60
|
|
|
148
|
-
##
|
|
61
|
+
## Tools
|
|
149
62
|
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
63
|
+
| Tool | Role | Description |
|
|
64
|
+
|---|---|---|
|
|
65
|
+
| `list_posts` | reader | List posts with optional status filter and pagination |
|
|
66
|
+
| `get_post` | reader | Fetch a single post by slug or postId |
|
|
67
|
+
| `create_post` | editor | Create a new post (draft or published) |
|
|
68
|
+
| `update_post` | editor | Patch fields on an existing post |
|
|
69
|
+
| `delete_post` | editor | Delete a post and clean up its tag index |
|
|
70
|
+
| `upload_media` | editor | Upload base64-encoded bytes to S3 and create a Media record |
|
|
71
|
+
| `get_schema` | reader | Return the CMS content schema |
|
|
72
|
+
| `upload_static_bundle` | editor | Upload a pre-built static bundle to S3 |
|
|
73
|
+
| `list_static_files` | reader | List static bundle files |
|
|
74
|
+
| `delete_static_file` | editor | Delete a static file from S3 |
|
|
75
|
+
| `get_site_context` | reader | Return current site context (name, url, environment) |
|
package/dist/index.d.ts
CHANGED
|
@@ -1,2 +1,128 @@
|
|
|
1
|
+
import { BundleExtractResult } from 'ampless';
|
|
1
2
|
|
|
2
|
-
|
|
3
|
+
/**
|
|
4
|
+
* Site context passed from the HTTP transport into each tool call.
|
|
5
|
+
* The mcp-handler Lambda resolves this from the MCP access token.
|
|
6
|
+
*/
|
|
7
|
+
interface ResolvedSite {
|
|
8
|
+
name: string;
|
|
9
|
+
url?: string;
|
|
10
|
+
environment: 'prod' | 'stg' | 'dev';
|
|
11
|
+
siteId: string;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Abstract contracts each tool handler depends on. Concrete
|
|
15
|
+
* implementations live in `@ampless/backend`'s mcp-handler Lambda:
|
|
16
|
+
*
|
|
17
|
+
* - `mcp-graphql-client.ts` — AppSync GraphQL client (Bearer token)
|
|
18
|
+
* - `mcp-storage-client.ts` — S3 client for media operations
|
|
19
|
+
*
|
|
20
|
+
* Both satisfy these interfaces structurally (no `implements` needed)
|
|
21
|
+
* — TypeScript's structural typing checks the shape on the call site.
|
|
22
|
+
* Tools never instantiate these themselves; the caller passes a ready
|
|
23
|
+
* `ToolContext` into `dispatchToolCall`.
|
|
24
|
+
*/
|
|
25
|
+
interface GraphqlClient {
|
|
26
|
+
query<T>(operation: string, variables?: Record<string, unknown>): Promise<T>;
|
|
27
|
+
}
|
|
28
|
+
interface StorageObject {
|
|
29
|
+
/** Full S3 key including any prefix. */
|
|
30
|
+
key: string;
|
|
31
|
+
/** Object size in bytes (0 when the backend can't supply it). */
|
|
32
|
+
size: number;
|
|
33
|
+
/** ISO 8601 timestamp of the last write, when the backend supplies it. */
|
|
34
|
+
lastModified?: string;
|
|
35
|
+
}
|
|
36
|
+
interface StorageClient {
|
|
37
|
+
/**
|
|
38
|
+
* Upload `body` to the bucket at `key` with `contentType`. Returns
|
|
39
|
+
* the public URL of the stored object (same format both routes use:
|
|
40
|
+
* https://{bucket}.s3.{region}.amazonaws.com/{key}).
|
|
41
|
+
*/
|
|
42
|
+
putObject(key: string, body: Uint8Array, contentType: string): Promise<string>;
|
|
43
|
+
/**
|
|
44
|
+
* Remove the object at `key`. Implementations should treat a missing
|
|
45
|
+
* key as success (S3 DeleteObject is idempotent by default).
|
|
46
|
+
*/
|
|
47
|
+
deleteObject(key: string): Promise<void>;
|
|
48
|
+
/**
|
|
49
|
+
* List every object under `prefix`. Implementations are expected to
|
|
50
|
+
* paginate internally so the caller gets the full set in a single
|
|
51
|
+
* resolved promise — the static-bundle tools never expect more than
|
|
52
|
+
* a few hundred entries per bundle in practice.
|
|
53
|
+
*/
|
|
54
|
+
listObjects(prefix: string): Promise<StorageObject[]>;
|
|
55
|
+
}
|
|
56
|
+
interface ToolContext {
|
|
57
|
+
graphql: GraphqlClient;
|
|
58
|
+
storage: () => StorageClient;
|
|
59
|
+
site?: ResolvedSite;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Server-side zip extractor used by the static-bundle MCP tools. Both
|
|
64
|
+
* the stdio CLI and the Lambda HTTP transport run this — `fflate` is
|
|
65
|
+
* a workspace dependency of `@ampless/mcp-server`, so the import
|
|
66
|
+
* resolves identically in both. The browser-side admin uploader has
|
|
67
|
+
* its own `extractZip(File)` based on JSZip (works on a `File`, not a
|
|
68
|
+
* `Buffer`).
|
|
69
|
+
*
|
|
70
|
+
* Behaviour parity with the admin extractor:
|
|
71
|
+
* - Skip directory entries (fflate gives byte arrays only, so this
|
|
72
|
+
* is naturally satisfied unless the zip has empty-byte directory
|
|
73
|
+
* placeholders — those still get filtered out by validateBundlePath
|
|
74
|
+
* returning "directory entry" for any path ending with `/`).
|
|
75
|
+
* - Silently drop OS-specific junk (`__MACOSX/*`, `.DS_Store`,
|
|
76
|
+
* `Thumbs.db`) so callers don't see them as bundle entries.
|
|
77
|
+
* - Surface structural issues (absolute paths, parent traversal, null
|
|
78
|
+
* bytes) so the tool can reject the upload.
|
|
79
|
+
* - Strip a common single top-level directory (macOS Finder zips
|
|
80
|
+
* wrap their contents in a folder).
|
|
81
|
+
*/
|
|
82
|
+
|
|
83
|
+
interface ExtractZipOptions {
|
|
84
|
+
/**
|
|
85
|
+
* Hard ceiling on uncompressed bundle bytes. Defaults to 50 MB,
|
|
86
|
+
* matching the browser uploader's MAX_BUNDLE_BYTES. Callers running
|
|
87
|
+
* inside a tight Lambda envelope (Function URL payload cap ~6 MB
|
|
88
|
+
* post-base64) can tighten this; setting it lower than the bundle
|
|
89
|
+
* causes `extractZipFromBuffer` to throw before fully populating
|
|
90
|
+
* `files`.
|
|
91
|
+
*/
|
|
92
|
+
maxBytes?: number;
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Unzip `buffer` in memory and return the same shape the browser
|
|
96
|
+
* `extractZip(File)` helper returns. Throws if the unzip itself fails
|
|
97
|
+
* (corrupt archive) or if the uncompressed size exceeds `maxBytes`.
|
|
98
|
+
*/
|
|
99
|
+
declare function extractZipFromBuffer(buffer: Uint8Array, opts?: ExtractZipOptions): BundleExtractResult;
|
|
100
|
+
/**
|
|
101
|
+
* Decode an extracted file's bytes as UTF-8 text. Used by the tool
|
|
102
|
+
* handler before running cross-file `validateBundle` so we don't
|
|
103
|
+
* instantiate a TextDecoder per entry. fflate provides a fast helper.
|
|
104
|
+
*/
|
|
105
|
+
declare function decodeUtf8(data: Uint8Array): string;
|
|
106
|
+
|
|
107
|
+
interface ToolDefinition {
|
|
108
|
+
name: string;
|
|
109
|
+
description: string;
|
|
110
|
+
inputSchema: Record<string, unknown>;
|
|
111
|
+
handler: (args: Record<string, unknown>, ctx: ToolContext) => Promise<unknown>;
|
|
112
|
+
destructive?: boolean;
|
|
113
|
+
}
|
|
114
|
+
declare const tools: ToolDefinition[];
|
|
115
|
+
/**
|
|
116
|
+
* Look up a tool definition by name and invoke its handler. Returns
|
|
117
|
+
* `null` when no tool with that name is registered — callers should
|
|
118
|
+
* surface that as a JSON-RPC "method not found" error.
|
|
119
|
+
*/
|
|
120
|
+
declare function dispatchToolCall(name: string, args: Record<string, unknown>, ctx: ToolContext): Promise<unknown>;
|
|
121
|
+
/**
|
|
122
|
+
* `tools` is the canonical registry; `getTools()` returns it for
|
|
123
|
+
* callers that prefer a function over a top-level constant (admin's
|
|
124
|
+
* HTTP factory exposes this through its options shape).
|
|
125
|
+
*/
|
|
126
|
+
declare function getTools(): readonly ToolDefinition[];
|
|
127
|
+
|
|
128
|
+
export { type ExtractZipOptions, type GraphqlClient, type StorageClient, type StorageObject, type ToolContext, type ToolDefinition, decodeUtf8, dispatchToolCall, extractZipFromBuffer, getTools, tools };
|