langgenius / langgenius/dify

[Bug] MCP provider detail endpoint returns 500 "invalid input syntax for type uuid" — server_identifier passed where a provider UUID is expected

Open
#41,512 1 comment 1 reaction 0 assignees View on GitHub
1.17.0
Dominant language
TypeScript
Stars
156k
Forks
24.6k
Avg merge
22h 9m
Merged PRs (30d)
610

Description

### Self Checks

- [x] I have read the [Contributing Guide](https://github.com/langgenius/dify/blob/main/CONTRIBUTING.md) and [Language Policy](https://github.com/langgenius/dify/issues/1542).
- [x] This is only for bug report, if you would like to ask a question, please head to [Discussions](https://github.com/langgenius/dify/discussions/categories/general).
- [x] I have searched for existing issues [search for existing issues](https://github.com/langgenius/dify/issues), including closed ones.
- [x] I confirm that I am using English to submit this report, otherwise it will be closed.
- [x] 【中文用户 & Non English User】请使用英语提交,否则会被关闭 :)
- [x] Please do not modify this template :) and fill in all the required fields.

### Dify version

1.17.0

### Cloud or Self Hosted

Self Hosted (Kubernetes)

### Steps to reproduce

1. Register an MCP tool provider (Tools → MCP → add a streamable-http server). In `tool_mcp_providers` the row gets a UUID `id` plus a human-readable `server_identifier` (e.g. `my-mcp-tools`).
2. Open the provider's detail page in the console (the view that lists its tools). The front-end calls:
```
GET /console/api/workspaces/current/tool-provider/mcp/tools/my-mcp-tools
```
i.e. the **server_identifier** is passed in the path (`web/service/use-tools.ts` → `useMCPTools(providerID)`).
3. The API returns HTTP 500.

Root cause chain (verified against the `1.17.0` tag and today's `main`):

- `api/controllers/console/workspace/tool_providers.py:1589` (`ToolMCPDetailApi.get`) calls `service.get_provider(provider_id=provider_id, tenant_id=...)` — the path segment is treated as the UUID `id`; `server_identifier` is never passed.
- `api/services/tools/mcp_tools_manage_service.py::get_provider` therefore builds `WHERE tool_mcp_providers.id = 'my-mcp-tools'::UUID`, and PostgreSQL rejects it.
- The identifier confusion originates in `api/services/tools/tools_transform_service.py:277`:
```python
response["id"] = db_provider.server_identifier if not for_list else db_provider.id
```
so non-list responses (create/update) expose the **server_identifier** as the entity `id`, which the front-end then round-trips into subsequent detail calls.
- `get_provider_entity(by_server_id=...)` in the same service already implements the intended dual-form dispatch, but `ToolMCPDetailApi` misses it.
- Sibling routes follow the same pattern (`/tool-provider/mcp/update/` via `list_provider_tools`, `/tool-provider/mcp/auth`, provider delete): all pass the path segment as `provider_id=`, so they hit the same failure once a non-UUID identifier is round-tripped.

### ✔️ Expected Behavior

`GET /console/api/workspaces/current/tool-provider/mcp/tools/{server_identifier}` returns the provider entity with its tools (as it does when a UUID `id` happens to be passed).

### ❌ Actual Behavior

HTTP 500 with:

```
psycopg2.errors.InvalidTextRepresentation: invalid input syntax for type uuid: "my-mcp-tools"

[SQL: SELECT ... FROM tool_mcp_providers
WHERE tool_mcp_providers.tenant_id = %(tenant_id_1)s::UUID AND tool_mcp_providers.id = %(id_1)s::UUID]

File "/app/api/services/tools/mcp_tools_manage_service.py", line 112, in get_provider
```

Suggested fix: dual-form dispatch in `get_provider` — when `provider_id` is not a valid UUID, fall back to the `server_identifier` branch (a single change covers detail/update/auth/delete), or apply `by_server_id=True` semantics at `ToolMCPDetailApi`.

Contributor guide

Open the contributing guide

Research direction

Start with api/controllers/console/workspace/tool_providers.py, api/services/tools/mcp_tools_manage_service.py, and api/services/tools/tools_transform_service.py; trace ToolMCPDetailApi.get, get_provider, get_provider_entity, and the frontend useMCPTools(providerID) call. Reproduce the detail request with a server_identifier, then verify that detail, update, auth, and delete routes resolve it without a UUID error and preserve UUID behavior.

Written by the indexing model from the issue text.

Assessment

Tech stack
postgresql, python, typescript
Domain
api, backend, databases
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Active
Clarity
Clearly specified
Newbie friendliness
72/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.