toy-mcp-server
toy-mcp-server
MCP가 실제로 어떻게 동작하는지 배우기 위해 처음부터 직접 만든 최소한의 Model Context Protocol (MCP) 서버입니다. 보일러플레이트 생성기나 템플릿 없이 SDK만 사용했습니다.
첫 MCP 실습 프로젝트로, 도구 2개와 리소스 1개를 갖추고 stdio로 Claude Desktop에 연결됩니다.
하는 일
MCP는 LLM 클라이언트(예: Claude Desktop)가 학습 데이터에서 텍스트만 생성하는 대신, 로컬 머신에서 실행되는 함수를 호출할 수 있게 합니다. 이 서버는 다음을 제공합니다:
도구(Claude가 호출할 수 있는 함수):
roll_dice— 면 수를 설정할 수 있는 주사위 N개를 굴립니다.flip_coin— 동전을 N번 던집니다.
리소스(Claude가 가져올 수 있는 읽기 전용 데이터):
server-info— 서버의 기본 메타데이터(이름, 목적, 시작 시간)
Related MCP server: Random-Generator
존재 이유
LLM은 학습 데이터 밖의 어떤 것에도 접근할 수 없고, 기본적으로는 어떤 것도 하지 못합니다 — 텍스트만 생성할 뿐입니다. MCP는 모델에게 다음을 제공하는 표준적인 방법입니다:
능력 — 스스로는 갖지 못한 능력(예: 진짜 무작위성 — LLM은 난수를 스스로 고르는 것을 매우 못하는 것으로 유명합니다)
접근 — 모델이 알 수 없는 실시간 또는 비공개 데이터에 대한 접근
이 프로젝트는 MCP 서버를 실제 대상(데이터베이스, 인증이 필요한 API 등)에 연결하기 전에 그 아이디어를 시험해보는 작고 안전한 샌드박스입니다.
기술 스택
TypeScript
@modelcontextprotocol/sdk— 공식 MCP SDKzod— 도구 인수의 런타임 스키마 검증stdio 전송(Claude Desktop과의 로컬 하위 프로세스 통신)
프로젝트 구조
toy-mcp-server/
├── src/
│ └── index.ts # server setup, tools, and resource
├── build/ # compiled output (git-ignored)
├── package.json
├── tsconfig.json
└── README.md설정
1. 의존성 설치
npm install2. 빌드
npm run build3. Claude Desktop에 연결
Claude Desktop 구성 파일을 찾으세요:
macOS:
~/Library/Application Support/Claude/claude_desktop_config.jsonWindows: 보통
%LOCALAPPDATA%\Packages\<Claude package folder>\LocalCache\Roaming\Claude\claude_desktop_config.json경로에 있습니다. 정확한 경로는 설치 방법(Microsoft Store vs 직접 설치 프로그램)에 따라 다를 수 있습니다. 가장 확실한 방법: Claude Desktop을 열고 Settings → Developer → Local MCP servers → Edit Config로 이동하면, 앱이 실제로 읽는 정확한 파일이 열립니다.
이 서버를 mcpServers 아래에 추가하세요(기존 파일을 덮어쓰지 말고 병합하세요):
{
"mcpServers": {
"toy-mcp-server": {
"command": "node",
"args": ["/absolute/path/to/toy-mcp-server/build/index.js"]
}
}
}경로를 사용자 컴퓨터의 build/index.js 실제 절대 경로로 바꾸세요. Windows에서는 JSON 문자열에서 백슬래시(\\)를 이스케이프해야 합니다.
4. Claude Desktop 다시 시작
완전히 종료하고(창을 닫기만 하는 것만으로는 안 됩니다) 다시 실행하세요. toy-mcp-server가 연결된 것으로 표시되는지 Settings → Developer → Local MCP servers에서 확인하세요.
5. 사용해 보기
채팅에서 이렇게 요청해 보세요:
"6면체 주사위 3개 굴려 줘"
"동전을 10번 던져 줘"
응답 위에 작은 도구 호출 표시(예: "Roll Dice")가 보일 것입니다. 이는 Claude가 답을 미리 추측한 것이 아니라 실제로 함수를 호출했음을 확인시켜 줍니다.
작동 방식(간단히)
McpServer— 서버의 기능을 연결하는 어떤 클라이언트에게든 선언하는 객체registerTool(name, config, handler)— 호출 가능한 함수를 등록합니다.config.inputSchema는 핸들러가 실행되기 전에 모델이 보낸 인수를 Zod로 검증합니다.registerResource(name, uri, config, handler)— URI로 접근할 수 있고 인수 없이 가져오는 읽기 전용 데이터를 등록합니다.StdioServerTransport— 통신 규약입니다. Claude Desktop은 이 파일을 하위 프로세스로 실행하고 JSON-RPC로 stdin/stdout을 통해 통신합니다.console.log는 여기서 로깅에 사용하지 않습니다. stdout이 실제 프로토콜 채널이기 때문이며, 대신console.error(stderr)를 사용합니다.
다음 단계
장난감 도구를 실제 데이터베이스(Prisma를 통한 Postgres) 대상 도구로 교체하기
GitHub 백엔드 도구(예:
list_open_prs)를 추가해 토큰 기반 인증 연습로컬에서 실행하는 수고 대신 원격으로 호스팅하기 위해 Streamable HTTP transport 탐구
라이선스
MIT
Available Tools
2 toolsflip_coinFlip CoinB
Flip a coin one or more times
| Name | Required | Description | Default |
|---|---|---|---|
| times | No | Number of flips |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden of disclosing behavior. It merely says 'Flip a coin one or more times' without mentioning that the outcome is random, what the return format is (e.g., 'heads'/'tails'), or any side effects. The agent is left to guess the result structure.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, efficient sentence that states the action and the parameter scope. There is zero wasted text, and the core information is front-loaded. It is appropriately concise for a trivial tool.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given there is no output schema, the description should explain what the tool returns (e.g., results of each flip). It omits any mention of return values or randomness, leaving the agent with incomplete information to use the tool correctly. For a tool this simple, more context is still needed.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The single parameter 'times' is fully described in the schema ('Number of flips'), covering 100% of parameters. The tool description repeats the concept ('one or more times') but adds no extra meaning beyond what the schema already provides, so the baseline score of 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource ('Flip a coin') and adds the scope 'one or more times', which distinguishes it from the sibling roll_dice by naming the object of the action. An agent can clearly identify what this tool does.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No guidance is given about when to use this tool versus roll_dice. The description only states the action, leaving the agent to infer from the name that this is for coins rather than dice. No exclusions, prerequisites, or alternative-routing hints are provided.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
roll_diceRoll DiceB
Roll one or more dice with a given number of sides
| Name | Required | Description | Default |
|---|---|---|---|
| count | No | Number of dice to roll | |
| sides | No | Number of sides per die |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries full responsibility for behavioral disclosure. It does not mention that the result is random, that it is a safe non-mutating operation, or any other behavioral trait beyond the literal act of rolling. This is a significant gap for a tool whose entire purpose is random generation.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single concise sentence with no waste. The core action is front-loaded. It is appropriately sized for a tool with only two parameters, though it could have been slightly more informative without losing conciseness.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple tool with two parameters fully documented in the schema, the description is reasonably complete. However, the lack of any mention of randomness or return behavior (even though no output schema is provided) leaves a small but notable gap. An agent might not know the outcome is random without prior knowledge.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already documents both parameters (count and sides) with defaults, minimums, and maximums. The description adds no semantic meaning beyond what the schema provides, which meets the baseline of 3.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states exactly what the tool does: 'Roll one or more dice with a given number of sides'. It uses a specific verb (roll) and resource (dice), and clearly distinguishes from the sibling flip_coin, since dice and coins are different objects.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No guidance on when to use this tool versus the sibling flip_coin. The context implies dice vs coin, but the description does not explicitly state that this is for dice and flip_coin is for coins, nor does it mention any exclusions or alternative conditions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
2 tool updates
v1.0.0- First observed
flip_coin - First observed
roll_dice
TDQS
Scored across 2 tools
The two tools, roll_dice and flip_coin, are completely distinct in their purpose and behavior. There is no overlap or ambiguity, making it trivial for an agent to select the correct tool.
Both tool names follow the same verb_noun pattern (roll_dice, flip_coin), using snake_case and clear action-object structure. This is perfectly consistent and predictable.
With only 2 tools, the server is minimal, but given its explicit 'toy' purpose and narrow domain (random chance events), this count is appropriate and focused. It is slightly thin by general standards but well-scoped for a toy.
The tool surface covers the two most common random generators (dice and coin flips). While a generic random number generator or card draw might be expected in a broader utilities server, for a toy server focused on simple chance, these tools are sufficient and leave no obvious dead ends.
Maintenance
Related MCP Connectors
Public read-only MCP server for Genvernium product and developer resources.
Read-only developer, date, finance, and text utilities. Authless remote MCP server by Clean.tools.
Public, read-only MCP server for FarmNeural company facts, packages, and capabilities.
Read-only MCP server for The Quiet Protocol's engines, benchmarks, proof, and business data.
Related MCP Servers
- AlicenseAqualityCmaintenanceProduction-ready MCP server that provides LLMs with essential random generation abilities, including random integers, floats, choices, shuffling, and cryptographically secure tokens.754 PyPI50MIT
- AlicenseAqualityDmaintenanceAn encrypted and secure random number generation server that complies with the MCP protocol, suitable for AI applications, LLMS, and other systems that require high-quality random numbers.72Apache 2.0
- AlicenseNot gradedqualityDmaintenanceA general-purpose MCP server with utility tools including datetime information, safe math calculations, text statistics, JSON extraction, knowledge base search, and HTTP GET requests. It demonstrates server-side MCP implementation and can be connected to Claude Desktop or LangGraph agents.MIT
- AlicenseAqualityCmaintenanceMCP server providing true randomness capabilities to Claude, enabling cryptographically secure random number generation for games, decision-making, sampling, simulations, and any operation requiring genuine randomness.132MIT