unique-sdk 2026.44.0.dev1__tar.gz → 2026.44.0.dev3__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.
- {unique_sdk-2026.44.0.dev1 → unique_sdk-2026.44.0.dev3}/PKG-INFO +1 -1
- {unique_sdk-2026.44.0.dev1 → unique_sdk-2026.44.0.dev3}/pyproject.toml +1 -1
- {unique_sdk-2026.44.0.dev1 → unique_sdk-2026.44.0.dev3}/unique_sdk/api_resources/_mcp.py +77 -0
- {unique_sdk-2026.44.0.dev1 → unique_sdk-2026.44.0.dev3}/unique_sdk/api_resources/_space.py +89 -1
- {unique_sdk-2026.44.0.dev1 → unique_sdk-2026.44.0.dev3}/unique_sdk/cli/cli.py +6 -2
- {unique_sdk-2026.44.0.dev1 → unique_sdk-2026.44.0.dev3}/unique_sdk/cli/commands/mcp.py +76 -7
- {unique_sdk-2026.44.0.dev1 → unique_sdk-2026.44.0.dev3}/README.md +0 -0
- {unique_sdk-2026.44.0.dev1 → unique_sdk-2026.44.0.dev3}/unique_sdk/__init__.py +0 -0
- {unique_sdk-2026.44.0.dev1 → unique_sdk-2026.44.0.dev3}/unique_sdk/_api_requestor.py +0 -0
- {unique_sdk-2026.44.0.dev1 → unique_sdk-2026.44.0.dev3}/unique_sdk/_api_resource.py +0 -0
- {unique_sdk-2026.44.0.dev1 → unique_sdk-2026.44.0.dev3}/unique_sdk/_api_version.py +0 -0
- {unique_sdk-2026.44.0.dev1 → unique_sdk-2026.44.0.dev3}/unique_sdk/_error.py +0 -0
- {unique_sdk-2026.44.0.dev1 → unique_sdk-2026.44.0.dev3}/unique_sdk/_http_client.py +0 -0
- {unique_sdk-2026.44.0.dev1 → unique_sdk-2026.44.0.dev3}/unique_sdk/_list_object.py +0 -0
- {unique_sdk-2026.44.0.dev1 → unique_sdk-2026.44.0.dev3}/unique_sdk/_object_classes.py +0 -0
- {unique_sdk-2026.44.0.dev1 → unique_sdk-2026.44.0.dev3}/unique_sdk/_request_options.py +0 -0
- {unique_sdk-2026.44.0.dev1 → unique_sdk-2026.44.0.dev3}/unique_sdk/_unique_object.py +0 -0
- {unique_sdk-2026.44.0.dev1 → unique_sdk-2026.44.0.dev3}/unique_sdk/_unique_ql.py +0 -0
- {unique_sdk-2026.44.0.dev1 → unique_sdk-2026.44.0.dev3}/unique_sdk/_unique_response.py +0 -0
- {unique_sdk-2026.44.0.dev1 → unique_sdk-2026.44.0.dev3}/unique_sdk/_util.py +0 -0
- {unique_sdk-2026.44.0.dev1 → unique_sdk-2026.44.0.dev3}/unique_sdk/_version.py +0 -0
- {unique_sdk-2026.44.0.dev1 → unique_sdk-2026.44.0.dev3}/unique_sdk/_webhook.py +0 -0
- {unique_sdk-2026.44.0.dev1 → unique_sdk-2026.44.0.dev3}/unique_sdk/api_resources/__init__.py +0 -0
- {unique_sdk-2026.44.0.dev1 → unique_sdk-2026.44.0.dev3}/unique_sdk/api_resources/_acronyms.py +0 -0
- {unique_sdk-2026.44.0.dev1 → unique_sdk-2026.44.0.dev3}/unique_sdk/api_resources/_agentic_table.py +0 -0
- {unique_sdk-2026.44.0.dev1 → unique_sdk-2026.44.0.dev3}/unique_sdk/api_resources/_analytics_order.py +0 -0
- {unique_sdk-2026.44.0.dev1 → unique_sdk-2026.44.0.dev3}/unique_sdk/api_resources/_benchmarking.py +0 -0
- {unique_sdk-2026.44.0.dev1 → unique_sdk-2026.44.0.dev3}/unique_sdk/api_resources/_briefing.py +0 -0
- {unique_sdk-2026.44.0.dev1 → unique_sdk-2026.44.0.dev3}/unique_sdk/api_resources/_chat_completion.py +0 -0
- {unique_sdk-2026.44.0.dev1 → unique_sdk-2026.44.0.dev3}/unique_sdk/api_resources/_content.py +0 -0
- {unique_sdk-2026.44.0.dev1 → unique_sdk-2026.44.0.dev3}/unique_sdk/api_resources/_context_memory.py +0 -0
- {unique_sdk-2026.44.0.dev1 → unique_sdk-2026.44.0.dev3}/unique_sdk/api_resources/_elicitation.py +0 -0
- {unique_sdk-2026.44.0.dev1 → unique_sdk-2026.44.0.dev3}/unique_sdk/api_resources/_embedding.py +0 -0
- {unique_sdk-2026.44.0.dev1 → unique_sdk-2026.44.0.dev3}/unique_sdk/api_resources/_event.py +0 -0
- {unique_sdk-2026.44.0.dev1 → unique_sdk-2026.44.0.dev3}/unique_sdk/api_resources/_folder.py +0 -0
- {unique_sdk-2026.44.0.dev1 → unique_sdk-2026.44.0.dev3}/unique_sdk/api_resources/_group.py +0 -0
- {unique_sdk-2026.44.0.dev1 → unique_sdk-2026.44.0.dev3}/unique_sdk/api_resources/_integrated.py +0 -0
- {unique_sdk-2026.44.0.dev1 → unique_sdk-2026.44.0.dev3}/unique_sdk/api_resources/_llm_models.py +0 -0
- {unique_sdk-2026.44.0.dev1 → unique_sdk-2026.44.0.dev3}/unique_sdk/api_resources/_message.py +0 -0
- {unique_sdk-2026.44.0.dev1 → unique_sdk-2026.44.0.dev3}/unique_sdk/api_resources/_message_assessment.py +0 -0
- {unique_sdk-2026.44.0.dev1 → unique_sdk-2026.44.0.dev3}/unique_sdk/api_resources/_message_execution.py +0 -0
- {unique_sdk-2026.44.0.dev1 → unique_sdk-2026.44.0.dev3}/unique_sdk/api_resources/_message_log.py +0 -0
- {unique_sdk-2026.44.0.dev1 → unique_sdk-2026.44.0.dev3}/unique_sdk/api_resources/_message_tool.py +0 -0
- {unique_sdk-2026.44.0.dev1 → unique_sdk-2026.44.0.dev3}/unique_sdk/api_resources/_module.py +0 -0
- {unique_sdk-2026.44.0.dev1 → unique_sdk-2026.44.0.dev3}/unique_sdk/api_resources/_scheduled_task.py +0 -0
- {unique_sdk-2026.44.0.dev1 → unique_sdk-2026.44.0.dev3}/unique_sdk/api_resources/_search.py +0 -0
- {unique_sdk-2026.44.0.dev1 → unique_sdk-2026.44.0.dev3}/unique_sdk/api_resources/_search_string.py +0 -0
- {unique_sdk-2026.44.0.dev1 → unique_sdk-2026.44.0.dev3}/unique_sdk/api_resources/_short_term_memory.py +0 -0
- {unique_sdk-2026.44.0.dev1 → unique_sdk-2026.44.0.dev3}/unique_sdk/api_resources/_user.py +0 -0
- {unique_sdk-2026.44.0.dev1 → unique_sdk-2026.44.0.dev3}/unique_sdk/api_resources/_web_search.py +0 -0
- {unique_sdk-2026.44.0.dev1 → unique_sdk-2026.44.0.dev3}/unique_sdk/cli/__init__.py +0 -0
- {unique_sdk-2026.44.0.dev1 → unique_sdk-2026.44.0.dev3}/unique_sdk/cli/__main__.py +0 -0
- {unique_sdk-2026.44.0.dev1 → unique_sdk-2026.44.0.dev3}/unique_sdk/cli/commands/__init__.py +0 -0
- {unique_sdk-2026.44.0.dev1 → unique_sdk-2026.44.0.dev3}/unique_sdk/cli/commands/_citation_manifest.py +0 -0
- {unique_sdk-2026.44.0.dev1 → unique_sdk-2026.44.0.dev3}/unique_sdk/cli/commands/agentic_table.py +0 -0
- {unique_sdk-2026.44.0.dev1 → unique_sdk-2026.44.0.dev3}/unique_sdk/cli/commands/agentic_table_write.py +0 -0
- {unique_sdk-2026.44.0.dev1 → unique_sdk-2026.44.0.dev3}/unique_sdk/cli/commands/browser.py +0 -0
- {unique_sdk-2026.44.0.dev1 → unique_sdk-2026.44.0.dev3}/unique_sdk/cli/commands/cite_file.py +0 -0
- {unique_sdk-2026.44.0.dev1 → unique_sdk-2026.44.0.dev3}/unique_sdk/cli/commands/elicitation.py +0 -0
- {unique_sdk-2026.44.0.dev1 → unique_sdk-2026.44.0.dev3}/unique_sdk/cli/commands/files.py +0 -0
- {unique_sdk-2026.44.0.dev1 → unique_sdk-2026.44.0.dev3}/unique_sdk/cli/commands/folders.py +0 -0
- {unique_sdk-2026.44.0.dev1 → unique_sdk-2026.44.0.dev3}/unique_sdk/cli/commands/navigation.py +0 -0
- {unique_sdk-2026.44.0.dev1 → unique_sdk-2026.44.0.dev3}/unique_sdk/cli/commands/read.py +0 -0
- {unique_sdk-2026.44.0.dev1 → unique_sdk-2026.44.0.dev3}/unique_sdk/cli/commands/scheduled_tasks.py +0 -0
- {unique_sdk-2026.44.0.dev1 → unique_sdk-2026.44.0.dev3}/unique_sdk/cli/commands/search.py +0 -0
- {unique_sdk-2026.44.0.dev1 → unique_sdk-2026.44.0.dev3}/unique_sdk/cli/commands/subagent.py +0 -0
- {unique_sdk-2026.44.0.dev1 → unique_sdk-2026.44.0.dev3}/unique_sdk/cli/commands/web_search.py +0 -0
- {unique_sdk-2026.44.0.dev1 → unique_sdk-2026.44.0.dev3}/unique_sdk/cli/commands/web_search_config.py +0 -0
- {unique_sdk-2026.44.0.dev1 → unique_sdk-2026.44.0.dev3}/unique_sdk/cli/config.py +0 -0
- {unique_sdk-2026.44.0.dev1 → unique_sdk-2026.44.0.dev3}/unique_sdk/cli/formatting.py +0 -0
- {unique_sdk-2026.44.0.dev1 → unique_sdk-2026.44.0.dev3}/unique_sdk/cli/identity.py +0 -0
- {unique_sdk-2026.44.0.dev1 → unique_sdk-2026.44.0.dev3}/unique_sdk/cli/metadata_filter.py +0 -0
- {unique_sdk-2026.44.0.dev1 → unique_sdk-2026.44.0.dev3}/unique_sdk/cli/shell.py +0 -0
- {unique_sdk-2026.44.0.dev1 → unique_sdk-2026.44.0.dev3}/unique_sdk/cli/skills/unique-cli-agentic-table/SKILL.md +0 -0
- {unique_sdk-2026.44.0.dev1 → unique_sdk-2026.44.0.dev3}/unique_sdk/cli/skills/unique-cli-elicitation/SKILL.md +0 -0
- {unique_sdk-2026.44.0.dev1 → unique_sdk-2026.44.0.dev3}/unique_sdk/cli/skills/unique-cli-file-management/SKILL.md +0 -0
- {unique_sdk-2026.44.0.dev1 → unique_sdk-2026.44.0.dev3}/unique_sdk/cli/skills/unique-cli-mcp/SKILL.md +0 -0
- {unique_sdk-2026.44.0.dev1 → unique_sdk-2026.44.0.dev3}/unique_sdk/cli/skills/unique-cli-scheduled-tasks/SKILL.md +0 -0
- {unique_sdk-2026.44.0.dev1 → unique_sdk-2026.44.0.dev3}/unique_sdk/cli/skills/unique-cli-search/SKILL.md +0 -0
- {unique_sdk-2026.44.0.dev1 → unique_sdk-2026.44.0.dev3}/unique_sdk/cli/skills/unique-cli-subagent/SKILL.md +0 -0
- {unique_sdk-2026.44.0.dev1 → unique_sdk-2026.44.0.dev3}/unique_sdk/cli/skills/unique-cli-uploaded-search/SKILL.md +0 -0
- {unique_sdk-2026.44.0.dev1 → unique_sdk-2026.44.0.dev3}/unique_sdk/cli/skills/unique-cli-web-search/SKILL.md +0 -0
- {unique_sdk-2026.44.0.dev1 → unique_sdk-2026.44.0.dev3}/unique_sdk/cli/state.py +0 -0
- {unique_sdk-2026.44.0.dev1 → unique_sdk-2026.44.0.dev3}/unique_sdk/cli/workspace.py +0 -0
- {unique_sdk-2026.44.0.dev1 → unique_sdk-2026.44.0.dev3}/unique_sdk/utils/analytics_order_run.py +0 -0
- {unique_sdk-2026.44.0.dev1 → unique_sdk-2026.44.0.dev3}/unique_sdk/utils/benchmarking_run.py +0 -0
- {unique_sdk-2026.44.0.dev1 → unique_sdk-2026.44.0.dev3}/unique_sdk/utils/chat_history.py +0 -0
- {unique_sdk-2026.44.0.dev1 → unique_sdk-2026.44.0.dev3}/unique_sdk/utils/chat_in_space.py +0 -0
- {unique_sdk-2026.44.0.dev1 → unique_sdk-2026.44.0.dev3}/unique_sdk/utils/file_io.py +0 -0
- {unique_sdk-2026.44.0.dev1 → unique_sdk-2026.44.0.dev3}/unique_sdk/utils/sources.py +0 -0
- {unique_sdk-2026.44.0.dev1 → unique_sdk-2026.44.0.dev3}/unique_sdk/utils/token.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.3
|
|
2
2
|
Name: unique-sdk
|
|
3
|
-
Version: 2026.44.0.
|
|
3
|
+
Version: 2026.44.0.dev3
|
|
4
4
|
Summary:
|
|
5
5
|
Author: Martin Fadler, Konstantin Krauss, Andreas Hauri
|
|
6
6
|
Author-email: Martin Fadler <martin.fadler@unique.ch>, Konstantin Krauss <konstantin@unique.ch>, Andreas Hauri <andreas@unique.ch>
|
|
@@ -46,6 +46,29 @@ class CallToolContentDto(TypedDict):
|
|
|
46
46
|
] # For type: "resource"
|
|
47
47
|
|
|
48
48
|
|
|
49
|
+
class McpServerToolDto(TypedDict):
|
|
50
|
+
"""A tool of an MCP server that the company has enabled."""
|
|
51
|
+
|
|
52
|
+
name: str
|
|
53
|
+
description: str | None
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
class McpServerDto(TypedDict):
|
|
57
|
+
"""An MCP server (connector) of the company that can be attached to a space."""
|
|
58
|
+
|
|
59
|
+
id: str
|
|
60
|
+
name: str
|
|
61
|
+
description: str | None
|
|
62
|
+
requiresOAuth: bool
|
|
63
|
+
isSpaceRestricted: bool
|
|
64
|
+
allowedSpaceIds: list[str]
|
|
65
|
+
tools: list[McpServerToolDto]
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
class McpServersResponse(TypedDict):
|
|
69
|
+
mcpServers: list[McpServerDto]
|
|
70
|
+
|
|
71
|
+
|
|
49
72
|
class MCP(APIResource["MCP"]):
|
|
50
73
|
@classproperty
|
|
51
74
|
def OBJECT_NAME(cls) -> Literal["mcp.call_tool"]:
|
|
@@ -128,3 +151,57 @@ class MCP(APIResource["MCP"]):
|
|
|
128
151
|
params=params,
|
|
129
152
|
),
|
|
130
153
|
)
|
|
154
|
+
|
|
155
|
+
@classmethod
|
|
156
|
+
def list_servers(
|
|
157
|
+
cls,
|
|
158
|
+
user_id: str,
|
|
159
|
+
company_id: str,
|
|
160
|
+
) -> McpServersResponse:
|
|
161
|
+
"""
|
|
162
|
+
List the company's MCP servers that can be attached to a space, with their
|
|
163
|
+
tools. Never returns server URLs or credentials.
|
|
164
|
+
|
|
165
|
+
Args:
|
|
166
|
+
user_id: The ID of the user making the request
|
|
167
|
+
company_id: The ID of the company
|
|
168
|
+
|
|
169
|
+
Returns:
|
|
170
|
+
McpServersResponse: The servers, sorted by name
|
|
171
|
+
"""
|
|
172
|
+
return cast(
|
|
173
|
+
McpServersResponse,
|
|
174
|
+
cls._static_request(
|
|
175
|
+
"get",
|
|
176
|
+
"/mcp/servers",
|
|
177
|
+
user_id,
|
|
178
|
+
company_id,
|
|
179
|
+
),
|
|
180
|
+
)
|
|
181
|
+
|
|
182
|
+
@classmethod
|
|
183
|
+
async def list_servers_async(
|
|
184
|
+
cls,
|
|
185
|
+
user_id: str,
|
|
186
|
+
company_id: str,
|
|
187
|
+
) -> McpServersResponse:
|
|
188
|
+
"""
|
|
189
|
+
Asynchronously list the company's MCP servers that can be attached to a space,
|
|
190
|
+
with their tools. Never returns server URLs or credentials.
|
|
191
|
+
|
|
192
|
+
Args:
|
|
193
|
+
user_id: The ID of the user making the request
|
|
194
|
+
company_id: The ID of the company
|
|
195
|
+
|
|
196
|
+
Returns:
|
|
197
|
+
McpServersResponse: The servers, sorted by name
|
|
198
|
+
"""
|
|
199
|
+
return cast(
|
|
200
|
+
McpServersResponse,
|
|
201
|
+
await cls._static_request_async(
|
|
202
|
+
"get",
|
|
203
|
+
"/mcp/servers",
|
|
204
|
+
user_id,
|
|
205
|
+
company_id,
|
|
206
|
+
),
|
|
207
|
+
)
|
|
@@ -19,7 +19,11 @@ class Space(APIResource["Space"]):
|
|
|
19
19
|
return "space"
|
|
20
20
|
|
|
21
21
|
UiType: TypeAlias = Literal[
|
|
22
|
-
"MAGIC_TABLE",
|
|
22
|
+
"MAGIC_TABLE",
|
|
23
|
+
"UNIQUE_CUSTOM",
|
|
24
|
+
"TRANSLATION",
|
|
25
|
+
"UNIQUE_AI",
|
|
26
|
+
"SWAPPABLE_INTELLIGENCE",
|
|
23
27
|
]
|
|
24
28
|
|
|
25
29
|
class ModuleParams(TypedDict):
|
|
@@ -57,6 +61,24 @@ class Space(APIResource["Space"]):
|
|
|
57
61
|
isExclusive: bool
|
|
58
62
|
configuration: dict[str, Any]
|
|
59
63
|
|
|
64
|
+
class McpServerToolParams(TypedDict):
|
|
65
|
+
name: str
|
|
66
|
+
isEnabled: bool
|
|
67
|
+
|
|
68
|
+
class McpServerParams(TypedDict):
|
|
69
|
+
"""
|
|
70
|
+
An MCP server (connector) to attach to a space.
|
|
71
|
+
|
|
72
|
+
Only listed servers change. ``tools`` is the complete selection for the server:
|
|
73
|
+
listed tools take ``isEnabled``, unlisted tools are disabled, and an empty list
|
|
74
|
+
disables the server for the space. Omit ``tools`` to enable every callable tool.
|
|
75
|
+
Applied after MCP tool entries in module configurations, so it wins for a server
|
|
76
|
+
that appears in both. Use ``MCP.list_servers`` for the ids and tool names.
|
|
77
|
+
"""
|
|
78
|
+
|
|
79
|
+
mcpServerId: str
|
|
80
|
+
tools: NotRequired[list["Space.McpServerToolParams"] | None]
|
|
81
|
+
|
|
60
82
|
class CreateSpaceParams(RequestOptions):
|
|
61
83
|
name: str
|
|
62
84
|
fallbackModule: str
|
|
@@ -77,6 +99,7 @@ class Space(APIResource["Space"]):
|
|
|
77
99
|
isSubAgent: NotRequired[bool | None]
|
|
78
100
|
subAgentSettings: NotRequired["Space.SubAgentSettings | None"]
|
|
79
101
|
subAgentIds: NotRequired[list[str] | None]
|
|
102
|
+
mcpServers: NotRequired[list["Space.McpServerParams"] | None]
|
|
80
103
|
|
|
81
104
|
class UpdateParams(RequestOptions):
|
|
82
105
|
name: NotRequired[str | None]
|
|
@@ -98,6 +121,7 @@ class Space(APIResource["Space"]):
|
|
|
98
121
|
isSubAgent: NotRequired[bool | None]
|
|
99
122
|
subAgentSettings: NotRequired["Space.SubAgentSettings | None"]
|
|
100
123
|
subAgentIds: NotRequired[list[str] | None]
|
|
124
|
+
mcpServers: NotRequired[list["Space.McpServerParams"] | None]
|
|
101
125
|
|
|
102
126
|
class AccessEntry(TypedDict):
|
|
103
127
|
entityId: str
|
|
@@ -261,6 +285,10 @@ class Space(APIResource["Space"]):
|
|
|
261
285
|
messages: list["Space.Message"]
|
|
262
286
|
totalCount: int
|
|
263
287
|
|
|
288
|
+
class McpServerTool(TypedDict):
|
|
289
|
+
name: str
|
|
290
|
+
isEnabled: bool
|
|
291
|
+
|
|
264
292
|
class McpServer(TypedDict):
|
|
265
293
|
"""
|
|
266
294
|
Represents an MCP server associated with a space.
|
|
@@ -271,9 +299,27 @@ class Space(APIResource["Space"]):
|
|
|
271
299
|
assistantId: str
|
|
272
300
|
mcpServerId: str
|
|
273
301
|
isEnabled: bool
|
|
302
|
+
tools: NotRequired[list["Space.McpServerTool"]]
|
|
274
303
|
createdAt: str
|
|
275
304
|
updatedAt: str
|
|
276
305
|
|
|
306
|
+
class McpServerStatus(TypedDict):
|
|
307
|
+
"""
|
|
308
|
+
The calling user's own state for an MCP server enabled on a space.
|
|
309
|
+
"""
|
|
310
|
+
|
|
311
|
+
mcpServerId: str
|
|
312
|
+
name: str
|
|
313
|
+
isEnabled: bool
|
|
314
|
+
requiresOAuth: bool
|
|
315
|
+
isOAuth2Connected: bool
|
|
316
|
+
oauth2Url: str | None
|
|
317
|
+
enabledToolNames: list[str]
|
|
318
|
+
|
|
319
|
+
class McpServerStatusResponse(TypedDict):
|
|
320
|
+
spaceId: str
|
|
321
|
+
mcpServers: list["Space.McpServerStatus"]
|
|
322
|
+
|
|
277
323
|
class Module(TypedDict):
|
|
278
324
|
"""
|
|
279
325
|
Represents a module configured for a space.
|
|
@@ -911,3 +957,45 @@ class Space(APIResource["Space"]):
|
|
|
911
957
|
params=params,
|
|
912
958
|
),
|
|
913
959
|
)
|
|
960
|
+
|
|
961
|
+
@classmethod
|
|
962
|
+
def get_mcp_server_status(
|
|
963
|
+
cls,
|
|
964
|
+
user_id: str,
|
|
965
|
+
company_id: str,
|
|
966
|
+
space_id: str,
|
|
967
|
+
) -> "Space.McpServerStatusResponse":
|
|
968
|
+
"""
|
|
969
|
+
Get the MCP servers enabled on a space with the calling user's own OAuth
|
|
970
|
+
connection state (``isOAuth2Connected``, ``oauth2Url``).
|
|
971
|
+
"""
|
|
972
|
+
return cast(
|
|
973
|
+
"Space.McpServerStatusResponse",
|
|
974
|
+
cls._static_request(
|
|
975
|
+
"get",
|
|
976
|
+
f"/space/{space_id}/mcp-servers/status",
|
|
977
|
+
user_id,
|
|
978
|
+
company_id,
|
|
979
|
+
),
|
|
980
|
+
)
|
|
981
|
+
|
|
982
|
+
@classmethod
|
|
983
|
+
async def get_mcp_server_status_async(
|
|
984
|
+
cls,
|
|
985
|
+
user_id: str,
|
|
986
|
+
company_id: str,
|
|
987
|
+
space_id: str,
|
|
988
|
+
) -> "Space.McpServerStatusResponse":
|
|
989
|
+
"""
|
|
990
|
+
Async get the MCP servers enabled on a space with the calling user's own OAuth
|
|
991
|
+
connection state (``isOAuth2Connected``, ``oauth2Url``).
|
|
992
|
+
"""
|
|
993
|
+
return cast(
|
|
994
|
+
"Space.McpServerStatusResponse",
|
|
995
|
+
await cls._static_request_async(
|
|
996
|
+
"get",
|
|
997
|
+
f"/space/{space_id}/mcp-servers/status",
|
|
998
|
+
user_id,
|
|
999
|
+
company_id,
|
|
1000
|
+
),
|
|
1001
|
+
)
|
|
@@ -63,6 +63,9 @@ from unique_sdk.cli.commands.folders import (
|
|
|
63
63
|
is_mkdir_error_output as _is_mkdir_error_output,
|
|
64
64
|
)
|
|
65
65
|
from unique_sdk.cli.commands.mcp import cmd_mcp
|
|
66
|
+
from unique_sdk.cli.commands.mcp import (
|
|
67
|
+
is_error_output as _is_mcp_error_output,
|
|
68
|
+
)
|
|
66
69
|
from unique_sdk.cli.commands.navigation import cmd_cd, cmd_ls, cmd_pwd
|
|
67
70
|
from unique_sdk.cli.commands.read import cmd_read
|
|
68
71
|
from unique_sdk.cli.commands.read import (
|
|
@@ -844,7 +847,7 @@ def mcp(
|
|
|
844
847
|
"""
|
|
845
848
|
resolved_message_id = _resolve_cli_message_id(ctx, message_id, required=True)
|
|
846
849
|
resolved_chat_id = _resolve_cli_chat_id(ctx, chat_id, required=True)
|
|
847
|
-
|
|
850
|
+
emit(
|
|
848
851
|
cmd_mcp(
|
|
849
852
|
LazyState.get(ctx),
|
|
850
853
|
chat_id=resolved_chat_id or "",
|
|
@@ -852,7 +855,8 @@ def mcp(
|
|
|
852
855
|
payload=payload,
|
|
853
856
|
file=file_path,
|
|
854
857
|
stdin=use_stdin,
|
|
855
|
-
)
|
|
858
|
+
),
|
|
859
|
+
is_error=_is_mcp_error_output,
|
|
856
860
|
)
|
|
857
861
|
|
|
858
862
|
|
|
@@ -26,6 +26,9 @@ from unique_sdk.cli.workspace import unique_dir as workspace_unique_dir
|
|
|
26
26
|
|
|
27
27
|
_LOGGER = logging.getLogger(__name__)
|
|
28
28
|
|
|
29
|
+
MCP_ERROR_PREFIX = "mcp:"
|
|
30
|
+
_FORMATTER_ERROR_PREFIX = "mcp: formatter error"
|
|
31
|
+
|
|
29
32
|
# Per-turn manifest of MCP tool output text, consumed by the Swappable
|
|
30
33
|
# Intelligence runner to ground the hallucination check against MCP-retrieved
|
|
31
34
|
# information (UN-21951). Carries *text only* — no source numbers/markers
|
|
@@ -1058,6 +1061,58 @@ def _parse_and_validate(raw: str) -> tuple[str, dict[str, Any]]:
|
|
|
1058
1061
|
return name, arguments
|
|
1059
1062
|
|
|
1060
1063
|
|
|
1064
|
+
class McpCommandResult(str):
|
|
1065
|
+
"""Text returned by ``cmd_mcp``, with whether that call failed.
|
|
1066
|
+
|
|
1067
|
+
Subclasses ``str`` so callers can print and search the text. ``failed``
|
|
1068
|
+
is set when the process should exit 1: a payload error, any
|
|
1069
|
+
``UniqueError``, or a tool result with ``isError`` set.
|
|
1070
|
+
"""
|
|
1071
|
+
|
|
1072
|
+
failed: bool
|
|
1073
|
+
|
|
1074
|
+
def __new__(cls, text: str, *, failed: bool) -> McpCommandResult:
|
|
1075
|
+
result = str.__new__(cls, text)
|
|
1076
|
+
result.failed = failed
|
|
1077
|
+
return result
|
|
1078
|
+
|
|
1079
|
+
|
|
1080
|
+
def _response_is_error(response: Any) -> bool:
|
|
1081
|
+
"""Return whether the tool result itself is marked ``isError``.
|
|
1082
|
+
|
|
1083
|
+
Args:
|
|
1084
|
+
response (Any): Raw MCP tool response.
|
|
1085
|
+
|
|
1086
|
+
Returns:
|
|
1087
|
+
bool: True when ``isError`` is set. False when it is absent, false,
|
|
1088
|
+
or unreadable, so a formatter failure on a successful result still
|
|
1089
|
+
exits 0.
|
|
1090
|
+
"""
|
|
1091
|
+
try:
|
|
1092
|
+
return bool(getattr(response, "isError", False))
|
|
1093
|
+
except Exception:
|
|
1094
|
+
return False
|
|
1095
|
+
|
|
1096
|
+
|
|
1097
|
+
def is_error_output(output: str) -> bool:
|
|
1098
|
+
"""Return whether an MCP command result should exit non-zero.
|
|
1099
|
+
|
|
1100
|
+
Args:
|
|
1101
|
+
output (str): Text returned by ``cmd_mcp``.
|
|
1102
|
+
|
|
1103
|
+
Returns:
|
|
1104
|
+
bool: True for payload errors, SDK errors, and ``isError`` tool
|
|
1105
|
+
results. False when the call succeeded, including when formatting
|
|
1106
|
+
that successful result failed and the fallback text was returned.
|
|
1107
|
+
"""
|
|
1108
|
+
failed = getattr(output, "failed", None)
|
|
1109
|
+
if isinstance(failed, bool):
|
|
1110
|
+
return failed
|
|
1111
|
+
if output.startswith(_FORMATTER_ERROR_PREFIX):
|
|
1112
|
+
return False
|
|
1113
|
+
return output.startswith(MCP_ERROR_PREFIX)
|
|
1114
|
+
|
|
1115
|
+
|
|
1061
1116
|
def cmd_mcp(
|
|
1062
1117
|
state: ShellState,
|
|
1063
1118
|
chat_id: str,
|
|
@@ -1065,8 +1120,21 @@ def cmd_mcp(
|
|
|
1065
1120
|
payload: str | None = None,
|
|
1066
1121
|
file: str | None = None,
|
|
1067
1122
|
stdin: bool = False,
|
|
1068
|
-
) ->
|
|
1069
|
-
"""Call an MCP tool with a JSON payload containing name and arguments.
|
|
1123
|
+
) -> McpCommandResult:
|
|
1124
|
+
"""Call an MCP tool with a JSON payload containing name and arguments.
|
|
1125
|
+
|
|
1126
|
+
Args:
|
|
1127
|
+
state (ShellState): CLI session holding the user and company ids.
|
|
1128
|
+
chat_id (str): Chat the tool call is attributed to.
|
|
1129
|
+
message_id (str): Message the tool call is attributed to.
|
|
1130
|
+
payload (str | None): Inline JSON payload.
|
|
1131
|
+
file (str | None): Path to a JSON payload file.
|
|
1132
|
+
stdin (bool): Read the JSON payload from stdin.
|
|
1133
|
+
|
|
1134
|
+
Returns:
|
|
1135
|
+
McpCommandResult: Formatted tool output, or an ``mcp:`` error line.
|
|
1136
|
+
``failed`` is true when the call itself failed.
|
|
1137
|
+
"""
|
|
1070
1138
|
try:
|
|
1071
1139
|
raw = _read_payload(payload, file, stdin)
|
|
1072
1140
|
name, arguments = _parse_and_validate(raw)
|
|
@@ -1080,8 +1148,8 @@ def cmd_mcp(
|
|
|
1080
1148
|
arguments=arguments,
|
|
1081
1149
|
)
|
|
1082
1150
|
|
|
1083
|
-
except (ValueError, OSError, unique_sdk.
|
|
1084
|
-
return f"
|
|
1151
|
+
except (ValueError, OSError, unique_sdk.UniqueError) as e:
|
|
1152
|
+
return McpCommandResult(f"{MCP_ERROR_PREFIX} {e}", failed=True)
|
|
1085
1153
|
|
|
1086
1154
|
try:
|
|
1087
1155
|
formatted = format_mcp_response(response, tool_name=name)
|
|
@@ -1090,7 +1158,8 @@ def cmd_mcp(
|
|
|
1090
1158
|
fallback = json.dumps(dict(response), indent=2, default=str)
|
|
1091
1159
|
except Exception:
|
|
1092
1160
|
fallback = repr(response)
|
|
1093
|
-
formatted = f"
|
|
1161
|
+
formatted = f"{_FORMATTER_ERROR_PREFIX} ({fmt_exc}); raw response:\n{fallback}"
|
|
1162
|
+
call_failed = _response_is_error(response)
|
|
1094
1163
|
|
|
1095
1164
|
server_name = _server_name_from_tool(name) or getattr(response, "mcpServerId", None)
|
|
1096
1165
|
sources_block = record_mcp_citations(
|
|
@@ -1104,5 +1173,5 @@ def cmd_mcp(
|
|
|
1104
1173
|
# Sources block FIRST: large outputs get spilled/truncated tail-first by
|
|
1105
1174
|
# the agent harness, and a trailing block is what partial reads miss.
|
|
1106
1175
|
if sources_block:
|
|
1107
|
-
|
|
1108
|
-
return formatted
|
|
1176
|
+
formatted = sources_block + "\n\n" + formatted
|
|
1177
|
+
return McpCommandResult(formatted, failed=call_failed)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{unique_sdk-2026.44.0.dev1 → unique_sdk-2026.44.0.dev3}/unique_sdk/api_resources/__init__.py
RENAMED
|
File without changes
|
{unique_sdk-2026.44.0.dev1 → unique_sdk-2026.44.0.dev3}/unique_sdk/api_resources/_acronyms.py
RENAMED
|
File without changes
|
{unique_sdk-2026.44.0.dev1 → unique_sdk-2026.44.0.dev3}/unique_sdk/api_resources/_agentic_table.py
RENAMED
|
File without changes
|
{unique_sdk-2026.44.0.dev1 → unique_sdk-2026.44.0.dev3}/unique_sdk/api_resources/_analytics_order.py
RENAMED
|
File without changes
|
{unique_sdk-2026.44.0.dev1 → unique_sdk-2026.44.0.dev3}/unique_sdk/api_resources/_benchmarking.py
RENAMED
|
File without changes
|
{unique_sdk-2026.44.0.dev1 → unique_sdk-2026.44.0.dev3}/unique_sdk/api_resources/_briefing.py
RENAMED
|
File without changes
|
{unique_sdk-2026.44.0.dev1 → unique_sdk-2026.44.0.dev3}/unique_sdk/api_resources/_chat_completion.py
RENAMED
|
File without changes
|
{unique_sdk-2026.44.0.dev1 → unique_sdk-2026.44.0.dev3}/unique_sdk/api_resources/_content.py
RENAMED
|
File without changes
|
{unique_sdk-2026.44.0.dev1 → unique_sdk-2026.44.0.dev3}/unique_sdk/api_resources/_context_memory.py
RENAMED
|
File without changes
|
{unique_sdk-2026.44.0.dev1 → unique_sdk-2026.44.0.dev3}/unique_sdk/api_resources/_elicitation.py
RENAMED
|
File without changes
|
{unique_sdk-2026.44.0.dev1 → unique_sdk-2026.44.0.dev3}/unique_sdk/api_resources/_embedding.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{unique_sdk-2026.44.0.dev1 → unique_sdk-2026.44.0.dev3}/unique_sdk/api_resources/_integrated.py
RENAMED
|
File without changes
|
{unique_sdk-2026.44.0.dev1 → unique_sdk-2026.44.0.dev3}/unique_sdk/api_resources/_llm_models.py
RENAMED
|
File without changes
|
{unique_sdk-2026.44.0.dev1 → unique_sdk-2026.44.0.dev3}/unique_sdk/api_resources/_message.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{unique_sdk-2026.44.0.dev1 → unique_sdk-2026.44.0.dev3}/unique_sdk/api_resources/_message_log.py
RENAMED
|
File without changes
|
{unique_sdk-2026.44.0.dev1 → unique_sdk-2026.44.0.dev3}/unique_sdk/api_resources/_message_tool.py
RENAMED
|
File without changes
|
|
File without changes
|
{unique_sdk-2026.44.0.dev1 → unique_sdk-2026.44.0.dev3}/unique_sdk/api_resources/_scheduled_task.py
RENAMED
|
File without changes
|
|
File without changes
|
{unique_sdk-2026.44.0.dev1 → unique_sdk-2026.44.0.dev3}/unique_sdk/api_resources/_search_string.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{unique_sdk-2026.44.0.dev1 → unique_sdk-2026.44.0.dev3}/unique_sdk/api_resources/_web_search.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{unique_sdk-2026.44.0.dev1 → unique_sdk-2026.44.0.dev3}/unique_sdk/cli/commands/agentic_table.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{unique_sdk-2026.44.0.dev1 → unique_sdk-2026.44.0.dev3}/unique_sdk/cli/commands/cite_file.py
RENAMED
|
File without changes
|
{unique_sdk-2026.44.0.dev1 → unique_sdk-2026.44.0.dev3}/unique_sdk/cli/commands/elicitation.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{unique_sdk-2026.44.0.dev1 → unique_sdk-2026.44.0.dev3}/unique_sdk/cli/commands/navigation.py
RENAMED
|
File without changes
|
|
File without changes
|
{unique_sdk-2026.44.0.dev1 → unique_sdk-2026.44.0.dev3}/unique_sdk/cli/commands/scheduled_tasks.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{unique_sdk-2026.44.0.dev1 → unique_sdk-2026.44.0.dev3}/unique_sdk/cli/commands/web_search.py
RENAMED
|
File without changes
|
{unique_sdk-2026.44.0.dev1 → unique_sdk-2026.44.0.dev3}/unique_sdk/cli/commands/web_search_config.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{unique_sdk-2026.44.0.dev1 → unique_sdk-2026.44.0.dev3}/unique_sdk/utils/analytics_order_run.py
RENAMED
|
File without changes
|
{unique_sdk-2026.44.0.dev1 → unique_sdk-2026.44.0.dev3}/unique_sdk/utils/benchmarking_run.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|