Skip to content
Development
Skill

/generate-codeful-mcp-tool

Generate a self-contained JavaScript server runtime and registration metadata for an MCP codeful tool. Use when the user asks to create a codeful MCP tool, generate server logic for an MCP tool, write a runTool function, build a Dataverse-backed MCP tool, or pair MCP server

From plugin
power-platform-skills
86896 skills19 agents4 MCP
Install
$ npx -y skills add microsoft/power-platform-skills --skill generate-codeful-mcp-tool --agent claude-code

How it fires

How this skill gets triggered: by you, by Claude, or both.

  • Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
  • You can call itInvoke it directly when you want it.
  • Slash command/generate-codeful-mcp-tool

Context preview

The summary Claude sees to decide when to auto-load this skill.

Generate a self-contained JavaScript server runtime and registration metadata for an MCP codeful tool. Use when the user asks to create a codeful MCP tool, generate server logic for an MCP tool, write a runTool function, build a Dataverse-backed MCP tool, or pair MCP server

SKILL.md

generate-codeful-mcp-tool.SKILL.md
name: generate-codeful-mcp-tool
version: 1.0.0
description: >
  Generate a self-contained JavaScript server runtime and registration metadata
  for an MCP codeful tool.
  Use when the user asks to create a codeful MCP tool, generate server logic for
  an MCP tool, write a runTool function, build a Dataverse-backed MCP tool, or
  pair MCP server logic with an MCP App widget.
author: Microsoft Corporation
argument-hint: <tool purpose, inputs, and expected result>
user-invocable: true
allowed-tools: Read, Write, Edit, Bash, Glob, Grep, AskUserQuestion, Skill

**Triggers:** codeful MCP tool, MCP server tool, generate runTool, MCP tool JavaScript, Dataverse MCP tool, server logic for MCP App

**Keywords:** mcp apps, codeful tool, runTool, dataApi, Dataverse, server runtime

**Aliases:** /generate-codeful-mcp-tool, /codeful-tool

**References:**

  • Host API types: [codeful-tool-host-data-api.d.ts](../../references/codeful-tool-host-data-api.d.ts)
  • Known-good tool: [account-summary.tool.js](../../samples/account-summary.tool.js)
  • Known-good metadata: [account-summary.tool.json](../../samples/account-summary.tool.json)
  • Widget generation: [generate-mcp-app-ui](../generate-mcp-app-ui/SKILL.md)

---

You generate a matched pair of files for one MCP tool:

  • `<tool-name>.tool.js`: the complete JavaScript server implementation.
  • `<tool-name>.tool.json`: declarative registration metadata containing the tool name,

description, input schema, output schema, and MCP tool annotations.

The host imports the JavaScript module and calls:

await runTool({ toolInput, dataApi });

Required information

Before generating, establish:

1. The tool's purpose and kebab-case tool name. Use the purpose to write a concise, model-actionable tool description; ask only when the intended behavior is ambiguous. 2. Its input fields, types, required fields, and constraints. Accept a JSON Schema, a representative input object, or an exact field description. Never guess the input shape. 3. The expected result, preferably as a representative output object. 4. Whether it reads or writes Dataverse, the requested tables in business terms, and whether any write creates, appends, updates, overwrites, or deletes state. 5. Whether the user also wants an MCP App widget.

Ask only for information that is missing. A sample input/output is preferred but not mandatory when the user has supplied an equally precise contract.

Phase 1: Read the runtime and metadata contracts

Read:

${PLUGIN_ROOT}/references/codeful-tool-host-data-api.d.ts
${PLUGIN_ROOT}/samples/account-summary.tool.js
${PLUGIN_ROOT}/samples/account-summary.tool.json

The generated runtime is plain ESM JavaScript, and the sidecar is plain JSON. Type files are generation-time references only and MUST NOT be imported by the output.

Phase 2: Verify Dataverse schema when needed

Skip this phase when the tool does not use Dataverse.

For a Dataverse-backed tool:

1. Confirm PAC CLI is authenticated to the intended environment. 2. Discover candidate tables:

   pac model list-tables --search "table terms"

`--search` is substring-based. Post-filter its output and accept a table only when its logical name exactly matches the selected result. If multiple tables remain plausible, ask the user to choose. 3. Create a unique temporary directory outside the final output path and generate types:

   pac model genpage generate-types --data-sources "logical1,logical2" --output-file "<temp>/RuntimeTypes.ts"

4. Read `RuntimeTypes.ts`. Extract the registered tables, exact readable/writable logical columns, lookup shapes, choice names, and raw numeric choice values. 5. Use ONLY names and values verified in that file. Custom columns are unpredictable; do not derive them from display names.

If discovery or type generation fails, stop and report the error. Do not fall back to invented tables or columns. Delete the temporary types and directory after validation so the final output contains only the requested `.tool.js`, `.tool.json`, and optional widget files.

Phase 3: Generate the paired tool artifacts

Write `<tool-name>.tool.js` and `<tool-name>.tool.json` in the user's working directory unless they requested another output directory. Both files MUST use the same basename, which MUST equal the confirmed kebab-case tool name.

The JavaScript file MUST:

  • Export exactly one MCP entry point named `runTool`, preferably:
  export async function runTool({ toolInput, dataApi }) {
    // complete implementation
  }
  • Be self-contained JavaScript with no runtime imports, packages, network calls,

filesystem access, environment-variable access, or generated-type dependency.

  • Validate all externally supplied `toolInput` before using it. Apply bounds to counts and

escape values interpolated into OData filters.

  • Use singular Dataverse entity logical names. Use exact logical column names in `select`,

`filter`, `orderBy`, and row objects.

  • Read choice and lookup labels from

`"<column>@OData.Community.Display.V1.FormattedValue"`.

  • Access query rows through `page.rows`. Follow `page.loadMoreRows()` only while

`page.hasMoreRows` is true and the function exists.

  • Set lookups through the verified `_<field>_value` shape from `RuntimeTypes.ts`; never

emit raw Web API `@odata.bind` keys.

  • Let `dataApi` failures throw. Catch only when adding useful context, and rethrow with the

original error as the cause. Never return a success-shaped fallback after a failed read or write.

  • Contain no placeholders, TODOs, ellipses, test credentials, or real environment IDs.
  • Return JSON-serializable values only. Never return `loadMoreRows`, functions, class

instances, or cyclic objects.

  • Emit telemetry only when the user explicitly asks for it, and never include tool inputs,

row contents, identifiers, or other user data in telemetry properties.

The JSON s

Read more
Ships withpower-platform-skills

Official agent skills/plugins for Power Platform development by Microsoft.

Get the whole plugin

Other skills on power-platform-skills.