@ampless/mcp-server 1.0.0-alpha.14 → 1.0.0-alpha.16
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 +5 -0
- package/README.md +5 -0
- package/dist/{chunk-K4GTND6P.js → chunk-HVSLKTKC.js} +6 -3
- package/dist/index.js +98 -14
- package/dist/tools/index.d.ts +9 -0
- package/dist/tools/index.js +1 -1
- package/package.json +2 -2
package/README.ja.md
CHANGED
|
@@ -130,9 +130,14 @@ AI に投稿本文を生成させる場合は、markdown を指定するのが
|
|
|
130
130
|
ampless-mcp [options]
|
|
131
131
|
|
|
132
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")
|
|
133
136
|
--site-id <id> クエリのデフォルト siteId(AMPLESS_MCP_SITE_ID でも指定可、デフォルト "default")
|
|
134
137
|
```
|
|
135
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
|
+
|
|
136
141
|
必須の環境変数:
|
|
137
142
|
|
|
138
143
|
```
|
package/README.md
CHANGED
|
@@ -130,9 +130,14 @@ If you're letting the AI generate post bodies, asking for markdown is usually ea
|
|
|
130
130
|
ampless-mcp [options]
|
|
131
131
|
|
|
132
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")
|
|
133
136
|
--site-id <id> Default siteId for queries (also AMPLESS_MCP_SITE_ID; default "default")
|
|
134
137
|
```
|
|
135
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
|
+
|
|
136
141
|
Required env:
|
|
137
142
|
|
|
138
143
|
```
|
|
@@ -894,7 +894,8 @@ var tools = [
|
|
|
894
894
|
name: "delete_post",
|
|
895
895
|
description: "Delete a post by postId. Also drops associated PostTag index entries.",
|
|
896
896
|
inputSchema: deletePostSchema,
|
|
897
|
-
handler: (args, ctx) => deletePost(ctx.graphql, args)
|
|
897
|
+
handler: (args, ctx) => deletePost(ctx.graphql, args),
|
|
898
|
+
destructive: true
|
|
898
899
|
},
|
|
899
900
|
{
|
|
900
901
|
name: "upload_media",
|
|
@@ -916,7 +917,8 @@ var tools = [
|
|
|
916
917
|
ctx.graphql,
|
|
917
918
|
ctx.storage(),
|
|
918
919
|
args
|
|
919
|
-
)
|
|
920
|
+
),
|
|
921
|
+
destructive: true
|
|
920
922
|
},
|
|
921
923
|
{
|
|
922
924
|
name: "upload_static_file",
|
|
@@ -934,7 +936,8 @@ var tools = [
|
|
|
934
936
|
handler: (args, ctx) => deleteStaticFile(
|
|
935
937
|
ctx.storage(),
|
|
936
938
|
args
|
|
937
|
-
)
|
|
939
|
+
),
|
|
940
|
+
destructive: true
|
|
938
941
|
},
|
|
939
942
|
{
|
|
940
943
|
name: "commit_static_post",
|
package/dist/index.js
CHANGED
|
@@ -24,7 +24,7 @@ import {
|
|
|
24
24
|
} from "./chunk-USNYVOYF.js";
|
|
25
25
|
import {
|
|
26
26
|
tools
|
|
27
|
-
} from "./chunk-
|
|
27
|
+
} from "./chunk-HVSLKTKC.js";
|
|
28
28
|
import {
|
|
29
29
|
eventStreamSerdeProvider2 as eventStreamSerdeProvider,
|
|
30
30
|
resolveEventStreamSerdeConfig
|
|
@@ -10898,6 +10898,22 @@ function parseArgs(argv) {
|
|
|
10898
10898
|
out.outputs = argv[++i2];
|
|
10899
10899
|
} else if (arg.startsWith("--outputs=")) {
|
|
10900
10900
|
out.outputs = arg.slice("--outputs=".length);
|
|
10901
|
+
} else if (arg === "--site-name") {
|
|
10902
|
+
out.siteName = argv[++i2];
|
|
10903
|
+
} else if (arg.startsWith("--site-name=")) {
|
|
10904
|
+
out.siteName = arg.slice("--site-name=".length);
|
|
10905
|
+
} else if (arg === "--site-url") {
|
|
10906
|
+
out.siteUrl = argv[++i2];
|
|
10907
|
+
} else if (arg.startsWith("--site-url=")) {
|
|
10908
|
+
out.siteUrl = arg.slice("--site-url=".length);
|
|
10909
|
+
} else if (arg === "--environment") {
|
|
10910
|
+
out.environment = argv[++i2];
|
|
10911
|
+
} else if (arg.startsWith("--environment=")) {
|
|
10912
|
+
out.environment = arg.slice("--environment=".length);
|
|
10913
|
+
} else if (arg === "--site-id") {
|
|
10914
|
+
out.siteId = argv[++i2];
|
|
10915
|
+
} else if (arg.startsWith("--site-id=")) {
|
|
10916
|
+
out.siteId = arg.slice("--site-id=".length);
|
|
10901
10917
|
}
|
|
10902
10918
|
}
|
|
10903
10919
|
return out;
|
|
@@ -10934,10 +10950,27 @@ async function loadConfig2(argv = process.argv.slice(2)) {
|
|
|
10934
10950
|
if (!outputs.data?.url) {
|
|
10935
10951
|
throw new Error("mcp-server: outputs.data.url missing");
|
|
10936
10952
|
}
|
|
10953
|
+
const siteName = args.siteName ?? process.env.AMPLESS_MCP_SITE_NAME;
|
|
10954
|
+
let site;
|
|
10955
|
+
if (siteName) {
|
|
10956
|
+
const rawEnv = args.environment ?? process.env.AMPLESS_MCP_ENVIRONMENT ?? "dev";
|
|
10957
|
+
if (rawEnv !== "prod" && rawEnv !== "stg" && rawEnv !== "dev") {
|
|
10958
|
+
throw new Error(
|
|
10959
|
+
`mcp-server: --environment must be one of prod, stg, dev (got "${rawEnv}")`
|
|
10960
|
+
);
|
|
10961
|
+
}
|
|
10962
|
+
site = {
|
|
10963
|
+
name: siteName,
|
|
10964
|
+
url: args.siteUrl ?? process.env.AMPLESS_MCP_SITE_URL,
|
|
10965
|
+
environment: rawEnv,
|
|
10966
|
+
siteId: args.siteId ?? process.env.AMPLESS_MCP_SITE_ID ?? "default"
|
|
10967
|
+
};
|
|
10968
|
+
}
|
|
10937
10969
|
return {
|
|
10938
10970
|
outputs,
|
|
10939
10971
|
email: requireEnv("AMPLESS_MCP_EMAIL"),
|
|
10940
|
-
password: requireEnv("AMPLESS_MCP_PASSWORD")
|
|
10972
|
+
password: requireEnv("AMPLESS_MCP_PASSWORD"),
|
|
10973
|
+
site
|
|
10941
10974
|
};
|
|
10942
10975
|
}
|
|
10943
10976
|
|
|
@@ -32167,6 +32200,60 @@ var StorageClient = class {
|
|
|
32167
32200
|
}
|
|
32168
32201
|
};
|
|
32169
32202
|
|
|
32203
|
+
// src/site.ts
|
|
32204
|
+
function buildServerName(site) {
|
|
32205
|
+
if (!site) return "@ampless/mcp-server";
|
|
32206
|
+
return `@ampless/mcp-server [${site.name}/${site.environment}]`;
|
|
32207
|
+
}
|
|
32208
|
+
function decorateToolListing(tools2, site) {
|
|
32209
|
+
if (!site) {
|
|
32210
|
+
return tools2.map((t8) => ({
|
|
32211
|
+
name: t8.name,
|
|
32212
|
+
description: t8.description,
|
|
32213
|
+
inputSchema: t8.inputSchema
|
|
32214
|
+
}));
|
|
32215
|
+
}
|
|
32216
|
+
return tools2.map((t8) => {
|
|
32217
|
+
const isProdDestructive = t8.destructive === true && site.environment === "prod";
|
|
32218
|
+
const envLabel = site.environment === "prod" ? "PROD" : site.environment;
|
|
32219
|
+
let description;
|
|
32220
|
+
if (isProdDestructive) {
|
|
32221
|
+
description = `[${site.name} / ${envLabel} \u2014 destructive] ${t8.description} Requires confirmSite: "${site.name}".`;
|
|
32222
|
+
} else if (t8.destructive) {
|
|
32223
|
+
description = `[${site.name} / ${envLabel} \u2014 destructive] ${t8.description}`;
|
|
32224
|
+
} else {
|
|
32225
|
+
description = `[${site.name} / ${site.environment}] ${t8.description}`;
|
|
32226
|
+
}
|
|
32227
|
+
let inputSchema = t8.inputSchema;
|
|
32228
|
+
if (isProdDestructive) {
|
|
32229
|
+
const cloned = JSON.parse(JSON.stringify(t8.inputSchema));
|
|
32230
|
+
const props = cloned.properties ?? {};
|
|
32231
|
+
props["confirmSite"] = {
|
|
32232
|
+
type: "string",
|
|
32233
|
+
const: site.name,
|
|
32234
|
+
description: `Must equal "${site.name}" to confirm this destructive operation on the production site.`
|
|
32235
|
+
};
|
|
32236
|
+
cloned.properties = props;
|
|
32237
|
+
const existing = cloned.required ?? [];
|
|
32238
|
+
cloned.required = ["confirmSite", ...existing];
|
|
32239
|
+
inputSchema = cloned;
|
|
32240
|
+
}
|
|
32241
|
+
return { name: t8.name, description, inputSchema };
|
|
32242
|
+
});
|
|
32243
|
+
}
|
|
32244
|
+
function assertConfirmSite(tool, args, site) {
|
|
32245
|
+
if (!site || site.environment !== "prod" || !tool.destructive) return;
|
|
32246
|
+
if (args["confirmSite"] !== site.name) {
|
|
32247
|
+
throw new Error(
|
|
32248
|
+
`confirmSite mismatch: expected "${site.name}", got ${JSON.stringify(args["confirmSite"])}. Pass confirmSite: "${site.name}" to confirm this destructive operation on the production site.`
|
|
32249
|
+
);
|
|
32250
|
+
}
|
|
32251
|
+
}
|
|
32252
|
+
function wrapResult(result, site) {
|
|
32253
|
+
if (!site) return result;
|
|
32254
|
+
return { site, result };
|
|
32255
|
+
}
|
|
32256
|
+
|
|
32170
32257
|
// src/server.ts
|
|
32171
32258
|
async function startServer(config2) {
|
|
32172
32259
|
const auth = new CognitoAuth(config2);
|
|
@@ -32179,18 +32266,15 @@ async function startServer(config2) {
|
|
|
32179
32266
|
};
|
|
32180
32267
|
const ctx = {
|
|
32181
32268
|
graphql,
|
|
32182
|
-
storage
|
|
32269
|
+
storage,
|
|
32270
|
+
site: config2.site
|
|
32183
32271
|
};
|
|
32184
32272
|
const server = new Server(
|
|
32185
|
-
{ name:
|
|
32273
|
+
{ name: buildServerName(config2.site), version: "0.0.1" },
|
|
32186
32274
|
{ capabilities: { tools: {} } }
|
|
32187
32275
|
);
|
|
32188
32276
|
server.setRequestHandler(ListToolsRequestSchema, async () => ({
|
|
32189
|
-
tools: tools.
|
|
32190
|
-
name: t8.name,
|
|
32191
|
-
description: t8.description,
|
|
32192
|
-
inputSchema: t8.inputSchema
|
|
32193
|
-
}))
|
|
32277
|
+
tools: decorateToolListing(tools, config2.site)
|
|
32194
32278
|
}));
|
|
32195
32279
|
server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
32196
32280
|
const tool = tools.find((t8) => t8.name === request.params.name);
|
|
@@ -32198,12 +32282,12 @@ async function startServer(config2) {
|
|
|
32198
32282
|
throw new Error(`Unknown tool: ${request.params.name}`);
|
|
32199
32283
|
}
|
|
32200
32284
|
try {
|
|
32201
|
-
const
|
|
32202
|
-
|
|
32203
|
-
|
|
32204
|
-
);
|
|
32285
|
+
const args = { ...request.params.arguments ?? {} };
|
|
32286
|
+
assertConfirmSite(tool, args, config2.site);
|
|
32287
|
+
delete args["confirmSite"];
|
|
32288
|
+
const result = await tool.handler(args, ctx);
|
|
32205
32289
|
return {
|
|
32206
|
-
content: [{ type: "text", text: JSON.stringify(result, null, 2) }]
|
|
32290
|
+
content: [{ type: "text", text: JSON.stringify(wrapResult(result, config2.site), null, 2) }]
|
|
32207
32291
|
};
|
|
32208
32292
|
} catch (err) {
|
|
32209
32293
|
return {
|
package/dist/tools/index.d.ts
CHANGED
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
import { BundleExtractResult } from 'ampless';
|
|
2
2
|
|
|
3
|
+
interface ResolvedSite {
|
|
4
|
+
name: string;
|
|
5
|
+
url?: string;
|
|
6
|
+
environment: 'prod' | 'stg' | 'dev';
|
|
7
|
+
siteId: string;
|
|
8
|
+
}
|
|
9
|
+
|
|
3
10
|
/**
|
|
4
11
|
* Abstract contracts each tool handler depends on. Concrete
|
|
5
12
|
* implementations live elsewhere:
|
|
@@ -48,6 +55,7 @@ interface StorageClient {
|
|
|
48
55
|
interface ToolContext {
|
|
49
56
|
graphql: GraphqlClient;
|
|
50
57
|
storage: () => StorageClient;
|
|
58
|
+
site?: ResolvedSite;
|
|
51
59
|
}
|
|
52
60
|
|
|
53
61
|
/**
|
|
@@ -100,6 +108,7 @@ interface ToolDefinition {
|
|
|
100
108
|
description: string;
|
|
101
109
|
inputSchema: Record<string, unknown>;
|
|
102
110
|
handler: (args: Record<string, unknown>, ctx: ToolContext) => Promise<unknown>;
|
|
111
|
+
destructive?: boolean;
|
|
103
112
|
}
|
|
104
113
|
declare const tools: ToolDefinition[];
|
|
105
114
|
/**
|
package/dist/tools/index.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ampless/mcp-server",
|
|
3
|
-
"version": "1.0.0-alpha.
|
|
3
|
+
"version": "1.0.0-alpha.16",
|
|
4
4
|
"description": "MCP server for ampless — lets AI agents (Claude Desktop, Cursor, Claude Code) read and write posts and media via AppSync",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -36,7 +36,7 @@
|
|
|
36
36
|
"@aws-sdk/client-s3": "^3.1053.0",
|
|
37
37
|
"amazon-cognito-identity-js": "^6.3.16",
|
|
38
38
|
"fflate": "^0.8.3",
|
|
39
|
-
"ampless": "1.0.0-alpha.
|
|
39
|
+
"ampless": "1.0.0-alpha.14"
|
|
40
40
|
},
|
|
41
41
|
"keywords": [
|
|
42
42
|
"ampless",
|