antics-mcp
Advanced tools
+39
-28
@@ -394,40 +394,45 @@ #!/usr/bin/env node | ||
| try { | ||
| const res = await fetch(`${client.baseUrl}/api/models`, { | ||
| method: "POST", | ||
| headers: { "content-type": "application/json", "x-antics-client": "mcp" }, | ||
| body: JSON.stringify({ | ||
| name: args.name, | ||
| glb: args.glb, | ||
| recipe: args.recipe, | ||
| licence: args.licence, | ||
| sources: args.sources, | ||
| kitVersion: args.kitVersion, | ||
| ...args.summary ? { summary: args.summary } : {}, | ||
| ...args.image ? { image: args.image } : {} | ||
| }) | ||
| const body = await client.publishModel({ | ||
| name: args.name, | ||
| glb: args.glb, | ||
| recipe: args.recipe, | ||
| licence: args.licence, | ||
| sources: args.sources, | ||
| kitVersion: args.kitVersion, | ||
| ...args.summary ? { summary: args.summary } : {}, | ||
| ...args.image ? { image: args.image } : {} | ||
| }); | ||
| const body = await res.json(); | ||
| if (!res.ok) { | ||
| return { | ||
| text: `Model rejected (${body.error ?? res.status})${body.fields ? `: ${body.fields.join(", ")}` : ""}. ${body.hint ?? ""}`.trim(), | ||
| data: body | ||
| }; | ||
| } | ||
| let demo = ""; | ||
| if (args.demoFiles && Object.keys(args.demoFiles).length && body.id) { | ||
| const d = await fetch(`${client.baseUrl}/api/models/${body.id}/demo`, { | ||
| method: "POST", | ||
| headers: { "content-type": "application/json", "x-antics-client": "mcp" }, | ||
| body: JSON.stringify({ files: args.demoFiles }) | ||
| }); | ||
| demo = d.ok ? " An interactive demo is attached." : " The demo bundle was rejected; the model still published."; | ||
| if (args.demoFiles && Object.keys(args.demoFiles).length && body.slug) { | ||
| try { | ||
| await client.attachModelDemo(body.slug, args.demoFiles); | ||
| demo = " An interactive demo is attached."; | ||
| } catch { | ||
| demo = " The demo bundle was rejected; the model still published."; | ||
| } | ||
| } | ||
| return { | ||
| text: `Published for review: ${body.url}.${demo} It is NOT public yet \u2014 an operator approves it, and the page is not indexed until then. The URL is permanent: republish the same model with PUT /api/models/${body.id} rather than publishing again, or the link you share goes stale.`, | ||
| text: `Published for review: ${body.url}.${demo} It is NOT public yet \u2014 an operator approves it, and the page is not indexed until then. The URL is permanent: to change the asset later, PUT /api/models/${body.slug} rather than publishing again, or the link you share goes stale. list_my_models shows this and everything else you have published, with its status.`, | ||
| data: body | ||
| }; | ||
| } catch (e) { | ||
| if (isAuthError(e)) return { text: LOGIN_HELP, data: null }; | ||
| return { text: `Could not publish (${e instanceof Error ? e.message : "network error"}).`, data: { error: true } }; | ||
| } | ||
| } | ||
| async function listMyModelsTool(client) { | ||
| try { | ||
| const mine = await client.listMyModels(); | ||
| if (!mine.length) { | ||
| return { text: "You have not published any models. Build one with antics-modelkit, then publish_model.", data: [] }; | ||
| } | ||
| const line = (m) => `${m.name} \u2014 ${m.status === "public" ? "PUBLIC" : m.status.replace("_", " ")}, ${m.tris.toLocaleString()} tris, ${m.licence} | ||
| ${m.url} | ||
| replace: ${m.update}`; | ||
| return { text: mine.map(line).join("\n"), data: mine }; | ||
| } catch (e) { | ||
| if (isAuthError(e)) return { text: LOGIN_HELP, data: null }; | ||
| return { text: `Could not list your models (${e instanceof Error ? e.message : "network error"}).`, data: { error: true } }; | ||
| } | ||
| } | ||
| async function findModelsTool(client, args) { | ||
@@ -546,2 +551,8 @@ const p = new URLSearchParams(); | ||
| server.tool( | ||
| "list_my_models", | ||
| "What 3D models have I published, and were they approved? Shows everything on your account including models still UNDER REVIEW \u2014 which /api/models and find_models do not, because those list only what is public. Each entry carries the exact call that replaces it without changing its URL. Requires login.", | ||
| {}, | ||
| async () => wrap(await listMyModelsTool(client)) | ||
| ); | ||
| server.tool( | ||
| "list_projects", | ||
@@ -548,0 +559,0 @@ "List your projects (requires login).", |
+1
-1
| { | ||
| "name": "antics-mcp", | ||
| "version": "0.2.5", | ||
| "version": "0.2.6", | ||
| "mcpName": "io.github.antics-gg/antics-mcp", | ||
@@ -5,0 +5,0 @@ "description": "Multiplayer for your game, in one prompt \u2014 an MCP server that lets an AI agent deploy a web game to a playable multiplayer URL (rooms, state sync, leaderboards).", |
53983
1.36%694
1.91%3
-40%