Tencent/WeKnora · error

stdio transport is disabled for security reasons; please use

Error message

stdio transport is disabled for security reasons; please use SSE or HTTP Streamable transport instead

What it means

GetOrCreateClient hard-blocks stdio transport for security reasons: launching local subprocesses from the server is disallowed, so MCPTransportStdio returns this error. Users must switch the service to SSE or HTTP Streamable transport.

Source

Thrown at internal/mcp/manager.go:66

	}
	return service.ID
}

// GetOrCreateClient gets an existing client or creates a new one
// Caches and reuses existing connections for SSE/HTTP Streamable
// Note: Stdio transport is disabled for security reasons
//
// For OAuth-enabled services the connection is keyed per principal (derived from
// ctx) so each identity connects with its own token.
func (m *MCPManager) GetOrCreateClient(ctx context.Context, service *types.MCPService) (MCPClient, error) {
	// Check if service is enabled
	if !service.Enabled {
		return nil, fmt.Errorf("MCP service %s is not enabled", service.Name)
	}

	// Stdio transport is disabled for security reasons
	if service.TransportType == types.MCPTransportStdio {
		return nil, fmt.Errorf("stdio transport is disabled for security reasons; please use SSE or HTTP Streamable transport instead")
	}

	var tenantID uint64
	var principal types.Principal
	if service.AuthConfig.IsOAuth() {
		tenantID, _ = types.TenantIDFromContext(ctx)
		principal, _ = types.PrincipalFromContext(ctx)
		principal = types.MCPOAuthPrincipalFromContext(ctx)
		if !principal.Valid() {
			return nil, fmt.Errorf("principal context is required to connect to OAuth MCP service %s", service.Name)
		}
	}
	key := cacheKey(service, principal)

	// For SSE/HTTP Streamable, check if client already exists and reuse
	m.clientsMu.RLock()
	client, exists := m.clients[key]
	m.clientsMu.RUnlock()

View on GitHub (pinned to 988cbb0330)

Solutions

  1. Change the service's TransportType to MCPTransportSSE or MCPTransportHTTP (streamable) and set the appropriate URL
  2. Run the stdio MCP server as a separate networked process (e.g. wrap it with a supergateway/proxy exposing SSE) and point the service at that URL
  3. Remove stdio services from the configuration since they will never be connectable

Example fix

// before
svc := &types.MCPService{Name: "fs", TransportType: types.MCPTransportStdio}
// after
svc := &types.MCPService{Name: "fs", TransportType: types.MCPTransportSSE, URL: "http://127.0.0.1:8080/sse"}
Defensive patterns

Strategy: validation

Validate before calling

if svc.TransportType == types.MCPTransportStdio {
    return errors.New("stdio MCP services are unsupported; use SSE or HTTP streamable")
}

Type guard

func supportsRemoteTransport(svc *types.MCPService) bool {
    return svc.TransportType == types.MCPTransportSSE || svc.TransportType == types.MCPTransportHTTP
}

Try / catch

client, err := manager.GetOrCreateClient(ctx, svc)
if err != nil && strings.Contains(err.Error(), "stdio transport is disabled") {
    return fmt.Errorf("reconfigure %q to SSE/HTTP transport", svc.Name)
}

Prevention

When it happens

Trigger: Creating/registering an MCPService with TransportType == types.MCPTransportStdio and calling GetOrCreateClient (directly or via GetMCPToolsInfo/GetMCPServiceTools/GetMCPServiceResources).

Common situations: Importing a config that was written for a local stdio-based MCP setup (e.g. claude-desktop style configs with command+args) into this server; migrating from a local dev setup to the hosted server.

Related errors


AI-assisted analysis of Tencent/WeKnora@988cbb0330 (2026-09-02). Data as JSON: /api/errors/8fb6caf34b5607f4. Report an issue: GitHub.