nocfo-cli 1.4.3__tar.gz → 1.4.4__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 (34) hide show
  1. {nocfo_cli-1.4.3 → nocfo_cli-1.4.4}/PKG-INFO +1 -1
  2. {nocfo_cli-1.4.3 → nocfo_cli-1.4.4}/pyproject.toml +1 -1
  3. {nocfo_cli-1.4.3 → nocfo_cli-1.4.4}/src/nocfo_toolkit/mcp/server.py +30 -2
  4. {nocfo_cli-1.4.3 → nocfo_cli-1.4.4}/LICENSE +0 -0
  5. {nocfo_cli-1.4.3 → nocfo_cli-1.4.4}/README.md +0 -0
  6. {nocfo_cli-1.4.3 → nocfo_cli-1.4.4}/src/nocfo_toolkit/__init__.py +0 -0
  7. {nocfo_cli-1.4.3 → nocfo_cli-1.4.4}/src/nocfo_toolkit/api_client.py +0 -0
  8. {nocfo_cli-1.4.3 → nocfo_cli-1.4.4}/src/nocfo_toolkit/cli/__init__.py +0 -0
  9. {nocfo_cli-1.4.3 → nocfo_cli-1.4.4}/src/nocfo_toolkit/cli/app.py +0 -0
  10. {nocfo_cli-1.4.3 → nocfo_cli-1.4.4}/src/nocfo_toolkit/cli/commands/__init__.py +0 -0
  11. {nocfo_cli-1.4.3 → nocfo_cli-1.4.4}/src/nocfo_toolkit/cli/commands/_helpers.py +0 -0
  12. {nocfo_cli-1.4.3 → nocfo_cli-1.4.4}/src/nocfo_toolkit/cli/commands/accounts.py +0 -0
  13. {nocfo_cli-1.4.3 → nocfo_cli-1.4.4}/src/nocfo_toolkit/cli/commands/auth.py +0 -0
  14. {nocfo_cli-1.4.3 → nocfo_cli-1.4.4}/src/nocfo_toolkit/cli/commands/businesses.py +0 -0
  15. {nocfo_cli-1.4.3 → nocfo_cli-1.4.4}/src/nocfo_toolkit/cli/commands/contacts.py +0 -0
  16. {nocfo_cli-1.4.3 → nocfo_cli-1.4.4}/src/nocfo_toolkit/cli/commands/documents.py +0 -0
  17. {nocfo_cli-1.4.3 → nocfo_cli-1.4.4}/src/nocfo_toolkit/cli/commands/files.py +0 -0
  18. {nocfo_cli-1.4.3 → nocfo_cli-1.4.4}/src/nocfo_toolkit/cli/commands/invoices.py +0 -0
  19. {nocfo_cli-1.4.3 → nocfo_cli-1.4.4}/src/nocfo_toolkit/cli/commands/products.py +0 -0
  20. {nocfo_cli-1.4.3 → nocfo_cli-1.4.4}/src/nocfo_toolkit/cli/commands/purchase_invoices.py +0 -0
  21. {nocfo_cli-1.4.3 → nocfo_cli-1.4.4}/src/nocfo_toolkit/cli/commands/reports.py +0 -0
  22. {nocfo_cli-1.4.3 → nocfo_cli-1.4.4}/src/nocfo_toolkit/cli/commands/schema.py +0 -0
  23. {nocfo_cli-1.4.3 → nocfo_cli-1.4.4}/src/nocfo_toolkit/cli/commands/tags.py +0 -0
  24. {nocfo_cli-1.4.3 → nocfo_cli-1.4.4}/src/nocfo_toolkit/cli/commands/user.py +0 -0
  25. {nocfo_cli-1.4.3 → nocfo_cli-1.4.4}/src/nocfo_toolkit/cli/context.py +0 -0
  26. {nocfo_cli-1.4.3 → nocfo_cli-1.4.4}/src/nocfo_toolkit/cli/output.py +0 -0
  27. {nocfo_cli-1.4.3 → nocfo_cli-1.4.4}/src/nocfo_toolkit/config.py +0 -0
  28. {nocfo_cli-1.4.3 → nocfo_cli-1.4.4}/src/nocfo_toolkit/mcp/__init__.py +0 -0
  29. {nocfo_cli-1.4.3 → nocfo_cli-1.4.4}/src/nocfo_toolkit/mcp/auth.py +0 -0
  30. {nocfo_cli-1.4.3 → nocfo_cli-1.4.4}/src/nocfo_toolkit/mcp/contract_validation.py +0 -0
  31. {nocfo_cli-1.4.3 → nocfo_cli-1.4.4}/src/nocfo_toolkit/mcp/error_handling.py +0 -0
  32. {nocfo_cli-1.4.3 → nocfo_cli-1.4.4}/src/nocfo_toolkit/mcp/http_error_capture.py +0 -0
  33. {nocfo_cli-1.4.3 → nocfo_cli-1.4.4}/src/nocfo_toolkit/mcp/middleware.py +0 -0
  34. {nocfo_cli-1.4.3 → nocfo_cli-1.4.4}/src/nocfo_toolkit/openapi.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: nocfo-cli
3
- Version: 1.4.3
3
+ Version: 1.4.4
4
4
  Summary: NoCFO CLI, MCP server, and Cursor skill toolkit.
5
5
  License: MIT
6
6
  License-File: LICENSE
@@ -4,7 +4,7 @@ build-backend = "poetry.core.masonry.api"
4
4
 
5
5
  [tool.poetry]
6
6
  name = "nocfo-cli"
7
- version = "1.4.3"
7
+ version = "1.4.4"
8
8
  description = "NoCFO CLI, MCP server, and Cursor skill toolkit."
9
9
  authors = ["NoCFO"]
10
10
  readme = "README.md"
@@ -125,6 +125,28 @@ def apply_mcp_operation_metadata(route: Any, component: Any) -> None:
125
125
  component.meta = meta
126
126
 
127
127
 
128
+ _VALIDATION_ONLY_KEYS = frozenset({"enum", "const"})
129
+
130
+
131
+ def _strip_validation_constraints(schema: Any) -> Any:
132
+ """Recursively strip strict validation constraints from a JSON schema.
133
+
134
+ Removes ``enum`` and ``const`` so that the MCP SDK's unconditional
135
+ ``jsonschema.validate()`` on ``outputSchema`` never rejects responses
136
+ containing values absent from the declared set (e.g. legacy DB values).
137
+ Structural information (types, properties, descriptions) is preserved.
138
+ """
139
+ if isinstance(schema, dict):
140
+ return {
141
+ key: _strip_validation_constraints(value)
142
+ for key, value in schema.items()
143
+ if key not in _VALIDATION_ONLY_KEYS
144
+ }
145
+ if isinstance(schema, list):
146
+ return [_strip_validation_constraints(item) for item in schema]
147
+ return schema
148
+
149
+
128
150
  def restore_openapi_output_schema(route: Any, component: Any) -> None:
129
151
  """Restore the real OpenAPI output schema on tools for agent-facing metadata.
130
152
 
@@ -132,7 +154,13 @@ def restore_openapi_output_schema(route: Any, component: Any) -> None:
132
154
  permissive fallback so that runtime responses are never rejected. This
133
155
  function re-derives the accurate schema from the route and writes it back
134
156
  onto the tool so that ``tools/list`` still exposes precise type information
135
- to the agent — without enforcing it at call time.
157
+ to the agent.
158
+
159
+ The MCP SDK (``mcp.server.lowlevel``) unconditionally validates
160
+ ``structured_content`` against ``outputSchema`` via ``jsonschema``.
161
+ To prevent validation failures on legacy or unexpected values the
162
+ restored schema has strict value constraints (``enum``, ``const``)
163
+ stripped while keeping full structural and type information.
136
164
  """
137
165
  if not isinstance(component, Tool):
138
166
  return
@@ -145,7 +173,7 @@ def restore_openapi_output_schema(route: Any, component: Any) -> None:
145
173
  getattr(route, "openapi_version", None),
146
174
  )
147
175
  if real_schema is not None:
148
- component.output_schema = real_schema
176
+ component.output_schema = _strip_validation_constraints(real_schema)
149
177
 
150
178
 
151
179
  def _get_server_instructions(openapi_spec: dict[str, Any]) -> str | None:
File without changes
File without changes