mcp-tool-resource-pattern

mcp-tool-resource-pattern is a skill for Claude Code from a5c-ai/babysitter. It costs 49 tokens per session (2,527 once invoked), scanned A, original, MIT.

A standard MCP App structure that connects a tool, which returns data, to a resource, which displays an interactive interface. MCP, or Model Context Protocol, is a way for AI hosts to call tools and show their results.

In plain words
What is it for?
Use it to register tools and HTML resources, link them with a resource address, pass structured results to the UI, and define tool input schemas.
Why use it?
It provides a defined way to pass structured data to an embedded UI while still returning plain text for hosts that cannot display the interface.

Skill for Claude Code

Written for Claude Code: allowed-tools in frontmatter.

Needs its repository: it reads a path above its own folder, which exists only inside the repository. The line is path.join(__dirname, '../dist/mcp-app.html'),.

Good fit Use it to register tools and HTML resources, link them with a resource address, pass structured results to the UI, and define tool input schemas.

Compare 6 skills from other repositories ↓
About the project

Babysitter is a workflow engine for AI coding agents that enforces predefined steps, quality checks, human approvals, and decision records. It is used to coordinate complex, repeatable agent workflows across supported coding tools. The catalogue contains skills, agents, instructions, settings, a plugin, and an MCP integration for its workflow.

a5c-ai/babysitter · 1,778 stars · on GitHub · a5c.ai

Install

Getting it into your agent

It runs from inside its repository, so the clone comes first — what it calls does not travel with the file alone.

Clone the repo
git clone --depth 1 https://github.com/a5c-ai/babysitter
agentmods
npx agentmods add skills/a5c-ai/babysitter/mcp-tool-resource-pattern

Made for: Claude Code.

Wrote this? Show the measurements

A badge with what this costs and how it scanned, read live from this page, so it follows the numbers instead of freezing them. Markdown for a README, HTML for a documentation site or a project page.

agentmods badge for mcp-tool-resource-pattern

README.md
[![agentmods](https://agentmods.dev/badge/skills/a5c-ai/babysitter/mcp-tool-resource-pattern/github.svg)](https://agentmods.dev/skills/a5c-ai/babysitter/mcp-tool-resource-pattern)
Your own site
<a href="https://agentmods.dev/skills/a5c-ai/babysitter/mcp-tool-resource-pattern"><img src="https://agentmods.dev/badge/skills/a5c-ai/babysitter/mcp-tool-resource-pattern/github.svg" alt="Measured on agentmods" height="20"></a>

Or the 80×15 button, for a site that already has a row of RSS and ATOM ones. Only the verdict fits; the numbers stay here.

agentmods 80×15 button for mcp-tool-resource-pattern

Your own site · 80×15
<a href="https://agentmods.dev/skills/a5c-ai/babysitter/mcp-tool-resource-pattern"><img src="https://agentmods.dev/badge/skills/a5c-ai/babysitter/mcp-tool-resource-pattern.svg" alt="Reviewed on agentmods" width="80" height="20"></a>
Per session 49 Skills are progressive disclosure: only the name and description are preloaded; the body loads when the skill is used.
When invoked 2,527 The whole file, excluding the scripts and references it only reads on demand.
Security scan A 0 findings. A grade says what 26 rules found in the file — not that it is safe. Third-party audits
  • NVIDIA SkillSpector pass 7 Sept 2026
How audits are shown
Origin original No closer match found in the catalogue.
Token cost

What it costs to keep this loaded

Counted locally with the o200k_base tokenizer, which is exact for GPT models; Claude uses its own tokenizer and its counts differ. Treat this as one consistent yardstick across the catalogue rather than a bill. Prices are per million input tokens.

ModelPer sessionOnce invoked
Fable 5.1 $0.00049 $0.02527
Opus 5 $0.00024 $0.01264
Sonnet 5 $0.00010 $0.00505
Haiku 4.5 $0.00005 $0.00253

Measured 4d ago against content hash f3dc2e09d66c, method: parsed. Prices are Anthropic first-party input rates as of 2026-09-09, from the pricing page.

Security

Grade A, and why

mcp-tool-resource-pattern scanned grade A with 0 findings against 26 rules in 11 categories — prompt injection, anti-refusal, data exfiltration, privilege escalation, supply chain, agent snooping, system-prompt leakage, SSRF and excessive agency — measured 4d ago.

A static scan of the body, not an audit. Every finding is printed with the line that produced it so you can judge whether it matters here. A mod is markdown that instructs an agent; that is exactly why what it instructs is worth reading.

Nothing flagged

None of the 26 patterns this scan looks for appear in this file: no shell pipes, no recursive deletes, no credential paths, no hidden text, no instruction-override or anti-refusal phrasing, no agent-config snooping. That is not a guarantee, it is the absence of the things that are checkable.

library/specializations/ai-agents-conversational/skills/mcp-tool-resource-pattern/SKILL.md · 339 lines

How it starts

The opening of the file, as written. The whole thing — 339 lines — stays where its author put it; the contents beside it link to each section on GitHub.

mcp-tool-resource-pattern

Implement the foundational Tool + Resource pattern that every MCP App requires: a Tool that returns data and references a Resource that serves the interactive UI.

Overview

Every MCP App is built on the Tool + Resource pattern:

  1. Tool (registered via registerAppTool): Called by the LLM/host, returns data. Its _meta.ui.resourceUri tells the host which Resource provides the UI.
  2. Resource (registered via registerAppResource): Serves a bundled HTML file that renders the interactive UI in a sandboxed iframe.
  3. The tool passes data to the UI via structuredContent (available in ontoolresult handler).
  4. The tool MUST also return a content array with text fallback for non-UI hosts.

Capabilities

registerAppTool Implementation

  • Register tools with _meta.ui.resourceUri linking to a resource
  • Pass data via structuredContent for rich UI rendering
  • Always include content array with text fallback
  • Configure tool input schemas via Zod

registerAppResource Implementation

  • Register HTML resources with RESOURCE_MIME_TYPE
  • Serve single-file bundled HTML
  • Configure CSP domains in contents[] return
  • Support multiple tools sharing the same resource URI

App-Only Helper Tools

  • Create tools with visibility: ['app'] -- only callable from the UI iframe, not by the LLM
  • Use cases: polling for updates, loading additional data, pagination, state mutations
  • Implement via app.callServerTool() from client-side

Graceful Degradation

  • Detect UI capability via getUiCapability() on the server
  • Return richer responses when UI is available
  • Always maintain text-only fallback path

Usage

Basic Tool + Resource Pattern

import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
import {
  registerAppTool,
  registerAppResource,
  RESOURCE_MIME_TYPE,
} from '@modelcontextprotocol/ext-apps';
import { z } from 'zod';
import fs from 'fs';
import path from 'path';

const server = new McpServer({ name: 'my-app', version: '1.0.0' });

// Read the bundled HTML (built by vite-plugin-singlefile)
const bundledHtml = fs.readFileSync(
  path.join(__dirname, '../dist/mcp-app.html'),
  'utf-8'
);

// 1. Register the Resource (serves the UI)
registerAppResource(server, {
  uri: 'app:///my-app',
  name: 'My App UI',
  mimeType: RESOURCE_MIME_TYPE,
  async read() {
    return {
      contents: [{
        uri: 'app:///my-app',
        mimeType: RESOURCE_MIME_TYPE,
        text: bundledHtml,
        // CSP domains (if needed)
        // resourceDomains: ['https://cdn.example.com'],
        // connectDomains: ['https://api.example.com'],
      }],
    };
  },
});

// 2. Register the Tool (returns data, references the resource)
registerAppTool(server, {
  name: 'show_dashboard',
  description: 'Show an interactive dashboard',
  inputSchema: {
    type: 'object' as const,
    properties: {
      query: { type: 'string', description: 'Search query' },
    },
    required: ['query'],
  },
  // _meta.ui.resourceUri is set automatically by registerAppTool
  resourceUri: 'app:///my-app',
  async handler(args) {
    const data = await fetchDashboardData(args.query);

    return {
      // Text fallback for non-UI hosts (REQUIRED)
      content: [
        {
          type: 'text' as const,
          text: `Dashboard results for "${args.query}":\n${formatAsText(data)}`,
        },
      ],
      // Rich data for the UI (available in ontoolresult handler)
      structuredContent: {
        query: args.query,
        results: data.results,
        metadata: data.metadata,
      },
    };
  },
});

Read the full file on GitHub · 339 lines

Files

What ships with it

1 file beside SKILL.md in the same directory: the scripts, references and assets a skill reads on demand. Not counted in the per-session cost; read them before you install if any of them is executable.

Changes

What this file has done since we first saw it

Hashed on every crawl. A supply-chain change to an agent config is a question of when, not whether, so the history is kept rather than the latest state alone.

  1. 4d ago First seen · 339 lines · 49 tokens per session scan A f3dc2e09d66c

Subscribe to this mod's changes

mcp-tool-resource-pattern is a skill published in the GitHub repository a5c-ai/babysitter (1,778 stars, last pushed 3d ago), licensed MIT. It adds 49 tokens to every session and 2,527 once invoked, about $0.0002 per session on Opus 5. A static security scan graded it A with 0 findings. No closer match exists in the catalogue, so it is treated as the original; first seen 2026-09-05.