Loading source
Pulling the file list, source metadata, and syntax-aware rendering for this listing.
Source from repo
Comprehensive guide for building production-ready MCP servers with tools, resources, prompts, and React widgets using mcp-use.
Files
Skill
Size
Entrypoint
Format
Open file
Syntax-highlighted preview of this file as included in the skill package.
references/foundations/concepts.md
1# MCP Concepts23Core primitives you'll use to build MCP servers with mcp-use.45## The Four Primitives67### 1. Tool8A **backend action** the AI can call. Takes input, returns output.910**Use for:** Actions, operations, mutations, API calls1112```typescript13server.tool({ name, description, schema }, async (input) => {14// Your logic here15return text("result");16});17```1819→ **Detailed guide:** [../server/tools.md](../server/tools.md)2021### 2. Resource22**Read-only data** that clients can fetch. No input parameters (use resource templates for that).2324**Use for:** Configuration, static data, listings2526```typescript27server.resource({ uri, name, mimeType }, async () => {28return object({ data });29});30```3132→ **Detailed guide:** [../server/resources.md](../server/resources.md)3334### 3. Prompt35A **reusable message template** with parameters.3637**Use for:** Common prompts, instruction templates3839```typescript40server.prompt({ name, description, schema }, async (input) => {41return text(`Your prompt template with ${input.param}`);42});43```4445→ **Detailed guide:** [../server/prompts.md](../server/prompts.md)4647### 4. Widget (Tool + UI)48A **tool that returns visual UI**. Same as a tool but renders a React component.4950**Use for:** Browsing data, interactive selection, visual feedback5152```typescript53server.tool(54{ name, schema, widget: { name: "widget-name" } },55async (input) => widget({ props: { data }, output: text("...") })56);57```5859→ **Detailed guide:** [../widgets/basics.md](../widgets/basics.md)6061---6263## Decision Matrix6465| Need | Use | Example |66|------|-----|---------|67| Backend action | Tool | send-email, create-user, fetch-data |68| Read-only data | Resource | config, user-profile, api-docs |69| Prompt template | Prompt | code-review, summarize, translate |70| Visual UI | Widget Tool | search-results, calendar, dashboard |7172---7374## Tool vs Widget?7576**Use a tool (no widget) when:**77- Output is simple text or data78- No visual representation helps79- Quick conversational response8081**Use a widget when:**82- Browsing/comparing multiple items83- Visual data improves understanding (charts, images)84- Interactive selection is easier visually8586**When in doubt:** Use a widget. It makes the experience better.8788---8990## Key Patterns9192### 1. One tool = one capability93❌ `manage-users` (too broad)94✅ `create-user`, `delete-user`, `list-users`9596### 2. Don't lazy-load97Tool calls are expensive. Return all needed data upfront.9899❌ `list-products` + `get-product-details` (two calls)100✅ `list-products` returns full data including details101102### 3. Widget handles its own state103UI state (selections, filters) lives in the widget via `useState` or `setState`.104105❌ `select-item` tool, `set-filter` tool106✅ Widget manages internally107108### 4. `exposeAsTool` defaults to `false`109Widgets are not auto-registered as tools by default. When defining a custom tool with `widget: { name }`, omitting `exposeAsTool` (or leaving it `false`) is correct — the custom tool handles registration:110111```typescript112export const widgetMetadata: WidgetMetadata = {113description: "...",114props: z.object({...}),115// exposeAsTool defaults to false — correct for custom-tool pattern116};117```118119---120121## Next Steps122123- Build your first tool: [quickstart.md](quickstart.md)124- Deep dive on tools: [../server/tools.md](../server/tools.md)125- Learn about widgets: [../widgets/basics.md](../widgets/basics.md)126