fast-agent-mcp 0.0.7__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of fast-agent-mcp might be problematic. Click here for more details.

Files changed (100) hide show
  1. fast_agent_mcp-0.0.7.dist-info/METADATA +322 -0
  2. fast_agent_mcp-0.0.7.dist-info/RECORD +100 -0
  3. fast_agent_mcp-0.0.7.dist-info/WHEEL +4 -0
  4. fast_agent_mcp-0.0.7.dist-info/entry_points.txt +5 -0
  5. fast_agent_mcp-0.0.7.dist-info/licenses/LICENSE +201 -0
  6. mcp_agent/__init__.py +0 -0
  7. mcp_agent/agents/__init__.py +0 -0
  8. mcp_agent/agents/agent.py +277 -0
  9. mcp_agent/app.py +303 -0
  10. mcp_agent/cli/__init__.py +0 -0
  11. mcp_agent/cli/__main__.py +4 -0
  12. mcp_agent/cli/commands/bootstrap.py +221 -0
  13. mcp_agent/cli/commands/config.py +11 -0
  14. mcp_agent/cli/commands/setup.py +229 -0
  15. mcp_agent/cli/main.py +68 -0
  16. mcp_agent/cli/terminal.py +24 -0
  17. mcp_agent/config.py +334 -0
  18. mcp_agent/console.py +28 -0
  19. mcp_agent/context.py +251 -0
  20. mcp_agent/context_dependent.py +48 -0
  21. mcp_agent/core/fastagent.py +1013 -0
  22. mcp_agent/eval/__init__.py +0 -0
  23. mcp_agent/event_progress.py +88 -0
  24. mcp_agent/executor/__init__.py +0 -0
  25. mcp_agent/executor/decorator_registry.py +120 -0
  26. mcp_agent/executor/executor.py +293 -0
  27. mcp_agent/executor/task_registry.py +34 -0
  28. mcp_agent/executor/temporal.py +405 -0
  29. mcp_agent/executor/workflow.py +197 -0
  30. mcp_agent/executor/workflow_signal.py +325 -0
  31. mcp_agent/human_input/__init__.py +0 -0
  32. mcp_agent/human_input/handler.py +49 -0
  33. mcp_agent/human_input/types.py +58 -0
  34. mcp_agent/logging/__init__.py +0 -0
  35. mcp_agent/logging/events.py +123 -0
  36. mcp_agent/logging/json_serializer.py +163 -0
  37. mcp_agent/logging/listeners.py +216 -0
  38. mcp_agent/logging/logger.py +365 -0
  39. mcp_agent/logging/rich_progress.py +120 -0
  40. mcp_agent/logging/tracing.py +140 -0
  41. mcp_agent/logging/transport.py +461 -0
  42. mcp_agent/mcp/__init__.py +0 -0
  43. mcp_agent/mcp/gen_client.py +85 -0
  44. mcp_agent/mcp/mcp_activity.py +18 -0
  45. mcp_agent/mcp/mcp_agent_client_session.py +242 -0
  46. mcp_agent/mcp/mcp_agent_server.py +56 -0
  47. mcp_agent/mcp/mcp_aggregator.py +394 -0
  48. mcp_agent/mcp/mcp_connection_manager.py +330 -0
  49. mcp_agent/mcp/stdio.py +104 -0
  50. mcp_agent/mcp_server_registry.py +275 -0
  51. mcp_agent/progress_display.py +10 -0
  52. mcp_agent/resources/examples/decorator/main.py +26 -0
  53. mcp_agent/resources/examples/decorator/optimizer.py +78 -0
  54. mcp_agent/resources/examples/decorator/orchestrator.py +68 -0
  55. mcp_agent/resources/examples/decorator/parallel.py +81 -0
  56. mcp_agent/resources/examples/decorator/router.py +56 -0
  57. mcp_agent/resources/examples/decorator/tiny.py +22 -0
  58. mcp_agent/resources/examples/mcp_researcher/main-evalopt.py +53 -0
  59. mcp_agent/resources/examples/mcp_researcher/main.py +38 -0
  60. mcp_agent/telemetry/__init__.py +0 -0
  61. mcp_agent/telemetry/usage_tracking.py +18 -0
  62. mcp_agent/workflows/__init__.py +0 -0
  63. mcp_agent/workflows/embedding/__init__.py +0 -0
  64. mcp_agent/workflows/embedding/embedding_base.py +61 -0
  65. mcp_agent/workflows/embedding/embedding_cohere.py +49 -0
  66. mcp_agent/workflows/embedding/embedding_openai.py +46 -0
  67. mcp_agent/workflows/evaluator_optimizer/__init__.py +0 -0
  68. mcp_agent/workflows/evaluator_optimizer/evaluator_optimizer.py +359 -0
  69. mcp_agent/workflows/intent_classifier/__init__.py +0 -0
  70. mcp_agent/workflows/intent_classifier/intent_classifier_base.py +120 -0
  71. mcp_agent/workflows/intent_classifier/intent_classifier_embedding.py +134 -0
  72. mcp_agent/workflows/intent_classifier/intent_classifier_embedding_cohere.py +45 -0
  73. mcp_agent/workflows/intent_classifier/intent_classifier_embedding_openai.py +45 -0
  74. mcp_agent/workflows/intent_classifier/intent_classifier_llm.py +161 -0
  75. mcp_agent/workflows/intent_classifier/intent_classifier_llm_anthropic.py +60 -0
  76. mcp_agent/workflows/intent_classifier/intent_classifier_llm_openai.py +60 -0
  77. mcp_agent/workflows/llm/__init__.py +0 -0
  78. mcp_agent/workflows/llm/augmented_llm.py +645 -0
  79. mcp_agent/workflows/llm/augmented_llm_anthropic.py +539 -0
  80. mcp_agent/workflows/llm/augmented_llm_openai.py +615 -0
  81. mcp_agent/workflows/llm/llm_selector.py +345 -0
  82. mcp_agent/workflows/llm/model_factory.py +175 -0
  83. mcp_agent/workflows/orchestrator/__init__.py +0 -0
  84. mcp_agent/workflows/orchestrator/orchestrator.py +407 -0
  85. mcp_agent/workflows/orchestrator/orchestrator_models.py +154 -0
  86. mcp_agent/workflows/orchestrator/orchestrator_prompts.py +113 -0
  87. mcp_agent/workflows/parallel/__init__.py +0 -0
  88. mcp_agent/workflows/parallel/fan_in.py +350 -0
  89. mcp_agent/workflows/parallel/fan_out.py +187 -0
  90. mcp_agent/workflows/parallel/parallel_llm.py +141 -0
  91. mcp_agent/workflows/router/__init__.py +0 -0
  92. mcp_agent/workflows/router/router_base.py +276 -0
  93. mcp_agent/workflows/router/router_embedding.py +240 -0
  94. mcp_agent/workflows/router/router_embedding_cohere.py +59 -0
  95. mcp_agent/workflows/router/router_embedding_openai.py +59 -0
  96. mcp_agent/workflows/router/router_llm.py +301 -0
  97. mcp_agent/workflows/swarm/__init__.py +0 -0
  98. mcp_agent/workflows/swarm/swarm.py +320 -0
  99. mcp_agent/workflows/swarm/swarm_anthropic.py +42 -0
  100. mcp_agent/workflows/swarm/swarm_openai.py +41 -0
@@ -0,0 +1,221 @@
1
+ """Bootstrap command to create example applications."""
2
+
3
+ import shutil
4
+ from pathlib import Path
5
+ import typer
6
+ from rich.console import Console
7
+ from rich.table import Table
8
+ from rich.panel import Panel
9
+
10
+ app = typer.Typer(
11
+ help="Create example applications and learn MCP Agent patterns",
12
+ no_args_is_help=True,
13
+ )
14
+ console = Console()
15
+
16
+ EXAMPLE_TYPES = {
17
+ "decorator": {
18
+ "description": "Decorator pattern example showing different agent composition approaches",
19
+ "details": """
20
+ The decorator example shows how to:
21
+ - Compose agents using the decorator pattern
22
+ - Add capabilities like optimization and routing
23
+ - Run agents in parallel
24
+ - Handle complex agent interactions
25
+ """,
26
+ "files": [
27
+ "main.py",
28
+ "optimizer.py",
29
+ "orchestrator.py",
30
+ "parallel.py",
31
+ "router.py",
32
+ "tiny.py",
33
+ ],
34
+ },
35
+ "researcher": {
36
+ "description": "Research agent example with evaluation optimization",
37
+ "details": """
38
+ The researcher example demonstrates:
39
+ - Building a research-focused agent
40
+ - Implementing evaluation strategies
41
+ - Optimizing agent responses
42
+ - Handling complex research tasks
43
+ """,
44
+ "files": ["main.py", "main-evalopt.py"],
45
+ },
46
+ }
47
+
48
+
49
+ def copy_example_files(
50
+ example_type: str, target_dir: Path, force: bool = False
51
+ ) -> list[str]:
52
+ """Copy example files from resources to target directory."""
53
+ created = []
54
+
55
+ # During development, use the source directory
56
+ source_dir = (
57
+ Path(__file__).parent.parent.parent
58
+ / "resources"
59
+ / "examples"
60
+ / ("decorator" if example_type == "decorator" else "mcp_researcher")
61
+ )
62
+
63
+ if not source_dir.exists():
64
+ console.print(f"[red]Error: Source directory not found: {source_dir}[/red]")
65
+ return created
66
+
67
+ for filename in EXAMPLE_TYPES[example_type]["files"]:
68
+ source = source_dir / filename
69
+ target = target_dir / filename
70
+
71
+ try:
72
+ if not source.exists():
73
+ console.print(f"[red]Error: Source file not found: {source}[/red]")
74
+ continue
75
+
76
+ if target.exists() and not force:
77
+ console.print(f"[yellow]Skipping[/yellow] {filename} (already exists)")
78
+ continue
79
+
80
+ shutil.copy2(source, target)
81
+ created.append(filename)
82
+ console.print(f"[green]Created[/green] {filename}")
83
+
84
+ except Exception as e:
85
+ console.print(f"[red]Error copying {filename}: {str(e)}[/red]")
86
+
87
+ return created
88
+
89
+
90
+ def show_examples_overview():
91
+ """Show an overview of available examples."""
92
+ console.print("\n[bold]MCP Agent Example Applications[/bold]")
93
+ console.print("Learn how to build effective agents through practical examples\n")
94
+
95
+ # Create a table for the examples
96
+ table = Table(title="Available Examples")
97
+ table.add_column("Example", style="green")
98
+ table.add_column("Description")
99
+ table.add_column("Files", style="blue")
100
+
101
+ for name, info in EXAMPLE_TYPES.items():
102
+ table.add_row(name, info["description"], "\n".join(info["files"]))
103
+
104
+ console.print(table)
105
+
106
+ # Show usage instructions
107
+ console.print("\n[bold]Usage:[/bold]")
108
+ console.print("1. Create a new example:")
109
+ console.print(" mcp-agent bootstrap create <example-name>")
110
+ console.print("\n2. Specify a directory:")
111
+ console.print(
112
+ " mcp-agent bootstrap create <example-name> --directory ./my-project"
113
+ )
114
+ console.print("\n3. Force overwrite existing files:")
115
+ console.print(" mcp-agent bootstrap create <example-name> --force")
116
+
117
+ console.print("\n[bold]Examples:[/bold]")
118
+ console.print(" mcp-agent bootstrap create decorator")
119
+ console.print(
120
+ " mcp-agent bootstrap create researcher --directory ./research-agent"
121
+ )
122
+
123
+
124
+ @app.callback(invoke_without_command=True)
125
+ def main(ctx: typer.Context):
126
+ """Bootstrap example applications to learn MCP Agent patterns.
127
+
128
+ Create working examples that demonstrate different agent patterns and capabilities.
129
+ Use these as starting points for your own agent applications.
130
+ """
131
+ if ctx.invoked_subcommand is None:
132
+ show_examples_overview()
133
+
134
+
135
+ @app.command()
136
+ def create(
137
+ example_type: str = typer.Argument(
138
+ None, help="Type of example to create (decorator or researcher)"
139
+ ),
140
+ directory: str = typer.Option(
141
+ ".", "--directory", "-d", help="Directory where example files will be created"
142
+ ),
143
+ force: bool = typer.Option(
144
+ False, "--force", "-f", help="Force overwrite existing files"
145
+ ),
146
+ ):
147
+ """Create a new example application.
148
+
149
+ This will create a set of example files based on the chosen type:
150
+
151
+ \b
152
+ - decorator: Decorator pattern example showing different agent composition approaches
153
+ - researcher: Research agent example with evaluation optimization
154
+ """
155
+ if not example_type:
156
+ show_examples_overview()
157
+ return
158
+
159
+ example_type = example_type.lower()
160
+ if example_type not in EXAMPLE_TYPES:
161
+ console.print(f"[red]Error:[/red] Unknown example type '{example_type}'")
162
+ console.print("\nAvailable types:")
163
+ for name in EXAMPLE_TYPES:
164
+ console.print(f" - {name}")
165
+ raise typer.Exit(1)
166
+
167
+ target_dir = Path(directory).resolve()
168
+ if not target_dir.exists():
169
+ target_dir.mkdir(parents=True)
170
+ console.print(f"Created directory: {target_dir}")
171
+
172
+ # Show example details
173
+ console.print(f"\n[bold]Creating {example_type} example[/bold]")
174
+ console.print(
175
+ Panel(
176
+ EXAMPLE_TYPES[example_type]["details"].strip(),
177
+ title="About this example",
178
+ expand=False,
179
+ )
180
+ )
181
+
182
+ if not force:
183
+ # Check for existing files first
184
+ existing = []
185
+ for f in EXAMPLE_TYPES[example_type]["files"]:
186
+ if (target_dir / f).exists():
187
+ existing.append(f)
188
+
189
+ if existing:
190
+ console.print(
191
+ "\n[yellow]Warning:[/yellow] The following files already exist:"
192
+ )
193
+ for f in existing:
194
+ console.print(f" - {f}")
195
+ console.print("\nUse --force to overwrite existing files")
196
+ raise typer.Exit(1)
197
+
198
+ created = copy_example_files(example_type, target_dir, force)
199
+
200
+ if created:
201
+ console.print("\n[green]Setup completed successfully![/green]")
202
+ console.print("\nCreated files:")
203
+ for f in created:
204
+ console.print(f" - {f}")
205
+
206
+ console.print("\n[bold]Next Steps:[/bold]")
207
+ if example_type == "decorator":
208
+ console.print("1. Review main.py for the basic example")
209
+ console.print("2. Check other files for different composition patterns:")
210
+ console.print(" - optimizer.py: Add optimization capabilities")
211
+ console.print(" - router.py: Route requests to different agents")
212
+ console.print(" - parallel.py: Run agents in parallel")
213
+ console.print("3. Run with: python main.py")
214
+ else:
215
+ console.print("1. Review main.py for the basic researcher example")
216
+ console.print(
217
+ "2. Try main-evalopt.py for the evaluation optimization version"
218
+ )
219
+ console.print("3. Run with: python main.py or python main-evalopt.py")
220
+ else:
221
+ console.print("\n[yellow]No files were created.[/yellow]")
@@ -0,0 +1,11 @@
1
+ import typer
2
+
3
+ app = typer.Typer()
4
+
5
+
6
+ @app.command()
7
+ def show():
8
+ """Show the configuration."""
9
+ raise NotImplementedError(
10
+ "The show configuration command has not been implemented yet"
11
+ )
@@ -0,0 +1,229 @@
1
+ from pathlib import Path
2
+ import typer
3
+ from rich.prompt import Confirm
4
+ from rich.console import Console
5
+
6
+ app = typer.Typer()
7
+ console = Console()
8
+
9
+ FASTAGENT_CONFIG_TEMPLATE = """
10
+ # FastAgent Configuration File
11
+
12
+ # Default Model Configuration:
13
+ #
14
+ # Takes format:
15
+ # <provider>.<model_string>.<reasoning_effort?> (e.g. anthropic.claude-3-5-sonnet-20241022 or openai.o3-mini.low)
16
+ # Accepts aliases for Anthropic Models: haiku, haiku3, sonnet, sonnet35, opus, opus3
17
+ # and OpenAI Models: gpt-4o-mini, gpt-4o, o1, o1-mini, o3-mini
18
+ #
19
+ # If not specified, defaults to "haiku".
20
+ # Can be overriden with a command line switch --model=<model>, or within the Agent constructor.
21
+
22
+ default_model: sonnet
23
+
24
+ # Logging and Console Configuration:
25
+ logging:
26
+ # level: "debug" | "info" | "warning" | "error"
27
+ # type: "none" | "console" | "file" | "http"
28
+ # path: "/path/to/logfile.jsonl"
29
+
30
+
31
+ # Switch the progress display on or off
32
+ # progress_display: true
33
+
34
+ # Show chat User/Assistant messages on the console
35
+ # show_chat: true
36
+ # Show tool calls on the console
37
+ # show_tools: true
38
+ # Truncate long tool responses on the console
39
+ # truncate_tools: true
40
+
41
+ # MCP Servers
42
+ mcp:
43
+ servers:
44
+ fetch:
45
+ command: "uvx"
46
+ args: ["mcp-server-fetch"]
47
+
48
+ """
49
+
50
+ FASTAGENT_SECRETS_TEMPLATE = """
51
+ # FastAgent Secrets Configuration
52
+ # WARNING: Keep this file secure and never commit to version control
53
+
54
+ openai:
55
+ api_key: <your-api-key-here>
56
+ anthropic:
57
+ api_key: <your-api-key-here>
58
+
59
+ # Example of setting an MCP Server environment variable
60
+ mcp:
61
+ servers:
62
+ brave:
63
+ env:
64
+ BRAVE_API_KEY: <your_api_key_here>
65
+
66
+ """
67
+
68
+ GITIGNORE_TEMPLATE = """
69
+ # FastAgent secrets file
70
+ fastagent-secrets.yaml
71
+
72
+ # Python
73
+ __pycache__/
74
+ *.py[cod]
75
+ *$py.class
76
+ *.so
77
+ .Python
78
+ build/
79
+ develop-eggs/
80
+ dist/
81
+ downloads/
82
+ eggs/
83
+ .eggs/
84
+ lib/
85
+ lib64/
86
+ parts/
87
+ sdist/
88
+ var/
89
+ wheels/
90
+ *.egg-info/
91
+ .installed.cfg
92
+ *.egg
93
+
94
+ # Virtual Environment
95
+ .env
96
+ .venv
97
+ env/
98
+ venv/
99
+ ENV/
100
+
101
+ # IDE
102
+ .idea/
103
+ .vscode/
104
+ *.swp
105
+ *.swo
106
+ """
107
+
108
+ AGENT_EXAMPLE_TEMPLATE = """
109
+ import asyncio
110
+ from mcp_agent.core.fastagent import FastAgent
111
+
112
+ # Create the application
113
+ agent_app = FastAgent("FastAgent Example")
114
+ # Uncomment the below to disable human input callback tool
115
+ # agent_app.app._human_input_callback = None
116
+
117
+
118
+ # Define the agent
119
+ @agent_app.agent(servers=["fetch"])
120
+ # @agent_app.agent(servers=["fetch"])
121
+ async def main():
122
+ # use the --model= command line switch to specify model
123
+ async with agent_app.run() as agent:
124
+ await agent()
125
+
126
+
127
+ if __name__ == "__main__":
128
+ asyncio.run(main())
129
+
130
+ """
131
+
132
+
133
+ def find_gitignore(path: Path) -> bool:
134
+ """Check if a .gitignore file exists in this directory or any parent."""
135
+ current = path
136
+ while current != current.parent: # Stop at root directory
137
+ if (current / ".gitignore").exists():
138
+ return True
139
+ current = current.parent
140
+ return False
141
+
142
+
143
+ def create_file(path: Path, content: str, force: bool = False) -> bool:
144
+ """Create a file with given content if it doesn't exist or force is True."""
145
+ if path.exists() and not force:
146
+ should_overwrite = Confirm.ask(
147
+ f"[yellow]Warning:[/yellow] {path} already exists. Overwrite?",
148
+ default=False,
149
+ )
150
+ if not should_overwrite:
151
+ console.print(f"Skipping {path}")
152
+ return False
153
+
154
+ path.write_text(content.strip() + "\n")
155
+ console.print(f"[green]Created[/green] {path}")
156
+ return True
157
+
158
+
159
+ @app.callback(invoke_without_command=True)
160
+ def init(
161
+ config_dir: str = typer.Option(
162
+ ".",
163
+ "--config-dir",
164
+ "-c",
165
+ help="Directory where configuration files will be created",
166
+ ),
167
+ force: bool = typer.Option(
168
+ False, "--force", "-f", help="Force overwrite existing files"
169
+ ),
170
+ ):
171
+ """Initialize a new FastAgent project with configuration files and example agent."""
172
+
173
+ config_path = Path(config_dir).resolve()
174
+ if not config_path.exists():
175
+ should_create = Confirm.ask(
176
+ f"Directory {config_path} does not exist. Create it?", default=True
177
+ )
178
+ if should_create:
179
+ config_path.mkdir(parents=True)
180
+ else:
181
+ raise typer.Abort()
182
+
183
+ # Check for existing .gitignore
184
+ needs_gitignore = not find_gitignore(config_path)
185
+
186
+ console.print("\n[bold]FastAgent Setup[/bold]\n")
187
+ console.print("This will create the following files:")
188
+ console.print(f" - {config_path}/fastagent.config.yaml")
189
+ console.print(f" - {config_path}/fastagent.secrets.yaml")
190
+ console.print(f" - {config_path}/agent.py")
191
+ if needs_gitignore:
192
+ console.print(f" - {config_path}/.gitignore")
193
+
194
+ if not Confirm.ask("\nContinue?", default=True):
195
+ raise typer.Abort()
196
+
197
+ # Create configuration files
198
+ created = []
199
+ if create_file(
200
+ config_path / "fastagent.config.yaml", FASTAGENT_CONFIG_TEMPLATE, force
201
+ ):
202
+ created.append("fastagent.yaml")
203
+
204
+ if create_file(
205
+ config_path / "fastagent.secrets.yaml", FASTAGENT_SECRETS_TEMPLATE, force
206
+ ):
207
+ created.append("fastagent.secrets.yaml")
208
+
209
+ if create_file(config_path / "agent.py", AGENT_EXAMPLE_TEMPLATE, force):
210
+ created.append("agent.py")
211
+
212
+ # Only create .gitignore if none exists in parent directories
213
+ if needs_gitignore and create_file(
214
+ config_path / ".gitignore", GITIGNORE_TEMPLATE, force
215
+ ):
216
+ created.append(".gitignore")
217
+
218
+ if created:
219
+ console.print("\n[green]Setup completed successfully![/green]")
220
+ if "fastagent-secrets.yaml" in created:
221
+ console.print("\n[yellow]Important:[/yellow] Remember to:")
222
+ console.print("1. Add your API keys to fastagent-secrets.yaml")
223
+ console.print(
224
+ "2. Keep fastagent-secrets.yaml secure and never commit it to version control"
225
+ )
226
+ console.print("\nTo get started, run:")
227
+ console.print(" uv run agent.py")
228
+ else:
229
+ console.print("\n[yellow]No files were created or modified.[/yellow]")
mcp_agent/cli/main.py ADDED
@@ -0,0 +1,68 @@
1
+ """Main CLI entry point for MCP Agent."""
2
+
3
+ import typer
4
+ from rich.console import Console
5
+ from rich.table import Table
6
+ from mcp_agent.cli.terminal import Application
7
+ from mcp_agent.cli.commands import setup, bootstrap
8
+
9
+ app = typer.Typer(
10
+ help="MCP Agent CLI - Build effective agents using Model Context Protocol",
11
+ add_completion=False, # We'll add this later when we have more commands
12
+ )
13
+
14
+ # Subcommands
15
+ app.add_typer(setup.app, name="setup", help="Set up a new agent project")
16
+ app.add_typer(bootstrap.app, name="bootstrap", help="Create example applications")
17
+
18
+ # Shared application context
19
+ application = Application()
20
+ console = Console()
21
+
22
+
23
+ def show_welcome():
24
+ """Show a welcome message with available commands."""
25
+ console.print("\n[bold]Welcome to MCP Agent![/bold]")
26
+ console.print("Build effective agents using Model Context Protocol (MCP)")
27
+
28
+ # Create a table for commands
29
+ table = Table(title="\nAvailable Commands")
30
+ table.add_column("Command", style="green")
31
+ table.add_column("Description")
32
+
33
+ table.add_row("setup", "Set up a new agent project with configuration files")
34
+ table.add_row(
35
+ "bootstrap", "Create example applications (decorator, researcher, etc.)"
36
+ )
37
+ # table.add_row("config", "Manage agent configuration settings")
38
+
39
+ console.print(table)
40
+
41
+ console.print("\n[bold]Getting Started:[/bold]")
42
+ console.print("1. Set up a new project:")
43
+ console.print(" mcp-agent setup")
44
+ console.print("\n2. Try an example:")
45
+ console.print(" mcp-agent bootstrap create decorator")
46
+ console.print("\nUse --help with any command for more information")
47
+ console.print("Example: mcp-agent bootstrap --help")
48
+
49
+
50
+ @app.callback(invoke_without_command=True)
51
+ def main(
52
+ ctx: typer.Context,
53
+ verbose: bool = typer.Option(False, "--verbose", "-v", help="Enable verbose mode"),
54
+ quiet: bool = typer.Option(False, "--quiet", "-q", help="Disable output"),
55
+ color: bool = typer.Option(
56
+ True, "--color/--no-color", help="Enable/disable color output"
57
+ ),
58
+ ):
59
+ """MCP Agent CLI - Build effective agents using Model Context Protocol (MCP).
60
+
61
+ Use --help with any command for detailed usage information.
62
+ """
63
+ application.verbosity = 1 if verbose else 0 if not quiet else -1
64
+ application.console = application.console if color else None
65
+
66
+ # Show welcome message if no command was invoked
67
+ if ctx.invoked_subcommand is None:
68
+ show_welcome()
@@ -0,0 +1,24 @@
1
+ from mcp_agent.console import console, error_console
2
+
3
+
4
+ class Application:
5
+ def __init__(self, verbosity: int = 0, enable_color: bool = True):
6
+ self.verbosity = verbosity
7
+ # Use the central console instances, respecting color setting
8
+ if not enable_color:
9
+ # Create new instances without color if color is disabled
10
+ self.console = console.__class__(color_system=None)
11
+ self.error_console = error_console.__class__(color_system=None, stderr=True)
12
+ else:
13
+ self.console = console
14
+ self.error_console = error_console
15
+
16
+ def log(self, message: str, level: str = "info"):
17
+ if level == "info" or (level == "debug" and self.verbosity > 0):
18
+ if level == "error":
19
+ self.error_console.print(f"[{level.upper()}] {message}")
20
+ else:
21
+ self.console.print(f"[{level.upper()}] {message}")
22
+
23
+ def status(self, message: str):
24
+ return self.console.status(f"[bold cyan]{message}[/bold cyan]")