universal-mcp 0.1.20__py3-none-any.whl → 0.1.20rc1__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.
@@ -17,7 +17,7 @@ def convert_tool_to_mcp_tool(
17
17
  from mcp.server.fastmcp.server import MCPTool
18
18
 
19
19
  return MCPTool(
20
- name=tool.name[:63],
20
+ name=tool.name,
21
21
  description=tool.description or "",
22
22
  inputSchema=tool.parameters,
23
23
  )
@@ -643,28 +643,43 @@ def _generate_method_code(path, method, operation):
643
643
  param_details[param_obj.name] = param_obj
644
644
 
645
645
  # Fetch request body example
646
- example_data = None # Initialize example_data here for wider scope
647
-
646
+ request_body_example_str = None
648
647
  if has_body:
649
648
  try:
650
649
  json_content = operation["requestBody"]["content"]["application/json"]
651
- #From direct content definition
650
+ example_data = None
652
651
  if "example" in json_content:
653
652
  example_data = json_content["example"]
654
653
  elif "examples" in json_content and json_content["examples"]:
655
654
  first_example_key = list(json_content["examples"].keys())[0]
656
655
  example_data = json_content["examples"][first_example_key].get("value")
657
- #If not found directly, try from resolved body schema (for nested/referenced examples)
658
- if example_data is None and body_schema_to_use and "example" in body_schema_to_use:
659
- example_data = body_schema_to_use["example"]
656
+
657
+ if example_data is not None:
658
+ try:
659
+ example_json = json.dumps(example_data, indent=2)
660
+ indented_example = textwrap.indent(example_json, " " * 8) # 8 spaces
661
+ request_body_example_str = f"\n Example:\n ```json\n{indented_example}\n ```"
662
+ except TypeError:
663
+ request_body_example_str = f"\n Example: {example_data}"
660
664
  except KeyError:
661
- pass # No example found or application/json content not present
665
+ pass # No example found
666
+
667
+ # Identify the last argument related to the request body
668
+ last_body_arg_name = None
669
+ # request_body_params contains the names as they appear in the signature
670
+ if final_request_body_arg_names_for_signature: # Use the new list with final aliased names
671
+ # Find which of these appears last in the combined args list
672
+ body_args_in_signature = [
673
+ a.split("=")[0] for a in args if a.split("=")[0] in final_request_body_arg_names_for_signature
674
+ ]
675
+ if body_args_in_signature:
676
+ last_body_arg_name = body_args_in_signature[-1]
662
677
 
663
678
  if signature_arg_names:
664
679
  args_doc_lines.append("Args:")
665
680
  for arg_signature_str in args:
666
681
  arg_name = arg_signature_str.split("=")[0]
667
- example_str = None # Initialize example_str here for each argument
682
+ example_str = None # Initialize example_str here
668
683
  detail = param_details.get(arg_name)
669
684
  if detail:
670
685
  desc = detail.description or "No description provided."
@@ -677,22 +692,26 @@ def _generate_method_code(path, method, operation):
677
692
  if detail.example and not detail.is_file: # Don't show schema example for file inputs
678
693
  example_str = repr(detail.example)
679
694
  arg_line += f" Example: {example_str}."
680
- # Fallback for body parameters if no direct example was found
681
- elif not example_str and detail.where == "body" and example_data and isinstance(example_data, dict) and detail.identifier in example_data:
682
- current_body_param_example = example_data[detail.identifier]
683
- if current_body_param_example is not None: # Ensure the extracted part is not None
684
- try:
685
- arg_line += f" Example: {repr(current_body_param_example)}."
686
- except Exception: # Fallback if repr fails
687
- arg_line += " Example: [Could not represent example]."
688
695
 
689
- args_doc_lines.append(arg_line)
696
+ # Append the full body example after the last body-related argument
697
+ if arg_name == last_body_arg_name and request_body_example_str:
698
+ # Remove the simple Example: if it exists before adding the detailed one
699
+ if example_str and (
700
+ f" Example: {example_str}." in arg_line or f" Example: {example_str} ." in arg_line
701
+ ):
702
+ arg_line = arg_line.replace(
703
+ f" Example: {example_str}.", ""
704
+ ) # Remove with or without trailing period
705
+ arg_line += request_body_example_str # Append the formatted JSON example
690
706
 
691
- elif arg_name == final_empty_body_param_name and has_empty_body:
707
+ args_doc_lines.append(arg_line)
708
+ elif arg_name == final_empty_body_param_name and has_empty_body: # Use potentially suffixed name
692
709
  args_doc_lines.append(
693
710
  f" {arg_name} (dict | None): Optional dictionary for an empty JSON request body (e.g., {{}})."
694
711
  )
695
- elif arg_name == raw_body_param_name:
712
+ if ( arg_name == last_body_arg_name and request_body_example_str ):
713
+ args_doc_lines[-1] += request_body_example_str
714
+ elif arg_name == raw_body_param_name: # Docstring for raw body parameter
696
715
  raw_body_type_hint = "bytes"
697
716
  raw_body_desc = "Raw binary content for the request body."
698
717
  if selected_content_type and "text" in selected_content_type:
@@ -701,9 +720,13 @@ def _generate_method_code(path, method, operation):
701
720
  elif selected_content_type and selected_content_type.startswith("image/"):
702
721
  raw_body_type_hint = "bytes (image data)"
703
722
  raw_body_desc = f"Raw image content ({selected_content_type}) for the request body."
723
+
704
724
  args_doc_lines.append(
705
725
  f" {arg_name} ({raw_body_type_hint} | None): {raw_body_desc}"
706
726
  )
727
+ # Example for raw body is harder to give generically, but if present in spec, could be added.
728
+ if ( arg_name == last_body_arg_name and request_body_example_str ):
729
+ args_doc_lines[-1] += request_body_example_str
707
730
 
708
731
  if args_doc_lines:
709
732
  docstring_parts.append("\n".join(args_doc_lines))
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: universal-mcp
3
- Version: 0.1.20
3
+ Version: 0.1.20rc1
4
4
  Summary: Universal MCP acts as a middle ware for your API applications. It can store your credentials, authorize, enable disable apps on the fly and much more.
5
5
  Author-email: Manoj Bajaj <manojbajaj95@gmail.com>
6
6
  License: MIT
@@ -19,7 +19,7 @@ universal_mcp/stores/__init__.py,sha256=quvuwhZnpiSLuojf0NfmBx2xpaCulv3fbKtKaSCE
19
19
  universal_mcp/stores/store.py,sha256=mxnmOVlDNrr8OKhENWDtCIfK7YeCBQcGdS6I2ogRCsU,6756
20
20
  universal_mcp/tools/README.md,sha256=RuxliOFqV1ZEyeBdj3m8UKfkxAsfrxXh-b6V4ZGAk8I,2468
21
21
  universal_mcp/tools/__init__.py,sha256=Fatza_R0qYWmNF1WQSfUZZKQFu5qf-16JhZzdmyx3KY,333
22
- universal_mcp/tools/adapters.py,sha256=OCZuWxLscys6mw1Q5ctQFshv9q3szlikwHhn4j5PMnE,1432
22
+ universal_mcp/tools/adapters.py,sha256=gz_sNDc_bseMHWmpQmqhOq65veE-DuK_kJYXGIx0Wi8,1427
23
23
  universal_mcp/tools/func_metadata.py,sha256=zIDXgIBvu5Gh8aNlg-Q7cZZos9Iky75MS0Me0BraXeM,8086
24
24
  universal_mcp/tools/manager.py,sha256=iwywaTjVGvBCJJasfwDWrASUleYqxenm4S-0txdhCF0,8076
25
25
  universal_mcp/tools/tools.py,sha256=qiuuLe0mCWtxXp6E5ISDDaNojCrMLfV1r5L8peFoJfg,3327
@@ -33,13 +33,13 @@ universal_mcp/utils/openapi/__inti__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMp
33
33
  universal_mcp/utils/openapi/api_generator.py,sha256=FjtvbnWuI1P8W8wXuKLCirUtsqQ4HI_TuQrhpA4SqTs,4749
34
34
  universal_mcp/utils/openapi/api_splitter.py,sha256=6O2y7fcCo2k3ixLr6_9-aAZx2kas3UAxQhqJy1esNkE,18829
35
35
  universal_mcp/utils/openapi/docgen.py,sha256=DNmwlhg_-TRrHa74epyErMTRjV2nutfCQ7seb_Rq5hE,21366
36
- universal_mcp/utils/openapi/openapi.py,sha256=EQME-VC5ccXpukIF0h96YsQOZj6oWip8W7a0bRN3s_k,45677
36
+ universal_mcp/utils/openapi/openapi.py,sha256=8XCIkJuwTN0UUcrBslQxitvz4y0NItBtuIgxdvb-Gdg,46857
37
37
  universal_mcp/utils/openapi/preprocessor.py,sha256=qLYv4ekors5B2OU_YUvXICYQ7XYhAOEPyAnKtnBvNpM,46699
38
38
  universal_mcp/utils/openapi/readme.py,sha256=R2Jp7DUXYNsXPDV6eFTkLiy7MXbSULUj1vHh4O_nB4c,2974
39
39
  universal_mcp/utils/templates/README.md.j2,sha256=Mrm181YX-o_-WEfKs01Bi2RJy43rBiq2j6fTtbWgbTA,401
40
40
  universal_mcp/utils/templates/api_client.py.j2,sha256=972Im7LNUAq3yZTfwDcgivnb-b8u6_JLKWXwoIwXXXQ,908
41
- universal_mcp-0.1.20.dist-info/METADATA,sha256=Ue8JfKp1O-fFRZ6WjcH30hcGhbS4_V61s3HEWk9Nx3o,12122
42
- universal_mcp-0.1.20.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
43
- universal_mcp-0.1.20.dist-info/entry_points.txt,sha256=QlBrVKmA2jIM0q-C-3TQMNJTTWOsOFQvgedBq2rZTS8,56
44
- universal_mcp-0.1.20.dist-info/licenses/LICENSE,sha256=NweDZVPslBAZFzlgByF158b85GR0f5_tLQgq1NS48To,1063
45
- universal_mcp-0.1.20.dist-info/RECORD,,
41
+ universal_mcp-0.1.20rc1.dist-info/METADATA,sha256=EQMj4vzDSQb57UmZIFan-NvV8MtE0ohsAyT-WiaXwHI,12125
42
+ universal_mcp-0.1.20rc1.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
43
+ universal_mcp-0.1.20rc1.dist-info/entry_points.txt,sha256=QlBrVKmA2jIM0q-C-3TQMNJTTWOsOFQvgedBq2rZTS8,56
44
+ universal_mcp-0.1.20rc1.dist-info/licenses/LICENSE,sha256=NweDZVPslBAZFzlgByF158b85GR0f5_tLQgq1NS48To,1063
45
+ universal_mcp-0.1.20rc1.dist-info/RECORD,,