For AI agents: a documentation index is available at the root level at /llms.txt and /llms-full.txt. Append /llms.txt to any URL for a page-level index, or .md for the markdown version of any page.
  • Getting Started
    • Welcome
    • Contributing
  • Concepts
    • Columns
    • Seed Datasets
    • Agent Rollout Ingestion
    • Custom Columns
    • Validators
    • Processors
    • Person Sampling
    • Traces
    • Architecture & Performance
    • Deployment Options
    • Security
  • Tutorials
    • Overview
    • The Basics
    • Structured Outputs, Jinja Expressions, and Conditional Generation
    • Seeding with an External Dataset
    • Providing Images as Context
    • Generating Images
    • Image-to-Image Editing
  • Recipes
    • Recipe Cards
      • Basic MCP Tool Use
      • PDF Document QA
      • Nemotron Super Search Agent
  • Plugins
    • Overview
    • Example Plugin
    • FileSystemSeedReader Plugins
    • Discover
  • Code Reference
    • Overview
  • Dev Notes
    • Overview
    • Have It Your Way
    • VLM Long Document Understanding
    • Push Datasets to Hugging Face Hub
    • Text-to-SQL for Nemotron Super
    • Async All the Way Down
    • Owning the Model Stack
NVIDIANVIDIA
Developer-friendly docs for your API
Privacy Policy | Your Privacy Choices | Terms of Service | Accessibility | Corporate Policies | Product Security | Contact

Copyright © 2026, NVIDIA Corporation.

LogoLogoNeMo Data Designer
RecipesMCP and Tool Use

Basic MCP Tool Use

||View as Markdown|
Previous

Agent Rollout Trace Distillation

Next

PDF Document QA

Download Recipe

Download the complete recipe script

1# SPDX-FileCopyrightText: Copyright (c) 2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
2# SPDX-License-Identifier: Apache-2.0
3# /// script
4# requires-python = ">=3.10"
5# dependencies = [
6# "data-designer",
7# "mcp",
8# ]
9# ///
10"""Basic MCP Recipe: Simple Tool Use Example
11
12This recipe demonstrates the minimal MCP tool-calling workflow with Data Designer:
13
141) Define a simple MCP server with basic tools (get_fact, add_numbers)
152) Configure Data Designer to use the MCP tools
163) Generate data that requires tool calls to complete
17
18Prerequisites:
19 - OPENAI_API_KEY environment variable for OpenAI provider model aliases.
20 - NVIDIA_API_KEY environment variable for NVIDIA provider model aliases (default model alias is "nvidia-text").
21
22Run:
23 # Basic usage (generates 2 records by default)
24 uv run basic_mcp.py
25
26 # For help message and available options
27 uv run basic_mcp.py --help
28"""
29
30from __future__ import annotations
31
32import argparse
33import json
34import os
35import sys
36from pathlib import Path
37
38from mcp.server.fastmcp import FastMCP
39
40import data_designer.config as dd
41from data_designer.interface import DataDesigner
42
43MCP_SERVER_NAME = "basic-tools"
44
45
46# =============================================================================
47# MCP Server Definition
48# =============================================================================
49
50mcp_server = FastMCP(MCP_SERVER_NAME)
51
52# Simple knowledge base for the get_fact tool
53FACTS = {
54 "python": "Python was created by Guido van Rossum and first released in 1991.",
55 "earth": "Earth is the third planet from the Sun and has one natural satellite, the Moon.",
56 "water": "Water (H2O) freezes at 0°C (32°F) and boils at 100°C (212°F) at sea level.",
57 "light": "The speed of light in a vacuum is approximately 299,792 kilometers per second.",
58}
59
60
61@mcp_server.tool()
62def get_fact(topic: str) -> str:
63 """Get a fact about a topic from the knowledge base.
64
65 Args:
66 topic: The topic to look up (e.g., "python", "earth", "water", "light")
67
68 Returns:
69 A fact about the topic, or an error message if not found.
70 """
71 topic_lower = topic.lower()
72 if topic_lower in FACTS:
73 return json.dumps({"topic": topic, "fact": FACTS[topic_lower]})
74 return json.dumps({"error": f"No fact found for topic: {topic}", "available_topics": list(FACTS.keys())})
75
76
77@mcp_server.tool()
78def add_numbers(a: float, b: float) -> str:
79 """Add two numbers together.
80
81 Args:
82 a: First number
83 b: Second number
84
85 Returns:
86 The sum of the two numbers.
87 """
88 result = a + b
89 return json.dumps({"a": a, "b": b, "sum": result})
90
91
92@mcp_server.tool()
93def list_topics() -> str:
94 """List all available topics in the knowledge base.
95
96 Returns:
97 List of available topics.
98 """
99 return json.dumps({"topics": list(FACTS.keys())})
100
101
102# =============================================================================
103# Data Designer Configuration
104# =============================================================================
105
106
107def build_config(model_alias: str, provider_name: str) -> dd.DataDesignerConfigBuilder:
108 """Build the Data Designer configuration for basic tool use."""
109 tool_config = dd.ToolConfig(
110 tool_alias="basic-tools",
111 providers=[provider_name],
112 allow_tools=["get_fact", "add_numbers", "list_topics"],
113 max_tool_call_turns=5,
114 timeout_sec=30.0,
115 )
116
117 config_builder = dd.DataDesignerConfigBuilder(tool_configs=[tool_config])
118
119 # Add a seed column with topics to look up
120 config_builder.add_column(
121 dd.SamplerColumnConfig(
122 name="topic",
123 sampler_type=dd.SamplerType.CATEGORY,
124 params=dd.CategorySamplerParams(values=["python", "earth", "water", "light"]),
125 )
126 )
127
128 # Add a column that uses the get_fact tool
129 config_builder.add_column(
130 dd.LLMTextColumnConfig(
131 name="fact_response",
132 model_alias=model_alias,
133 prompt=(
134 "Use the get_fact tool to look up information about '{{ topic }}', "
135 "then provide a one-sentence summary of what you learned."
136 ),
137 system_prompt="You must call the get_fact tool before answering. Only use information from tool results.",
138 tool_alias="basic-tools",
139 with_trace=dd.TraceType.ALL_MESSAGES,
140 )
141 )
142
143 # Add a column that uses the add_numbers tool
144 config_builder.add_column(
145 dd.SamplerColumnConfig(
146 name="num_a",
147 sampler_type=dd.SamplerType.UNIFORM,
148 params=dd.UniformSamplerParams(low=1, high=100),
149 )
150 )
151
152 config_builder.add_column(
153 dd.SamplerColumnConfig(
154 name="num_b",
155 sampler_type=dd.SamplerType.UNIFORM,
156 params=dd.UniformSamplerParams(low=1, high=100),
157 )
158 )
159
160 config_builder.add_column(
161 dd.LLMTextColumnConfig(
162 name="math_response",
163 model_alias=model_alias,
164 prompt=(
165 "Use the add_numbers tool to calculate {{ num_a }} + {{ num_b }}, "
166 "then report the result in a complete sentence."
167 ),
168 system_prompt="You must call the add_numbers tool to perform the calculation. Report the exact result.",
169 tool_alias="basic-tools",
170 with_trace=dd.TraceType.ALL_MESSAGES,
171 )
172 )
173
174 return config_builder
175
176
177# =============================================================================
178# Main Entry Points
179# =============================================================================
180
181
182def serve() -> None:
183 """Run the MCP server (called when launched as subprocess by Data Designer)."""
184 mcp_server.run()
185
186
187def parse_args() -> argparse.Namespace:
188 """Parse command line arguments."""
189 parser = argparse.ArgumentParser(description="Basic MCP tool use example with Data Designer.")
190 subparsers = parser.add_subparsers(dest="command")
191
192 # 'serve' subcommand for running the MCP server
193 subparsers.add_parser("serve", help="Run the MCP server (used by Data Designer)")
194
195 # Default command arguments (demo mode)
196 parser.add_argument("--model-alias", type=str, default="nvidia-text", help="Model alias to use for generation")
197 parser.add_argument("--num-records", type=int, default=2, help="Number of records to generate")
198 # For compatibility with Makefile test-run-recipes target (ignored in demo mode)
199 parser.add_argument("--artifact-path", type=str, default=None, help=argparse.SUPPRESS)
200
201 return parser.parse_args()
202
203
204def main() -> None:
205 """Main entry point for the demo."""
206 args = parse_args()
207
208 # Handle 'serve' subcommand
209 if args.command == "serve":
210 serve()
211 return
212
213 # Demo mode: run Data Designer with the MCP server
214 if os.environ.get("NVIDIA_API_KEY") is None and args.model_alias.startswith("nvidia"):
215 raise RuntimeError("NVIDIA_API_KEY must be set when using NVIDIA model aliases.")
216
217 # Configure MCP provider to run via stdio transport (local subprocess)
218 mcp_provider = dd.LocalStdioMCPProvider(
219 name=MCP_SERVER_NAME,
220 command=sys.executable,
221 args=[str(Path(__file__).resolve()), "serve"],
222 )
223
224 config_builder = build_config(
225 model_alias=args.model_alias,
226 provider_name=MCP_SERVER_NAME,
227 )
228
229 data_designer = DataDesigner(mcp_providers=[mcp_provider])
230 preview_results = data_designer.preview(config_builder, num_records=args.num_records)
231
232 # Display results
233 print("\n" + "=" * 60)
234 print("GENERATED DATA")
235 print("=" * 60)
236 preview_results.display_sample_record()
237
238
239if __name__ == "__main__":
240 main()