本文へ移動
cccskills
無料GitHub で公開

mcp-server-development

Expert guidance for building MCP (Model Context Protocol) servers using the TypeScript SDK. Use when developing MCP servers, implementing tools/resources/prompts, or working with the @modelcontextprotocol/sdk package. Covers server initialization, request handlers, Zod schemas, error handling, and JSON-RPC patterns.

日本語の概要は準備中です。原文の説明を表示しています。

インストール方法を見る

含まれるファイル(1)

  • SKILL.md5.7 KB

SKILL.md(原文)

インストールする前に、エージェントに与えられる指示の中身を確認できます。

This skill provides comprehensive guidance for building robust MCP servers, with specific focus on the unity-mcp-server architecture and patterns.

Core Philosophy

MCP servers bridge AI assistants to external systems. They must be:

  • Reliable: Handle errors gracefully, never crash unexpectedly
  • Discoverable: Tools should have clear, self-documenting schemas
  • Performant: Minimize latency, especially for stdio transport
  • Protocol-compliant: Follow JSON-RPC 2.0 and MCP spec exactly

Architecture Patterns

Handler-Based Design

ALWAYS use a handler class per tool. Each handler encapsulates:

  • Input validation (Zod schema)
  • Business logic execution
  • Error handling and response formatting
// Pattern: One handler per tool
export class SystemPingToolHandler extends BaseToolHandler {
  constructor(unityConnection) {
    super({
      name: 'system_ping',
      description: 'Check Unity Editor connectivity',
      inputSchema: { type: 'object', properties: {} }
    });
    this.unityConnection = unityConnection;
  }

  async execute(params) {
    const result = await this.unityConnection.send({ command: 'ping' });
    return { status: 'ok', ...result };
  }
}

BaseToolHandler Contract

All handlers MUST:

  1. Call super() with tool metadata
  2. Implement execute(params) method
  3. Return plain objects (framework handles JSON-RPC wrapping)
  4. Throw errors with descriptive messages

Input Validation with Zod

ALWAYS validate inputs before processing:

import { z } from 'zod';

const inputSchema = z.object({
  name: z.string().min(1).describe('GameObject name'),
  primitiveType: z.enum(['cube', 'sphere', 'cylinder']).optional()
});

validate(input) {
  return inputSchema.parse(input);
}

Transport Layer

Content-Length Framing (Standard)

MCP uses LSP-style Content-Length framing for stdio:

Content-Length: 123\r\n
\r\n
{"jsonrpc":"2.0","id":1,"method":"tools/call"...}

ALWAYS use Content-Length for output. NEVER mix framing formats in a session.

Hybrid Input (Compatibility)

Accept both Content-Length and NDJSON input for client compatibility:

  • Claude Desktop: Content-Length
  • Some CLI tools: NDJSON (newline-delimited)

Error Handling

Structured Errors

Use MCP error codes from the spec:

const McpError = {
  ParseError: -32700,
  InvalidRequest: -32600,
  MethodNotFound: -32601,
  InvalidParams: -32602,
  InternalError: -32603
};

throw new Error(JSON.stringify({
  code: McpError.InvalidParams,
  message: 'primitiveType must be one of: cube, sphere, cylinder'
}));

Error Response Format

{
  jsonrpc: '2.0',
  id: requestId,
  error: {
    code: -32602,
    message: 'Invalid params',
    data: { field: 'name', issue: 'required' }
  }
}

Unity-Specific Patterns

Command Protocol

Unity communication uses a simple request/response pattern:

const result = await this.unityConnection.send({
  command: 'gameobject_create',
  params: { name: 'Cube', primitiveType: 'cube' }
});

Workspace Root Resolution

ALWAYS include workspaceRoot in commands requiring file paths:

execute(params) {
  return this.unityConnection.send({
    command: 'screenshot_capture',
    workspaceRoot: config.workspaceRoot,
    ...params
  });
}

Testing Patterns

TDD for Handlers

  1. Contract test first: Define expected input/output schema
  2. Mock Unity connection: Isolate handler logic
  3. Test error paths: Invalid input, connection failures
  4. Test happy path last: After contracts are verified
describe('CreateGameObjectHandler', () => {
  it('validates primitiveType enum', async () => {
    const handler = new CreateGameObjectHandler(mockConnection);
    await assert.rejects(
      () => handler.handle({ name: 'Cube', primitiveType: 'invalid' }),
      /primitiveType must be one of/
    );
  });
});

Integration Testing

Test full request/response cycle including JSON-RPC framing:

const stdin = new PassThrough();
const stdout = new PassThrough();
const transport = new HybridStdioServerTransport(stdin, stdout);

stdin.write('Content-Length: 50\r\n\r\n{"jsonrpc":"2.0","id":1,"method":"ping"}');
// Assert stdout contains Content-Length response

Common Mistakes

Mixing framing formats:

  • NEVER: Output NDJSON after receiving Content-Length input
  • ALWAYS: Output Content-Length regardless of input format

Swallowing errors:

  • NEVER: catch (e) { return null; }
  • ALWAYS: Propagate errors with context

Missing validation:

  • NEVER: Trust raw input from clients
  • ALWAYS: Validate with Zod before processing

Blocking stdio:

  • NEVER: Synchronous operations on transport
  • ALWAYS: Use async/await throughout

Handler Registration

Register all handlers in a central index:

// src/handlers/index.js
export function createHandlers(unityConnection) {
  return [
    new SystemPingToolHandler(unityConnection),
    new CreateGameObjectHandler(unityConnection),
    new ScreenshotHandler(unityConnection),
    // ...
  ];
}

Remember

  • Content-Length always: Output framing must be consistent
  • Validate everything: Never trust client input
  • One handler, one tool: Keep handlers focused
  • Test error paths: Most bugs hide in error handling
  • Protocol compliance: Follow JSON-RPC 2.0 exactly

レビュー

まだレビューはありません。使ってみた感想をお寄せください。

コメント

ログインなしで書き込めます。使ってみた感想、質問、動かなかった環境などを気軽にどうぞ。

まだコメントはありません。最初のコメントを書いてみませんか。

送信するとすぐに公開されます。メールアドレスや電話番号などの個人情報は書かないでください。URL は 2 つまでです。

0 / 1000 文字

このフォームは reCAPTCHA で保護されており、Google のプライバシーポリシーと利用規約が適用されます。

同じリポジトリのスキル

drawio

無料

Create and edit draw.io diagrams in XML format. Use when the user wants to create flowcharts, architecture diagrams, sequence diagrams, or any visual diagrams. Handles XML structure, styling, fonts (Noto Sans JP), arrows, connectors, and PNG export.

日本語の概要は準備中です。原文の説明を表示しています。

akiojin/llmlb102026年10月18日 更新

Create distinctive, production-grade frontend interfaces with high design quality. Use this skill when the user asks to build web components, pages, or applications. Generates creative, polished code that avoids generic AI aesthetics.

日本語の概要は準備中です。原文の説明を表示しています。

akiojin/llmlb102026年10月18日 更新

Inspect GitHub PR for CI failures, merge conflicts, update-branch requirements, reviewer comments, change requests, and unresolved review threads. Create fix plans and implement after user approval. Reply to ALL reviewer comments with action taken or reason for not addressing, then resolve threads. Notify reviewers after fixes.

日本語の概要は準備中です。原文の説明を表示しています。

akiojin/llmlb102026年10月18日 更新

gwt-pr

無料

Create or update GitHub Pull Requests with the gh CLI, including deciding whether to create a new PR or only push based on existing PR merge status. Use when the user asks to open/create/edit a PR, generate a PR body/template, or says 'open a PR/create a PR/gh pr'. Defaults: base=develop, head=current branch (same-branch only; never create/switch branches).

日本語の概要は準備中です。原文の説明を表示しています。

akiojin/llmlb102026年10月18日 更新

Check GitHub PR status with the gh CLI, including unmerged PR detection and post-merge new-commit detection for the current branch.

日本語の概要は準備中です。原文の説明を表示しています。

akiojin/llmlb102026年10月18日 更新

Semantic search over project source files using vector embeddings. Use to find files related to a feature, bug, or concept.

日本語の概要は準備中です。原文の説明を表示しています。

akiojin/llmlb102026年10月18日 更新

akiojin のスキルをすべて見る

このスキルの問題を報告する