plugins/medusa-dev/skills/creating-internal-agents/SKILL.md
--- name: creating-agents-in-medusa description: Use when building an internal admin-facing AI agent in a Medusa project. These agents are operated by merchants and store operators — not customers. Covers data models, module service, agent runtime (tools, system prompt, streamText), streaming API routes (NDJSON), and admin UI chat extensions. Load for any internal agent type: store operations assistant, product audit, cohort analysis, customer service tooling for support staff, etc. Do NOT use f
npx skillsauth add medusajs/medusa-agent-skills plugins/medusa-dev/skills/creating-internal-agentsInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
This skill covers the full stack for adding an internal, admin-facing AI agent to a Medusa project. These agents are used by merchants and store operators through the Medusa admin dashboard — not by customers on a storefront. For customer-facing agents (e.g. a storefront chatbot), a different architecture is needed: public API routes, no MedusaExec, and storefront auth.
src/api/admin/, the UI lives in the Medusa admin dashboard, and access is gated by admin authentication throughout.AuthenticatedMedusaRequest and live under src/api/admin/. An unauthenticated endpoint is a remote code execution vulnerability.AgentSession and AgentMessage are shared infrastructure. Use agent_type to distinguish sessions per agent. Never create separate models per agent.MedusaContainer via experimental_context — never import services directly in tool files; that causes circular dependencies.Content-Type: application/x-ndjson, one JSON object per line followed by \n.npx medusa db:generate agent && npx medusa db:migrate).tool() — the config object overrides them at runtime.⚠️ The quick reference below is NOT sufficient for implementation. Load the relevant reference file before writing any code.
| Task | Load this file |
|------|---------------|
| Defining conversation models | reference/data-models.md |
| Setting up the module service | reference/service.md |
| Configuring tools, prompt, streamText | reference/agent-setup.md |
| Building the POST chat endpoint | reference/api-route.md |
| Implementing NDJSON streaming | reference/streaming.md |
| Building the admin chat UI | reference/admin-extension.md |
| Giving the agent code execution capability | reference/medusa-exec.md |
Minimum requirement: Load at least the reference file matching your current task before writing code.
Load these alongside this skill when relevant:
building-with-medusa — Medusa module patterns, workflows, data model conventions. Load when implementing the module service or custom backend logic.building-admin-dashboard-customizations — Admin UI component patterns, TanStack Query, route registration. Load when building or extending the admin chat UI.src/modules/agent/
index.ts ← Module() export + AGENT_MODULE constant
service.ts ← MedusaService + Anthropic client + stream(messages, container, config)
models/
session.ts ← AgentSession (shared across all agents, filtered by agent_type)
message.ts ← AgentMessage
agents/index.ts ← streamText() orchestration
tools/
medusa-exec.ts ← MedusaExec tool (primary tool for all data operations)
todo-write.ts ← TodoWrite tool
config/
<agent-type>.ts ← per-agent system prompt + tool descriptions
src/api/admin/agent/<agent-type>/
route.ts ← POST (AuthenticatedMedusaRequest, session lifecycle, NDJSON stream)
sessions/route.ts ← GET session list (filtered by agent_type)
sessions/[id]/route.ts ← GET messages for a session
src/admin/routes/<agent-type>/
page.tsx ← React chat UI (admin extension)
src/lib/code-mode/
executor.ts ← sandboxed TypeScript executor used by MedusaExec
Verify you are NOT doing these:
Security:
MedusaRequest instead of AuthenticatedMedusaRequestsrc/api/admin/Architecture:
AgentSession/AgentMessage models per agent instead of using agent_typeexperimental_contextStreaming:
res.end() after the stream loop (response never closes)Transfer-Encoding: chunked or Content-Type: application/x-ndjson headersModule:
medusa-config.tstool() instead of the config objectreference/data-models.md - model.define(), agent_type discriminator, relationships, migrations
reference/service.md - MedusaService extension, Anthropic init, stream(), module index, config registration
reference/agent-setup.md - streamText(), MedusaExec tool wiring, system prompt, context passing
reference/api-route.md - POST route, session lifecycle, message persistence, streaming headers
reference/streaming.md - NDJSON emission, fullStream iteration, chunk types, client-side parsing
reference/admin-extension.md - React chat UI, streaming fetch, message rendering, tool call display, session sidebar
reference/medusa-exec.md - Executor setup, MedusaExec tool, query.graph() patterns, error codes
Once the agent is implemented, test it end-to-end directly in the admin dashboard:
npx medusa develop)defineRouteConfig)If anything is broken, check:
Content-Type: application/x-ndjson with chunked lines[agent] tool_call and [agent] step_finish lines confirm the agent is runningagent_session and agent_message tables should have rows with the correct agent_typetools
--- name: mcloud-auth description: Execute mcloud authentication and context commands: login, logout, whoami, use, version, and signup. Use when setting up the CLI, switching accounts, verifying auth state, setting the active org/project/environment context, or checking the CLI version. allowed-tools: Bash(mcloud whoami*), Bash(mcloud use*), Bash(mcloud version*), Bash(mcloud logout*), Bash(jq*) --- # Cloud CLI: Auth and Context Commands Execute authentication and context commands for the Medu
tools
Create an admin user in Medusa
data-ai
Run database migrations in Medusa
data-ai
Generate database migrations for a Medusa module