Skip to main content

server

Write or review the server side of an Apps in Toss mini-app: any backend that stores per-user data or calls the Apps in Toss partner API (Toss login token exchange, anonymous-key exchange, other partner calls), on Cloudflare Workers, Node, a BaaS (Supabase, Firebase) or any other hosting. Use it right away, before writing server code, for "์„œ๋ฒ„์— ์ €์žฅํ•ด์„œ ๋‹ค๋ฅธ ๊ธฐ๊ธฐ์—์„œ๋„ ๋ณด์ด๊ฒŒ ํ•ด์ค˜", "์„œ๋ฒ„ ๋ถ™์—ฌ์ค˜", "SupabaseยทFirebase์— ๋‚ด ๊ธฐ๋ก ์ €์žฅํ•ด์ค˜", "Workers๋กœ ์„œ๋ฒ„ ๋งŒ๋“ค์–ด์ค˜", "ํ† ์Šค ๋กœ๊ทธ์ธ ๋ถ™์—ฌ์ค˜" (even client side only โ€” login needs console setup and a server exchange), "์„œ๋ฒ„์—์„œ ์‚ฌ์šฉ์ž ๊ตฌ๋ถ„์€ ์–ด๋–ป๊ฒŒ ํ•ด?", or "getAnonymousKey ๊ฐ’์„ ์„œ๋ฒ„์—์„œ ๊ทธ๋Œ€๋กœ ์จ๋„ ๋ผ?" โ€” even when the user only names the feature. It decides how the server identifies users (anonymous-key exchange vs Toss login), wires mTLS for partner API calls, parses the resultType envelope and sets exact CORS origins, then writes or fixes the code. Keeps the user's chosen hosting. Deploys only when asked; no console calls. Client screens are `/ait:design`; phone testing is `/ait:test-on-device`. Triggered by `/ait:server [request]`.

Source facts

Repository
toss/apps-in-toss-harness
Last source activity
October 16, 2026 at 23:31
Detected SKILL.md language
Korean
Stars
4
Forks
0

Install options

The review-first prompt is selected by default. You can switch to a direct command or download a local copy.

Review the source files

Read SKILL.md and any companion files shown by SkillsMP before deciding whether to install.

Showing SKILL.md

SKILL.md
Source instructions ยท Read-only preview
name
server
description
Write or review the server side of an Apps in Toss mini-app: any backend that stores per-user data or calls the Apps in Toss partner API (Toss login token exchange, anonymous-key exchange, other partner calls), on Cloudflare Workers, Node, a BaaS (Supabase, Firebase) or any other hosting. Use it right away, before writing server code, for "์„œ๋ฒ„์— ์ €์žฅํ•ด์„œ ๋‹ค๋ฅธ ๊ธฐ๊ธฐ์—์„œ๋„ ๋ณด์ด๊ฒŒ ํ•ด์ค˜", "์„œ๋ฒ„ ๋ถ™์—ฌ์ค˜", "SupabaseยทFirebase์— ๋‚ด ๊ธฐ๋ก ์ €์žฅํ•ด์ค˜", "Workers๋กœ ์„œ๋ฒ„ ๋งŒ๋“ค์–ด์ค˜", "ํ† ์Šค ๋กœ๊ทธ์ธ ๋ถ™์—ฌ์ค˜" (even client side only โ€” login needs console setup and a server exchange), "์„œ๋ฒ„์—์„œ ์‚ฌ์šฉ์ž ๊ตฌ๋ถ„์€ ์–ด๋–ป๊ฒŒ ํ•ด?", or "getAnonymousKey ๊ฐ’์„ ์„œ๋ฒ„์—์„œ ๊ทธ๋Œ€๋กœ ์จ๋„ ๋ผ?" โ€” even when the user only names the feature. It decides how the server identifies users (anonymous-key exchange vs Toss login), wires mTLS for partner API calls, parses the resultType envelope and sets exact CORS origins, then writes or fixes the code. Keeps the user's chosen hosting. Deploys only when asked; no console calls. Client screens are `/ait:design`; phone testing is `/ait:test-on-device`. Triggered by `/ait:server [request]`.
argument-hint
[request]
# server skill ## ๋ชฉ์  ๋ฏธ๋‹ˆ์•ฑ์ด ์“ฐ๋Š” ์„œ๋ฒ„ ์ฝ”๋“œ๋ฅผ ์“ฐ๊ฑฐ๋‚˜ ๊ณ ์น  ๋•Œ ์•ฑ์ธํ† ์Šค ๊ณ ์œ ์˜ ํŒ๋‹จ๊ณผ ์—ฐ๊ฒฐ๋ถ€๋ฅผ ๋งก๋Š”๋‹ค. ์‚ฌ์šฉ์ž๋ณ„ ์ €์žฅ, ํŒŒํŠธ๋„ˆ API ํ˜ธ์ถœ(ํ† ์Šค ๋กœ๊ทธ์ธ ํ† ํฐ ๊ตํ™˜, ์ต๋ช… ์‹๋ณ„ํ‚ค ๊ตํ™˜ ๋“ฑ)์ด ๋Œ€์ƒ์ด๋‹ค. ํ”„๋ ˆ์ž„์›Œํฌ ํ…œํ”Œ๋ฆฟ์„ ์ƒˆ๋กœ ๊น”์ง€ ์•Š๊ณ , ์‚ฌ์šฉ์ž๊ฐ€ ๊ณ ๋ฅธ ํ˜ธ์ŠคํŒ…๊ณผ ๊ธฐ์กด ์ฝ”๋“œ๋ฅผ ๋”ฐ๋ฅธ๋‹ค. ์‚ฌ์‹ค(๊ฒฝ๋กœ, ์Šคํ‚ค๋งˆ, ํ—ˆ์šฉ origin)์€ docs MCP๋กœ ์ฝ๋Š” ๊ฐœ๋ฐœ์ž์„ผํ„ฐ ๋ฌธ์„œ๊ฐ€ ์ •๋ณธ์ด๊ณ , ์ด skill์€ ํŒ๋‹จ ๊ธฐ์ค€๊ณผ ์ ๊ฒ€ ์ˆœ์„œ๋ฅผ ๋”ํ•œ๋‹ค. ## ์‹คํ–‰ ์ˆœ์„œ ### 0. ๋ฒ”์œ„ ํ™•์ธ ์ž‘์—… ๋””๋ ‰ํ„ฐ๋ฆฌ๋ถ€ํ„ฐ ์ฝ๋Š”๋‹ค(ํด๋ผ์ด์–ธํŠธ `package.json`์˜ web-framework ๋ฒ„์ „, ์„œ๋ฒ„ ๋””๋ ‰ํ„ฐ๋ฆฌ, `wrangler.jsonc`ยท`wrangler.toml` ๊ฐ™์€ ํ˜ธ์ŠคํŒ… ์„ค์ •). ์„œ๋ฒ„๊ฐ€ ์•„์ง ์—†๊ณ  ์‚ฌ์šฉ์ž๊ฐ€ ํ˜ธ์ŠคํŒ…์„ ์ •ํ•˜์ง€ ์•Š์•˜์œผ๋ฉด ๋ฌด์—‡์œผ๋กœ ํ• ์ง€ ํ•œ ๋ฒˆ ๋ฌป๋Š”๋‹ค. ์‚ฌ์šฉ์ž๊ฐ€ ์ด๋ฏธ ๊ณ ๋ฅธ ํ˜ธ์ŠคํŒ…์„ ๋‹ค๋ฅธ ๊ฒƒ์œผ๋กœ ๋ฐ”๊พธ์ž๊ณ  ๋จผ์ € ์ œ์•ˆํ•˜์ง€ ์•Š๋Š”๋‹ค. ### 1. ๊ธฐ์ค€ ์ฝ๊ธฐ `../launch/references/server-runtime.md`๋ฅผ ์ฒ˜์Œ๋ถ€ํ„ฐ ๋๊นŒ์ง€ `Read`๋กœ ์ฝ๋Š”๋‹ค. ์„œ๋ฒ„ ์ฝ”๋“œ๋ฅผ ํ•œ ์ค„์ด๋ผ๋„ ์“ฐ๊ธฐ ์ „์— ์ฝ๋Š”๋‹ค. ์‚ฌ์šฉ์ž ์‹๋ณ„, mTLS ์ธ์ฆ์„œ, Workers ๊ฒฝ๋กœ, ์‘๋‹ต ๋ด‰ํˆฌ, CORS, ๋กœ์ปฌ ๊ฒ€์ฆ ๊ธฐ์ค€์ด ๋ชจ๋‘ ๊ฑฐ๊ธฐ ์žˆ๋‹ค. ๊ฒฝ๋กœ์™€ ์Šคํ‚ค๋งˆ๋Š” ๊ทธ ๋ฌธ์„œ๊ฐ€ ๊ฐ€๋ฆฌํ‚ค๋Š” docs ํŽ˜์ด์ง€๋ฅผ getPage๋กœ ์ฝ์–ด ๋งž์ถ˜๋‹ค. ### 2. ์‚ฌ์šฉ์ž ์‹๋ณ„ ์ •ํ•˜๊ธฐ - ๊ฐœ์ธ์ •๋ณด๊ฐ€ ํ•„์š” ์—†๋Š” ์‚ฌ์šฉ์ž๋ณ„ ์ €์žฅ์ด๋ฉด ์ต๋ช… ์‹๋ณ„ํ‚ค ๊ตํ™˜์„ ๋จผ์ € ์ œ์•ˆํ•œ๋‹ค. ํด๋ผ์ด์–ธํŠธ `User.createAnonymousKeyAuthCode()` โ†’ ์„œ๋ฒ„์˜ ๊ตํ™˜ API โ†’ `success.anonKey`. - ์‚ฌ์šฉ์ž๊ฐ€ ํ† ์Šค ๋กœ๊ทธ์ธ์„ ์ฝ• ์ง‘์—ˆ์œผ๋ฉด ๋”ฐ๋ฅด๋˜, ์ฝ˜์†”์—์„œ ํ† ์Šค ๋กœ๊ทธ์ธ ๋“ฑ๋ก๊ณผ ์•ฝ๊ด€ ์„ค์ •์ด ๋จผ์ € ๋ผ ์žˆ์–ด์•ผ ํ•œ๋‹ค๊ณ  ์•Œ๋ฆฐ๋‹ค(๋“ฑ๋ก ์ „์—๋Š” ํ† ํฐ ๋ฐœ๊ธ‰์ด errorCode 4050์œผ๋กœ ์‹คํŒจํ•œ๋‹ค). ํด๋ผ์ด์–ธํŠธ ์ชฝ๋งŒ ์š”์ฒญ๋ฐ›์•„๋„ ์ด ์„ ํ–‰ ์กฐ๊ฑด๊ณผ, ๋ฐ›์€ ์ธ๊ฐ€ ์ฝ”๋“œ๋ฅผ ์„œ๋ฒ„๊ฐ€ ํ† ํฐ์œผ๋กœ ๋ฐ”๊ฟ”์•ผ ํ•œ๋‹ค๋Š” ์ ์„ ํ•จ๊ป˜ ๋งํ•œ๋‹ค. - ํด๋ผ์ด์–ธํŠธ๊ฐ€ `getAnonymousKey()`๋กœ ์–ป์€ ๊ฐ’์„ ์„œ๋ฒ„๊ฐ€ ๊ทธ๋Œ€๋กœ ๋ฏฟ๊ฒŒ ์งœ์ง€ ์•Š๋Š”๋‹ค. ์‚ฌ์šฉ์ž๊ฐ€ ๊ทธ๋ ‡๊ฒŒ ํ•ด ๋‹ฌ๋ผ๊ณ  ํ•ด๋„ ์ด์œ (๊ทธ ๊ฐ’์€ ์š”์ฒญ์ž๋ฅผ ์ฆ๋ช…ํ•˜์ง€ ์•Š๋Š”๋‹ค)๋ฅผ ๋งํ•˜๊ณ  ๊ตํ™˜ ๋ฐฉ์‹์œผ๋กœ ์ง ๋‹ค. - ์‚ฌ์šฉ์ž๊ฐ€ SupabaseยทFirebase๋ฅผ ๊ณจ๋ž์œผ๋ฉด ์‚ฌ์šฉ์ž๋ณ„ ๋ฐ์ดํ„ฐ๋Š” ์„œ๋ฒ„๋ฅผ ๊ฑฐ์น˜๊ฒŒ ํ•˜๊ณ , ํด๋ผ์ด์–ธํŠธ ์ง๊ฒฐ์€ ๊ณต์šฉ ๋ฐ์ดํ„ฐ์—๋งŒ ์“ด๋‹ค. secret key๋Š” ์„œ๋ฒ„์—๋งŒ ๋‘๊ณ  `supabase.auth` ๊ฐ™์€ ์ž์ฒด ๋กœ๊ทธ์ธ์€ ๋ถ™์ด์ง€ ์•Š๋Š”๋‹ค. ์ž์„ธํ•œ ๊ฒฝ๊ณ„๋Š” server-runtime.md์˜ BaaS ์ ˆ. ### 3. ์ฝ”๋“œ ์“ฐ๊ธฐยท๊ณ ์น˜๊ธฐ server-runtime.md์˜ ๊ธฐ์ค€๋Œ€๋กœ ์“ด๋‹ค. ์ตœ์†Œํ•œ ๋‹ค์Œ์„ ์ง€ํ‚จ๋‹ค. - ํŒŒํŠธ๋„ˆ API ํ˜ธ์ถœ์—๋Š” mTLS ํด๋ผ์ด์–ธํŠธ ์ธ์ฆ์„œ๋ฅผ ์‹ฃ๋Š”๋‹ค. Workers๋Š” `mtls_certificates` ๋ฐ”์ธ๋”ฉ๊ณผ `env.<BINDING>.fetch`. - ์„ฑ๊ณต ํŒ์ •์€ HTTP ์ƒํƒœ๊ฐ€ ์•„๋‹ˆ๋ผ `resultType`์ด๊ณ , ๋ฐ์ดํ„ฐ๋Š” `success` ์•ˆ์— ์žˆ๋‹ค. - CORS๋Š” `*`๊ฐ€ ์•„๋‹ˆ๋ผ ์•ฑ์˜ SDK ๋ฒ„์ „์— ๋งž๋Š” ์ •ํ™•ํ•œ origin๋งŒ ํ—ˆ์šฉํ•œ๋‹ค. - ์ธ์ฆ์„œยทํ‚คยทํ† ํฐ ๊ฐ’์€ ์ฝ”๋“œ, ์ปค๋ฐ‹, ๋กœ๊ทธ, ์‘๋‹ต์— ๋„ฃ์ง€ ์•Š๋Š”๋‹ค. ๊ฒฝ๋กœ์™€ ๋ฐ”์ธ๋”ฉ ์ด๋ฆ„๋งŒ ๋‹ค๋ฃฌ๋‹ค. - ๋กœ์ปฌ ๊ฒ€์ฆ์€ ๊ฐ€์งœ mTLS fetch๋กœ ๋ด‰ํˆฌ ๊ฒฝ์šฐ๋ฅผ ๋Œ๋ฆฐ๋‹ค. ๋กœ๊ทธ์ธ ์šฐํšŒ ํ”Œ๋ž˜๊ทธ๋ฅผ ๋‘์ง€ ์•Š๋Š”๋‹ค. ### 4. ๋ณด๊ณ  ์‚ฌ์šฉ์ž๊ฐ€ ์ง์ ‘ ํ•ด์•ผ ํ•  ์ผ์„ ๋น ๋œจ๋ฆฌ์ง€ ์•Š๋Š”๋‹ค: ์ฝ˜์†”์—์„œ mTLS ์ธ์ฆ์„œ ๋ฐœ๊ธ‰, ํ˜ธ์ŠคํŒ… ๋กœ๊ทธ์ธ(`! npx wrangler login` ๋“ฑ), ๋ฐฐํฌ ํ›„ ํด๋ผ์ด์–ธํŠธ ์„œ๋ฒ„ ์ฃผ์†Œ ๊ฐฑ์‹ ๊ณผ ์žฌ๋นŒ๋“œ. ``` ์„œ๋ฒ„ ์ž‘์—… ๊ฒฐ๊ณผ ์‹๋ณ„ ๋ฐฉ์‹: <์ต๋ช… ์‹๋ณ„ํ‚ค ๊ตํ™˜ | ํ† ์Šค ๋กœ๊ทธ์ธ> ํ™•์ธํ•œ ๊ฒƒ: <๋กœ์ปฌ ํ…Œ์ŠคํŠธยท๋ด‰ํˆฌ ๊ฒฝ์šฐ> ์‚ฌ์šฉ์ž๊ฐ€ ํ•  ์ผ: <์ธ์ฆ์„œ ๋ฐœ๊ธ‰, ๋กœ๊ทธ์ธ, ๋ฐฐํฌ ๋“ฑ> ๋‹ค์Œ ๋‹จ๊ณ„ /ait:test-on-device # ์„œ๋ฒ„ ์ฃผ์†Œ๋กœ ๋‹ค์‹œ ๋นŒ๋“œํ•œ ๋ฒˆ๋“ค์„ ํฐ์—์„œ ํ™•์ธ # ๋ง๋กœ: "๋งŒ๋“  ๋ฏธ๋‹ˆ์•ฑ์„ ์‹ค์ œ ํ† ์Šค ์•ฑ์—์„œ ๋Œ๋ ค๋ณด๊ณ  ์‹ถ์–ด. ๋ฒˆ๋“ค ์˜ฌ๋ ค์„œ ํฐ์—์„œ ํ™•์ธํ•˜๊ฒŒ ํ•ด์ค˜" /ait:launch # ์ถœ์‹œ ์ „ ์ ๊ฒ€ # ๋ง๋กœ: "๊ฒ€์ˆ˜ ๋„ฃ๊ธฐ ์ „์— ํ•œ๋ฒˆ ๋ด์ค˜" ๋ฌธ์„œ๊ฐ€ ํ•„์š”ํ•˜๋ฉด docs MCP(searchDocumentation/getPage)๋กœ ์กฐํšŒํ•˜์„ธ์š”. ``` ## Out of scope (์ด skill์ด ํ•˜์ง€ ์•Š๋Š” ๊ฒƒ) - โŒ ์‚ฌ์šฉ์ž๊ฐ€ ์š”์ฒญํ•˜์ง€ ์•Š์€ ๋ฐฐํฌ(`wrangler deploy` ๋“ฑ), ์ฝ˜์†” ์“ฐ๊ธฐ - โŒ mTLS ์ธ์ฆ์„œ ๋ฐœ๊ธ‰(์ฝ˜์†”์—์„œ ์‚ฌ์šฉ์ž๊ฐ€ ํ•œ๋‹ค), ์ธ์ฆ์„œยทํ‚ค ํŒŒ์ผ ๋‚ด์šฉ ์ฝ๊ธฐ๋‚˜ ์ถœ๋ ฅ - โŒ ํ™”๋ฉด ์ž‘์—…(`/ait:design`), ๊ฒ€์ˆ˜ ์ ๊ฒ€(`/ait:launch`) - โŒ ํ™•์ธํ•˜์ง€ ๋ชปํ•œ ๋Ÿฐํƒ€์ž„์˜ mTLS ์ง€์› ์—ฌ๋ถ€ ๋‹จ์ • ## ์ฐธ๊ณ  - `../launch/references/server-runtime.md`: ์„œ๋ฒ„ ์—ฐ๊ฒฐ ๊ธฐ์ค€(์‹๋ณ„, mTLS, Workers, ์‘๋‹ต ๋ด‰ํˆฌ, CORS, ๋กœ์ปฌ ๊ฒ€์ฆ) - ์ง skill: `launch`(์ถœ์‹œ ์ „ ์ ๊ฒ€), `test-on-device`(ํฐ ํ™•์ธ), `design`(ํ™”๋ฉด)
View on GitHub