toolfuncs 1.1.0__tar.gz → 1.2.0__tar.gz

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.
Files changed (38) hide show
  1. {toolfuncs-1.1.0 → toolfuncs-1.2.0}/PKG-INFO +42 -8
  2. {toolfuncs-1.1.0 → toolfuncs-1.2.0}/README.md +41 -7
  3. {toolfuncs-1.1.0 → toolfuncs-1.2.0}/docs/contract.md +6 -2
  4. {toolfuncs-1.1.0 → toolfuncs-1.2.0}/pyproject.toml +1 -1
  5. {toolfuncs-1.1.0 → toolfuncs-1.2.0}/src/toolfuncs/__main__.py +37 -5
  6. toolfuncs-1.2.0/src/toolfuncs/_catalog.py +447 -0
  7. {toolfuncs-1.1.0 → toolfuncs-1.2.0}/src/toolfuncs/_contract.py +8 -3
  8. {toolfuncs-1.1.0 → toolfuncs-1.2.0}/src/toolfuncs/_mcp.py +37 -3
  9. {toolfuncs-1.1.0 → toolfuncs-1.2.0}/src/toolfuncs/agent_hooks.py +36 -5
  10. {toolfuncs-1.1.0 → toolfuncs-1.2.0}/src/toolfuncs/sdk.py +12 -0
  11. {toolfuncs-1.1.0 → toolfuncs-1.2.0}/tests/test_agent_hooks.py +21 -0
  12. toolfuncs-1.2.0/tests/test_path_mcp.py +306 -0
  13. {toolfuncs-1.1.0 → toolfuncs-1.2.0}/uv.lock +1 -1
  14. {toolfuncs-1.1.0 → toolfuncs-1.2.0}/.github/workflows/release.yml +0 -0
  15. {toolfuncs-1.1.0 → toolfuncs-1.2.0}/.github/workflows/test.yml +0 -0
  16. {toolfuncs-1.1.0 → toolfuncs-1.2.0}/.gitignore +0 -0
  17. {toolfuncs-1.1.0 → toolfuncs-1.2.0}/.python-version +0 -0
  18. {toolfuncs-1.1.0 → toolfuncs-1.2.0}/docs/migrating-to-1.0.md +0 -0
  19. {toolfuncs-1.1.0 → toolfuncs-1.2.0}/src/toolfuncs/__init__.py +0 -0
  20. {toolfuncs-1.1.0 → toolfuncs-1.2.0}/src/toolfuncs/_descriptions.py +0 -0
  21. {toolfuncs-1.1.0 → toolfuncs-1.2.0}/src/toolfuncs/_doctor.py +0 -0
  22. {toolfuncs-1.1.0 → toolfuncs-1.2.0}/src/toolfuncs/_errors.py +0 -0
  23. {toolfuncs-1.1.0 → toolfuncs-1.2.0}/src/toolfuncs/_import_path.py +0 -0
  24. {toolfuncs-1.1.0 → toolfuncs-1.2.0}/src/toolfuncs/_packages.py +0 -0
  25. {toolfuncs-1.1.0 → toolfuncs-1.2.0}/src/toolfuncs/_runtime.py +0 -0
  26. {toolfuncs-1.1.0 → toolfuncs-1.2.0}/src/toolfuncs/_setup.py +0 -0
  27. {toolfuncs-1.1.0 → toolfuncs-1.2.0}/src/toolfuncs/_tools.py +0 -0
  28. {toolfuncs-1.1.0 → toolfuncs-1.2.0}/src/toolfuncs/py.typed +0 -0
  29. {toolfuncs-1.1.0 → toolfuncs-1.2.0}/tests/__init__.py +0 -0
  30. {toolfuncs-1.1.0 → toolfuncs-1.2.0}/tests/conftest.py +0 -0
  31. {toolfuncs-1.1.0 → toolfuncs-1.2.0}/tests/test_contract.py +0 -0
  32. {toolfuncs-1.1.0 → toolfuncs-1.2.0}/tests/test_doctor.py +0 -0
  33. {toolfuncs-1.1.0 → toolfuncs-1.2.0}/tests/test_import_path.py +0 -0
  34. {toolfuncs-1.1.0 → toolfuncs-1.2.0}/tests/test_managed_runtime.py +0 -0
  35. {toolfuncs-1.1.0 → toolfuncs-1.2.0}/tests/test_mcp.py +0 -0
  36. {toolfuncs-1.1.0 → toolfuncs-1.2.0}/tests/test_packages.py +0 -0
  37. {toolfuncs-1.1.0 → toolfuncs-1.2.0}/tests/test_sdk_cli.py +0 -0
  38. {toolfuncs-1.1.0 → toolfuncs-1.2.0}/tests/test_tools.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: toolfuncs
3
- Version: 1.1.0
3
+ Version: 1.2.0
4
4
  Summary: Typed Python functions with native Python, CLI, and MCP interfaces
5
5
  Project-URL: Repository, https://github.com/nimashoghi/toolfuncs
6
6
  Project-URL: Issues, https://github.com/nimashoghi/toolfuncs/issues
@@ -185,24 +185,55 @@ Function commands inherit help and error presentation from their parent app. All
185
185
 
186
186
  ## Use MCP
187
187
 
188
- Register each script or opted-in package executable explicitly in your MCP client. For example, a client using an `mcpServers` configuration can launch:
188
+ Register one server to expose the effective PATH catalog. Scripts and opted-in package executables remain separate tool families:
189
189
 
190
190
  ```json
191
191
  {
192
192
  "mcpServers": {
193
- "weather": {
193
+ "toolfuncs": {
194
194
  "command": "/absolute/path/to/toolfuncs",
195
- "args": ["mcp", "/absolute/path/to/weather-report"]
195
+ "args": ["mcp"]
196
196
  }
197
197
  }
198
198
  }
199
199
  ```
200
200
 
201
- `toolfuncs mcp SOURCE` prepares the same isolated dependency environment as the CLI and starts one stdio server. Use `--prepared` only when the selected interpreter already contains the source's dependencies. Toolfuncs does not edit client configuration. Each server exposes all registered operations; restart it after source or dependency changes.
201
+ `toolfuncs mcp` captures PATH and starts one persistent child per family, using each source's isolated dependency environment. Children inherit the launch directory and environment. Startup is bounded to 120 seconds, including dependency preparation, with at most eight families starting concurrently. Configure the client's startup timeout to at least 180 seconds for cold installations. Failed families appear in `catalog` with an error; healthy families remain callable. `toolfuncs doctor` loads all families and exits nonzero if any are unavailable. It does not invoke their operations. Use `toolfuncs doctor SOURCE` for the full source documentation and help checks.
202
+
203
+ The server's operation catalog remains fixed until restart. A crashed child becomes unavailable and is not restarted automatically. Interrupted operations are never replayed, since their side effects may already have occurred. Ordinary function exceptions remain tool errors and leave the family available. Shutdown closes the children. Installing tools, changing PATH, or updating source/dependencies requires restarting the server.
204
+
205
+ `toolfuncs mcp SOURCE` remains available to serve one source or opted-in package command. Use `--prepared` only when the selected interpreter already contains every selected source's dependencies. Toolfuncs does not edit client configuration.
206
+
207
+ ### Progressive discovery
208
+
209
+ The hook advertises families. Inspect one group at a time, then one selected operation:
210
+
211
+ ```console
212
+ toolfuncs catalog
213
+ toolfuncs commands weather-report
214
+ toolfuncs commands weather-report --group '["records"]'
215
+ toolfuncs inspect-operation weather-report '["records", "show"]'
216
+ ```
217
+
218
+ The generic MCP server exposes these same three discovery functions as `catalog`, `commands`, and `inspect_operation`. Group views contain only immediate child names and short descriptions. Selected operation views contain the original input/output schemas, documentation, canonical CLI argv, MCP name, and a Python attribute when it is verifiably exported by the source module. Do not reconstruct Python access from an MCP name: registered aliases and nested CLI groups need not match Python attributes.
219
+
220
+ Python uses the same bound functions:
221
+
222
+ ```python
223
+ from toolfuncs.sdk import ToolCatalog
224
+
225
+ async with ToolCatalog() as catalog:
226
+ families = catalog.catalog() # static discovery, no child startup
227
+ await catalog.start(["weather-report"])
228
+ children = catalog.commands("weather-report")
229
+ detail = catalog.inspect_operation("weather-report", ["records", "show"])
230
+ ```
231
+
232
+ In Codex Code Mode, use toolfuncs discovery to select an operation, resolve its runtime name from `ALL_TOOLS`, and invoke `tools[name](arguments)`. Retain deferred MCP exposure; native tool search is unnecessary. In Claude Code, keep the server's tools deferred (`"alwaysLoad": false` on supported versions), load the selected tool with `ToolSearch` query `select:mcp__toolfuncs__NAME`, then call it normally. Claude still exposes operation names initially. These context policies belong to the client; generic MCP clients may expose all schemas. For the agent hook's client-specific guidance, set `TOOLFUNCS_MCP_SERVER=toolfuncs` in the host environment when that server is registered.
202
233
 
203
234
  For programmatic use, `server = app.to_mcp()` returns a FastMCP server. Sync functions use FastMCP's thread dispatch and async functions are awaited. FastMCP owns request handling and cancellation. MCP calls do not share live state with an IPython kernel. The function implementation is shared.
204
235
 
205
- A nested CLI command such as `records show` becomes `records__show`; hyphens become underscores. Aliases remain CLI aliases. Ambiguous or invalid MCP names fail at startup. Every successful MCP result has structured content `{"result": value}`, including scalar and null results, plus JSON text content. Exceptions become MCP tool errors.
236
+ A nested CLI command such as `records show` becomes `records__show`; the PATH server prefixes the family, for example `weather_report__records__show`. Hyphens become underscores. Aliases remain CLI aliases. Collisions and names exceeding 64 characters fail explicitly. Every successful MCP result has structured content `{"result": value}`, including scalar and null results, plus JSON text content. Exceptions become MCP tool errors.
206
237
 
207
238
  Use stderr for logs and diagnostics. Stdout belongs to the CLI result or MCP protocol; an operation that prints to stdout can corrupt that stream. Durable background tasks, push notifications, remote hosting, resources and prompts are outside the 1.0 interface.
208
239
 
@@ -341,9 +372,12 @@ Setup does not discover, copy, register, link, synchronize, or remove tools. The
341
372
 
342
373
  ```console
343
374
  toolfuncs SOURCE [ARGS...]
344
- toolfuncs doctor SOURCE
345
- toolfuncs mcp [--prepared] SOURCE
375
+ toolfuncs doctor [--prepared] [SOURCE]
376
+ toolfuncs mcp [--prepared] [SOURCE]
346
377
  toolfuncs list
378
+ toolfuncs catalog
379
+ toolfuncs commands FAMILY [--group JSON_PATH]
380
+ toolfuncs inspect-operation FAMILY JSON_PATH
347
381
  toolfuncs setup [--bin-dir DIRECTORY]
348
382
  ```
349
383
 
@@ -167,24 +167,55 @@ Function commands inherit help and error presentation from their parent app. All
167
167
 
168
168
  ## Use MCP
169
169
 
170
- Register each script or opted-in package executable explicitly in your MCP client. For example, a client using an `mcpServers` configuration can launch:
170
+ Register one server to expose the effective PATH catalog. Scripts and opted-in package executables remain separate tool families:
171
171
 
172
172
  ```json
173
173
  {
174
174
  "mcpServers": {
175
- "weather": {
175
+ "toolfuncs": {
176
176
  "command": "/absolute/path/to/toolfuncs",
177
- "args": ["mcp", "/absolute/path/to/weather-report"]
177
+ "args": ["mcp"]
178
178
  }
179
179
  }
180
180
  }
181
181
  ```
182
182
 
183
- `toolfuncs mcp SOURCE` prepares the same isolated dependency environment as the CLI and starts one stdio server. Use `--prepared` only when the selected interpreter already contains the source's dependencies. Toolfuncs does not edit client configuration. Each server exposes all registered operations; restart it after source or dependency changes.
183
+ `toolfuncs mcp` captures PATH and starts one persistent child per family, using each source's isolated dependency environment. Children inherit the launch directory and environment. Startup is bounded to 120 seconds, including dependency preparation, with at most eight families starting concurrently. Configure the client's startup timeout to at least 180 seconds for cold installations. Failed families appear in `catalog` with an error; healthy families remain callable. `toolfuncs doctor` loads all families and exits nonzero if any are unavailable. It does not invoke their operations. Use `toolfuncs doctor SOURCE` for the full source documentation and help checks.
184
+
185
+ The server's operation catalog remains fixed until restart. A crashed child becomes unavailable and is not restarted automatically. Interrupted operations are never replayed, since their side effects may already have occurred. Ordinary function exceptions remain tool errors and leave the family available. Shutdown closes the children. Installing tools, changing PATH, or updating source/dependencies requires restarting the server.
186
+
187
+ `toolfuncs mcp SOURCE` remains available to serve one source or opted-in package command. Use `--prepared` only when the selected interpreter already contains every selected source's dependencies. Toolfuncs does not edit client configuration.
188
+
189
+ ### Progressive discovery
190
+
191
+ The hook advertises families. Inspect one group at a time, then one selected operation:
192
+
193
+ ```console
194
+ toolfuncs catalog
195
+ toolfuncs commands weather-report
196
+ toolfuncs commands weather-report --group '["records"]'
197
+ toolfuncs inspect-operation weather-report '["records", "show"]'
198
+ ```
199
+
200
+ The generic MCP server exposes these same three discovery functions as `catalog`, `commands`, and `inspect_operation`. Group views contain only immediate child names and short descriptions. Selected operation views contain the original input/output schemas, documentation, canonical CLI argv, MCP name, and a Python attribute when it is verifiably exported by the source module. Do not reconstruct Python access from an MCP name: registered aliases and nested CLI groups need not match Python attributes.
201
+
202
+ Python uses the same bound functions:
203
+
204
+ ```python
205
+ from toolfuncs.sdk import ToolCatalog
206
+
207
+ async with ToolCatalog() as catalog:
208
+ families = catalog.catalog() # static discovery, no child startup
209
+ await catalog.start(["weather-report"])
210
+ children = catalog.commands("weather-report")
211
+ detail = catalog.inspect_operation("weather-report", ["records", "show"])
212
+ ```
213
+
214
+ In Codex Code Mode, use toolfuncs discovery to select an operation, resolve its runtime name from `ALL_TOOLS`, and invoke `tools[name](arguments)`. Retain deferred MCP exposure; native tool search is unnecessary. In Claude Code, keep the server's tools deferred (`"alwaysLoad": false` on supported versions), load the selected tool with `ToolSearch` query `select:mcp__toolfuncs__NAME`, then call it normally. Claude still exposes operation names initially. These context policies belong to the client; generic MCP clients may expose all schemas. For the agent hook's client-specific guidance, set `TOOLFUNCS_MCP_SERVER=toolfuncs` in the host environment when that server is registered.
184
215
 
185
216
  For programmatic use, `server = app.to_mcp()` returns a FastMCP server. Sync functions use FastMCP's thread dispatch and async functions are awaited. FastMCP owns request handling and cancellation. MCP calls do not share live state with an IPython kernel. The function implementation is shared.
186
217
 
187
- A nested CLI command such as `records show` becomes `records__show`; hyphens become underscores. Aliases remain CLI aliases. Ambiguous or invalid MCP names fail at startup. Every successful MCP result has structured content `{"result": value}`, including scalar and null results, plus JSON text content. Exceptions become MCP tool errors.
218
+ A nested CLI command such as `records show` becomes `records__show`; the PATH server prefixes the family, for example `weather_report__records__show`. Hyphens become underscores. Aliases remain CLI aliases. Collisions and names exceeding 64 characters fail explicitly. Every successful MCP result has structured content `{"result": value}`, including scalar and null results, plus JSON text content. Exceptions become MCP tool errors.
188
219
 
189
220
  Use stderr for logs and diagnostics. Stdout belongs to the CLI result or MCP protocol; an operation that prints to stdout can corrupt that stream. Durable background tasks, push notifications, remote hosting, resources and prompts are outside the 1.0 interface.
190
221
 
@@ -323,9 +354,12 @@ Setup does not discover, copy, register, link, synchronize, or remove tools. The
323
354
 
324
355
  ```console
325
356
  toolfuncs SOURCE [ARGS...]
326
- toolfuncs doctor SOURCE
327
- toolfuncs mcp [--prepared] SOURCE
357
+ toolfuncs doctor [--prepared] [SOURCE]
358
+ toolfuncs mcp [--prepared] [SOURCE]
328
359
  toolfuncs list
360
+ toolfuncs catalog
361
+ toolfuncs commands FAMILY [--group JSON_PATH]
362
+ toolfuncs inspect-operation FAMILY JSON_PATH
329
363
  toolfuncs setup [--bin-dir DIRECTORY]
330
364
  ```
331
365
 
@@ -55,7 +55,11 @@ Cyclopts tokenizes and binds CLI arguments. Its central converter uses Pydantic'
55
55
 
56
56
  ## MCP interface
57
57
 
58
- `toolfuncs mcp SOURCE` prepares dependencies and serves one source or opted-in package executable over stdio. `--prepared` uses the current interpreter without dependency preparation. Each script is registered separately in the client's configuration. `app.to_mcp(name=...)` produces a FastMCP server for programmatic use.
58
+ `toolfuncs mcp SOURCE` prepares dependencies and serves one source or opted-in package executable over stdio. Omitting SOURCE serves the effective PATH catalog with one isolated persistent child per family. `--prepared` uses the current interpreter without dependency preparation. `app.to_mcp(name=...)` produces a FastMCP server for programmatic use.
59
+
60
+ The PATH server snapshots discovery and operation schemas at startup, retains healthy families when another fails, and records failed families in its `catalog` discovery result. Each native tool name is prefixed by its family Python name and `__`; the complete name must be unique and at most 64 characters. There is no automatic refresh, reconnect or failed-call replay. Child processes inherit the server's launch directory and environment. They are closed when the server exits.
61
+
62
+ `catalog`, `commands`, and `inspect_operation` use the same implementations in MCP, the management CLI and `toolfuncs.sdk.ToolCatalog`. Each group listing exposes immediate children only. One selected operation exposes its authoritative contract. The Python catalog is an async context manager; `await catalog.start()` loads all families, or a supplied sequence selects families. Static `sdk.discover()` and `toolfuncs list` remain import-free. Native domain calls still use the original functions through `toolfuncs.NAME`; discovery does not turn Python domain calls into RPC.
59
63
 
60
64
  Canonical command paths become tool names by replacing hyphens with underscores and joining path segments with `__`. A root default operation uses its function name. Names must contain 1-64 ASCII letters, digits, underscores or hyphens. CLI aliases are deduplicated; name collisions fail.
61
65
 
@@ -118,7 +122,7 @@ Successful default CLI operations render one Python value through Rich on an int
118
122
 
119
123
  Setup does not discover, install, copy, link, register, synchronize, or remove tool sources. Adding and removing tools are ordinary filesystem operations in directories already on `PATH`.
120
124
 
121
- The public management commands are `toolfuncs mcp [--prepared] SOURCE`, `toolfuncs doctor SOURCE`, `toolfuncs list`, and `toolfuncs setup [--bin-dir DIRECTORY]`. The explicit-source execution form is `toolfuncs SOURCE [ARGS...]`; it is not a universal name dispatcher. Tools on `PATH` are invoked directly by their own CLI names. There is no `run`, `exec`, `describe`, or `sync` command.
125
+ The public management commands include `toolfuncs mcp [--prepared] [SOURCE]`, `toolfuncs doctor [--prepared] [SOURCE]`, `toolfuncs list`, `toolfuncs catalog`, `toolfuncs commands FAMILY [--group JSON_PATH]`, `toolfuncs inspect-operation FAMILY JSON_PATH`, and `toolfuncs setup [--bin-dir DIRECTORY]`. Doctor without SOURCE checks aggregate loading and name validity; doctor with SOURCE also checks its authoring documentation and generated help. The explicit-source execution form is `toolfuncs SOURCE [ARGS...]`; it is not a universal name dispatcher. Tools on `PATH` are invoked directly by their own CLI names. There is no generic operation-call command.
122
126
 
123
127
  ## Compatibility
124
128
 
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "toolfuncs"
3
- version = "1.1.0"
3
+ version = "1.2.0"
4
4
  description = "Typed Python functions with native Python, CLI, and MCP interfaces"
5
5
  readme = "README.md"
6
6
  authors = [
@@ -2,6 +2,7 @@
2
2
 
3
3
  from __future__ import annotations
4
4
 
5
+ import asyncio
5
6
  import json
6
7
  import sys
7
8
  from collections.abc import Iterator, Sequence
@@ -31,9 +32,12 @@ Usage:
31
32
  toolfuncs --version
32
33
  toolfuncs SOURCE [ARGS...]
33
34
  toolfuncs run-prepared SOURCE [ARGS...]
34
- toolfuncs doctor [--prepared] SOURCE
35
- toolfuncs mcp [--prepared] SOURCE
35
+ toolfuncs doctor [--prepared] [SOURCE]
36
+ toolfuncs mcp [--prepared] [SOURCE]
36
37
  toolfuncs list
38
+ toolfuncs catalog
39
+ toolfuncs commands FAMILY [--group JSON_PATH]
40
+ toolfuncs inspect-operation FAMILY JSON_PATH
37
41
  toolfuncs setup [--bin-dir DIRECTORY]
38
42
 
39
43
  A toolfunc is an executable Python script whose first line is exactly:
@@ -53,8 +57,12 @@ run-prepared and doctor --prepared use the current interpreter without resolving
53
57
  or installing dependencies. Installers must prepare the script's declared runtime
54
58
  first. They still validate the source and its Python-version requirement.
55
59
 
56
- mcp serves one selected script or installed package command over stdio. Register
57
- this command explicitly with your MCP client. No PATH aggregation or live reload.
60
+ mcp serves native tools from PATH over stdio, or one selected SOURCE. Register it
61
+ once with your client. Each family runs in its own persistent process. Restart
62
+ the server after installing or changing tools; there is no automatic reload.
63
+ Discovery proceeds from catalog to commands to inspect-operation. These commands
64
+ share their implementation with the Python ToolCatalog and native MCP discovery.
65
+ doctor without SOURCE checks all discovered families and reports partial failures.
58
66
  """
59
67
 
60
68
 
@@ -108,11 +116,27 @@ def main(argv: Sequence[str] | None = None) -> int:
108
116
  _print_json(_catalog_payload(catalog))
109
117
  _warn_invalid_tools(catalog.invalid_tools)
110
118
  return 0
119
+ if command in {"catalog", "commands", "inspect-operation"}:
120
+ from ._catalog import run_discovery
121
+
122
+ return asyncio.run(run_discovery(command, tokens))
111
123
  if command in {"doctor", "__doctor-source"}:
112
124
  prepared = command == "__doctor-source"
113
125
  if command == "doctor" and tokens[:1] == ["--prepared"]:
114
126
  prepared = True
115
127
  tokens.pop(0)
128
+ if not tokens and command == "doctor":
129
+ from ._catalog import doctor_catalog
130
+
131
+ families = asyncio.run(doctor_catalog(prepared=prepared))
132
+ healthy = all(family.status == "ready" for family in families)
133
+ _print_json(
134
+ {
135
+ "status": "success" if healthy else "error",
136
+ "families": [family.model_dump(mode="json") for family in families],
137
+ }
138
+ )
139
+ return 0 if healthy else 1
116
140
  if len(tokens) != 1:
117
141
  raise SystemExit("usage: toolfuncs doctor SOURCE")
118
142
  if not prepared and Path(tokens[0]).is_file():
@@ -136,6 +160,11 @@ def main(argv: Sequence[str] | None = None) -> int:
136
160
  if tokens[:1] == ["--prepared"]:
137
161
  prepared = True
138
162
  tokens.pop(0)
163
+ if not tokens and command == "mcp":
164
+ from ._catalog import create_path_server
165
+
166
+ create_path_server(prepared=prepared).run(transport="stdio", show_banner=False)
167
+ return 0
139
168
  if len(tokens) != 1:
140
169
  raise SystemExit("usage: toolfuncs mcp [--prepared] SOURCE")
141
170
  source = Path(tokens[0])
@@ -144,7 +173,10 @@ def main(argv: Sequence[str] | None = None) -> int:
144
173
  raise AssertionError("exec returned")
145
174
  # Import diagnostics must not be mistaken for JSON-RPC protocol frames.
146
175
  with redirect_stdout(sys.stderr), _tool_program_name(source):
147
- server = _application(_load_prepared_source(source)).to_mcp(name=source.name)
176
+ from ._mcp import create_server
177
+
178
+ module = _load_prepared_source(source)
179
+ server = create_server(_application(module), name=source.name, source_module=module)
148
180
  server.run(transport="stdio", show_banner=False)
149
181
  return 0
150
182
  if command == "setup":